Joined with branch XORG-6_8_2.
[xf86-video-sis/mirage.git] / src / init301.c
blob1512fe31e1b434e12833b2520c0b1ee33a65caae
1 /* $XFree86$ */
2 /* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.13.2.1 2005/02/02 01:36:05 gisburn Exp $ */
3 /*
4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730 and
6 * SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760
7 * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x)
9 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
11 * If distributed as part of the Linux kernel, the following license terms
12 * apply:
14 * * This program is free software; you can redistribute it and/or modify
15 * * it under the terms of the GNU General Public License as published by
16 * * the Free Software Foundation; either version 2 of the named License,
17 * * or any later version.
18 * *
19 * * This program is distributed in the hope that it will be useful,
20 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * * GNU General Public License for more details.
23 * *
24 * * You should have received a copy of the GNU General Public License
25 * * along with this program; if not, write to the Free Software
26 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
28 * Otherwise, the following license terms apply:
30 * * Redistribution and use in source and binary forms, with or without
31 * * modification, are permitted provided that the following conditions
32 * * are met:
33 * * 1) Redistributions of source code must retain the above copyright
34 * * notice, this list of conditions and the following disclaimer.
35 * * 2) Redistributions in binary form must reproduce the above copyright
36 * * notice, this list of conditions and the following disclaimer in the
37 * * documentation and/or other materials provided with the distribution.
38 * * 3) The name of the author may not be used to endorse or promote products
39 * * derived from this software without specific prior written permission.
40 * *
41 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
42 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
44 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
45 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
50 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 * Author: Thomas Winischhofer <thomas@winischhofer.net>
54 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
55 * Used by permission.
57 * TW says: This code looks awful, I know. But please don't do anything about
58 * this otherwise debugging will be hell.
59 * The code is extremely fragile as regards the different chipsets, different
60 * video bridges and combinations thereof. If anything is changed, extreme
61 * care has to be taken that that change doesn't break it for other chipsets,
62 * bridges or combinations thereof.
63 * All comments in this file are by me, regardless if marked TW or not.
67 #if 1
68 #define SET_EMI /* 302LV/ELV: Set EMI values */
69 #endif
71 #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
72 #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
73 #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
75 #include "init301.h"
77 #ifdef SIS300
78 #include "oem300.h"
79 #endif
81 #ifdef SIS315H
82 #include "oem310.h"
83 #endif
85 #define SiS_I2CDELAY 1000
86 #define SiS_I2CDELAYSHORT 150
88 static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
90 /*********************************************/
91 /* HELPER: Lock/Unlock CRT2 */
92 /*********************************************/
94 void
95 SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
97 if(HwInfo->jChipType >= SIS_315H)
98 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
99 else
100 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
103 void
104 SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
106 if(HwInfo->jChipType >= SIS_315H)
107 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
108 else
109 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
112 /*********************************************/
113 /* HELPER: Write SR11 */
114 /*********************************************/
116 static void
117 SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
119 if(HwInfo->jChipType >= SIS_661) {
120 DataAND &= 0x0f;
121 DataOR &= 0x0f;
123 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
126 /*********************************************/
127 /* HELPER: Get Pointer to LCD structure */
128 /*********************************************/
130 #ifdef SIS315H
131 static UCHAR *
132 GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
134 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
135 UCHAR *myptr = NULL;
136 USHORT romindex = 0, reg = 0, idx = 0;
138 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
139 * due to the variaty of panels the BIOS doesn't know about.
140 * Exception: If the BIOS has better knowledge (such as in case
141 * of machines with a 301C and a panel that does not support DDC)
142 * use the BIOS data as well.
145 if((SiS_Pr->SiS_ROMNew) &&
146 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
148 if(HwInfo->jChipType < SIS_661) reg = 0x3c;
149 else reg = 0x7d;
151 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
153 if(idx < (8*26)) {
154 myptr = (UCHAR *)&SiS_LCDStruct661[idx];
156 romindex = SISGETROMW(0x100);
157 if(romindex) {
158 romindex += idx;
159 myptr = &ROMAddr[romindex];
162 return myptr;
165 static USHORT
166 GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
168 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
169 USHORT romptr = 0;
171 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
172 * due to the variaty of panels the BIOS doesn't know about.
173 * Exception: If the BIOS has better knowledge (such as in case
174 * of machines with a 301C and a panel that does not support DDC)
175 * use the BIOS data as well.
178 if((SiS_Pr->SiS_ROMNew) &&
179 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
180 romptr = SISGETROMW(0x102);
181 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
184 return(romptr);
186 #endif
188 /*********************************************/
189 /* Adjust Rate for CRT2 */
190 /*********************************************/
192 static BOOLEAN
193 SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
194 USHORT RRTI, USHORT *i, PSIS_HW_INFO HwInfo)
196 USHORT checkmask=0,modeid,infoflag;
198 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
200 if(SiS_Pr->SiS_VBType & VB_SISVB) {
202 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
204 checkmask |= SupportRAMDAC2;
205 if(HwInfo->jChipType >= SIS_315H) {
206 checkmask |= SupportRAMDAC2_135;
207 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
208 checkmask |= SupportRAMDAC2_162;
209 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
210 checkmask |= SupportRAMDAC2_202;
215 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
217 checkmask |= SupportLCD;
218 if(HwInfo->jChipType >= SIS_315H) {
219 if(SiS_Pr->SiS_VBType & VB_SISVB) {
220 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
221 if(modeid == 0x2e) checkmask |= Support64048060Hz;
226 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
228 checkmask |= SupportHiVision;
230 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
232 checkmask |= SupportTV;
233 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
234 checkmask |= SupportTV1024;
235 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
236 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
237 checkmask |= SupportYPbPr750p;
244 } else { /* LVDS */
246 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
247 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
248 checkmask |= SupportCHTV;
252 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
253 checkmask |= SupportLCD;
258 /* Look backwards in table for matching CRT2 mode */
259 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
260 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
261 if(infoflag & checkmask) return TRUE;
262 if((*i) == 0) break;
265 /* Look through the whole mode-section of the table from the beginning
266 * for a matching CRT2 mode if no mode was found yet.
268 for((*i) = 0; ; (*i)++) {
269 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
270 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
271 if(infoflag & checkmask) return TRUE;
273 return FALSE;
276 /*********************************************/
277 /* Get rate index */
278 /*********************************************/
280 USHORT
281 SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
282 PSIS_HW_INFO HwInfo)
284 SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
285 0x01, 0x01, 0x01, 0x01,
286 0x01, 0x01, 0x01, 0x01,
287 0x01, 0x01, 0x01, 0x01,
288 0x00, 0x00, 0x00, 0x00 };
289 USHORT RRTI,i,backup_i;
290 USHORT modeflag,index,temp,backupindex;
292 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
293 if(ModeNo == 0xfe) return 0;
295 if(ModeNo <= 0x13) {
296 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
297 } else {
298 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
301 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
302 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
303 if(modeflag & HalfDCLK) return 0;
307 if(ModeNo < 0x14) return 0xFFFF;
309 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
310 backupindex = index;
312 if(index > 0) index--;
314 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
315 if(SiS_Pr->SiS_VBType & VB_SISVB) {
316 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
317 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
318 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
320 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
321 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
322 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
323 if(index > temp) index = temp;
326 } else {
327 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
328 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
329 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
334 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
335 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
337 if(HwInfo->jChipType >= SIS_315H) {
338 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
339 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
340 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
341 if(backupindex <= 1) RRTI++;
346 i = 0;
347 do {
348 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
349 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
350 temp &= ModeTypeMask;
351 if(temp < SiS_Pr->SiS_ModeType) break;
352 i++;
353 index--;
354 } while(index != 0xFFFF);
356 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
357 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
358 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
359 if(temp & InterlaceMode) i++;
363 i--;
365 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
366 backup_i = i;
367 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i, HwInfo))) {
368 i = backup_i;
372 return(RRTI + i);
375 /*********************************************/
376 /* STORE CRT2 INFO in CR34 */
377 /*********************************************/
379 static void
380 SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
382 USHORT temp1,temp2;
384 /* Store CRT1 ModeNo in CR34 */
385 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
386 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
387 temp2 = ~(SetInSlaveMode >> 8);
388 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
391 /*********************************************/
392 /* HELPER: GET SOME DATA FROM BIOS ROM */
393 /*********************************************/
395 #ifdef SIS300
396 static BOOLEAN
397 SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
399 UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
400 USHORT temp,temp1;
402 if(SiS_Pr->SiS_UseROM) {
403 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
404 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
405 temp1 = SISGETROMW(0x23b);
406 if(temp1 & temp) return TRUE;
409 return FALSE;
412 static BOOLEAN
413 SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
415 UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
416 USHORT temp,temp1;
418 if(SiS_Pr->SiS_UseROM) {
419 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
420 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
421 temp1 = SISGETROMW(0x23d);
422 if(temp1 & temp) return TRUE;
425 return FALSE;
427 #endif
429 /*********************************************/
430 /* HELPER: DELAY FUNCTIONS */
431 /*********************************************/
433 void
434 SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
436 USHORT i, j;
438 for(i=0; i<delaytime; i++) {
439 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
443 #if defined(SIS300) || defined(SIS315H)
444 static void
445 SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
447 USHORT temp,flag;
449 flag = SiS_GetRegByte(0x61) & 0x10;
451 while(delay) {
452 temp = SiS_GetRegByte(0x61) & 0x10;
453 if(temp == flag) continue;
454 flag = temp;
455 delay--;
458 #endif
460 #ifdef SIS315H
461 static void
462 SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
464 while(delay--) {
465 SiS_GenericDelay(SiS_Pr,0x19df);
468 #endif
470 #if defined(SIS300) || defined(SIS315H)
471 static void
472 SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
474 while(delay--) {
475 SiS_GenericDelay(SiS_Pr,0x42);
478 #endif
480 static void
481 SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
483 #if defined(SIS300) || defined(SIS315H)
484 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
485 USHORT PanelID, DelayIndex, Delay=0;
486 #endif
488 if(HwInfo->jChipType < SIS_315H) {
490 #ifdef SIS300
492 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
493 if(SiS_Pr->SiS_VBType & VB_SISVB) {
494 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
496 DelayIndex = PanelID >> 4;
497 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
498 Delay = 3;
499 } else {
500 if(DelayTime >= 2) DelayTime -= 2;
501 if(!(DelayTime & 0x01)) {
502 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
503 } else {
504 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
506 if(SiS_Pr->SiS_UseROM) {
507 if(ROMAddr[0x220] & 0x40) {
508 if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
509 else Delay = (USHORT)ROMAddr[0x226];
513 SiS_ShortDelay(SiS_Pr, Delay);
515 #endif /* SIS300 */
517 } else {
519 #ifdef SIS315H
521 if((HwInfo->jChipType >= SIS_661) ||
522 (HwInfo->jChipType <= SIS_315PRO) ||
523 (HwInfo->jChipType == SIS_330) ||
524 (SiS_Pr->SiS_ROMNew)) {
526 if(!(DelayTime & 0x01)) {
527 SiS_DDC2Delay(SiS_Pr, 0x1000);
528 } else {
529 SiS_DDC2Delay(SiS_Pr, 0x4000);
532 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
533 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
534 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
536 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
537 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
538 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
539 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
541 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
542 DelayIndex = PanelID & 0x0f;
543 } else {
544 DelayIndex = PanelID >> 4;
546 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
547 Delay = 3;
548 } else {
549 if(DelayTime >= 2) DelayTime -= 2;
550 if(!(DelayTime & 0x01)) {
551 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
552 } else {
553 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
555 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
556 if(ROMAddr[0x13c] & 0x40) {
557 if(!(DelayTime & 0x01)) {
558 Delay = (USHORT)ROMAddr[0x17e];
559 } else {
560 Delay = (USHORT)ROMAddr[0x17f];
565 SiS_ShortDelay(SiS_Pr, Delay);
568 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
570 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
571 if(!(DelayTime & 0x01)) {
572 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
573 } else {
574 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
576 Delay <<= 8;
577 SiS_DDC2Delay(SiS_Pr, Delay);
581 #endif /* SIS315H */
586 #ifdef SIS315H
587 static void
588 SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
589 USHORT DelayTime, USHORT DelayLoop)
591 int i;
592 for(i=0; i<DelayLoop; i++) {
593 SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
596 #endif
598 /*********************************************/
599 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
600 /*********************************************/
602 void
603 SiS_WaitRetrace1(SiS_Private *SiS_Pr)
605 USHORT watchdog;
607 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
608 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
610 watchdog = 65535;
611 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
612 watchdog = 65535;
613 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
616 #if defined(SIS300) || defined(SIS315H)
617 static void
618 SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
620 USHORT watchdog;
622 watchdog = 65535;
623 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
624 watchdog = 65535;
625 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
627 #endif
629 static void
630 SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
632 if(HwInfo->jChipType < SIS_315H) {
633 #ifdef SIS300
634 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
635 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
637 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
638 SiS_WaitRetrace1(SiS_Pr);
639 } else {
640 SiS_WaitRetrace2(SiS_Pr, 0x25);
642 #endif
643 } else {
644 #ifdef SIS315H
645 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
646 SiS_WaitRetrace1(SiS_Pr);
647 } else {
648 SiS_WaitRetrace2(SiS_Pr, 0x30);
650 #endif
654 static void
655 SiS_VBWait(SiS_Private *SiS_Pr)
657 USHORT tempal,temp,i,j;
659 temp = 0;
660 for(i=0; i<3; i++) {
661 for(j=0; j<100; j++) {
662 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
663 if(temp & 0x01) {
664 if((tempal & 0x08)) continue;
665 else break;
666 } else {
667 if(!(tempal & 0x08)) continue;
668 else break;
671 temp ^= 0x01;
675 static void
676 SiS_VBLongWait(SiS_Private *SiS_Pr)
678 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
679 SiS_VBWait(SiS_Pr);
680 } else {
681 SiS_WaitRetrace1(SiS_Pr);
685 /*********************************************/
686 /* HELPER: MISC */
687 /*********************************************/
689 #ifdef SIS300
690 static BOOLEAN
691 SiS_Is301B(SiS_Private *SiS_Pr)
693 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
694 return FALSE;
696 #endif
698 static BOOLEAN
699 SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
701 USHORT flag;
703 if(HwInfo->jChipType == SIS_730) {
704 flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
705 if(flag & 0x20) return TRUE;
707 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
708 if(flag & 0x20) return TRUE;
709 return FALSE;
712 BOOLEAN
713 SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
715 #ifdef SIS315H
716 USHORT flag;
718 if(HwInfo->jChipType >= SIS_315H) {
719 if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
720 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
721 if(flag & EnableDualEdge) return TRUE;
724 #endif
725 return FALSE;
728 BOOLEAN
729 SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
731 #ifdef SIS315H
732 USHORT flag;
734 if(HwInfo->jChipType >= SIS_315H) {
735 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
736 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
738 #endif
739 return FALSE;
742 #ifdef SIS315H
743 static BOOLEAN
744 SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
746 if(SiS_IsVAMode(SiS_Pr,HwInfo)) return TRUE;
747 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
748 return FALSE;
750 #endif
752 static BOOLEAN
753 SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
755 #ifdef SIS315H
756 if(HwInfo->jChipType >= SIS_315H) {
757 if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
758 (SiS_IsVAMode(SiS_Pr, HwInfo))) {
759 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
762 #endif
763 return FALSE;
766 #ifdef SIS315H
767 static BOOLEAN
768 SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
770 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
771 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
772 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
774 return FALSE;
776 #endif
778 #ifdef SIS315H
779 static BOOLEAN
780 SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
782 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
783 return FALSE;
785 #endif
787 #ifdef SIS315H
788 static BOOLEAN
789 SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
791 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
792 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
794 return FALSE;
796 #endif
798 #ifdef SIS315H
799 static BOOLEAN
800 SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
802 USHORT flag;
804 if(HwInfo->jChipType == SIS_650) {
805 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
806 flag &= 0xF0;
807 /* Check for revision != A0 only */
808 if((flag == 0xe0) || (flag == 0xc0) ||
809 (flag == 0xb0) || (flag == 0x90)) return FALSE;
810 } else if(HwInfo->jChipType >= SIS_661) return FALSE;
811 return TRUE;
813 #endif
815 #ifdef SIS315H
816 static BOOLEAN
817 SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
819 USHORT flag;
821 if(HwInfo->jChipType >= SIS_315H) {
822 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
823 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
825 return FALSE;
827 #endif
829 #ifdef SIS315H
830 static BOOLEAN
831 SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
833 USHORT flag;
835 if(HwInfo->jChipType >= SIS_315H) {
836 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
837 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 */
839 return FALSE;
841 #endif
843 #ifdef SIS315H
844 static BOOLEAN
845 SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
847 USHORT flag;
849 if(HwInfo->jChipType >= SIS_315H) {
850 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
851 if(flag & SetCRT2ToTV) return TRUE;
852 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
853 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
854 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
855 } else {
856 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
857 if(flag & SetCRT2ToTV) return TRUE;
859 return FALSE;
861 #endif
863 #ifdef SIS315H
864 static BOOLEAN
865 SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
867 USHORT flag;
869 if(HwInfo->jChipType >= SIS_315H) {
870 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
871 if(flag & SetCRT2ToLCD) return TRUE;
872 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
873 if(flag & SetToLCDA) return TRUE;
874 } else {
875 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
876 if(flag & SetCRT2ToLCD) return TRUE;
878 return FALSE;
880 #endif
882 static BOOLEAN
883 SiS_BridgeIsOn(SiS_Private *SiS_Pr)
885 USHORT flag;
887 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
888 return TRUE;
889 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
890 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
891 if((flag == 1) || (flag == 2)) return TRUE;
893 return FALSE;
896 static BOOLEAN
897 SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
899 USHORT flag;
901 if(SiS_BridgeIsOn(SiS_Pr)) {
902 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
903 if(HwInfo->jChipType < SIS_315H) {
904 flag &= 0xa0;
905 if((flag == 0x80) || (flag == 0x20)) return TRUE;
906 } else {
907 flag &= 0x50;
908 if((flag == 0x40) || (flag == 0x10)) return TRUE;
911 return FALSE;
914 static BOOLEAN
915 SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
917 USHORT flag1;
919 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
920 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
921 return FALSE;
924 /*********************************************/
925 /* GET VIDEO BRIDGE CONFIG INFO */
926 /*********************************************/
928 /* Setup general purpose IO for Chrontel communication */
929 void
930 SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
932 unsigned long acpibase;
933 unsigned short temp;
935 if(!(SiS_Pr->SiS_ChSW)) return;
937 #ifndef LINUX_XF86
938 SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */
939 acpibase = SiS_GetRegLong(0xcfc);
940 #else
941 acpibase = pciReadLong(0x00000800, 0x74);
942 #endif
943 acpibase &= 0xFFFF;
944 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
945 temp &= 0xFEFF;
946 SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
947 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
948 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
949 temp &= 0xFEFF;
950 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
951 SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
952 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
955 void
956 SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
957 PSIS_HW_INFO HwInfo, int checkcrt2mode)
959 USHORT tempax,tempbx,temp;
960 USHORT modeflag, resinfo=0;
962 if(ModeNo <= 0x13) {
963 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
964 } else if(SiS_Pr->UseCustomMode) {
965 modeflag = SiS_Pr->CModeFlag;
966 } else {
967 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
968 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
971 SiS_Pr->SiS_SetFlag = 0;
973 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
975 tempbx = 0;
976 if(SiS_BridgeIsOn(SiS_Pr)) {
977 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
978 #if 0
979 if(HwInfo->jChipType < SIS_661) {
980 /* NO - YPbPr not set yet ! */
981 if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
982 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
983 temp |= SetCRT2ToHiVision; /* 0x80 */
985 if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
986 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
987 temp |= SetCRT2ToSVIDEO; /* 0x08 */
990 #endif
991 tempbx |= temp;
992 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
993 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
994 tempbx |= tempax;
996 #ifdef SIS315H
997 if(HwInfo->jChipType >= SIS_315H) {
998 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
999 if(ModeNo == 0x03) {
1000 /* Mode 0x03 is never in driver mode */
1001 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1003 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1004 /* Reset LCDA setting if not driver mode */
1005 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1007 if(IS_SIS650) {
1008 if(SiS_Pr->SiS_UseLCDA) {
1009 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1010 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1011 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1016 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1017 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1018 tempbx |= SetCRT2ToLCDA;
1022 if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1023 tempbx &= ~(SetCRT2ToRAMDAC);
1026 if(HwInfo->jChipType >= SIS_661) {
1027 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1028 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1029 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1030 if(temp & 0x04) {
1031 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1032 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1033 else tempbx |= SetCRT2ToYPbPr525750;
1035 } else if(SiS_Pr->SiS_VBType & VB_SISHIVISION) {
1036 if(temp & 0x04) {
1037 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1038 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1043 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1044 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1045 if(temp & SetToLCDA) {
1046 tempbx |= SetCRT2ToLCDA;
1048 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1049 if(temp & EnableCHYPbPr) {
1050 tempbx |= SetCRT2ToCHYPbPr;
1056 #endif /* SIS315H */
1058 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1059 temp = SetCRT2ToSVIDEO |
1060 SetCRT2ToAVIDEO |
1061 SetCRT2ToSCART |
1062 SetCRT2ToLCDA |
1063 SetCRT2ToLCD |
1064 SetCRT2ToRAMDAC |
1065 SetCRT2ToHiVision |
1066 SetCRT2ToYPbPr525750;
1067 } else {
1068 if(HwInfo->jChipType >= SIS_315H) {
1069 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1070 temp = SetCRT2ToAVIDEO |
1071 SetCRT2ToSVIDEO |
1072 SetCRT2ToSCART |
1073 SetCRT2ToLCDA |
1074 SetCRT2ToLCD |
1075 SetCRT2ToCHYPbPr;
1076 } else {
1077 temp = SetCRT2ToLCDA |
1078 SetCRT2ToLCD;
1080 } else {
1081 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1082 temp = SetCRT2ToTV | SetCRT2ToLCD;
1083 } else {
1084 temp = SetCRT2ToLCD;
1089 if(!(tempbx & temp)) {
1090 tempax = DisableCRT2Display;
1091 tempbx = 0;
1094 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1095 USHORT clearmask = ( DriverMode |
1096 DisableCRT2Display |
1097 LoadDACFlag |
1098 SetNotSimuMode |
1099 SetInSlaveMode |
1100 SetPALTV |
1101 SwitchCRT2 |
1102 SetSimuScanMode );
1103 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1104 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1105 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1106 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1107 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1108 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1109 } else {
1110 if(HwInfo->jChipType >= SIS_315H) {
1111 if(tempbx & SetCRT2ToLCDA) {
1112 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1115 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1116 if(tempbx & SetCRT2ToTV) {
1117 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1120 if(tempbx & SetCRT2ToLCD) {
1121 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1123 if(HwInfo->jChipType >= SIS_315H) {
1124 if(tempbx & SetCRT2ToLCDA) {
1125 tempbx |= SetCRT2ToLCD;
1130 if(tempax & DisableCRT2Display) {
1131 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1132 tempbx = SetSimuScanMode | DisableCRT2Display;
1136 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1138 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1139 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1140 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1141 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1142 modeflag &= (~CRT2Mode);
1146 if(!(tempbx & SetSimuScanMode)) {
1147 if(tempbx & SwitchCRT2) {
1148 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1149 if( (HwInfo->jChipType >= SIS_315H) &&
1150 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1151 if(resinfo != SIS_RI_1600x1200) {
1152 tempbx |= SetSimuScanMode;
1154 } else {
1155 tempbx |= SetSimuScanMode;
1158 } else {
1159 if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
1160 if(!(tempbx & DriverMode)) {
1161 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1162 tempbx |= SetSimuScanMode;
1169 if(!(tempbx & DisableCRT2Display)) {
1170 if(tempbx & DriverMode) {
1171 if(tempbx & SetSimuScanMode) {
1172 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1173 if( (HwInfo->jChipType >= SIS_315H) &&
1174 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1175 if(resinfo != SIS_RI_1600x1200) {
1176 tempbx |= SetInSlaveMode;
1178 } else {
1179 tempbx |= SetInSlaveMode;
1183 } else {
1184 tempbx |= SetInSlaveMode;
1190 SiS_Pr->SiS_VBInfo = tempbx;
1192 if(HwInfo->jChipType == SIS_630) {
1193 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1196 #ifdef TWDEBUG
1197 #ifdef LINUX_KERNEL
1198 printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1199 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1200 #endif
1201 #ifdef LINUX_XF86
1202 xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1203 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1204 #endif
1205 #endif
1208 /*********************************************/
1209 /* DETERMINE YPbPr MODE */
1210 /*********************************************/
1212 void
1213 SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1216 UCHAR temp;
1218 /* Note: This variable is only used on 30xLV systems.
1219 * CR38 has a different meaning on LVDS/CH7019 systems.
1220 * On 661 and later, these bits moved to CR35.
1222 * On 301, 301B, only HiVision 1080i is supported.
1223 * On 30xLV, 301C, only YPbPr 1080i is supported.
1226 SiS_Pr->SiS_YPbPr = 0;
1227 if(HwInfo->jChipType >= SIS_661) return;
1229 if(SiS_Pr->SiS_VBType) {
1230 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1231 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1235 if(HwInfo->jChipType >= SIS_315H) {
1236 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
1237 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1238 if(temp & 0x08) {
1239 switch((temp >> 4)) {
1240 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1241 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1242 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1243 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1251 /*********************************************/
1252 /* DETERMINE TVMode flag */
1253 /*********************************************/
1255 void
1256 SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
1258 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1259 USHORT temp, temp1, resinfo = 0, romindex = 0;
1260 UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1262 SiS_Pr->SiS_TVMode = 0;
1264 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1265 if(SiS_Pr->UseCustomMode) return;
1267 if(ModeNo > 0x13) {
1268 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1271 if(HwInfo->jChipType < SIS_661) {
1273 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1275 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1276 temp = 0;
1277 if((HwInfo->jChipType == SIS_630) ||
1278 (HwInfo->jChipType == SIS_730)) {
1279 temp = 0x35;
1280 romindex = 0xfe;
1281 } else if(HwInfo->jChipType >= SIS_315H) {
1282 temp = 0x38;
1283 romindex = 0xf3;
1284 if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
1286 if(temp) {
1287 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1288 OutputSelect = ROMAddr[romindex];
1289 if(!(OutputSelect & EnablePALMN)) {
1290 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1293 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1294 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1295 if(temp1 & EnablePALM) { /* 0x40 */
1296 SiS_Pr->SiS_TVMode |= TVSetPALM;
1297 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1298 } else if(temp1 & EnablePALN) { /* 0x80 */
1299 SiS_Pr->SiS_TVMode |= TVSetPALN;
1301 } else {
1302 if(temp1 & EnableNTSCJ) { /* 0x40 */
1303 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1307 /* Translate HiVision/YPbPr to our new flags */
1308 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1309 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1310 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1311 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1312 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1313 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1314 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1315 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1316 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1317 SiS_Pr->SiS_TVMode |= TVSetPAL;
1320 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1321 if(SiS_Pr->SiS_CHOverScan) {
1322 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1323 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1324 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1325 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1327 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1328 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1329 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1330 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1333 if(SiS_Pr->SiS_CHSOverScan) {
1334 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1337 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1338 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1339 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1340 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1341 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1342 } else {
1343 if(temp & EnableNTSCJ) {
1344 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1350 } else { /* 661 and later */
1352 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1353 if(temp1 & 0x01) {
1354 SiS_Pr->SiS_TVMode |= TVSetPAL;
1355 if(temp1 & 0x08) {
1356 SiS_Pr->SiS_TVMode |= TVSetPALN;
1357 } else if(temp1 & 0x04) {
1358 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1359 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1361 SiS_Pr->SiS_TVMode |= TVSetPALM;
1363 } else {
1364 if(temp1 & 0x02) {
1365 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1368 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1369 if(SiS_Pr->SiS_CHOverScan) {
1370 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1371 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1375 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1376 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1377 temp1 &= 0xe0;
1378 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1379 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1380 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1381 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1382 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1384 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1385 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1386 SiS_Pr->SiS_TVMode |= TVAspect169;
1387 } else {
1388 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1389 if(temp1 & 0x02) {
1390 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1391 SiS_Pr->SiS_TVMode |= TVAspect169;
1392 } else {
1393 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1395 } else {
1396 SiS_Pr->SiS_TVMode |= TVAspect43;
1403 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1405 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1407 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1408 SiS_Pr->SiS_TVMode |= TVSetPAL;
1409 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1410 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1411 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1412 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1416 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1417 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1418 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1422 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1423 /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
1424 if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
1425 if(resinfo == SIS_RI_1024x768) {
1426 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1431 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1432 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1433 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1434 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1435 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1436 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1437 } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
1438 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1439 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1445 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1447 #ifdef TWDEBUG
1448 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1449 #endif
1452 /*********************************************/
1453 /* GET LCD INFO */
1454 /*********************************************/
1456 static USHORT
1457 SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
1459 USHORT temp = SiS_Pr->SiS_LCDResInfo;
1460 /* Translate my LCDResInfo to BIOS value */
1461 if(temp == Panel_1280x768_2) temp = Panel_1280x768;
1462 if(temp == Panel_1280x800_2) temp = Panel_1280x800;
1463 return temp;
1466 static void
1467 SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1469 #ifdef SIS315H
1470 UCHAR *ROMAddr;
1471 USHORT temp;
1473 #ifdef TWDEBUG
1474 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1475 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1476 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1477 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1478 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1479 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1480 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1481 #endif
1483 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1484 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1485 SiS_Pr->SiS_NeedRomModeData = TRUE;
1486 SiS_Pr->PanelHT = temp;
1488 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1489 SiS_Pr->SiS_NeedRomModeData = TRUE;
1490 SiS_Pr->PanelVT = temp;
1492 SiS_Pr->PanelHRS = SISGETROMW(10);
1493 SiS_Pr->PanelHRE = SISGETROMW(12);
1494 SiS_Pr->PanelVRS = SISGETROMW(14);
1495 SiS_Pr->PanelVRE = SISGETROMW(16);
1496 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1497 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1498 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
1499 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1500 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1501 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1502 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1504 #ifdef TWDEBUG
1505 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1506 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1507 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1508 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1509 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1510 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1511 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1512 #endif
1515 #endif
1518 static void
1519 SiS_CheckScaling(SiS_Private *SiS_Pr, USHORT resinfo, const UCHAR *nonscalingmodes)
1521 int i = 0;
1522 while(nonscalingmodes[i] != 0xff) {
1523 if(nonscalingmodes[i++] == resinfo) {
1524 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1525 (SiS_Pr->UsePanelScaler == -1)) {
1526 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1528 break;
1533 void
1534 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1535 PSIS_HW_INFO HwInfo)
1537 #ifdef SIS300
1538 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1539 #endif
1540 #ifdef SIS315H
1541 UCHAR *myptr = NULL;
1542 #endif
1543 USHORT temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1544 BOOLEAN panelcanscale = FALSE;
1545 const unsigned char SiS300SeriesLCDRes[] =
1546 { 0, 1, 2, 3, 7, 4, 5, 8,
1547 0, 0, 10, 0, 0, 0, 0, 15 };
1549 SiS_Pr->SiS_LCDResInfo = 0;
1550 SiS_Pr->SiS_LCDTypeInfo = 0;
1551 SiS_Pr->SiS_LCDInfo = 0;
1552 SiS_Pr->PanelHRS = 999; /* HSync start */
1553 SiS_Pr->PanelHRE = 999; /* HSync end */
1554 SiS_Pr->PanelVRS = 999; /* VSync start */
1555 SiS_Pr->PanelVRE = 999; /* VSync end */
1556 SiS_Pr->SiS_NeedRomModeData = FALSE;
1558 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1560 if(ModeNo <= 0x13) {
1561 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1562 } else if(SiS_Pr->UseCustomMode) {
1563 modeflag = SiS_Pr->CModeFlag;
1564 } else {
1565 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1566 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1567 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1568 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1571 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1573 /* For broken BIOSes: Assume 1024x768 */
1574 if(temp == 0) temp = 0x02;
1576 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1577 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1578 } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
1579 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1580 } else {
1581 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1583 temp &= 0x0f;
1584 if(HwInfo->jChipType < SIS_315H) {
1585 /* Translate 300 series LCDRes to 315 series for unified usage */
1586 temp = SiS300SeriesLCDRes[temp];
1589 /* Translate to our internal types */
1590 if(HwInfo->jChipType == SIS_550) {
1591 if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
1592 if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
1595 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1596 if(temp == Panel310_1280x768) {
1597 temp = Panel_1280x768_2;
1599 if(SiS_Pr->SiS_ROMNew) {
1600 if(temp == Panel661_1280x800) {
1601 temp = Panel_1280x800_2;
1606 SiS_Pr->SiS_LCDResInfo = temp;
1608 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1609 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1610 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1611 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1612 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1616 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1617 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1618 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1619 } else {
1620 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1621 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1624 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1625 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1626 /* Need temp below! */
1628 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1630 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
1632 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1633 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1635 /* Dual link, Pass 1:1 BIOS default, etc. */
1636 #ifdef SIS315H
1637 if(HwInfo->jChipType >= SIS_661) {
1638 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1639 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1641 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1642 if(SiS_Pr->SiS_ROMNew) {
1643 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1644 } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1645 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1648 } else if(HwInfo->jChipType >= SIS_315H) {
1649 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1650 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1652 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1653 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1654 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1655 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1656 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1657 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1659 } else if(!(SiS_Pr->SiS_ROMNew)) {
1660 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1661 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1662 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1663 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1665 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1666 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1667 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1668 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1669 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1674 #endif
1676 /* Pass 1:1 */
1677 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1678 /* Always center screen on LVDS (if scaling is disabled) */
1679 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1680 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1681 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1682 /* Always center screen on SiS LVDS (if scaling is disabled) */
1683 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1684 } else {
1685 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1686 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1687 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1691 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1692 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1694 switch(SiS_Pr->SiS_LCDResInfo) {
1695 case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480;
1696 SiS_Pr->PanelHT = 400; SiS_Pr->PanelVT = 525;
1697 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1698 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1699 break;
1700 case Panel_640x480_2:
1701 case Panel_640x480_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1702 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1703 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1704 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1705 break;
1706 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1707 SiS_Pr->PanelVRE = 3;
1708 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1709 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1710 break;
1711 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1712 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1713 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1714 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1715 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1716 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1717 break;
1718 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1719 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1720 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1721 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1722 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1723 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1724 break;
1725 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1726 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1727 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1728 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1729 if(HwInfo->jChipType < SIS_315H) {
1730 SiS_Pr->PanelHRS = 23;
1731 SiS_Pr->PanelVRE = 5;
1733 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1734 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1735 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1736 break;
1737 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1738 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1739 SiS_Pr->PanelHRS = 24;
1740 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1741 if(HwInfo->jChipType < SIS_315H) {
1742 SiS_Pr->PanelHRS = 23;
1743 SiS_Pr->PanelVRE = 5;
1745 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1746 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1747 break;
1748 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1749 break;
1750 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1751 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1752 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1753 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1754 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1755 /* Data above for TMDS (projector); get from BIOS for LVDS */
1756 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1757 break;
1758 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1759 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1760 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1761 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1762 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1763 } else {
1764 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1765 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1766 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1767 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1768 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1770 break;
1771 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1772 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1773 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1774 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1775 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1776 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1777 break;
1778 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1779 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1780 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1781 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1782 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1783 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1784 break;
1785 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1786 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1787 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1788 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1789 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1790 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1791 break;
1792 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1793 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1794 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1795 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1796 if(resinfo == SIS_RI_1280x1024) {
1797 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1798 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1800 break;
1801 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1802 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1803 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1804 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1805 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1806 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1807 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1808 break;
1809 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1810 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1811 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; /* HRE OK for LVDS, not for LCDA */
1812 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1813 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1814 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1815 break;
1816 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1817 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1818 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1819 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1820 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1821 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1822 break;
1823 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1824 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1825 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1826 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1827 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1828 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1829 break;
1830 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1831 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1832 break;
1833 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1834 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1835 break;
1836 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1837 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1838 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1839 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1840 if(SiS_Pr->CP_PreferredIndex != -1) {
1841 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1842 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1843 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1844 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1845 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1846 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1847 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1848 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1849 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1850 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1851 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1852 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1853 if(SiS_Pr->CP_PrefClock) {
1854 int idx;
1855 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1856 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1857 if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1858 else idx = VCLK_CUSTOM_315;
1859 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1860 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1861 SiS_Pr->SiS_VCLKData[idx].SR2B =
1862 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1863 SiS_Pr->SiS_VCLKData[idx].SR2C =
1864 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1867 break;
1868 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1869 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1870 break;
1873 /* Special cases */
1874 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1875 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1876 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1877 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1878 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1879 SiS_Pr->PanelHRS = 999;
1880 SiS_Pr->PanelHRE = 999;
1883 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1884 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1885 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1886 SiS_Pr->PanelVRS = 999;
1887 SiS_Pr->PanelVRE = 999;
1890 /* DontExpand overrule */
1891 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1893 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1894 /* No scaling for this mode on any panel */
1895 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1898 switch(SiS_Pr->SiS_LCDResInfo) {
1900 case Panel_Custom:
1901 case Panel_1152x864:
1902 case Panel_1280x768: /* TMDS only */
1903 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1904 break;
1906 case Panel_800x600: {
1907 static const UCHAR nonscalingmodes[] = {
1908 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1909 SIS_RI_856x480, SIS_RI_960x540, 0xff
1911 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1912 break;
1914 case Panel_1024x768: {
1915 static const UCHAR nonscalingmodes[] = {
1916 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1917 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600,0xff
1919 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1920 break;
1922 case Panel_1280x720: {
1923 static const UCHAR nonscalingmodes[] = {
1924 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1925 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600,0xff
1927 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1928 if(SiS_Pr->PanelHT == 1650) {
1929 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1931 break;
1933 case Panel_1280x768_2: { /* LVDS only */
1934 static const UCHAR nonscalingmodes[] = {
1935 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1936 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600,SIS_RI_1152x768,
1937 0xff
1939 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1940 switch(resinfo) {
1941 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1942 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1944 break;
1946 break;
1948 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1949 static const UCHAR nonscalingmodes[] = {
1950 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1951 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600,SIS_RI_1152x768,
1952 SIS_RI_1280x720, SIS_RI_1280x768, 0xff
1954 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1955 break;
1957 case Panel_1280x800_2: { /* SiS LVDS */
1958 static const UCHAR nonscalingmodes[] = {
1959 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1960 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600,SIS_RI_1152x768,
1961 0xff
1963 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1964 switch(resinfo) {
1965 case SIS_RI_1280x720:
1966 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1967 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1969 break;
1971 break;
1973 case Panel_1280x960: {
1974 static const UCHAR nonscalingmodes[] = {
1975 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1976 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600,SIS_RI_1152x768,
1977 SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,0xff
1979 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1980 break;
1982 case Panel_1280x1024: {
1983 static const UCHAR nonscalingmodes[] = {
1984 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1985 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600,SIS_RI_1152x768,
1986 SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960,
1987 0xff
1989 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1990 break;
1992 case Panel_1400x1050: {
1993 static const UCHAR nonscalingmodes[] = {
1994 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1995 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600,SIS_RI_1152x768,
1996 SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960,0xff
1998 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1999 switch(resinfo) {
2000 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2001 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2003 break;
2004 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2005 break;
2007 break;
2009 case Panel_1600x1200: {
2010 static const UCHAR nonscalingmodes[] = {
2011 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2012 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600,SIS_RI_1152x768,
2013 SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960,
2014 SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2016 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2017 break;
2019 case Panel_1680x1050: {
2020 static const UCHAR nonscalingmodes[] = {
2021 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2022 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_1024x576,SIS_RI_1024x600, SIS_RI_1152x768,
2023 SIS_RI_1152x864,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2025 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2026 break;
2031 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2032 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2033 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2037 #ifdef SIS300
2038 if(HwInfo->jChipType < SIS_315H) {
2039 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2040 if(SiS_Pr->SiS_UseROM) {
2041 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2042 if(!(ROMAddr[0x235] & 0x02)) {
2043 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2047 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2048 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2049 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2053 #endif
2055 /* Special cases */
2057 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2058 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2061 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2062 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2065 switch(SiS_Pr->SiS_LCDResInfo) {
2066 case Panel_640x480:
2067 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2068 break;
2069 case Panel_1280x800:
2070 /* Don't pass 1:1 by default (TMDS special) */
2071 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2072 break;
2073 case Panel_1280x960:
2074 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2075 break;
2076 case Panel_Custom:
2077 if((!SiS_Pr->CP_PrefClock) ||
2078 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2079 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2081 break;
2084 if(SiS_Pr->UseCustomMode) {
2085 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2088 /* (In)validate LCDPass11 flag */
2089 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2090 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2093 /* LVDS DDA */
2094 if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2096 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2097 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2098 if(ModeNo == 0x12) {
2099 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2100 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2102 } else if(ModeNo > 0x13) {
2103 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2104 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2105 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2106 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2114 if(modeflag & HalfDCLK) {
2115 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2116 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2117 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2118 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2119 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2120 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2121 } else if(ModeNo > 0x13) {
2122 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2123 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2124 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2125 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2132 /* VESA timing */
2133 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2134 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2135 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2137 } else {
2138 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2141 #ifdef LINUX_KERNEL
2142 #ifdef TWDEBUG
2143 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2144 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2145 #endif
2146 #endif
2147 #ifdef LINUX_XF86
2148 xf86DrvMsgVerb(0, X_PROBED, 4,
2149 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2150 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2151 #endif
2154 /*********************************************/
2155 /* GET VCLK */
2156 /*********************************************/
2158 USHORT
2159 SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2160 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
2162 USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
2163 USHORT modeflag,resinfo,tempbx;
2164 const UCHAR *CHTVVCLKPtr = NULL;
2166 if(ModeNo <= 0x13) {
2167 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2168 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2169 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2170 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2171 } else {
2172 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2173 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2174 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2175 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2176 if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
2179 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2181 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2183 CRT2Index >>= 6;
2184 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2186 if(HwInfo->jChipType < SIS_315H) {
2187 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2188 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2189 VCLKIndex = VCLKIndexGEN;
2191 } else {
2192 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2193 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2194 switch(resinfo) {
2195 /* Only those whose IndexGEN doesn't match VBVCLK array */
2196 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2197 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2198 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2199 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2200 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2201 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2202 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2203 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2204 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2205 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2206 default: VCLKIndex = VCLKIndexGEN;
2209 if(ModeNo <= 0x13) {
2210 if(HwInfo->jChipType <= SIS_315PRO) {
2211 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2212 } else {
2213 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2216 if(HwInfo->jChipType <= SIS_315PRO) {
2217 if(VCLKIndex == 0) VCLKIndex = 0x41;
2218 if(VCLKIndex == 1) VCLKIndex = 0x43;
2219 if(VCLKIndex == 4) VCLKIndex = 0x44;
2224 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2226 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2227 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2228 else VCLKIndex = HiTVVCLK;
2229 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
2230 if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
2231 else VCLKIndex = HiTVTextVCLK;
2233 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2234 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2235 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2236 else VCLKIndex = TVVCLK;
2238 if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2239 else VCLKIndex += TVCLKBASE_315;
2241 } else { /* VGA2 */
2243 VCLKIndex = VCLKIndexGEN;
2244 if(HwInfo->jChipType < SIS_315H) {
2245 if(ModeNo > 0x13) {
2246 if( (HwInfo->jChipType == SIS_630) &&
2247 (HwInfo->jChipRevision >= 0x30)) {
2248 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2250 /* Better VGA2 clock for 1280x1024@75 */
2251 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2256 } else { /* If not programming CRT2 */
2258 VCLKIndex = VCLKIndexGEN;
2259 if(HwInfo->jChipType < SIS_315H) {
2260 if(ModeNo > 0x13) {
2261 if( (HwInfo->jChipType != SIS_630) &&
2262 (HwInfo->jChipType != SIS_300) ) {
2263 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2269 } else { /* LVDS */
2271 VCLKIndex = CRT2Index;
2273 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2275 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2277 VCLKIndex &= 0x1f;
2278 tempbx = 0;
2279 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2280 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2281 tempbx += 2;
2282 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2283 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2285 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2286 tempbx = 4;
2287 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2288 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2289 tempbx = 6;
2290 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2293 switch(tempbx) {
2294 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2295 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2296 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2297 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2298 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2299 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2300 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2301 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2302 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2303 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2305 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2307 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2309 if(HwInfo->jChipType < SIS_315H) {
2310 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2311 } else {
2312 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2315 /* Special Timing: Barco iQ Pro R series */
2316 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2318 /* Special Timing: 848x480 parallel lvds */
2319 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2320 if(HwInfo->jChipType < SIS_315H) {
2321 VCLKIndex = VCLK34_300;
2322 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2323 } else {
2324 VCLKIndex = VCLK34_315;
2325 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2329 } else {
2331 VCLKIndex = VCLKIndexGEN;
2332 if(HwInfo->jChipType < SIS_315H) {
2333 if(ModeNo > 0x13) {
2334 if( (HwInfo->jChipType == SIS_630) &&
2335 (HwInfo->jChipRevision >= 0x30) ) {
2336 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2342 } else { /* if not programming CRT2 */
2344 VCLKIndex = VCLKIndexGEN;
2345 if(HwInfo->jChipType < SIS_315H) {
2346 if(ModeNo > 0x13) {
2347 if( (HwInfo->jChipType != SIS_630) &&
2348 (HwInfo->jChipType != SIS_300) ) {
2349 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2351 #if 0
2352 if(HwInfo->jChipType == SIS_730) {
2353 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2354 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2356 #endif
2364 #ifdef TWDEBUG
2365 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2366 #endif
2368 return(VCLKIndex);
2371 /*********************************************/
2372 /* SET CRT2 MODE TYPE REGISTERS */
2373 /*********************************************/
2375 static void
2376 SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2377 PSIS_HW_INFO HwInfo)
2379 USHORT i,j,modeflag;
2380 USHORT tempcl,tempah=0;
2381 #if defined(SIS300) || defined(SIS315H)
2382 USHORT tempbl;
2383 #endif
2384 #ifdef SIS315H
2385 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
2386 USHORT tempah2, tempbl2;
2387 #endif
2389 if(ModeNo <= 0x13) {
2390 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2391 } else if(SiS_Pr->UseCustomMode) {
2392 modeflag = SiS_Pr->CModeFlag;
2393 } else {
2394 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2397 /* BIOS does not do this (neither 301 nor LVDS) */
2398 /* (But it's harmless; see SetCRT2Offset) */
2399 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x00); /* fix write part1 index 0 BTDRAM bit Bug */
2401 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2403 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2404 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2406 } else {
2408 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2409 if(HwInfo->jChipType >= SIS_315H) {
2410 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2413 tempcl = SiS_Pr->SiS_ModeType;
2415 if(HwInfo->jChipType < SIS_315H) {
2417 #ifdef SIS300 /* ---- 300 series ---- */
2419 /* For 301BDH: (with LCD via LVDS) */
2420 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2421 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2422 tempbl &= 0xef;
2423 tempbl |= 0x02;
2424 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2425 tempbl |= 0x10;
2426 tempbl &= 0xfd;
2428 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2431 if(ModeNo > 0x13) {
2432 tempcl -= ModeVGA;
2433 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2434 tempah = ((0x10 >> tempcl) | 0x80);
2436 } else tempah = 0x80;
2438 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2440 #endif /* SIS300 */
2442 } else {
2444 #ifdef SIS315H /* ------- 315/330 series ------ */
2446 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2447 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2448 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2452 if(ModeNo > 0x13) {
2453 tempcl -= ModeVGA;
2454 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2455 tempah = (0x08 >> tempcl);
2456 if (tempah == 0) tempah = 1;
2457 tempah |= 0x40;
2459 } else tempah = 0x40;
2461 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2463 #endif /* SIS315H */
2467 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2469 if(HwInfo->jChipType < SIS_315H) {
2470 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2471 } else {
2472 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2473 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2474 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2475 if(IS_SIS740) {
2476 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2477 } else {
2478 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2483 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2485 tempah = 0x01;
2486 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2487 tempah |= 0x02;
2489 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2490 tempah ^= 0x05;
2491 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2492 tempah ^= 0x01;
2496 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2498 if(HwInfo->jChipType < SIS_315H) {
2500 tempah = (tempah << 5) & 0xFF;
2501 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2502 tempah = (tempah >> 5) & 0xFF;
2504 } else {
2506 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2510 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2511 tempah |= 0x10;
2514 if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
2515 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2516 (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)) {
2517 tempah |= 0x80;
2519 } else {
2520 tempah |= 0x80;
2523 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2524 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2525 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2526 tempah |= 0x20;
2531 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2533 tempah = 0;
2535 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
2537 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2538 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2539 tempah |= 0x40;
2543 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2544 (SiS_Pr->SiS_LCDResInfo == Panel_1280x960) ||
2545 ((SiS_Pr->SiS_LCDResInfo == Panel_Custom) &&
2546 (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
2547 tempah |= 0x80;
2550 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2552 } else { /* LVDS */
2554 if(HwInfo->jChipType >= SIS_315H) {
2556 /* LVDS can only be slave in 8bpp modes */
2557 tempah = 0x80;
2558 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2559 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2560 tempah |= 0x02;
2564 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2565 tempah |= 0x02;
2568 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2569 tempah ^= 0x01;
2572 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2573 tempah = 1;
2576 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2578 } else {
2580 tempah = 0;
2581 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2582 tempah |= 0x02;
2584 tempah <<= 5;
2586 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2588 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2594 } /* LCDA */
2596 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2598 if(HwInfo->jChipType >= SIS_315H) {
2600 #ifdef SIS315H
2602 unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
2604 /* The following is nearly unpreditable and varies from machine
2605 * to machine. Especially the 301DH seems to be a real trouble
2606 * maker. Some BIOSes simply set the registers (like in the
2607 * NoLCD-if-statements here), some set them according to the
2608 * LCDA stuff. It is very likely that some machines are not
2609 * treated correctly in the following, very case-orientated
2610 * code. What do I do then...?
2613 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2615 if(!(IS_SIS740)) {
2616 tempah = 0x04; /* For all bridges */
2617 tempbl = 0xfb;
2618 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2619 tempah = 0x00;
2620 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2621 tempbl = 0xff;
2624 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2627 /* The following two are responsible for eventually wrong colors
2628 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2629 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2630 * in a 650 box (Jake). What is the criteria?
2633 if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2634 tempah = 0x30;
2635 tempbl = 0xc0;
2636 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2637 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2638 tempah = 0x00;
2639 tempbl = 0x00;
2641 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2642 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2643 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2644 /* Fixes "TV-blue-bug" on 315+301 */
2645 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2646 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2647 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2648 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2649 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2650 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2651 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */
2652 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2653 } else {
2654 tempah = 0x30; tempah2 = 0xc0; /* For 30xB (and 301BDH rev b1) */
2655 tempbl = 0xcf; tempbl2 = 0x3f;
2656 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2657 tempah = tempah2 = 0x00;
2658 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2659 tempbl = tempbl2 = 0xff;
2662 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2663 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2666 if(IS_SIS740) {
2667 tempah = 0x80;
2668 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2669 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2670 } else {
2671 tempah = 0x00;
2672 tempbl = 0x7f;
2673 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2674 tempbl = 0xff;
2675 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
2677 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2680 #if 0
2681 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
2682 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0xc0);
2684 #endif
2686 #endif /* SIS315H */
2688 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2690 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2692 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2693 ( (SiS_Pr->SiS_VBType & VB_NoLCD) &&
2694 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
2695 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2696 } else {
2697 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2702 } else { /* LVDS */
2704 #ifdef SIS315H
2705 if(HwInfo->jChipType >= SIS_315H) {
2707 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2709 tempah = 0x04;
2710 tempbl = 0xfb;
2711 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2712 tempah = 0x00;
2713 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
2715 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2717 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2718 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2721 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2723 } else if(HwInfo->jChipType == SIS_550) {
2725 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2726 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2731 #endif
2737 /*********************************************/
2738 /* GET RESOLUTION DATA */
2739 /*********************************************/
2741 USHORT
2742 SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
2744 if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2745 else return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2748 static void
2749 SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2750 PSIS_HW_INFO HwInfo)
2752 USHORT xres,yres,modeflag=0,resindex;
2754 if(SiS_Pr->UseCustomMode) {
2755 xres = SiS_Pr->CHDisplay;
2756 if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
2757 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2758 yres = SiS_Pr->CVDisplay;
2759 if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
2760 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2761 return;
2764 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2766 if(ModeNo <= 0x13) {
2767 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2768 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2769 } else {
2770 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2771 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2772 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2775 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2777 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2778 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2779 if(yres == 350) yres = 400;
2781 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2782 if(ModeNo == 0x12) yres = 400;
2786 if(modeflag & HalfDCLK) xres *= 2;
2787 if(modeflag & DoubleScanMode) yres *= 2;
2791 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2793 #if 0
2794 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
2795 if(xres == 720) xres = 640;
2797 #endif
2799 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2800 switch(SiS_Pr->SiS_LCDResInfo) {
2801 case Panel_1024x768:
2802 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2803 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2804 if(yres == 350) yres = 357;
2805 if(yres == 400) yres = 420;
2806 if(yres == 480) yres = 525;
2809 break;
2810 case Panel_1280x1024:
2811 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2812 /* BIOS bug - does this regardless of scaling */
2813 if(yres == 400) yres = 405;
2815 if(yres == 350) yres = 360;
2816 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2817 if(yres == 360) yres = 375;
2819 break;
2820 case Panel_1600x1200:
2821 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2822 if(yres == 1024) yres = 1056;
2824 break;
2828 } else {
2830 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2831 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2832 if(xres == 720) xres = 640;
2834 } else if(xres == 720) xres = 640;
2836 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2837 yres = 400;
2838 if(HwInfo->jChipType >= SIS_315H) {
2839 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2840 } else {
2841 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2843 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2847 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2848 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2851 /*********************************************/
2852 /* GET CRT2 TIMING DATA */
2853 /*********************************************/
2855 static BOOLEAN
2856 SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2857 USHORT RefreshRateTableIndex, USHORT *ResIndex,
2858 USHORT *DisplayType)
2860 USHORT modeflag=0;
2862 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2863 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2864 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2866 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2867 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2868 } else
2869 return FALSE;
2871 if(ModeNo <= 0x13) {
2872 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2873 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2874 } else {
2875 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2876 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2879 (*ResIndex) &= 0x3F;
2881 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2882 (*DisplayType) = 18;
2883 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2884 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2885 (*DisplayType) += 2;
2886 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2887 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
2889 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2890 (*DisplayType) = 18; /* PALM uses NTSC data */
2891 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2892 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2893 (*DisplayType) = 20; /* PALN uses PAL data */
2894 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2897 } else {
2898 switch(SiS_Pr->SiS_LCDResInfo) {
2899 case Panel_640x480: (*DisplayType) = 50; break;
2900 case Panel_640x480_2: (*DisplayType) = 52; break;
2901 case Panel_640x480_3: (*DisplayType) = 54; break;
2902 case Panel_800x600: (*DisplayType) = 0; break;
2903 case Panel_1024x600: (*DisplayType) = 23; break;
2904 case Panel_1024x768: (*DisplayType) = 4; break;
2905 case Panel_1152x768: (*DisplayType) = 27; break;
2906 case Panel_1280x768: (*DisplayType) = 40; break;
2907 case Panel_1280x1024: (*DisplayType) = 8; break;
2908 case Panel_1400x1050: (*DisplayType) = 14; break;
2909 case Panel_1600x1200: (*DisplayType) = 36; break;
2910 default: return FALSE;
2913 if(modeflag & HalfDCLK) (*DisplayType)++;
2915 switch(SiS_Pr->SiS_LCDResInfo) {
2916 case Panel_640x480:
2917 case Panel_640x480_2:
2918 case Panel_640x480_3:
2919 break;
2920 default:
2921 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
2924 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2925 (*DisplayType) = 12;
2926 if(modeflag & HalfDCLK) (*DisplayType)++;
2930 #if 0
2931 if(SiS_Pr->SiS_IF_DEF_FSTN) {
2932 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2933 (*DisplayType) = 22;
2936 #endif
2938 return TRUE;
2941 static void
2942 SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2943 USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
2944 PSIS_HW_INFO HwInfo)
2946 USHORT tempbx=0,tempal=0,resinfo=0;
2948 if(ModeNo <= 0x13) {
2949 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2950 } else {
2951 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2952 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2955 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2957 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2959 tempbx = SiS_Pr->SiS_LCDResInfo;
2960 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2962 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2963 if (resinfo == SIS_RI_1280x800) tempal = 9;
2964 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2965 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2966 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2)) {
2967 if (resinfo == SIS_RI_1280x768) tempal = 9;
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;
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++;
2989 #endif
2991 } else { /* TV */
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;
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 tempbx = 5;
3004 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3005 } else {
3006 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3007 else tempbx = 4;
3008 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3013 tempal &= 0x3F;
3015 if(ModeNo > 0x13) {
3016 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3017 if(tempal == 6) tempal = 7;
3018 if((resinfo == SIS_RI_720x480) ||
3019 (resinfo == SIS_RI_720x576) ||
3020 (resinfo == SIS_RI_768x576)) {
3021 tempal = 6;
3022 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
3023 if(resinfo == SIS_RI_720x480) tempal = 9;
3026 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3027 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3028 if(resinfo == SIS_RI_1024x768) tempal = 8;
3030 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3031 if((resinfo == SIS_RI_720x576) ||
3032 (resinfo == SIS_RI_768x576)) {
3033 tempal = 8;
3035 if(resinfo == SIS_RI_1280x720) tempal = 9;
3041 *CRT2Index = tempbx;
3042 *ResIndex = tempal;
3044 } else { /* LVDS, 301B-DH (if running on LCD) */
3046 tempbx = 0;
3047 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3049 tempbx = 10;
3050 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3051 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3052 tempbx += 2;
3053 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3054 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3056 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
3057 tempbx = 90;
3058 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3059 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
3060 tempbx = 92;
3061 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3065 } else {
3067 switch(SiS_Pr->SiS_LCDResInfo) {
3068 case Panel_640x480: tempbx = 6; break;
3069 case Panel_640x480_2:
3070 case Panel_640x480_3: tempbx = 30; break;
3071 case Panel_800x600: tempbx = 0; break;
3072 case Panel_1024x600: tempbx = 15; break;
3073 case Panel_1024x768: tempbx = 2; break;
3074 case Panel_1152x768: tempbx = 17; break;
3075 case Panel_1280x768: tempbx = 18; break;
3076 case Panel_1280x1024: tempbx = 4; break;
3077 case Panel_1400x1050: tempbx = 8; break;
3078 case Panel_1600x1200: tempbx = 21; break;
3079 case Panel_Barco1366: tempbx = 80; break;
3082 switch(SiS_Pr->SiS_LCDResInfo) {
3083 case Panel_640x480:
3084 case Panel_640x480_2:
3085 case Panel_640x480_3:
3086 break;
3087 default:
3088 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3091 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
3093 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3094 tempbx = 82;
3095 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3096 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
3097 tempbx = 84;
3098 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3101 if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
3102 (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
3103 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3104 (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3105 tempal = 0;
3111 (*CRT2Index) = tempbx;
3112 (*ResIndex) = tempal & 0x1F;
3116 static void
3117 SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3118 USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
3120 USHORT tempax=0,tempbx=0;
3121 USHORT temp1=0,modeflag=0,tempcx=0;
3122 USHORT index;
3124 SiS_Pr->SiS_RVBHCMAX = 1;
3125 SiS_Pr->SiS_RVBHCFACT = 1;
3127 if(ModeNo <= 0x13) {
3129 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3130 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3132 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3133 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3134 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3136 } else {
3138 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3139 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3141 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3142 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3143 tempax &= 0x03FF;
3144 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3145 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3146 tempcx &= 0x0100;
3147 tempcx <<= 2;
3148 tempbx |= tempcx;
3149 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3153 if(temp1 & 0x01) tempbx |= 0x0100;
3154 if(temp1 & 0x20) tempbx |= 0x0200;
3156 tempax += 5;
3158 /* Charx8Dot is no more used (and assumed), so we set it */
3159 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3160 modeflag |= Charx8Dot;
3163 if(modeflag & Charx8Dot) tempax *= 8;
3164 else tempax *= 9;
3166 if(modeflag & HalfDCLK) tempax <<= 1;
3168 tempbx++;
3170 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3171 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3174 static void
3175 SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3176 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3178 USHORT CRT2Index, ResIndex;
3179 const SiS_LVDSDataStruct *LVDSData = NULL;
3181 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3183 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3184 SiS_Pr->SiS_RVBHCMAX = 1;
3185 SiS_Pr->SiS_RVBHCFACT = 1;
3186 SiS_Pr->SiS_NewFlickerMode = 0;
3187 SiS_Pr->SiS_RVBHRS = 50;
3188 SiS_Pr->SiS_RY1COE = 0;
3189 SiS_Pr->SiS_RY2COE = 0;
3190 SiS_Pr->SiS_RY3COE = 0;
3191 SiS_Pr->SiS_RY4COE = 0;
3194 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3196 #ifdef SIS315H
3197 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3198 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3199 if(SiS_Pr->UseCustomMode) {
3200 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3201 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3202 } else {
3203 if(ModeNo < 0x13) {
3204 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3205 } else {
3206 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3208 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3209 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3210 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3211 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3213 } else {
3214 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3215 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3217 } else {
3218 /* This handles custom modes and custom panels */
3219 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3220 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3221 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3222 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3223 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3224 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3227 SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
3229 #endif
3231 } else {
3233 /* 301BDH needs LVDS Data */
3234 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3235 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3238 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3239 &CRT2Index, &ResIndex, HwInfo);
3241 /* 301BDH needs LVDS Data */
3242 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3243 SiS_Pr->SiS_IF_DEF_LVDS = 0;
3246 switch (CRT2Index) {
3247 case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3248 case 1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
3249 case 2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3250 case 3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
3251 case 4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
3252 case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
3253 case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3254 case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
3255 case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
3256 case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
3257 case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3258 case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3259 case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3260 case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3261 case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
3262 case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3263 case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
3264 case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
3265 case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
3266 case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
3267 case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
3268 case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
3269 case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
3270 case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
3271 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3272 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3273 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3274 case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
3275 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3276 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3277 case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3278 case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3279 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3280 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3281 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
3282 default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3285 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3286 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3287 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3288 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3290 if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
3291 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3292 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3293 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3294 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3295 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3296 if(ResIndex < 0x08) {
3297 SiS_Pr->SiS_HDE = 1280;
3298 SiS_Pr->SiS_VDE = 1024;
3307 static void
3308 SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3309 USHORT RefreshRateTableIndex,
3310 PSIS_HW_INFO HwInfo)
3312 UCHAR *ROMAddr = NULL;
3313 USHORT tempax,tempbx,modeflag,romptr=0;
3314 USHORT resinfo,CRT2Index,ResIndex;
3315 const SiS_LCDDataStruct *LCDPtr = NULL;
3316 const SiS_TVDataStruct *TVPtr = NULL;
3317 #ifdef SIS315H
3318 SHORT resinfo661;
3319 #endif
3321 if(ModeNo <= 0x13) {
3322 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3323 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3324 } else if(SiS_Pr->UseCustomMode) {
3325 modeflag = SiS_Pr->CModeFlag;
3326 resinfo = 0;
3327 } else {
3328 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3329 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3330 #ifdef SIS315H
3331 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3332 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3333 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3334 (resinfo661 >= 0) &&
3335 (SiS_Pr->SiS_NeedRomModeData) ) {
3336 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
3337 if((romptr = (SISGETROMW(21)))) {
3338 romptr += (resinfo661 * 10);
3339 ROMAddr = HwInfo->pjVirtualRomBase;
3343 #endif
3346 SiS_Pr->SiS_NewFlickerMode = 0;
3347 SiS_Pr->SiS_RVBHRS = 50;
3348 SiS_Pr->SiS_RY1COE = 0;
3349 SiS_Pr->SiS_RY2COE = 0;
3350 SiS_Pr->SiS_RY3COE = 0;
3351 SiS_Pr->SiS_RY4COE = 0;
3353 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
3355 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
3357 if(SiS_Pr->UseCustomMode) {
3359 SiS_Pr->SiS_RVBHCMAX = 1;
3360 SiS_Pr->SiS_RVBHCFACT = 1;
3361 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3362 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3363 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3364 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3365 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3366 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3368 } else {
3370 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3374 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3376 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3377 &CRT2Index,&ResIndex,HwInfo);
3379 switch(CRT2Index) {
3380 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3381 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3382 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3383 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3384 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3385 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3386 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3387 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3388 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3389 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3390 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3391 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3392 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3393 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3396 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3397 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3398 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3399 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3400 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3401 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3402 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3403 SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3404 if(modeflag & HalfDCLK) {
3405 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3408 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3410 if((resinfo == SIS_RI_1024x768) ||
3411 (resinfo == SIS_RI_1280x1024) ||
3412 (resinfo == SIS_RI_1280x720)) {
3413 SiS_Pr->SiS_NewFlickerMode = 0x40;
3416 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3418 SiS_Pr->SiS_HT = ExtHiTVHT;
3419 SiS_Pr->SiS_VT = ExtHiTVVT;
3420 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3421 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3422 SiS_Pr->SiS_HT = StHiTVHT;
3423 SiS_Pr->SiS_VT = StHiTVVT;
3424 #if 0
3425 if(!(modeflag & Charx8Dot)) {
3426 SiS_Pr->SiS_HT = StHiTextTVHT;
3427 SiS_Pr->SiS_VT = StHiTextTVVT;
3429 #endif
3433 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3435 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3436 SiS_Pr->SiS_HT = 1650;
3437 SiS_Pr->SiS_VT = 750;
3438 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3439 SiS_Pr->SiS_HT = NTSCHT;
3440 SiS_Pr->SiS_VT = NTSCVT;
3441 } else {
3442 SiS_Pr->SiS_HT = NTSCHT;
3443 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3444 SiS_Pr->SiS_VT = NTSCVT;
3447 } else {
3449 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3450 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3451 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3452 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3454 if(modeflag & HalfDCLK) {
3455 SiS_Pr->SiS_RY1COE = 0x00;
3456 SiS_Pr->SiS_RY2COE = 0xf4;
3457 SiS_Pr->SiS_RY3COE = 0x10;
3458 SiS_Pr->SiS_RY4COE = 0x38;
3461 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3462 SiS_Pr->SiS_HT = NTSCHT;
3463 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3464 SiS_Pr->SiS_VT = NTSCVT;
3465 } else {
3466 SiS_Pr->SiS_HT = PALHT;
3467 SiS_Pr->SiS_VT = PALVT;
3472 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3474 SiS_Pr->SiS_RVBHCMAX = 1;
3475 SiS_Pr->SiS_RVBHCFACT = 1;
3477 if(SiS_Pr->UseCustomMode) {
3479 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3480 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3481 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3482 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3483 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3484 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3486 } else {
3488 BOOLEAN gotit = FALSE;
3490 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3492 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3493 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3494 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3495 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3496 gotit = TRUE;
3498 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3500 #ifdef SIS315H
3501 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3502 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3503 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3504 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3505 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3506 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3507 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3508 else {
3509 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3510 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
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;
3517 #endif
3521 if(!gotit) {
3523 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3524 &CRT2Index,&ResIndex,HwInfo);
3526 switch(CRT2Index) {
3527 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3528 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3529 case Panel_1280x720 :
3530 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3531 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3532 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3533 case Panel_1280x800 :
3534 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3535 case Panel_1280x800_2 :
3536 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3537 case Panel_1280x960 :
3538 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3539 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3540 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3541 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3542 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3543 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3544 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3545 case Panel_1680x1050 :
3546 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3547 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3548 #ifdef SIS315H
3549 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3550 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3551 #endif
3552 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3555 #ifdef TWDEBUG
3556 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3557 #endif
3559 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3560 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3561 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3562 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3563 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3564 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3568 tempax = SiS_Pr->PanelXRes;
3569 tempbx = SiS_Pr->PanelYRes;
3571 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3572 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3573 if(HwInfo->jChipType < SIS_315H) {
3574 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3575 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3577 } else {
3578 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3579 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3580 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3581 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3582 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3583 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3585 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
3586 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3587 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3588 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3589 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3590 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3591 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3592 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3593 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
3594 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3595 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3596 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3600 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3601 tempax = SiS_Pr->SiS_VGAHDE;
3602 tempbx = SiS_Pr->SiS_VGAVDE;
3605 SiS_Pr->SiS_HDE = tempax;
3606 SiS_Pr->SiS_VDE = tempbx;
3611 static void
3612 SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3613 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3616 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3618 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3619 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3620 } else {
3621 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3622 /* Need LVDS Data for LCD on 301B-DH */
3623 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3624 } else {
3625 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3629 } else {
3631 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3636 /*********************************************/
3637 /* GET LVDS DES (SKEW) DATA */
3638 /*********************************************/
3640 static void
3641 SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3642 USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3643 USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3645 USHORT modeflag;
3647 if(ModeNo <= 0x13) {
3648 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3649 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3650 } else {
3651 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3652 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3655 (*ResIndex) &= 0x1F;
3656 (*PanelIndex) = 0;
3658 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3659 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3660 (*PanelIndex) = 50;
3661 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
3662 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
3663 /* Nothing special needed for SOverscan */
3664 /* PALM uses NTSC data, PALN uses PAL data */
3668 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3669 *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
3670 if(HwInfo->jChipType >= SIS_661) {
3671 /* As long as we don's use the BIOS tables, we
3672 * need to convert the TypeInfo as for 315 series
3674 (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
3676 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3677 (*PanelIndex) += 16;
3678 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3679 (*PanelIndex) = 32;
3680 if(modeflag & HalfDCLK) (*PanelIndex)++;
3685 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3686 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
3687 (*ResIndex) = 7;
3688 if(HwInfo->jChipType < SIS_315H) {
3689 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
3695 static void
3696 SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3697 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3699 USHORT modeflag;
3700 USHORT PanelIndex,ResIndex;
3701 const SiS_LVDSDesStruct *PanelDesPtr = NULL;
3703 SiS_Pr->SiS_LCDHDES = 0;
3704 SiS_Pr->SiS_LCDVDES = 0;
3706 if( (SiS_Pr->UseCustomMode) ||
3707 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3708 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3709 ((SiS_Pr->SiS_VBType & VB_SISVB) &&
3710 (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3711 (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3712 return;
3715 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3717 #ifdef SIS315H
3718 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3719 /* non-pass 1:1 only, see above */
3720 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3721 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3723 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3724 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3727 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3728 switch(SiS_Pr->SiS_CustomT) {
3729 case CUT_UNIWILL1024:
3730 case CUT_UNIWILL10242:
3731 case CUT_CLEVO1400:
3732 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3733 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3735 break;
3737 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3738 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3739 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3743 #endif
3745 } else {
3747 SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3748 &PanelIndex, &ResIndex, HwInfo);
3750 switch(PanelIndex) {
3751 case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */
3752 case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break;
3753 case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break;
3754 case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break;
3755 case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break;
3756 case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break;
3757 case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break;
3758 case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break;
3759 case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break;
3760 case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break;
3761 case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break;
3762 case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break;
3763 case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break;
3764 case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break;
3765 case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break;
3766 case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break;
3767 case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */
3768 case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break;
3769 case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break;
3770 case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break;
3771 case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break;
3772 case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break;
3773 case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break;
3774 case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break;
3775 case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break;
3776 case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break;
3777 case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break;
3778 case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break;
3779 case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break;
3780 case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break;
3781 case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break;
3782 case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break;
3783 case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */
3784 case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break;
3785 case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */
3786 case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
3787 case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
3788 case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
3789 default: return;
3792 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3793 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3795 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3796 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3797 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3798 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3799 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3800 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3801 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3802 if(HwInfo->jChipType < SIS_315H) {
3803 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3804 } else {
3805 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3806 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3807 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3808 if(!(modeflag & HalfDCLK)) {
3809 SiS_Pr->SiS_LCDHDES = 320;
3810 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3811 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3821 /*********************************************/
3822 /* DISABLE VIDEO BRIDGE */
3823 /*********************************************/
3825 /* NEVER use any variables (VBInfo), this will be called
3826 * from outside the context of modeswitch!
3827 * MUST call getVBType before calling this
3829 void
3830 SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3832 #ifdef SIS315H
3833 USHORT tempah,pushax=0,modenum;
3834 #endif
3835 USHORT temp=0;
3837 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3839 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
3841 if(HwInfo->jChipType < SIS_315H) {
3843 #ifdef SIS300 /* 300 series */
3845 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3846 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3847 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3848 } else {
3849 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3851 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3853 if(SiS_Is301B(SiS_Pr)) {
3854 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3855 SiS_ShortDelay(SiS_Pr,1);
3857 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3858 SiS_DisplayOff(SiS_Pr);
3859 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3860 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3861 SiS_UnLockCRT2(SiS_Pr,HwInfo);
3862 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
3863 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3864 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3866 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3867 (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3868 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3869 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3870 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3871 } else {
3872 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3876 #endif /* SIS300 */
3878 } else {
3880 #ifdef SIS315H /* 315 series */
3882 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3883 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3885 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3887 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3889 #ifdef SET_EMI
3890 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3891 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3892 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3895 #endif
3896 if( (modenum <= 0x13) ||
3897 (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3898 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
3899 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3900 if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3903 if(!custom1) {
3904 SiS_DDC2Delay(SiS_Pr,0xff00);
3905 SiS_DDC2Delay(SiS_Pr,0xe000);
3906 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3907 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3908 if(IS_SIS740) {
3909 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3911 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3916 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
3917 if(HwInfo->jChipType < SIS_340) {
3918 tempah = 0xef;
3919 if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
3920 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3924 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3925 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3928 tempah = 0x3f;
3929 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3930 tempah = 0x7f;
3931 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
3933 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3935 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3936 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3938 SiS_DisplayOff(SiS_Pr);
3939 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3940 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3942 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3943 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3947 if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
3948 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3950 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3951 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3952 SiS_DisplayOff(SiS_Pr);
3954 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3956 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3957 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3960 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3961 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3962 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3963 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3964 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3968 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
3969 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3972 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3974 if(!custom1) {
3976 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3977 if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3978 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3979 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3984 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3986 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3987 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
3988 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
3992 } else {
3994 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3995 (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
3996 if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
3997 (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
3998 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3999 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4000 SiS_PanelDelay(SiS_Pr, HwInfo, 4);
4007 #endif /* SIS315H */
4011 } else { /* ============ For 301 ================ */
4013 if(HwInfo->jChipType < SIS_315H) {
4014 #ifdef SIS300
4015 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4016 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4017 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4019 #endif
4022 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4023 SiS_DisplayOff(SiS_Pr);
4025 if(HwInfo->jChipType >= SIS_315H) {
4026 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4029 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4031 if(HwInfo->jChipType >= SIS_315H) {
4032 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4033 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4034 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4035 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4036 } else {
4037 #ifdef SIS300
4038 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4039 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4040 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4041 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4042 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4044 #endif
4049 } else { /* ============ For LVDS =============*/
4051 if(HwInfo->jChipType < SIS_315H) {
4053 #ifdef SIS300 /* 300 series */
4055 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4056 SiS_SetCH700x(SiS_Pr,0x090E);
4059 if(HwInfo->jChipType == SIS_730) {
4060 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4061 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4063 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4064 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4065 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4067 } else {
4068 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4069 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4070 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4071 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4072 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4073 SiS_DisplayOff(SiS_Pr);
4075 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4076 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4082 SiS_DisplayOff(SiS_Pr);
4084 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4086 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4087 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4088 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4089 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4091 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4092 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4093 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4094 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4097 #endif /* SIS300 */
4099 } else {
4101 #ifdef SIS315H /* 315 series */
4103 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4104 if(HwInfo->jChipType < SIS_340) {
4105 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4109 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4111 if(HwInfo->jChipType == SIS_740) {
4112 temp = SiS_GetCH701x(SiS_Pr,0x61);
4113 if(temp < 1) {
4114 SiS_SetCH701x(SiS_Pr,0xac76);
4115 SiS_SetCH701x(SiS_Pr,0x0066);
4118 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4119 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4120 SiS_SetCH701x(SiS_Pr,0x3e49);
4124 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4125 (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
4126 SiS_Chrontel701xBLOff(SiS_Pr);
4127 SiS_Chrontel701xOff(SiS_Pr,HwInfo);
4130 if(HwInfo->jChipType != SIS_740) {
4131 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4132 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4133 SiS_SetCH701x(SiS_Pr,0x0149);
4139 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4140 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4141 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4144 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4145 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4146 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
4147 SiS_DisplayOff(SiS_Pr);
4150 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4151 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4152 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4153 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4156 if(HwInfo->jChipType == SIS_740) {
4157 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4160 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4162 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4163 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4164 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4165 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4168 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4169 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4170 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4171 if(HwInfo->jChipType == SIS_550) {
4172 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4173 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4176 } else {
4177 if(HwInfo->jChipType == SIS_740) {
4178 if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
4179 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4181 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4182 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4186 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4187 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4188 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4189 } else {
4190 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4194 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4196 if(HwInfo->jChipType == SIS_550) {
4197 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4198 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4199 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4200 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4201 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4202 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4205 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4206 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4207 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4208 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4209 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4214 #endif /* SIS315H */
4216 } /* 315 series */
4218 } /* LVDS */
4222 /*********************************************/
4223 /* ENABLE VIDEO BRIDGE */
4224 /*********************************************/
4226 /* NEVER use any variables (VBInfo), this will be called
4227 * from outside the context of a mode switch!
4228 * MUST call getVBType before calling this
4230 void
4231 SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4233 USHORT temp=0,tempah;
4234 #ifdef SIS315H
4235 USHORT temp1,pushax=0;
4236 BOOLEAN delaylong = FALSE;
4237 #endif
4239 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4241 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */
4243 if(HwInfo->jChipType < SIS_315H) {
4245 #ifdef SIS300 /* 300 series */
4247 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4248 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4249 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4250 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4251 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4253 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
4254 if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
4255 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4260 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4261 (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4263 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4264 SiS_DisplayOn(SiS_Pr);
4265 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4266 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4267 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4268 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4269 } else {
4270 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4272 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4273 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4274 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4275 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4277 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4278 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4282 } else {
4284 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4285 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4286 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4287 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4289 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4290 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4291 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4292 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4293 SiS_DisplayOn(SiS_Pr);
4294 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4295 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4296 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4297 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4298 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4300 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4308 #endif /* SIS300 */
4310 } else {
4312 #ifdef SIS315H /* 315 series */
4314 #ifdef SET_EMI
4315 UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
4316 /* USHORT emidelay=0; */
4317 #endif
4319 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4320 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4321 #ifdef SET_EMI
4322 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4323 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4325 #endif
4328 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
4329 if(HwInfo->jChipType < SIS_340) {
4330 tempah = 0x10;
4331 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4332 if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4333 else tempah = 0x08;
4335 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4339 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4341 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4342 SiS_DisplayOff(SiS_Pr);
4343 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4344 if(IS_SIS740) {
4345 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4348 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4349 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4350 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4351 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4352 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4353 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4354 SiS_GenericDelay(SiS_Pr, 0x4500);
4359 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4360 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4361 delaylong = TRUE;
4366 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4368 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4369 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4370 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4371 if(!(tempah & SetCRT2ToRAMDAC)) {
4372 if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
4375 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4377 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4379 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4380 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4382 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4383 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4386 } else {
4388 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4392 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4393 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4395 tempah = 0xc0;
4396 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
4397 tempah = 0x80;
4398 if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
4400 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4402 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4404 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4406 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4407 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4409 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4410 #ifdef SET_EMI
4411 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4412 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4413 SiS_GenericDelay(SiS_Pr, 0x500);
4415 #endif
4416 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4418 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4419 #ifdef SET_EMI
4420 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4422 if(SiS_Pr->SiS_ROMNew) {
4423 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4424 USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
4425 if(romptr) {
4426 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4427 SiS_Pr->EMI_30 = 0;
4428 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4429 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4430 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4431 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4432 /* emidelay = SISGETROMW((romptr + 0x22)); */
4433 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4437 /* (P4_30|0x40) */
4438 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4439 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4440 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4441 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4442 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4443 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4444 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4445 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4446 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4448 if(SiS_Pr->HaveEMI) {
4449 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4450 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4451 } else {
4452 r30 = 0;
4455 /* EMI_30 is read at driver start; however, the BIOS sets this
4456 * (if it is used) only if the LCD is in use. In case we caught
4457 * the machine while on TV output, this bit is not set and we
4458 * don't know if it should be set - hence our detection is wrong.
4459 * Work-around this here:
4462 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4463 switch((cr36 & 0x0f)) {
4464 case 2:
4465 r30 |= 0x40;
4466 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4467 if(!SiS_Pr->HaveEMI) {
4468 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4469 if((cr36 & 0xf0) == 0x30) {
4470 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4473 break;
4474 case 3: /* 1280x1024 */
4475 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4476 if(!SiS_Pr->HaveEMI) {
4477 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4478 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4479 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4482 break;
4483 case 9: /* 1400x1050 */
4484 r30 |= 0x40;
4485 if(!SiS_Pr->HaveEMI) {
4486 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4487 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4488 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4491 break;
4492 case 11: /* 1600x1200 - unknown */
4493 r30 |= 0x40;
4494 if(!SiS_Pr->HaveEMI) {
4495 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4500 /* BIOS values don't work so well sometimes */
4501 if(!SiS_Pr->OverruleEMI) {
4502 #ifdef COMPAL_HACK
4503 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4504 if((cr36 & 0x0f) == 0x09) {
4505 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4508 #endif
4509 #ifdef COMPAQ_HACK
4510 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4511 if((cr36 & 0x0f) == 0x03) {
4512 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4515 #endif
4516 #ifdef ASUS_HACK
4517 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4518 if((cr36 & 0x0f) == 0x02) {
4519 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4520 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4521 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4522 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4525 #endif
4528 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4529 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4530 SiS_GenericDelay(SiS_Pr, 0x500);
4532 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4533 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4534 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4535 #endif /* SET_EMI */
4537 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4539 #ifdef SET_EMI
4540 if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
4541 (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4542 if(r30 & 0x40) {
4543 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4544 if(delaylong) {
4545 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4546 delaylong = FALSE;
4548 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4549 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4550 SiS_GenericDelay(SiS_Pr, 0x500);
4552 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4555 #endif
4559 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4560 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4561 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4562 if(delaylong) {
4563 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4565 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4566 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4567 SiS_GenericDelay(SiS_Pr, 0x500);
4569 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4573 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4574 SiS_DisplayOn(SiS_Pr);
4575 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4579 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4580 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4583 #endif /* SIS315H */
4587 } else { /* ============ For 301 ================ */
4589 if(HwInfo->jChipType < SIS_315H) {
4590 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4591 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4592 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4596 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4597 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4598 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4599 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4601 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4603 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4605 if(HwInfo->jChipType >= SIS_315H) {
4606 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4607 if(!(temp & 0x80)) {
4608 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4612 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4614 SiS_VBLongWait(SiS_Pr);
4615 SiS_DisplayOn(SiS_Pr);
4616 if(HwInfo->jChipType >= SIS_315H) {
4617 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4619 SiS_VBLongWait(SiS_Pr);
4621 if(HwInfo->jChipType < SIS_315H) {
4622 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4623 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4624 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4630 } else { /* =================== For LVDS ================== */
4632 if(HwInfo->jChipType < SIS_315H) {
4634 #ifdef SIS300 /* 300 series */
4636 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4637 if(HwInfo->jChipType == SIS_730) {
4638 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4639 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4640 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4642 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4643 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4644 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4648 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4649 SiS_DisplayOn(SiS_Pr);
4650 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4651 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4652 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4653 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4654 } else {
4655 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4658 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4659 if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4660 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4661 SiS_SetCH700x(SiS_Pr,0x0B0E);
4665 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4666 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4667 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4668 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4669 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4670 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4672 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4673 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4678 #endif /* SIS300 */
4680 } else {
4682 #ifdef SIS315H /* 315 series */
4684 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4685 if(HwInfo->jChipType < SIS_340) {
4686 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4690 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4691 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4692 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4693 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4697 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4698 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4700 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4702 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4703 temp = SiS_GetCH701x(SiS_Pr,0x66);
4704 temp &= 0x20;
4705 SiS_Chrontel701xBLOff(SiS_Pr);
4708 if(HwInfo->jChipType != SIS_550) {
4709 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4712 if(HwInfo->jChipType == SIS_740) {
4713 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4714 if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
4715 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4720 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4721 if(!(temp1 & 0x80)) {
4722 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4725 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4726 if(temp) {
4727 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4731 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4732 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4733 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4734 if(HwInfo->jChipType == SIS_550) {
4735 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4736 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4739 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4740 if(HwInfo->jChipType != SIS_740) {
4741 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4745 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4746 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4749 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4750 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
4751 SiS_Chrontel701xOn(SiS_Pr,HwInfo);
4753 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4754 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4755 SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
4759 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4760 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4761 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4762 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4763 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4764 SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
4767 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4768 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4769 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4770 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4771 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4776 #endif /* SIS315H */
4778 } /* 310 series */
4780 } /* LVDS */
4784 /*********************************************/
4785 /* SET PART 1 REGISTER GROUP */
4786 /*********************************************/
4788 /* Set CRT2 OFFSET / PITCH */
4789 static void
4790 SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
4791 USHORT RRTI, PSIS_HW_INFO HwInfo)
4793 USHORT offset;
4794 UCHAR temp;
4796 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4798 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
4800 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
4801 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
4802 offset >>= 1;
4805 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4806 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4807 temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
4808 if(offset % 8) temp++;
4809 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4812 /* Set CRT2 sync and PanelLink mode */
4813 static void
4814 SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
4815 PSIS_HW_INFO HwInfo)
4817 USHORT tempah=0,tempbl,infoflag;
4819 tempbl = 0xC0;
4821 if(SiS_Pr->UseCustomMode) {
4822 infoflag = SiS_Pr->CInfoFlag;
4823 } else {
4824 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4827 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4829 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4830 tempah = 0;
4831 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4832 tempah = SiS_Pr->SiS_LCDInfo;
4833 } else tempah = infoflag >> 8;
4834 tempah &= 0xC0;
4835 tempah |= 0x20;
4836 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4837 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4838 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4839 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4840 tempah |= 0xf0;
4842 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4843 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4844 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4845 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
4846 tempah |= 0x30;
4849 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4850 if(HwInfo->jChipType >= SIS_315H) {
4851 tempah >>= 3;
4852 tempah &= 0x18;
4853 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4854 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4855 } else {
4856 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4858 } else {
4859 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4862 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4864 if(HwInfo->jChipType < SIS_315H) {
4866 #ifdef SIS300 /* ---- 300 series --- */
4868 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */
4870 tempah = infoflag >> 8;
4871 tempbl = 0;
4872 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4873 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4874 tempah = SiS_Pr->SiS_LCDInfo;
4875 tempbl = (tempah >> 6) & 0x03;
4878 tempah &= 0xC0;
4879 tempah |= 0x20;
4880 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4881 tempah |= 0xc0;
4882 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4883 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4884 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4887 } else { /* 630 - 301 */
4889 tempah = infoflag >> 8;
4890 tempah &= 0xC0;
4891 tempah |= 0x20;
4892 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4893 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4897 #endif /* SIS300 */
4899 } else {
4901 #ifdef SIS315H /* ------- 315 series ------ */
4903 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - LVDS */
4905 tempbl = 0;
4906 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4907 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4908 tempah = infoflag >> 8;
4909 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4910 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4912 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4913 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4914 tempah = infoflag >> 8;
4915 tempbl = 0x03;
4916 } else {
4917 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4918 tempbl = (tempah >> 6) & 0x03;
4919 tempbl |= 0x08;
4920 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4922 tempah &= 0xC0;
4923 tempah |= 0x20;
4924 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4925 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4926 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4927 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4928 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4929 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4933 } else { /* 315 - TMDS */
4935 tempah = tempbl = infoflag >> 8;
4936 if(!SiS_Pr->UseCustomMode) {
4937 tempbl = 0;
4938 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4939 if(ModeNo <= 0x13) {
4940 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4943 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4944 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4945 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4946 tempah = SiS_Pr->SiS_LCDInfo;
4947 tempbl = (tempah >> 6) & 0x03;
4952 tempah &= 0xC0;
4953 tempah |= 0x20;
4954 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4955 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4956 /* Imitate BIOS bug */
4957 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4959 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4960 tempah >>= 3;
4961 tempah &= 0x18;
4962 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4963 } else {
4964 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4965 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4966 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4967 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4973 #endif /* SIS315H */
4978 /* Set CRT2 FIFO on 300/630/730 */
4979 #ifdef SIS300
4980 static void
4981 SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
4982 PSIS_HW_INFO HwInfo)
4984 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4985 USHORT temp,index;
4986 USHORT modeidindex,refreshratetableindex;
4987 USHORT VCLK=0,MCLK,colorth=0,data2=0;
4988 USHORT tempal, tempah, tempbx, tempcl, tempax;
4989 USHORT CRT1ModeNo,CRT2ModeNo;
4990 USHORT SelectRate_backup;
4991 ULONG data,eax;
4992 const UCHAR LatencyFactor[] = {
4993 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
4994 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
4995 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
4996 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
4997 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
4998 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
4999 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
5000 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
5002 const UCHAR LatencyFactor730[] = {
5003 69, 63, 61,
5004 86, 79, 77,
5005 103, 96, 94,
5006 120,113,111,
5007 137,130,128, /* <-- last entry, data below */
5008 137,130,128, /* to avoid using illegal values */
5009 137,130,128,
5010 137,130,128,
5011 137,130,128,
5012 137,130,128,
5013 137,130,128,
5014 137,130,128,
5015 137,130,128,
5016 137,130,128,
5017 137,130,128,
5018 137,130,128,
5020 const UCHAR ThLowB[] = {
5021 81, 4, 72, 6, 88, 8,120,12,
5022 55, 4, 54, 6, 66, 8, 90,12,
5023 42, 4, 45, 6, 55, 8, 75,12
5025 const UCHAR ThTiming[] = {
5026 1, 2, 2, 3, 0, 1, 1, 2
5029 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5031 if(!SiS_Pr->CRT1UsesCustomMode) {
5033 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5034 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5035 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5036 SiS_Pr->SiS_SelectCRT2Rate = 0;
5037 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
5039 if(CRT1ModeNo >= 0x13) {
5040 index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
5041 index &= 0x3F;
5042 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5044 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); /* Get colordepth */
5045 colorth >>= 1;
5046 if(!colorth) colorth++;
5049 } else {
5051 CRT1ModeNo = 0xfe;
5052 VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
5053 data2 = (SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2;
5054 switch(data2) { /* Get color depth */
5055 case 0 : colorth = 1; break;
5056 case 1 : colorth = 1; break;
5057 case 2 : colorth = 2; break;
5058 case 3 : colorth = 2; break;
5059 case 4 : colorth = 3; break;
5060 case 5 : colorth = 4; break;
5061 default: colorth = 2;
5066 if(CRT1ModeNo >= 0x13) {
5067 if(HwInfo->jChipType == SIS_300) {
5068 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5069 } else {
5070 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5072 index &= 0x07;
5073 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
5075 data2 = (colorth * VCLK) / MCLK;
5077 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5078 temp = ((temp & 0x00FF) >> 6) << 1;
5079 if(temp == 0) temp = 1;
5080 temp <<= 2;
5081 temp &= 0xff;
5083 data2 = temp - data2;
5085 if((28 * 16) % data2) {
5086 data2 = (28 * 16) / data2;
5087 data2++;
5088 } else {
5089 data2 = (28 * 16) / data2;
5092 if(HwInfo->jChipType == SIS_300) {
5094 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
5095 tempah &= 0x62;
5096 tempah >>= 1;
5097 tempal = tempah;
5098 tempah >>= 3;
5099 tempal |= tempah;
5100 tempal &= 0x07;
5101 tempcl = ThTiming[tempal];
5102 tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
5103 tempbx >>= 6;
5104 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5105 tempah >>= 4;
5106 tempah &= 0x0c;
5107 tempbx |= tempah;
5108 tempbx <<= 1;
5109 tempal = ThLowB[tempbx + 1];
5110 tempal *= tempcl;
5111 tempal += ThLowB[tempbx];
5112 data = tempal;
5114 } else if(HwInfo->jChipType == SIS_730) {
5116 #ifndef LINUX_XF86
5117 SiS_SetRegLong(0xcf8,0x80000050);
5118 eax = SiS_GetRegLong(0xcfc);
5119 #else
5120 eax = pciReadLong(0x00000000, 0x50);
5121 #endif
5122 tempal = (USHORT)(eax >> 8);
5123 tempal &= 0x06;
5124 tempal <<= 5;
5126 #ifndef LINUX_XF86
5127 SiS_SetRegLong(0xcf8,0x800000A0);
5128 eax = SiS_GetRegLong(0xcfc);
5129 #else
5130 eax = pciReadLong(0x00000000, 0xA0);
5131 #endif
5132 temp = (USHORT)(eax >> 28);
5133 temp &= 0x0F;
5134 tempal |= temp;
5136 tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5137 tempbx = 0; /* -- do it like the BIOS anyway... */
5138 tempax = tempbx;
5139 tempbx &= 0xc0;
5140 tempbx >>= 6;
5141 tempax &= 0x0f;
5142 tempax *= 3;
5143 tempbx += tempax;
5145 data = LatencyFactor730[tempbx];
5146 data += 15;
5147 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5148 if(!(temp & 0x80)) data += 5;
5150 } else {
5152 index = 0;
5153 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5154 if(temp & 0x0080) index += 12;
5156 #ifndef LINUX_XF86
5157 SiS_SetRegLong(0xcf8,0x800000A0);
5158 eax = SiS_GetRegLong(0xcfc);
5159 #else
5160 /* We use pci functions X offers. We use tag 0, because
5161 * we want to read/write to the host bridge (which is always
5162 * 00:00.0 on 630, 730 and 540), not the VGA device.
5164 eax = pciReadLong(0x00000000, 0xA0);
5165 #endif
5166 temp = (USHORT)(eax >> 24);
5167 if(!(temp&0x01)) index += 24;
5169 #ifndef LINUX_XF86
5170 SiS_SetRegLong(0xcf8,0x80000050);
5171 eax = SiS_GetRegLong(0xcfc);
5172 #else
5173 eax = pciReadLong(0x00000000, 0x50);
5174 #endif
5175 temp=(USHORT)(eax >> 24);
5176 if(temp & 0x01) index += 6;
5178 temp = (temp & 0x0F) >> 1;
5179 index += temp;
5181 data = LatencyFactor[index];
5182 data += 15;
5183 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5184 if(!(temp & 0x80)) data += 5;
5187 data += data2; /* CRT1 Request Period */
5189 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5190 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5192 if(!SiS_Pr->UseCustomMode) {
5194 CRT2ModeNo = ModeNo;
5195 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5197 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
5199 index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
5200 refreshratetableindex,HwInfo);
5201 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5203 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5204 if(SiS_Pr->SiS_UseROM) {
5205 if(ROMAddr[0x220] & 0x01) {
5206 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5211 } else {
5213 CRT2ModeNo = 0xfe;
5214 VCLK = SiS_Pr->CSRClock; /* Get VCLK */
5218 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
5219 colorth >>= 1;
5220 if(!colorth) colorth++;
5222 data = data * VCLK * colorth;
5223 if(data % (MCLK << 4)) {
5224 data = data / (MCLK << 4);
5225 data++;
5226 } else {
5227 data = data / (MCLK << 4);
5230 if(data <= 6) data = 6;
5231 if(data > 0x14) data = 0x14;
5233 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
5234 if(HwInfo->jChipType == SIS_300) {
5235 if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
5236 else temp = (temp & (~0x1F)) | 0x16;
5237 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
5238 temp = (temp & (~0x1F)) | 0x13;
5240 } else {
5241 if( ( (HwInfo->jChipType == SIS_630) ||
5242 (HwInfo->jChipType == SIS_730) ) &&
5243 (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5245 temp = (temp & (~0x1F)) | 0x1b;
5246 } else {
5247 temp = (temp & (~0x1F)) | 0x16;
5250 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5252 if( (HwInfo->jChipType == SIS_630) &&
5253 (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
5255 if(data > 0x13) data = 0x13;
5257 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5259 } else { /* If mode <= 0x13, we just restore everything */
5261 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5262 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5266 #endif
5268 /* Set CRT2 FIFO on 315/330 series */
5269 #ifdef SIS315H
5270 static void
5271 SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
5273 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5274 if( (HwInfo->jChipType == SIS_760) &&
5275 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5276 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5277 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5278 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5279 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5280 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5281 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5282 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5283 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5284 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5285 } else {
5286 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5290 #endif
5292 static USHORT
5293 SiS_GetVGAHT2(SiS_Private *SiS_Pr)
5295 ULONG tempax,tempbx;
5297 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5298 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5299 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5300 return((USHORT)tempax);
5303 /* Set Part 1 / SiS bridge slave mode */
5304 static void
5305 SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5306 PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
5308 USHORT push1,push2;
5309 USHORT tempax,tempbx,tempcx,temp;
5310 USHORT resinfo,modeflag,xres=0;
5311 unsigned char p1_7, p1_8;
5313 if(ModeNo <= 0x13) {
5314 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5315 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5316 } else if(SiS_Pr->UseCustomMode) {
5317 modeflag = SiS_Pr->CModeFlag;
5318 resinfo = 0;
5319 xres = SiS_Pr->CHDisplay;
5320 } else {
5321 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5322 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5323 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5326 /* The following is only done if bridge is in slave mode: */
5328 if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
5329 if(xres >= 1600) {
5330 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5334 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
5336 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
5338 if(modeflag & Charx8Dot) tempcx = 0x08;
5339 else tempcx = 0x09;
5341 tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
5342 if(modeflag & HalfDCLK) tempax >>= 1;
5343 tempax = ((tempax / tempcx) - 1) & 0xff;
5344 tempbx = tempax;
5346 temp = tempax;
5347 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5349 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5350 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
5351 temp += 2;
5354 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5355 if(resinfo == SIS_RI_800x600) temp -= 2;
5357 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
5359 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
5361 tempax = 0xFFFF;
5362 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5363 if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5364 if(modeflag & HalfDCLK) tempax >>= 1;
5365 tempax = (tempax / tempcx) - 5;
5366 tempcx = tempax;
5368 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5369 temp = tempcx - 1;
5370 if(!(modeflag & HalfDCLK)) {
5371 temp -= 6;
5372 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5373 temp -= 2;
5374 if(ModeNo > 0x13) temp -= 10;
5377 } else {
5378 tempcx = (tempcx + tempbx) >> 1;
5379 temp = (tempcx & 0x00FF) + 2;
5380 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5381 temp--;
5382 if(!(modeflag & HalfDCLK)) {
5383 if((modeflag & Charx8Dot)) {
5384 temp += 4;
5385 if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5386 if(HwInfo->jChipType >= SIS_315H) {
5387 if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5391 } else {
5392 if(!(modeflag & HalfDCLK)) {
5393 temp -= 4;
5394 if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
5395 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
5396 if(SiS_Pr->SiS_VGAHDE >= 800) {
5397 temp -= 7;
5398 if(HwInfo->jChipType < SIS_315H) {
5399 if(SiS_Pr->SiS_ModeType == ModeEGA) {
5400 if(SiS_Pr->SiS_VGAVDE == 1024) {
5401 temp += 15;
5402 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
5403 temp += 7;
5407 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5408 if(SiS_Pr->SiS_VGAHDE >= 1280) {
5409 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5418 p1_7 = temp;
5419 p1_8 = 0x00;
5421 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5422 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5423 if(ModeNo <= 0x01) {
5424 p1_7 = 0x2a;
5425 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5426 else p1_8 = 0x41;
5427 } else if(SiS_Pr->SiS_ModeType == ModeText) {
5428 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5429 else p1_7 = 0x55;
5430 p1_8 = 0x00;
5431 } else if(ModeNo <= 0x13) {
5432 if(modeflag & HalfDCLK) {
5433 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5434 p1_7 = 0x30;
5435 p1_8 = 0x03;
5436 } else {
5437 p1_7 = 0x2f;
5438 p1_8 = 0x02;
5440 } else {
5441 p1_7 = 0x5b;
5442 p1_8 = 0x03;
5444 } else if( ((HwInfo->jChipType >= SIS_315H) &&
5445 ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5446 ((HwInfo->jChipType < SIS_315H) &&
5447 (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5448 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5449 p1_7 = 0x30,
5450 p1_8 = 0x03;
5451 } else {
5452 p1_7 = 0x2f;
5453 p1_8 = 0x03;
5459 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
5460 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
5461 p1_7 = 0x63;
5462 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
5464 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5465 if(!(modeflag & HalfDCLK)) {
5466 p1_7 = 0xb2;
5467 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
5468 p1_7 = 0xab;
5471 } else {
5472 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
5473 if(modeflag & HalfDCLK) p1_7 = 0x30;
5478 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */
5479 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */
5481 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */
5483 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
5485 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */
5487 tempcx = 0x121;
5488 tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */
5489 if (tempbx == 357) tempbx = 350;
5490 else if(tempbx == 360) tempbx = 350;
5491 else if(tempbx == 375) tempbx = 350;
5492 else if(tempbx == 405) tempbx = 400;
5493 else if(tempbx == 420) tempbx = 400;
5494 else if(tempbx == 525) tempbx = 480;
5495 push2 = tempbx;
5496 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5497 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5498 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5499 if (tempbx == 350) tempbx += 5;
5500 else if(tempbx == 480) tempbx += 5;
5504 tempbx -= 2;
5505 temp = tempbx & 0x00FF;
5506 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
5508 tempbx = push2;
5509 tempbx--;
5510 temp = tempbx & 0x00FF;
5511 #if 0
5512 /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5513 if(xxx()) {
5514 if(temp == 0xdf) temp = 0xda;
5516 #endif
5517 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5519 temp = 0;
5520 if(modeflag & DoubleScanMode) temp |= 0x80;
5521 if(HwInfo->jChipType >= SIS_661) {
5522 if(tempbx & 0x0200) temp |= 0x20;
5523 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5524 if(tempbx & 0x0100) tempcx |= 0x000a;
5525 if(tempbx & 0x0400) tempcx |= 0x1200;
5526 } else {
5527 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5528 if(tempbx & 0x0100) tempcx |= 0x0002;
5529 if(tempbx & 0x0400) tempcx |= 0x0600;
5532 if(tempbx & 0x0200) tempcx |= 0x0040;
5534 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */
5536 tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
5538 if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
5539 if(resinfo != SIS_RI_1280x1024) {
5540 tempbx += (tempax << 1);
5542 } else if(HwInfo->jChipType >= SIS_315H) {
5543 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5544 tempbx += (tempax << 1);
5548 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5549 tempbx -= 10;
5550 } else {
5551 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5552 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5553 tempbx += 40;
5554 if(HwInfo->jChipType >= SIS_315H) {
5555 if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5560 tempax >>= 2;
5561 tempax++;
5562 tempax += tempbx;
5563 push1 = tempax;
5564 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5565 if(tempbx <= 513) {
5566 if(tempax >= 513) tempbx = 513;
5569 temp = tempbx & 0x00FF;
5570 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */
5572 tempbx--;
5573 temp = tempbx & 0x00FF;
5574 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5576 if(tempbx & 0x0100) tempcx |= 0x0008;
5578 if(tempbx & 0x0200) {
5579 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5581 tempbx++;
5583 if(tempbx & 0x0100) tempcx |= 0x0004;
5584 if(tempbx & 0x0200) tempcx |= 0x0080;
5585 if(tempbx & 0x0400) {
5586 if(HwInfo->jChipType >= SIS_661) tempcx |= 0x0800;
5587 else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5588 else tempcx |= 0x0C00;
5591 tempbx = push1;
5592 temp = tempbx & 0x000F;
5593 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
5595 if(tempbx & 0x0010) tempcx |= 0x2000;
5597 temp = tempcx & 0x00FF;
5598 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
5600 temp = (tempcx & 0xFF00) >> 8;
5601 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */
5603 tempax = modeflag;
5604 temp = (tempax & 0xFF00) >> 8;
5605 temp = (temp >> 1) & 0x09;
5606 if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01; /* Always 8 dotclock */
5607 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
5609 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */
5611 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */
5613 temp = 0x00;
5614 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5615 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
5616 temp = 0x80;
5619 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
5621 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5622 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
5625 /* Setup panel link
5626 * This is used for LVDS, LCDA and Chrontel TV output
5627 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5629 static void
5630 SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5631 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5633 USHORT modeflag,resinfo;
5634 USHORT push2,tempax,tempbx,tempcx,temp;
5635 ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
5636 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5637 #ifdef SIS300
5638 USHORT crt2crtc;
5639 #endif
5640 #ifdef SIS315H
5641 USHORT pushcx;
5642 #endif
5644 if(ModeNo <= 0x13) {
5645 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5646 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5647 #ifdef SIS300
5648 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5649 #endif
5650 } else if(SiS_Pr->UseCustomMode) {
5651 modeflag = SiS_Pr->CModeFlag;
5652 resinfo = 0;
5653 #ifdef SIS300
5654 crt2crtc = 0;
5655 #endif
5656 } else {
5657 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5658 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5659 #ifdef SIS300
5660 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5661 #endif
5664 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5665 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5666 islvds = TRUE;
5669 /* is really sis if sis bridge, but not 301B-DH */
5670 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5671 issis = TRUE;
5674 if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5675 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5676 chkdclkfirst = TRUE;
5680 #ifdef SIS315H
5681 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5682 if(IS_SIS330) {
5683 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5684 } else if(IS_SIS740) {
5685 if(islvds) {
5686 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5687 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5688 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5689 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5691 } else {
5692 if(islvds) {
5693 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5694 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5695 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5696 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5697 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
5698 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5699 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5700 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5706 #endif
5708 /* Horizontal */
5710 tempax = SiS_Pr->SiS_LCDHDES;
5711 if(islvds) {
5712 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5713 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5714 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5715 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5716 tempax -= 8;
5722 temp = (tempax & 0x0007);
5723 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5724 temp = (tempax >> 3) & 0x00FF;
5725 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5727 tempbx = SiS_Pr->SiS_HDE;
5728 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5729 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
5730 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
5731 tempbx >>= 1;
5733 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5734 tempbx = SiS_Pr->PanelXRes;
5738 tempax += tempbx;
5739 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5741 temp = tempax;
5742 if(temp & 0x07) temp += 8;
5743 temp >>= 3;
5744 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5746 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5748 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5749 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5750 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5754 tempcx += tempax;
5755 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5757 temp = (tempcx >> 3) & 0x00FF;
5758 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5759 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5760 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5761 switch(ModeNo) {
5762 case 0x04:
5763 case 0x05:
5764 case 0x0d: temp = 0x56; break;
5765 case 0x10: temp = 0x60; break;
5766 case 0x13: temp = 0x5f; break;
5767 case 0x40:
5768 case 0x41:
5769 case 0x4f:
5770 case 0x43:
5771 case 0x44:
5772 case 0x62:
5773 case 0x56:
5774 case 0x53:
5775 case 0x5d:
5776 case 0x5e: temp = 0x54; break;
5781 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5783 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5784 temp += 2;
5785 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5786 temp += 8;
5787 if(SiS_Pr->PanelHRE != 999) {
5788 temp = tempcx + SiS_Pr->PanelHRE;
5789 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5790 temp >>= 3;
5793 } else {
5794 temp += 10;
5797 temp &= 0x1F;
5798 temp |= ((tempcx & 0x07) << 5);
5799 #if 0
5800 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
5801 #endif
5802 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5804 /* Vertical */
5806 tempax = SiS_Pr->SiS_VGAVDE;
5807 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5808 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5809 tempax = SiS_Pr->PanelYRes;
5813 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5814 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5816 push2 = tempbx;
5818 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5819 if(HwInfo->jChipType < SIS_315H) {
5820 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5821 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5822 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5826 if(islvds) tempcx >>= 1;
5827 else tempcx >>= 2;
5829 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5830 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5831 (SiS_Pr->PanelVRS != 999) ) {
5832 tempcx = SiS_Pr->PanelVRS;
5833 tempbx += tempcx;
5834 if(issis) tempbx++;
5835 } else {
5836 tempbx += tempcx;
5837 if(HwInfo->jChipType < SIS_315H) tempbx++;
5838 else if(issis) tempbx++;
5841 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; /* BPLVRS */
5843 temp = tempbx & 0x00FF;
5844 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5845 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5846 if(ModeNo == 0x10) temp = 0xa9;
5849 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
5851 tempcx >>= 3;
5852 tempcx++;
5854 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5855 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5856 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5860 tempcx += tempbx;
5861 temp = tempcx & 0x000F;
5862 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5864 temp = ((tempbx >> 8) & 0x07) << 3;
5865 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5866 if(SiS_Pr->SiS_HDE != 640) {
5867 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5869 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5870 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5871 tempbx = 0x87;
5872 if((HwInfo->jChipType >= SIS_315H) ||
5873 (HwInfo->jChipRevision >= 0x30)) {
5874 tempbx = 0x07;
5875 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5876 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5878 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
5879 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5880 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5881 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5882 } else {
5883 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5887 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5889 tempbx = push2; /* BPLVDEE */
5891 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5893 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5894 switch(SiS_Pr->SiS_LCDResInfo) {
5895 case Panel_640x480:
5896 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5897 tempcx = SiS_Pr->SiS_VGAVDE;
5898 break;
5899 case Panel_800x600:
5900 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5901 if(resinfo == SIS_RI_800x600) tempcx++;
5903 break;
5904 case Panel_1024x600:
5905 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5906 if(resinfo == SIS_RI_1024x600) tempcx++;
5907 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5908 if(resinfo == SIS_RI_800x600) tempcx++;
5911 break;
5912 case Panel_1024x768:
5913 if(HwInfo->jChipType < SIS_315H) {
5914 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5915 if(resinfo == SIS_RI_1024x768) tempcx++;
5918 break;
5922 temp = ((tempbx >> 8) & 0x07) << 3;
5923 temp = temp | ((tempcx >> 8) & 0x07);
5924 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5925 /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++; */
5926 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5927 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5929 /* Vertical scaling */
5931 if(HwInfo->jChipType < SIS_315H) {
5933 #ifdef SIS300 /* 300 series */
5934 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5935 temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
5936 tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
5937 if(temp) tempeax++;
5939 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5941 temp = (USHORT)(tempeax & 0x00FF);
5942 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5943 tempvcfact = temp;
5944 #endif /* SIS300 */
5946 } else {
5948 #ifdef SIS315H /* 315 series */
5949 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5950 tempebx = SiS_Pr->SiS_VDE;
5951 temp = (tempeax % tempebx);
5952 tempeax = tempeax / tempebx;
5953 if(temp) tempeax++;
5954 tempvcfact = tempeax;
5956 temp = (USHORT)(tempeax & 0x00FF);
5957 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5958 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5959 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5960 temp = (USHORT)((tempeax & 0x00030000) >> 16);
5961 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5962 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5964 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
5965 temp = (USHORT)(tempeax & 0x00FF);
5966 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5967 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5968 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5969 temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
5970 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5971 temp = 0;
5972 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5973 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5975 #endif
5979 /* Horizontal scaling */
5981 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5982 if(chkdclkfirst) {
5983 if(modeflag & HalfDCLK) tempeax >>= 1;
5985 tempebx = tempeax << 16;
5986 if(SiS_Pr->SiS_HDE == tempeax) {
5987 tempecx = 0xFFFF;
5988 } else {
5989 tempecx = tempebx / SiS_Pr->SiS_HDE;
5990 if(HwInfo->jChipType >= SIS_315H) {
5991 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5995 if(HwInfo->jChipType >= SIS_315H) {
5996 tempeax = (tempebx / tempecx) - 1;
5997 } else {
5998 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6000 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6001 temp = (USHORT)(tempecx & 0x00FF);
6002 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6004 if(HwInfo->jChipType >= SIS_315H) {
6005 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6006 tempbx = (USHORT)(tempeax & 0xFFFF);
6007 } else {
6008 tempeax = SiS_Pr->SiS_VGAVDE << 6;
6009 tempbx = tempvcfact & 0x3f;
6010 if(tempbx == 0) tempbx = 64;
6011 tempeax /= tempbx;
6012 tempbx = (USHORT)(tempeax & 0xFFFF);
6014 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6015 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6016 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6017 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
6020 temp = ((tempbx >> 8) & 0x07) << 3;
6021 temp = temp | ((tempecx >> 8) & 0x07);
6022 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6023 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6025 tempecx >>= 16; /* BPLHCFACT */
6026 if(!chkdclkfirst) {
6027 if(modeflag & HalfDCLK) tempecx >>= 1;
6029 temp = (USHORT)((tempecx & 0xFF00) >> 8);
6030 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6031 temp = (USHORT)(tempecx & 0x00FF);
6032 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6034 #ifdef SIS315H
6035 if(HwInfo->jChipType >= SIS_315H) {
6036 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6037 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
6038 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6040 } else {
6041 if(islvds) {
6042 if(HwInfo->jChipType == SIS_740) {
6043 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6044 } else {
6045 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6050 #endif
6052 #ifdef SIS300
6053 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6054 int i;
6055 UCHAR TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
6056 UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6057 UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6059 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6060 for(i=0; i<5; i++) {
6061 SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
6063 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6064 if(ModeNo == 0x13) {
6065 for(i=0; i<4; i++) {
6066 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6068 } else if(ModeNo == 0x10) {
6069 for(i=0; i<4; i++) {
6070 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6071 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6075 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6077 #endif
6079 #ifdef SIS315H
6080 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6081 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6082 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6083 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6084 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6085 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6086 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6087 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6088 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6089 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6090 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6091 tempax += 64;
6092 temp = tempax & 0x00FF;
6093 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
6094 temp = ((tempax & 0xFF00) >> 8) << 3;
6095 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6096 tempax += 32; /* Blpe=lBlps+32 */
6097 temp = tempax & 0x00FF;
6098 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
6099 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
6100 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */
6101 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
6103 tempax = SiS_Pr->SiS_VDE;
6104 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6105 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6106 tempax >>= 1;
6107 temp = tempax & 0x00FF;
6108 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
6109 temp = ((tempax & 0xFF00) >> 8) << 3;
6110 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6112 tempeax = SiS_Pr->SiS_HDE;
6113 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6114 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
6115 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6116 tempebx = 128;
6117 temp = (USHORT)(tempeax % tempebx);
6118 tempeax = tempeax / tempebx;
6119 if(temp) tempeax++;
6120 temp = (USHORT)(tempeax & 0x003F);
6121 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
6122 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6123 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6124 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6125 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
6127 tempax = SiS_Pr->SiS_HDE;
6128 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6129 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6130 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6131 pushcx = tempax;
6132 temp = tempax & 0x00FF;
6133 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6134 temp = ((tempax & 0xFF00) >> 8) << 3;
6135 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
6137 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6138 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6139 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6140 tempeax = (tempax * pushcx);
6141 tempebx = 0x00100000 + tempeax;
6142 temp = (USHORT)tempebx & 0x000000FF;
6143 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6144 temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
6145 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6146 temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
6147 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6148 temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
6149 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6151 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6152 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6153 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6154 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6155 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6157 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6158 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6159 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6160 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6161 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6162 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6163 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6165 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6166 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6167 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6168 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6169 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6170 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6171 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6172 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6173 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6174 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6175 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6176 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6177 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6180 #endif /* SIS315H */
6183 /* Set Part 1 */
6184 static void
6185 SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6186 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
6188 #if defined(SIS300) || defined(SIS315H)
6189 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
6190 #endif
6191 USHORT temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6192 USHORT pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6193 #ifdef SIS315H
6194 USHORT tempbl=0;
6195 #endif
6197 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6198 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6199 return;
6202 if(ModeNo <= 0x13) {
6203 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6204 } else if(SiS_Pr->UseCustomMode) {
6205 modeflag = SiS_Pr->CModeFlag;
6206 } else {
6207 CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
6208 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6209 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6212 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
6214 if( ! ((HwInfo->jChipType >= SIS_315H) &&
6215 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6216 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6218 if(HwInfo->jChipType < SIS_315H ) {
6219 #ifdef SIS300
6220 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
6221 #endif
6222 } else {
6223 #ifdef SIS315H
6224 SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
6225 #endif
6228 /* 1. Horizontal setup */
6230 if(HwInfo->jChipType < SIS_315H ) {
6232 #ifdef SIS300 /* ------------- 300 series --------------*/
6234 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6235 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6237 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6238 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6240 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6241 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6243 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6244 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6245 tempbx = pushbx + tempcx;
6246 tempcx <<= 1;
6247 tempcx += tempbx;
6249 bridgeadd = 12;
6251 #endif /* SIS300 */
6253 } else {
6255 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6257 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6258 if(modeflag & HalfDCLK) {
6259 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6260 tempcx >>= 1;
6261 } else {
6262 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6263 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6264 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6265 tempcx = SiS_Pr->SiS_HT - tempax;
6269 tempcx--;
6270 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6271 temp = (tempcx >> 4) & 0xF0;
6272 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6274 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6275 tempbx = SiS_Pr->SiS_VGAHDE;
6276 tempcx -= tempbx;
6277 tempcx >>= 2;
6278 if(modeflag & HalfDCLK) {
6279 tempbx >>= 1;
6280 tempcx >>= 1;
6282 tempbx += 16;
6284 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6286 pushbx = tempbx;
6287 tempcx >>= 1;
6288 tempbx += tempcx;
6289 tempcx += tempbx;
6291 bridgeadd = 16;
6293 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6294 if(HwInfo->jChipType >= SIS_661) {
6295 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6296 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6297 if(resinfo == SIS_RI_1280x1024) {
6298 tempcx = (tempcx & 0xff00) | 0x30;
6299 } else if(resinfo == SIS_RI_1600x1200) {
6300 tempcx = (tempcx & 0xff00) | 0xff;
6306 #endif /* SIS315H */
6308 } /* 315/330 series */
6310 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6312 if(SiS_Pr->UseCustomMode) {
6313 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6314 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6315 tempax = SiS_Pr->SiS_VGAHT;
6316 if(modeflag & HalfDCLK) tempax >>= 1;
6317 tempax--;
6318 if(tempcx > tempax) tempcx = tempax;
6321 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6322 unsigned char cr4, cr14, cr5, cr15;
6323 if(SiS_Pr->UseCustomMode) {
6324 cr4 = SiS_Pr->CCRT1CRTC[4];
6325 cr14 = SiS_Pr->CCRT1CRTC[14];
6326 cr5 = SiS_Pr->CCRT1CRTC[5];
6327 cr15 = SiS_Pr->CCRT1CRTC[15];
6328 } else {
6329 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6330 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6331 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6332 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6334 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6335 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6336 tempcx &= 0x00FF;
6337 tempcx |= (tempbx & 0xFF00);
6338 tempbx += bridgeadd;
6339 tempcx += bridgeadd;
6340 tempax = SiS_Pr->SiS_VGAHT;
6341 if(modeflag & HalfDCLK) tempax >>= 1;
6342 tempax--;
6343 if(tempcx > tempax) tempcx = tempax;
6346 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6347 tempbx = 1040;
6348 tempcx = 1044; /* HWCursor bug! */
6353 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6355 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6357 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6358 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6360 /* 2. Vertical setup */
6362 tempcx = SiS_Pr->SiS_VGAVT - 1;
6363 temp = tempcx & 0x00FF;
6365 if(HwInfo->jChipType < SIS_661) {
6366 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6367 if(HwInfo->jChipType < SIS_315H) {
6368 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6369 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6370 temp--;
6373 } else {
6374 temp--;
6376 } else if(HwInfo->jChipType >= SIS_315H) {
6377 temp--;
6380 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6382 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6383 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6385 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6386 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6388 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
6389 tempbx++;
6390 tempax = tempbx;
6391 tempcx++;
6392 tempcx -= tempax;
6393 tempcx >>= 2;
6394 tempbx += tempcx;
6395 if(tempcx < 4) tempcx = 4;
6396 tempcx >>= 2;
6397 tempcx += tempbx;
6398 tempcx++;
6399 } else {
6400 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6401 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6404 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6405 if(SiS_Pr->UseCustomMode) {
6406 tempbx = SiS_Pr->CVSyncStart;
6407 tempcx = SiS_Pr->CVSyncEnd;
6409 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6410 unsigned char cr8, cr7, cr13;
6411 if(SiS_Pr->UseCustomMode) {
6412 cr8 = SiS_Pr->CCRT1CRTC[8];
6413 cr7 = SiS_Pr->CCRT1CRTC[7];
6414 cr13 = SiS_Pr->CCRT1CRTC[13];
6415 tempcx = SiS_Pr->CCRT1CRTC[9];
6416 } else {
6417 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6418 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6419 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6420 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6422 tempbx = cr8;
6423 if(cr7 & 0x04) tempbx |= 0x0100;
6424 if(cr7 & 0x80) tempbx |= 0x0200;
6425 if(cr13 & 0x08) tempbx |= 0x0400;
6428 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6430 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6431 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6433 /* 3. Panel delay compensation */
6435 if(HwInfo->jChipType < SIS_315H) {
6437 #ifdef SIS300 /* ---------- 300 series -------------- */
6439 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6440 temp = 0x20;
6441 if(HwInfo->jChipType == SIS_300) {
6442 temp = 0x10;
6443 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6444 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6446 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6447 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6449 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6450 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6451 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6452 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6453 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6454 else temp = 0x20;
6456 if(SiS_Pr->SiS_UseROM) {
6457 if(ROMAddr[0x220] & 0x80) {
6458 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6459 temp = ROMAddr[0x221];
6460 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6461 temp = ROMAddr[0x222];
6462 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6463 temp = ROMAddr[0x223];
6464 else
6465 temp = ROMAddr[0x224];
6466 temp &= 0x3c;
6469 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6470 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6473 } else {
6474 temp = 0x20;
6475 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6476 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6478 if(SiS_Pr->SiS_UseROM) {
6479 if(ROMAddr[0x220] & 0x80) {
6480 temp = ROMAddr[0x220] & 0x3c;
6483 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6484 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6488 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6490 #endif /* SIS300 */
6492 } else {
6494 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6496 if(HwInfo->jChipType < SIS_661) {
6498 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6500 if(HwInfo->jChipType == SIS_740) temp = 0x03;
6501 else temp = 0x00;
6503 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6504 tempbl = 0xF0;
6505 if(HwInfo->jChipType == SIS_650) {
6506 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6507 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6511 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6512 temp = 0x08;
6513 tempbl = 0;
6514 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6515 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6519 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6522 } /* < 661 */
6524 tempax = 0;
6525 if(modeflag & DoubleScanMode) tempax |= 0x80;
6526 if(modeflag & HalfDCLK) tempax |= 0x40;
6527 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6529 #endif /* SIS315H */
6533 } /* Slavemode */
6535 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6536 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6537 /* For 301BDH with LCD, we set up the Panel Link */
6538 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6539 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6540 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6542 } else {
6543 if(HwInfo->jChipType < SIS_315H) {
6544 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6545 } else {
6546 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6547 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6548 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6550 } else {
6551 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6557 /*********************************************/
6558 /* SET PART 2 REGISTER GROUP */
6559 /*********************************************/
6561 #ifdef SIS315H
6562 static UCHAR *
6563 SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
6565 const UCHAR *tableptr = NULL;
6566 USHORT a, b, p = 0;
6568 a = SiS_Pr->SiS_VGAHDE;
6569 b = SiS_Pr->SiS_HDE;
6570 if(tabletype) {
6571 a = SiS_Pr->SiS_VGAVDE;
6572 b = SiS_Pr->SiS_VDE;
6575 if(a < b) {
6576 tableptr = SiS_Part2CLVX_1;
6577 } else if(a == b) {
6578 tableptr = SiS_Part2CLVX_2;
6579 } else {
6580 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6581 tableptr = SiS_Part2CLVX_4;
6582 } else {
6583 tableptr = SiS_Part2CLVX_3;
6585 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6586 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6587 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6588 else tableptr = SiS_Part2CLVX_5;
6589 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6590 tableptr = SiS_Part2CLVX_6;
6592 do {
6593 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6594 p += 0x42;
6595 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6596 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6598 p += 2;
6599 return((UCHAR *)&tableptr[p]);
6602 static void
6603 SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6604 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
6606 UCHAR *tableptr;
6607 int i, j;
6608 UCHAR temp;
6610 if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
6612 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
6613 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6614 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6616 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6617 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
6618 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6619 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6622 temp = 0x10;
6623 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6624 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6627 static BOOLEAN
6628 SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
6629 USHORT RefreshRateTableIndex,USHORT *CRT2Index,
6630 USHORT *ResIndex,PSIS_HW_INFO HwInfo)
6633 if(HwInfo->jChipType < SIS_315H) return FALSE;
6635 if(ModeNo <= 0x13)
6636 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6637 else
6638 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6640 (*ResIndex) &= 0x3f;
6641 (*CRT2Index) = 0;
6643 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6644 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6645 (*CRT2Index) = 200;
6649 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6650 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6651 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6654 return(((*CRT2Index) != 0));
6656 #endif
6658 #ifdef SIS300
6659 static void
6660 SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
6662 USHORT tempcx;
6663 const UCHAR atable[] = {
6664 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6665 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6668 if(!SiS_Pr->UseCustomMode) {
6669 if( ( ( (HwInfo->jChipType == SIS_630) ||
6670 (HwInfo->jChipType == SIS_730) ) &&
6671 (HwInfo->jChipRevision > 2) ) &&
6672 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6673 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6674 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6675 if(ModeNo == 0x13) {
6676 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6677 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6678 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6679 } else {
6680 if((crt2crtc & 0x3F) == 4) {
6681 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6682 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6683 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6684 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6685 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6690 if(HwInfo->jChipType < SIS_315H) {
6691 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6692 crt2crtc &= 0x1f;
6693 tempcx = 0;
6694 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6695 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6696 tempcx += 7;
6699 tempcx += crt2crtc;
6700 if(crt2crtc >= 4) {
6701 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6704 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6705 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6706 if(crt2crtc == 4) {
6707 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6711 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6712 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6718 /* For ECS A907. Highly preliminary. */
6719 static void
6720 SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6721 USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
6722 USHORT ModeNo)
6724 USHORT crt2crtc, resindex;
6725 int i,j;
6726 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6728 if(HwInfo->jChipType != SIS_300) return;
6729 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6730 if(SiS_Pr->UseCustomMode) return;
6732 if(ModeNo <= 0x13) {
6733 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6734 } else {
6735 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6738 resindex = crt2crtc & 0x3F;
6739 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6740 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6742 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6743 if(ModeNo > 0x13) {
6744 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6745 resindex = 4;
6748 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6749 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6750 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6751 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6753 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6754 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6756 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6757 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6759 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6760 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6762 #endif
6764 static void
6765 SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
6767 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6768 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6769 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6771 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6772 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6773 const UCHAR specialtv[] = {
6774 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6775 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6776 0x58,0xe4,0x73,0xda,0x13
6778 int i, j;
6779 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6780 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6782 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6783 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6784 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6785 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6786 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6787 } else {
6788 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6789 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6793 } else {
6794 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6795 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6796 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6797 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6798 } else {
6799 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6800 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6805 static void
6806 SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6808 USHORT temp;
6810 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6811 if(SiS_Pr->SiS_VGAVDE == 525) {
6812 temp = 0xc3;
6813 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6814 temp++;
6815 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
6817 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6818 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6819 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6820 temp = 0x4d;
6821 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6822 temp++;
6823 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6829 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6830 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6831 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
6832 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6833 /* Not always for LV, see SetGrp2 */
6835 temp = 1;
6836 if(ModeNo <= 0x13) temp = 3;
6837 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6839 #if 0
6840 /* 651+301C, for 1280x768 - do I really need that? */
6841 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6842 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6843 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6844 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6845 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6846 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6847 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6848 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6849 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6850 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6851 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6852 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6853 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6854 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6855 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6856 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6860 #endif
6864 static void
6865 SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
6866 PSIS_HW_INFO HwInfo)
6868 USHORT i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6869 USHORT push2, modeflag, crt2crtc, bridgeoffset;
6870 ULONG longtemp;
6871 const UCHAR *PhasePoint;
6872 const UCHAR *TimingPoint;
6873 #ifdef SIS315H
6874 USHORT resindex, CRT2Index;
6875 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6877 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6878 #endif
6880 if(ModeNo <= 0x13) {
6881 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6882 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6883 } else if(SiS_Pr->UseCustomMode) {
6884 modeflag = SiS_Pr->CModeFlag;
6885 crt2crtc = 0;
6886 } else {
6887 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6888 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6891 temp = 0;
6892 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6893 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6894 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6895 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6897 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6899 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6901 PhasePoint = SiS_Pr->SiS_PALPhase;
6902 TimingPoint = SiS_Pr->SiS_PALTiming;
6904 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6906 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6907 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6908 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6909 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6910 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6911 #if 0
6912 if(!(modeflag & Charx8Dot)) TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
6913 #endif
6917 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6919 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) TimingPoint = &SiS_YPbPrTable[2][0];
6920 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
6921 else TimingPoint = &SiS_YPbPrTable[0][0];
6923 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6925 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6927 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6928 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6929 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6930 PhasePoint = SiS_Pr->SiS_PALPhase2;
6933 } else {
6935 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6936 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6937 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6938 PhasePoint = SiS_Pr->SiS_PALPhase;
6941 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6942 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6943 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6944 PhasePoint = SiS_Pr->SiS_NTSCPhase2;
6945 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6946 PhasePoint = SiS_Pr->SiS_PALPhase2;
6952 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6953 PhasePoint = SiS_Pr->SiS_PALMPhase;
6954 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6955 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6956 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6957 PhasePoint = SiS_Pr->SiS_PALMPhase2;
6961 if(SiS_Pr->SiS_TVMode & TVSetPALN) {
6962 PhasePoint = SiS_Pr->SiS_PALNPhase;
6963 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6964 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6965 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6966 PhasePoint = SiS_Pr->SiS_PALNPhase2;
6970 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6971 PhasePoint = SiS_Pr->SiS_SpecialPhase;
6972 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6973 PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
6974 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6975 PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
6979 for(i=0x31, j=0; i<=0x34; i++, j++) {
6980 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
6983 for(i=0x01, j=0; i<=0x2D; i++, j++) {
6984 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6986 for(i=0x39; i<=0x45; i++, j++) {
6987 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6990 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6991 if(SiS_Pr->SiS_ModeType != ModeText) {
6992 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6996 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6998 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6999 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7000 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7001 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7003 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
7004 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
7005 else tempax = 440; /* NTSC, YPbPr 525, 750 */
7007 if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
7008 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7009 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7011 tempax -= SiS_Pr->SiS_VDE;
7012 tempax >>= 2;
7013 tempax &= 0x00ff;
7015 temp = tempax + (USHORT)TimingPoint[0];
7016 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7018 temp = tempax + (USHORT)TimingPoint[1];
7019 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7021 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7022 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7023 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 19 */
7024 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 52 */
7025 } else {
7026 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7027 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7033 tempcx = SiS_Pr->SiS_HT;
7034 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7035 tempcx--;
7036 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
7037 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7038 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7040 tempcx = SiS_Pr->SiS_HT >> 1;
7041 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7042 tempcx += 7;
7043 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7044 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7046 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7047 tempbx += tempcx;
7048 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7049 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7051 tempbx += 8;
7052 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7053 tempbx -= 4;
7054 tempcx = tempbx;
7056 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7058 j += 2;
7059 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7060 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7061 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7063 tempcx += 8;
7064 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7065 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7067 tempcx = SiS_Pr->SiS_HT >> 1;
7068 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7069 j += 2;
7070 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7071 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7073 tempcx -= 11;
7074 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7075 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7077 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7079 tempbx = SiS_Pr->SiS_VDE;
7080 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7081 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7082 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7083 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7084 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7085 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7086 tempbx >>= 1;
7087 if(HwInfo->jChipType >= SIS_315H) {
7088 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7089 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7090 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7091 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7092 if(crt2crtc == 4) tempbx++;
7096 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7097 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7098 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7100 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7101 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7105 tempbx -= 2;
7106 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7108 temp = (tempcx >> 8) & 0x0F;
7109 temp |= ((tempbx >> 2) & 0xC0);
7110 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7111 temp |= 0x10;
7112 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7114 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7116 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
7117 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7120 #if 0
7121 /* TEST qqqq */
7122 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7123 for(i=0x01, j=0; i<=0x2D; i++, j++) {
7124 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7126 for(i=0x39; i<=0x45; i++, j++) {
7127 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7130 #endif
7132 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7133 tempbx = SiS_Pr->SiS_VDE;
7134 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7135 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7136 tempbx >>= 1;
7138 tempbx -= 3;
7139 temp = ((tempbx >> 3) & 0x60) | 0x18;
7140 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7141 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7143 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
7144 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7148 tempbx = 0;
7149 if(!(modeflag & HalfDCLK)) {
7150 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7151 tempax = 0;
7152 tempbx |= 0x20;
7156 tempch = tempcl = 0x01;
7157 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7158 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7159 if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
7160 tempch = 0x19;
7161 tempcl = 0x20;
7162 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7163 tempch = 0x14;
7164 tempbx &= ~0x20;
7170 if(!(tempbx & 0x20)) {
7171 if(modeflag & HalfDCLK) tempcl <<= 1;
7172 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7173 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
7174 tempax = longtemp / SiS_Pr->SiS_HDE;
7175 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7176 tempbx |= ((tempax >> 8) & 0x1F);
7177 tempcx = tempax >> 13;
7180 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7181 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7183 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7185 tempcx &= 0x07;
7186 if(tempbx & 0x20) tempcx = 0;
7187 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7189 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7190 tempbx = 0x0382;
7191 tempcx = 0x007e;
7192 } else {
7193 tempbx = 0x0369;
7194 tempcx = 0x0061;
7196 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7197 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7198 temp = (tempcx & 0x0300) >> 6;
7199 temp |= ((tempbx >> 8) & 0x03);
7200 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7201 temp |= 0x10;
7202 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7203 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7205 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7207 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7208 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7210 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7212 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
7213 temp = 0;
7214 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7215 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7220 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7221 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7222 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7223 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7225 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7228 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7229 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7230 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7234 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7236 /* From here: Part2 LCD setup */
7238 tempbx = SiS_Pr->SiS_HDE;
7239 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7240 tempbx--; /* RHACTE = HDE - 1 */
7241 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7242 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7244 temp = 0x01;
7245 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7246 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7247 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7248 temp = 0x02;
7249 if(HwInfo->jChipType >= SIS_315H) {
7250 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7251 temp = 0x01;
7257 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7259 tempbx = SiS_Pr->SiS_VDE - 1;
7260 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7261 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7263 tempcx = SiS_Pr->SiS_VT - 1;
7264 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7265 temp = (tempcx >> 3) & 0xE0;
7266 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7267 /* Enable dithering; only do this for 32bpp mode */
7268 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7269 temp |= 0x10;
7272 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7274 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7275 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7277 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7278 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7280 #ifdef SIS315H
7281 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7282 &CRT2Index, &resindex, HwInfo)) {
7283 switch(CRT2Index) {
7284 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7285 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7286 default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
7289 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7290 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7291 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7292 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7294 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7295 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7297 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7298 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7300 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7301 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7303 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7306 } else {
7307 #endif
7309 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7310 /* Clevo dual-link 1024x768 */
7311 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7312 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7314 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7315 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7316 tempbx = SiS_Pr->SiS_VDE - 1;
7317 tempcx = SiS_Pr->SiS_VT - 1;
7318 } else {
7319 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7320 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7322 } else {
7323 tempbx = SiS_Pr->PanelYRes;
7324 tempcx = SiS_Pr->SiS_VT;
7325 tempax = 1;
7326 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7327 tempax = SiS_Pr->PanelYRes;
7328 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7329 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7330 tempax = tempcx = 0;
7331 } else {
7332 tempax -= SiS_Pr->SiS_VDE;
7334 tempax >>= 1;
7336 tempcx -= tempax; /* lcdvdes */
7337 tempbx -= tempax; /* lcdvdee */
7340 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7342 #ifdef TWDEBUG
7343 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7344 #endif
7346 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7347 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7349 temp = (tempbx >> 5) & 0x38;
7350 temp |= ((tempcx >> 8) & 0x07);
7351 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7353 tempax = SiS_Pr->SiS_VDE;
7354 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7355 tempax = SiS_Pr->PanelYRes;
7357 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7358 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7359 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7360 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7364 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7365 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7366 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7367 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7368 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7369 if(tempax % 4) { tempax >>= 2; tempax++; }
7370 else { tempax >>= 2; }
7371 tempbx -= (tempax - 1);
7372 } else {
7373 tempbx -= 10;
7374 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7378 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7379 tempbx++;
7380 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7381 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7382 tempbx = 770;
7383 tempcx = 3;
7388 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7390 if(SiS_Pr->UseCustomMode) {
7391 tempbx = SiS_Pr->CVSyncStart;
7394 #ifdef TWDEBUG
7395 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7396 #endif
7398 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7400 temp = (tempbx >> 4) & 0xF0;
7401 tempbx += (tempcx + 1);
7402 temp |= (tempbx & 0x0F);
7404 if(SiS_Pr->UseCustomMode) {
7405 temp &= 0xf0;
7406 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7409 #ifdef TWDEBUG
7410 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7411 #endif
7413 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7415 #ifdef SIS300
7416 SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
7417 #endif
7419 bridgeoffset = 7;
7420 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) bridgeoffset += 2;
7421 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
7422 if(SiS_IsDualLink(SiS_Pr, HwInfo)) bridgeoffset++;
7424 temp = 0;
7425 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7426 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7427 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7428 if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
7431 temp += bridgeoffset;
7432 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7433 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7435 tempcx = SiS_Pr->SiS_HT;
7436 tempax = tempbx = SiS_Pr->SiS_HDE;
7437 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7438 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7439 tempax = SiS_Pr->PanelXRes;
7440 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7443 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7444 tempcx >>= 1;
7445 tempbx >>= 1;
7446 tempax >>= 1;
7449 #ifdef TWDEBUG
7450 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7451 #endif
7453 tempbx += bridgeoffset;
7455 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7456 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7458 tempcx = (tempcx - tempax) >> 2;
7460 tempbx += tempcx;
7461 push2 = tempbx;
7463 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7464 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7465 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7466 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7471 if(SiS_Pr->UseCustomMode) {
7472 tempbx = SiS_Pr->CHSyncStart;
7473 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7474 tempbx += bridgeoffset;
7477 #ifdef TWDEBUG
7478 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7479 #endif
7481 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7482 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7484 tempbx = push2;
7486 tempcx <<= 1;
7487 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7488 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7490 tempbx += tempcx;
7492 if(SiS_Pr->UseCustomMode) {
7493 tempbx = SiS_Pr->CHSyncEnd;
7494 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7495 tempbx += bridgeoffset;
7498 #ifdef TWDEBUG
7499 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7500 #endif
7502 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7504 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7506 #ifdef SIS300
7507 SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7508 #endif
7509 #ifdef SIS315H
7510 } /* CRT2-LCD from table */
7511 #endif
7514 /*********************************************/
7515 /* SET PART 3 REGISTER GROUP */
7516 /*********************************************/
7518 static void
7519 SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7520 PSIS_HW_INFO HwInfo)
7522 USHORT i;
7523 const UCHAR *tempdi;
7525 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7527 #ifndef SIS_CP
7528 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7529 #else
7530 SIS_CP_INIT301_CP
7531 #endif
7533 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7534 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7535 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7536 } else {
7537 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7538 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7541 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7542 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7543 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7544 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7547 tempdi = NULL;
7548 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7549 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7550 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7551 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7553 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7554 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7555 tempdi = SiS_HiTVGroup3_1;
7556 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7559 if(tempdi) {
7560 for(i=0; i<=0x3E; i++) {
7561 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7563 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
7564 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7565 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7570 #ifdef SIS_CP
7571 SIS_CP_INIT301_CP2
7572 #endif
7575 /*********************************************/
7576 /* SET PART 4 REGISTER GROUP */
7577 /*********************************************/
7579 #ifdef SIS315H
7580 static void
7581 SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
7583 USHORT temp, temp1, temp2;
7585 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7586 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7587 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7588 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7589 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7590 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7591 temp = (USHORT)((int)(temp) + shift);
7592 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7593 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7594 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7595 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7596 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7597 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7600 static void
7601 SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7602 USHORT ModeNo, USHORT ModeIdIndex)
7604 USHORT temp, temp1, resinfo = 0;
7606 if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
7607 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7609 if(ModeNo > 0x13) {
7610 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7613 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7614 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7615 if(!(temp & 0x01)) {
7616 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7617 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7618 if((HwInfo->jChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7619 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7621 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7622 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7623 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7624 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7625 else temp = 0x0402;
7626 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7627 temp1 = 0;
7628 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7629 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7630 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7631 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7632 } else {
7633 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7634 if(temp1 == 0x01) temp |= 0x01;
7635 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7636 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7638 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7639 if(ModeNo > 0x13) {
7640 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7643 if(HwInfo->jChipType >= SIS_661) { /* ? */
7644 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7645 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7646 if(resinfo == SIS_RI_1024x768) {
7647 SiS_ShiftXPos(SiS_Pr, 97);
7648 } else {
7649 SiS_ShiftXPos(SiS_Pr, 111);
7651 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7652 SiS_ShiftXPos(SiS_Pr, 136);
7658 #endif
7660 static void
7661 SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7662 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7664 USHORT vclkindex;
7665 USHORT temp, reg1, reg2;
7667 if(SiS_Pr->UseCustomMode) {
7668 reg1 = SiS_Pr->CSR2B;
7669 reg2 = SiS_Pr->CSR2C;
7670 } else {
7671 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7672 HwInfo);
7673 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7674 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7677 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7678 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7679 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7680 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7681 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7682 } else {
7683 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7684 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7686 } else {
7687 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7688 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7691 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7692 temp = 0x08;
7693 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7694 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7697 static void
7698 SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7699 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7701 USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
7702 ULONG tempebx,tempeax,templong;
7704 if(ModeNo <= 0x13) {
7705 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7706 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7707 } else if(SiS_Pr->UseCustomMode) {
7708 modeflag = SiS_Pr->CModeFlag;
7709 resinfo = 0;
7710 } else {
7711 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7712 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7715 if(HwInfo->jChipType >= SIS_315H) {
7716 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7717 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7718 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7723 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
7724 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7725 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7729 if(HwInfo->jChipType >= SIS_315H) {
7730 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7731 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7732 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7733 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7734 } else {
7735 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7738 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7739 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7740 #ifdef SET_EMI
7741 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7742 #endif
7743 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7746 return;
7750 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7752 tempbx = SiS_Pr->SiS_RVBHCMAX;
7753 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7755 temp = (tempbx >> 1) & 0x80;
7757 tempcx = SiS_Pr->SiS_VGAHT - 1;
7758 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7760 temp |= ((tempcx >> 5) & 0x78);
7762 tempcx = SiS_Pr->SiS_VGAVT - 1;
7763 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7764 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7766 temp |= ((tempcx >> 8) & 0x07);
7767 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7769 tempbx = SiS_Pr->SiS_VGAHDE;
7770 if(modeflag & HalfDCLK) tempbx >>= 1;
7771 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7773 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7774 temp = 0;
7775 if(tempbx > 800) temp = 0x60;
7776 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7777 temp = 0;
7778 if(tempbx == 1024) temp = 0xA0;
7779 else if(tempbx > 1024) temp = 0xC0;
7780 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7781 temp = 0;
7782 if(tempbx >= 1280) temp = 0x40;
7783 else if(tempbx >= 1024) temp = 0x20;
7784 } else {
7785 temp = 0x80;
7786 if(tempbx >= 1024) temp = 0xA0;
7789 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7790 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
7793 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7795 tempeax = SiS_Pr->SiS_VGAVDE;
7796 tempebx = SiS_Pr->SiS_VDE;
7797 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7798 if(!(temp & 0xE0)) tempebx >>=1;
7801 tempcx = SiS_Pr->SiS_RVBHRS;
7802 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7803 tempcx >>= 8;
7804 tempcx |= 0x40;
7806 if(tempeax <= tempebx) {
7807 tempcx ^= 0x40;
7808 } else {
7809 tempeax -= tempebx;
7812 tempeax *= (256 * 1024);
7813 templong = tempeax % tempebx;
7814 tempeax /= tempebx;
7815 if(templong) tempeax++;
7817 temp = (USHORT)(tempeax & 0x000000FF);
7818 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7819 temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
7820 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7821 temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
7822 temp |= (tempcx & 0x4F);
7823 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7825 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7827 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7829 /* Calc Linebuffer max address and set/clear decimode */
7830 tempbx = 0;
7831 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7832 tempax = SiS_Pr->SiS_VGAHDE;
7833 if(modeflag & HalfDCLK) tempax >>= 1;
7834 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
7835 if(tempax > 800) {
7836 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7837 tempax -= 800;
7838 } else { /* 651+301C: Only if TVNoHiviNoYPbPr */
7839 tempbx = 0x08;
7840 if(tempax == 1024) tempax *= 25;
7841 else tempax *= 20;
7842 temp = tempax % 32;
7843 tempax /= 32;
7844 if(temp) tempax++;
7845 tempax++;
7846 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
7847 (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7848 if(resinfo == SIS_RI_1024x768) {
7849 /* Otherwise white line at right edge */
7850 tempax = (tempax & 0xff00) | 0x20;
7855 tempax--;
7856 temp = ((tempax >> 4) & 0x30) | tempbx;
7857 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7858 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7860 temp = 0x0036; tempbx = 0xD0;
7861 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
7862 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7864 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7865 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7866 temp |= 0x01;
7867 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7868 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7869 temp &= ~0x01;
7874 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7876 tempbx = SiS_Pr->SiS_HT >> 1;
7877 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7878 tempbx -= 2;
7879 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7880 temp = (tempbx >> 5) & 0x38;
7881 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7883 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7884 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7885 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7886 /* LCD-too-dark-error-source, see FinalizeLCD() */
7888 if(HwInfo->jChipType >= SIS_315H) {
7889 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7890 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7891 } else {
7892 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7895 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7896 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7897 #ifdef SET_EMI
7898 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7899 #endif
7900 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7904 } /* 301B */
7906 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
7909 /*********************************************/
7910 /* SET PART 5 REGISTER GROUP */
7911 /*********************************************/
7913 static void
7914 SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7915 PSIS_HW_INFO HwInfo)
7918 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7920 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7921 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7922 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7923 SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
7928 /*********************************************/
7929 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7930 /*********************************************/
7932 static void
7933 SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7934 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7936 USHORT tempah,i,modeflag,j;
7937 USHORT ResIndex,DisplayType;
7938 const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
7940 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7941 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7943 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7944 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7945 (SiS_Pr->SiS_CustomT == CUT_PANEL848))
7946 return;
7948 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7949 &ResIndex, &DisplayType))) {
7950 return;
7953 if(HwInfo->jChipType < SIS_315H) {
7954 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7957 switch(DisplayType) {
7958 case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
7959 case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
7960 case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
7961 case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
7962 case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
7963 case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
7964 case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
7965 case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
7966 case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
7967 case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
7968 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
7969 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
7970 case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
7971 case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
7972 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
7973 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
7974 case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
7975 case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
7976 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7977 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7978 case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7979 case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7980 case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */
7981 case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7982 case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7983 case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7984 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7985 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break;
7986 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break;
7987 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break;
7988 case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break;
7989 case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break;
7990 case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break;
7991 case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break;
7992 case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break;
7993 case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1; break;
7994 case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break;
7995 case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break;
7996 case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break;
7997 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7998 case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7999 case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break;
8000 case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break;
8001 case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break;
8002 case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break;
8003 case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
8004 default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
8007 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8009 tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
8010 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
8012 for(i=0x02,j=1;i<=0x05;i++,j++){
8013 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8014 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8016 for(i=0x06,j=5;i<=0x07;i++,j++){
8017 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8018 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8020 for(i=0x10,j=7;i<=0x11;i++,j++){
8021 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8022 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8024 for(i=0x15,j=9;i<=0x16;i++,j++){
8025 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8026 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8028 for(i=0x0A,j=11;i<=0x0C;i++,j++){
8029 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8030 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8033 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8034 tempah &= 0xE0;
8035 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8037 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8038 tempah &= 0x01;
8039 tempah <<= 5;
8040 if(modeflag & DoubleScanMode) tempah |= 0x080;
8041 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8044 /*********************************************/
8045 /* SET CRT2 ECLK */
8046 /*********************************************/
8048 static void
8049 SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8050 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
8052 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8053 USHORT clkbase, vclkindex=0;
8054 UCHAR sr2b, sr2c;
8056 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8057 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8058 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
8059 RefreshRateTableIndex--;
8061 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8062 RefreshRateTableIndex, HwInfo);
8063 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8064 } else {
8065 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8066 RefreshRateTableIndex, HwInfo);
8069 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8070 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8072 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8073 if(SiS_Pr->SiS_UseROM) {
8074 if(ROMAddr[0x220] & 0x01) {
8075 sr2b = ROMAddr[0x227];
8076 sr2c = ROMAddr[0x228];
8081 clkbase = 0x02B;
8082 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8083 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8084 clkbase += 3;
8088 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8089 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8090 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8091 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8092 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8093 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8094 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8095 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8096 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8099 /*********************************************/
8100 /* SET UP CHRONTEL CHIPS */
8101 /*********************************************/
8103 static void
8104 SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8105 USHORT RefreshRateTableIndex)
8107 #if defined(SIS300) || defined(SIS315H)
8108 USHORT temp, tempbx;
8109 #endif
8110 USHORT tempcl;
8111 USHORT TVType, resindex;
8112 const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
8114 if(ModeNo <= 0x13)
8115 tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8116 else
8117 tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8119 TVType = 0;
8120 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8121 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8122 TVType += 2;
8123 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8124 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8126 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8127 TVType = 4;
8128 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8129 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8130 TVType = 6;
8131 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8134 switch(TVType) {
8135 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8136 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8137 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8138 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8139 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8140 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8141 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8142 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8143 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8144 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8146 resindex = tempcl & 0x3F;
8148 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8150 #ifdef SIS300
8152 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8154 /* We don't support modes >800x600 */
8155 if (resindex > 5) return;
8157 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8158 SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8159 SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/
8160 } else {
8161 SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8162 SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/
8165 temp = CHTVRegData[resindex].Reg[0];
8166 tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */
8167 SiS_SetCH700x(SiS_Pr,tempbx);
8168 temp = CHTVRegData[resindex].Reg[1];
8169 tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */
8170 SiS_SetCH700x(SiS_Pr,tempbx);
8171 temp = CHTVRegData[resindex].Reg[2];
8172 tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */
8173 SiS_SetCH700x(SiS_Pr,tempbx);
8174 temp = CHTVRegData[resindex].Reg[3];
8175 tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */
8176 SiS_SetCH700x(SiS_Pr,tempbx);
8177 temp = CHTVRegData[resindex].Reg[4];
8178 tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */
8179 SiS_SetCH700x(SiS_Pr,tempbx);
8181 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8182 minimum text enhancement (S3-2=10),
8183 maximum flicker filter for Chroma channel (S5-4=10)
8184 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8186 SiS_SetCH700x(SiS_Pr,0x2801);
8188 /* Set video bandwidth
8189 High bandwith Luma composite video filter(S0=1)
8190 low bandwith Luma S-video filter (S2-1=00)
8191 disable peak filter in S-video channel (S3=0)
8192 high bandwidth Chroma Filter (S5-4=11)
8193 =00110001=0x31
8195 SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */
8197 /* Register 0x3D does not exist in non-macrovision register map
8198 (Maybe this is a macrovision register?)
8200 #ifndef SIS_CP
8201 SiS_SetCH70xx(SiS_Pr,0x003D);
8202 #endif
8204 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8205 all other bits a read-only. Macrovision?
8207 SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
8209 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8210 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8212 SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
8214 /* Clear DSEN
8216 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
8218 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8219 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8220 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8221 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8222 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on, no need to set FSCI */
8223 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8224 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8225 SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
8226 SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
8227 SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
8228 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
8229 SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
8230 SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
8231 SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
8232 SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF); /* Loop filter on for mode 23 */
8233 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8235 } else {
8236 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8237 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8238 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8239 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8240 #if 0
8241 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8242 SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */
8243 SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0); /* 198b3a63 */
8244 SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
8245 SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
8246 SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
8247 SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
8248 SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
8249 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */
8250 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8251 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8252 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8253 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8256 } else { /* ---- PAL ---- */
8257 /* We don't play around with FSCI in PAL mode */
8258 if(resindex == 0x04) {
8259 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8260 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8261 } else {
8262 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8263 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8267 #endif /* 300 */
8269 } else {
8271 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8273 #ifdef SIS315H
8275 /* We don't support modes >1024x768 */
8276 if (resindex > 6) return;
8278 temp = CHTVRegData[resindex].Reg[0];
8279 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8280 temp |= 0x10;
8282 tempbx=((temp & 0x00FF) << 8) | 0x00;
8283 SiS_SetCH701x(SiS_Pr,tempbx);
8285 temp = CHTVRegData[resindex].Reg[1];
8286 tempbx=((temp & 0x00FF) << 8) | 0x01;
8287 SiS_SetCH701x(SiS_Pr,tempbx);
8289 temp = CHTVRegData[resindex].Reg[2];
8290 tempbx=((temp & 0x00FF) << 8) | 0x02;
8291 SiS_SetCH701x(SiS_Pr,tempbx);
8293 temp = CHTVRegData[resindex].Reg[3];
8294 tempbx=((temp & 0x00FF) << 8) | 0x04;
8295 SiS_SetCH701x(SiS_Pr,tempbx);
8297 temp = CHTVRegData[resindex].Reg[4];
8298 tempbx=((temp & 0x00FF) << 8) | 0x03;
8299 SiS_SetCH701x(SiS_Pr,tempbx);
8301 temp = CHTVRegData[resindex].Reg[5];
8302 tempbx=((temp & 0x00FF) << 8) | 0x05;
8303 SiS_SetCH701x(SiS_Pr,tempbx);
8305 temp = CHTVRegData[resindex].Reg[6];
8306 tempbx=((temp & 0x00FF) << 8) | 0x06;
8307 SiS_SetCH701x(SiS_Pr,tempbx);
8309 temp = CHTVRegData[resindex].Reg[7];
8310 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8311 temp = 0x66;
8313 tempbx=((temp & 0x00FF) << 8) | 0x07;
8314 SiS_SetCH701x(SiS_Pr,tempbx);
8316 temp = CHTVRegData[resindex].Reg[8];
8317 tempbx=((temp & 0x00FF) << 8) | 0x08;
8318 SiS_SetCH701x(SiS_Pr,tempbx);
8320 temp = CHTVRegData[resindex].Reg[9];
8321 tempbx=((temp & 0x00FF) << 8) | 0x15;
8322 SiS_SetCH701x(SiS_Pr,tempbx);
8324 temp = CHTVRegData[resindex].Reg[10];
8325 tempbx=((temp & 0x00FF) << 8) | 0x1f;
8326 SiS_SetCH701x(SiS_Pr,tempbx);
8328 temp = CHTVRegData[resindex].Reg[11];
8329 tempbx=((temp & 0x00FF) << 8) | 0x0c;
8330 SiS_SetCH701x(SiS_Pr,tempbx);
8332 temp = CHTVRegData[resindex].Reg[12];
8333 tempbx=((temp & 0x00FF) << 8) | 0x0d;
8334 SiS_SetCH701x(SiS_Pr,tempbx);
8336 temp = CHTVRegData[resindex].Reg[13];
8337 tempbx=((temp & 0x00FF) << 8) | 0x0e;
8338 SiS_SetCH701x(SiS_Pr,tempbx);
8340 temp = CHTVRegData[resindex].Reg[14];
8341 tempbx=((temp & 0x00FF) << 8) | 0x0f;
8342 SiS_SetCH701x(SiS_Pr,tempbx);
8344 temp = CHTVRegData[resindex].Reg[15];
8345 tempbx=((temp & 0x00FF) << 8) | 0x10;
8346 SiS_SetCH701x(SiS_Pr,tempbx);
8348 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8349 /* D1 should be set for PAL, PAL-N and NTSC-J,
8350 but I won't do that for PAL unless somebody
8351 tells me to do so. Since the BIOS uses
8352 non-default CIV values and blacklevels,
8353 this might be compensated anyway.
8355 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8356 SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
8358 #endif /* 315 */
8362 #ifdef SIS_CP
8363 SIS_CP_INIT301_CP3
8364 #endif
8368 void
8369 SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8371 USHORT temp;
8373 /* Enable Chrontel 7019 LCD panel backlight */
8374 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8375 if(HwInfo->jChipType == SIS_740) {
8376 SiS_SetCH701x(SiS_Pr,0x6566);
8377 } else {
8378 temp = SiS_GetCH701x(SiS_Pr,0x66);
8379 temp |= 0x20;
8380 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8385 void
8386 SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
8388 USHORT temp;
8390 /* Disable Chrontel 7019 LCD panel backlight */
8391 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8392 temp = SiS_GetCH701x(SiS_Pr,0x66);
8393 temp &= 0xDF;
8394 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8398 #ifdef SIS315H /* ----------- 315 series only ---------- */
8400 static void
8401 SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8403 UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8404 UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8405 UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8406 UCHAR asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8407 UCHAR asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8408 UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8409 UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8410 UCHAR *tableptr = NULL;
8411 int i;
8413 /* Set up Power up/down timing */
8415 if(HwInfo->jChipType == SIS_740) {
8416 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8417 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8418 else tableptr = table1024_740;
8419 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8420 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8421 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8422 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8423 else tableptr = table1400_740;
8424 } else return;
8425 } else {
8426 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8427 tableptr = table1024_650;
8428 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8429 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8430 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8431 tableptr = table1400_650;
8432 } else return;
8435 for(i=0; i<5; i++) {
8436 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8440 static void
8441 SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8443 UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8444 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
8445 UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8446 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
8447 UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8448 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8449 UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8450 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8451 UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8452 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
8453 UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8454 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
8455 UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8456 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
8457 UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8458 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
8459 UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8460 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
8461 UCHAR *tableptr = NULL;
8462 USHORT tempbh;
8463 int i;
8465 if(HwInfo->jChipType == SIS_740) {
8466 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8467 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8468 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8469 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8470 else return;
8471 } else {
8472 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8473 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8474 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8475 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8476 else return;
8479 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8480 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8481 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8482 if(tempbh == 0xc8) {
8483 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8484 } else if(tempbh == 0xdb) {
8485 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8486 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8487 } else if(tempbh == 0xde) {
8488 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8492 if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
8493 else tempbh = 0x0c;
8495 for(i = 0; i < tempbh; i++) {
8496 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8498 SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
8499 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8500 tempbh |= 0xc0;
8501 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
8503 if(HwInfo->jChipType == SIS_740) {
8504 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8505 tempbh &= 0xfb;
8506 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
8507 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8508 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8509 tempbh |= 0x40;
8510 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
8511 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8512 tempbh &= 0x3f;
8513 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
8517 static void
8518 SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
8520 unsigned char temp, temp1;
8522 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8523 SiS_SetCH701x(SiS_Pr,0x3e49);
8524 temp = SiS_GetCH701x(SiS_Pr,0x47);
8525 temp &= 0x7f; /* Use external VSYNC */
8526 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8527 SiS_LongDelay(SiS_Pr,3);
8528 temp = SiS_GetCH701x(SiS_Pr,0x47);
8529 temp |= 0x80; /* Use internal VSYNC */
8530 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8531 SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
8534 void
8535 SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8537 USHORT temp;
8539 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8540 if(HwInfo->jChipType == SIS_740) {
8541 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8542 temp |= 0x04; /* Invert XCLK phase */
8543 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8545 if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
8546 temp = SiS_GetCH701x(SiS_Pr,0x01);
8547 temp &= 0x3f;
8548 temp |= 0x80; /* Enable YPrPb (HDTV) */
8549 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8551 if(SiS_IsChScart(SiS_Pr, HwInfo)) {
8552 temp = SiS_GetCH701x(SiS_Pr,0x01);
8553 temp &= 0x3f;
8554 temp |= 0xc0; /* Enable SCART + CVBS */
8555 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8557 if(HwInfo->jChipType == SIS_740) {
8558 SiS_ChrontelResetVSync(SiS_Pr);
8559 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8560 } else {
8561 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8562 temp = SiS_GetCH701x(SiS_Pr,0x49);
8563 if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
8564 temp = SiS_GetCH701x(SiS_Pr,0x73);
8565 temp |= 0x60;
8566 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
8568 temp = SiS_GetCH701x(SiS_Pr,0x47);
8569 temp &= 0x7f;
8570 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8571 SiS_LongDelay(SiS_Pr,2);
8572 temp = SiS_GetCH701x(SiS_Pr,0x47);
8573 temp |= 0x80;
8574 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8579 void
8580 SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8582 USHORT temp;
8584 /* Complete power down of LVDS */
8585 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8586 if(HwInfo->jChipType == SIS_740) {
8587 SiS_LongDelay(SiS_Pr,1);
8588 SiS_GenericDelay(SiS_Pr,0x16ff);
8589 SiS_SetCH701x(SiS_Pr,0xac76);
8590 SiS_SetCH701x(SiS_Pr,0x0066);
8591 } else {
8592 SiS_LongDelay(SiS_Pr,2);
8593 temp = SiS_GetCH701x(SiS_Pr,0x76);
8594 temp &= 0xfc;
8595 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8596 SiS_SetCH701x(SiS_Pr,0x0066);
8601 static void
8602 SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8604 USHORT temp;
8606 if(HwInfo->jChipType == SIS_740) {
8608 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8609 temp &= 0x01;
8610 if(!temp) {
8612 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8613 temp = SiS_GetCH701x(SiS_Pr,0x49);
8614 SiS_SetCH701x(SiS_Pr,0x3e49);
8616 /* Reset Chrontel 7019 datapath */
8617 SiS_SetCH701x(SiS_Pr,0x1048);
8618 SiS_LongDelay(SiS_Pr,1);
8619 SiS_SetCH701x(SiS_Pr,0x1848);
8621 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8622 SiS_ChrontelResetVSync(SiS_Pr);
8623 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
8626 } else {
8628 /* Clear/set/clear GPIO */
8629 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8630 temp &= 0xef;
8631 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8632 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8633 temp |= 0x10;
8634 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8635 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8636 temp &= 0xef;
8637 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8638 temp = SiS_GetCH701x(SiS_Pr,0x61);
8639 if(!temp) {
8640 SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
8644 } else { /* 650 */
8645 /* Reset Chrontel 7019 datapath */
8646 SiS_SetCH701x(SiS_Pr,0x1048);
8647 SiS_LongDelay(SiS_Pr,1);
8648 SiS_SetCH701x(SiS_Pr,0x1848);
8652 void
8653 SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8655 USHORT temp;
8657 if(HwInfo->jChipType == SIS_740) {
8659 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8660 SiS_ChrontelResetVSync(SiS_Pr);
8663 } else {
8665 SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
8666 temp = SiS_GetCH701x(SiS_Pr,0x49);
8667 temp &= 1;
8668 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8669 temp = SiS_GetCH701x(SiS_Pr,0x47);
8670 temp &= 0x70;
8671 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
8672 SiS_LongDelay(SiS_Pr,3);
8673 temp = SiS_GetCH701x(SiS_Pr,0x47);
8674 temp |= 0x80;
8675 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
8681 static void
8682 SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
8684 USHORT temp,temp1;
8686 if(HwInfo->jChipType == SIS_740) {
8688 temp = SiS_GetCH701x(SiS_Pr,0x61);
8689 if(temp < 1) {
8690 temp++;
8691 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8693 SiS_SetCH701x(SiS_Pr,0x4566); /* Panel power on */
8694 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on */
8695 SiS_LongDelay(SiS_Pr,1);
8696 SiS_GenericDelay(SiS_Pr,0x16ff);
8698 } else { /* 650 */
8700 temp1 = 0;
8701 temp = SiS_GetCH701x(SiS_Pr,0x61);
8702 if(temp < 2) {
8703 temp++;
8704 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8705 temp1 = 1;
8707 SiS_SetCH701x(SiS_Pr,0xac76);
8708 temp = SiS_GetCH701x(SiS_Pr,0x66);
8709 temp |= 0x5f;
8710 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8711 if(ModeNo > 0x13) {
8712 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8713 SiS_GenericDelay(SiS_Pr,0x3ff);
8714 } else {
8715 SiS_GenericDelay(SiS_Pr,0x2ff);
8717 } else {
8718 if(!temp1)
8719 SiS_GenericDelay(SiS_Pr,0x2ff);
8721 temp = SiS_GetCH701x(SiS_Pr,0x76);
8722 temp |= 0x03;
8723 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8724 temp = SiS_GetCH701x(SiS_Pr,0x66);
8725 temp &= 0x7f;
8726 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8727 SiS_LongDelay(SiS_Pr,1);
8732 static void
8733 SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8735 USHORT temp,tempcl,tempch;
8737 SiS_LongDelay(SiS_Pr, 1);
8738 tempcl = 3;
8739 tempch = 0;
8741 do {
8742 temp = SiS_GetCH701x(SiS_Pr,0x66);
8743 temp &= 0x04; /* PLL stable? -> bail out */
8744 if(temp == 0x04) break;
8746 if(HwInfo->jChipType == SIS_740) {
8747 /* Power down LVDS output, PLL normal operation */
8748 SiS_SetCH701x(SiS_Pr,0xac76);
8751 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8753 if(tempcl == 0) {
8754 if(tempch == 3) break;
8755 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8756 tempcl = 3;
8757 tempch++;
8759 tempcl--;
8760 temp = SiS_GetCH701x(SiS_Pr,0x76);
8761 temp &= 0xfb; /* Reset PLL */
8762 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8763 SiS_LongDelay(SiS_Pr,2);
8764 temp = SiS_GetCH701x(SiS_Pr,0x76);
8765 temp |= 0x04; /* PLL normal operation */
8766 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8767 if(HwInfo->jChipType == SIS_740) {
8768 SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */
8769 } else {
8770 SiS_SetCH701x(SiS_Pr,0x6078);
8772 SiS_LongDelay(SiS_Pr,2);
8773 } while(0);
8775 SiS_SetCH701x(SiS_Pr,0x0077); /* MV? */
8778 void
8779 SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8781 USHORT temp;
8783 temp = SiS_GetCH701x(SiS_Pr,0x03);
8784 temp |= 0x80; /* Set datapath 1 to TV */
8785 temp &= 0xbf; /* Set datapath 2 to LVDS */
8786 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8788 if(HwInfo->jChipType == SIS_740) {
8790 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8791 temp &= 0xfb; /* Normal XCLK phase */
8792 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8794 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8796 temp = SiS_GetCH701x(SiS_Pr,0x64);
8797 temp |= 0x40; /* ? Bit not defined */
8798 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
8800 temp = SiS_GetCH701x(SiS_Pr,0x03);
8801 temp &= 0x3f; /* D1 input to both LVDS and TV */
8802 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8804 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8805 SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
8806 SiS_LongDelay(SiS_Pr, 1);
8807 SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
8808 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8809 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8810 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8811 } else {
8812 temp = SiS_GetCH701x(SiS_Pr,0x66);
8813 if(temp != 0x45) {
8814 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8815 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8816 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8820 } else { /* 650 */
8822 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8823 SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
8824 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8825 SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
8826 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on, LVDS normal operation */
8831 #endif /* 315 series */
8833 /*********************************************/
8834 /* MAIN: SET CRT2 REGISTER GROUP */
8835 /*********************************************/
8837 BOOLEAN
8838 SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8840 #ifdef SIS300
8841 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8842 #endif
8843 USHORT ModeIdIndex, RefreshRateTableIndex;
8844 #if 0
8845 USHORT temp;
8846 #endif
8848 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8850 if(!SiS_Pr->UseCustomMode) {
8851 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8852 } else {
8853 ModeIdIndex = 0;
8856 /* Used for shifting CR33 */
8857 SiS_Pr->SiS_SelectCRT2Rate = 4;
8859 SiS_UnLockCRT2(SiS_Pr, HwInfo);
8861 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8863 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8865 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8866 SiS_DisableBridge(SiS_Pr,HwInfo);
8867 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
8868 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8870 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8873 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8874 SiS_LockCRT2(SiS_Pr, HwInfo);
8875 SiS_DisplayOn(SiS_Pr);
8876 return TRUE;
8879 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8881 /* Set up Panel Link for LVDS and LCDA */
8882 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8883 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8884 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8885 ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
8886 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8889 #ifdef LINUX_XF86
8890 #ifdef TWDEBUG
8891 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8892 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8893 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8894 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8895 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8896 #endif
8897 #endif
8899 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8900 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
8903 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8905 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8907 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8908 #ifdef SIS315H
8909 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8910 #endif
8911 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8912 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8913 #ifdef SIS315H
8914 SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8915 #endif
8916 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8918 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8920 /* For 301BDH (Panel link initialization): */
8921 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8922 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
8923 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8924 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8925 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
8926 RefreshRateTableIndex,HwInfo);
8930 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
8931 RefreshRateTableIndex,HwInfo);
8935 } else {
8937 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8939 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8940 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8943 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8945 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8946 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8947 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8948 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8949 #ifdef SIS315H
8950 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8951 #endif
8954 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8955 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8962 #ifdef SIS300
8963 if(HwInfo->jChipType < SIS_315H) {
8964 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8965 if(SiS_Pr->SiS_UseOEM) {
8966 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8967 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8968 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8969 RefreshRateTableIndex);
8971 } else {
8972 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8973 RefreshRateTableIndex);
8976 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8977 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8978 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8979 SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8981 SiS_DisplayOn(SiS_Pr);
8985 #endif
8987 #ifdef SIS315H
8988 if(HwInfo->jChipType >= SIS_315H) {
8989 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8990 if(HwInfo->jChipType < SIS_661) {
8991 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8992 SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8993 } else {
8994 SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8996 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8999 #endif
9001 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9002 SiS_EnableBridge(SiS_Pr, HwInfo);
9005 SiS_DisplayOn(SiS_Pr);
9007 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
9008 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9009 /* Disable LCD panel when using TV */
9010 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
9011 } else {
9012 /* Disable TV when using LCD */
9013 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
9017 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9018 SiS_LockCRT2(SiS_Pr,HwInfo);
9021 return TRUE;
9025 /*********************************************/
9026 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
9027 /*********************************************/
9029 void
9030 SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9032 /* Switch on LCD backlight on SiS30xLV */
9033 SiS_DDC2Delay(SiS_Pr,0xff00);
9034 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9035 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9036 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
9038 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9039 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9043 void
9044 SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9046 /* Switch off LCD backlight on SiS30xLV */
9047 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9048 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
9049 SiS_DDC2Delay(SiS_Pr,0xe000);
9052 /*********************************************/
9053 /* DDC RELATED FUNCTIONS */
9054 /*********************************************/
9056 static void
9057 SiS_SetupDDCN(SiS_Private *SiS_Pr)
9059 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9060 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
9061 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9062 SiS_Pr->SiS_DDC_NData &= 0x0f;
9063 SiS_Pr->SiS_DDC_NClk &= 0x0f;
9067 #ifdef SIS300
9068 static UCHAR *
9069 SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
9071 int i, j, num;
9072 USHORT tempah,temp;
9073 UCHAR *mydataptr;
9075 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9076 mydataptr = dataptr;
9077 num = *mydataptr++;
9078 if(!num) return mydataptr;
9079 if(i) {
9080 SiS_SetStop(SiS_Pr);
9081 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
9083 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9084 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9085 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9086 if(temp) continue; /* (ERROR: no ack) */
9087 tempah = *mydataptr++;
9088 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
9089 if(temp) continue; /* (ERROR: no ack) */
9090 for(j=0; j<num; j++) {
9091 tempah = *mydataptr++;
9092 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9093 if(temp) break;
9095 if(temp) continue;
9096 if(SiS_SetStop(SiS_Pr)) continue;
9097 return mydataptr;
9099 return NULL;
9102 static BOOLEAN
9103 SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
9105 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9106 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9107 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9108 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9109 SiS_SetupDDCN(SiS_Pr);
9111 SiS_SetSwitchDDC2(SiS_Pr);
9113 while(*dataptr) {
9114 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9115 if(!dataptr) return FALSE;
9117 #ifdef TWDEBUG
9118 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
9119 #endif
9120 return TRUE;
9122 #endif
9124 /* The Chrontel 700x is connected to the 630/730 via
9125 * the 630/730's DDC/I2C port.
9127 * On 630(S)T chipset, the index changed from 0x11 to
9128 * 0x0a, possibly for working around the DDC problems
9131 static BOOLEAN
9132 SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
9134 USHORT tempah,temp,i;
9136 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9137 if(i) {
9138 SiS_SetStop(SiS_Pr);
9139 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9141 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9142 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9143 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9144 if(temp) continue; /* (ERROR: no ack) */
9145 tempah = tempbx & 0x00FF; /* Write RAB */
9146 tempah |= myor; /* (700x: set bit 7, see datasheet) */
9147 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9148 if(temp) continue; /* (ERROR: no ack) */
9149 tempah = (tempbx & 0xFF00) >> 8;
9150 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
9151 if(temp) continue; /* (ERROR: no ack) */
9152 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9153 SiS_Pr->SiS_ChrontelInit = 1;
9154 return TRUE;
9156 return FALSE;
9159 #ifdef SIS300
9160 /* Write Trumpion register */
9161 void
9162 SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9164 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9165 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9166 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9167 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9168 SiS_SetupDDCN(SiS_Pr);
9169 SiS_SetChReg(SiS_Pr, tempbx, 0);
9171 #endif
9173 /* Write to Chrontel 700x */
9174 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9175 void
9176 SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9178 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9180 if(!(SiS_Pr->SiS_ChrontelInit)) {
9181 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9182 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9183 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9184 SiS_SetupDDCN(SiS_Pr);
9187 if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
9188 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9189 SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */
9190 SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
9191 SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
9192 SiS_SetupDDCN(SiS_Pr);
9194 SiS_SetChReg(SiS_Pr, tempbx, 0x80);
9198 /* Write to Chrontel 701x */
9199 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9200 void
9201 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9203 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9204 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9205 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9206 SiS_SetupDDCN(SiS_Pr);
9207 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9208 SiS_SetChReg(SiS_Pr, tempbx, 0);
9211 void
9212 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9214 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9215 SiS_SetCH700x(SiS_Pr,tempbx);
9216 else
9217 SiS_SetCH701x(SiS_Pr,tempbx);
9220 static USHORT
9221 SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
9223 USHORT tempah,temp,i;
9225 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9226 if(i) {
9227 SiS_SetStop(SiS_Pr);
9228 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9230 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9231 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9232 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9233 if(temp) continue; /* (ERROR: no ack) */
9234 tempah = SiS_Pr->SiS_DDC_ReadAddr | myor; /* Write RAB (700x: | 0x80) */
9235 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9236 if(temp) continue; /* (ERROR: no ack) */
9237 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9238 tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
9239 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
9240 if(temp) continue; /* (ERROR: no ack) */
9241 tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
9242 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9243 SiS_Pr->SiS_ChrontelInit = 1;
9244 return(tempah);
9246 return 0xFFFF;
9249 #ifdef SIS300
9250 /* Read from Trumpion */
9251 USHORT
9252 SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9254 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB */
9255 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9256 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9257 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9258 SiS_SetupDDCN(SiS_Pr);
9259 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9260 return(SiS_GetChReg(SiS_Pr,0));
9262 #endif
9264 /* Read from Chrontel 700x */
9265 /* Parameter is [Register no (S7-S0)] */
9266 USHORT
9267 SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9269 USHORT result;
9271 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9273 if(!(SiS_Pr->SiS_ChrontelInit)) {
9274 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9275 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9276 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9277 SiS_SetupDDCN(SiS_Pr);
9280 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9282 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9283 (!SiS_Pr->SiS_ChrontelInit) ) {
9285 SiS_Pr->SiS_DDC_Index = 0x0a;
9286 SiS_Pr->SiS_DDC_Data = 0x80;
9287 SiS_Pr->SiS_DDC_Clk = 0x40;
9288 SiS_SetupDDCN(SiS_Pr);
9290 result = SiS_GetChReg(SiS_Pr,0x80);
9292 return(result);
9295 /* Read from Chrontel 701x */
9296 /* Parameter is [Register no (S7-S0)] */
9297 USHORT
9298 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9300 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9301 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9302 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9303 SiS_SetupDDCN(SiS_Pr);
9304 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9306 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9308 return(SiS_GetChReg(SiS_Pr,0));
9311 /* Read from Chrontel 70xx */
9312 /* Parameter is [Register no (S7-S0)] */
9313 USHORT
9314 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9316 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9317 return(SiS_GetCH700x(SiS_Pr, tempbx));
9318 else
9319 return(SiS_GetCH701x(SiS_Pr, tempbx));
9322 /* Our own DDC functions */
9323 USHORT
9324 SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9325 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
9327 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9328 unsigned char flag, cr32;
9329 USHORT temp = 0, myadaptnum = adaptnum;
9331 if(adaptnum != 0) {
9332 if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
9333 if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9336 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9338 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9340 SiS_Pr->SiS_DDC_SecAddr = 0;
9341 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9342 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9343 SiS_Pr->SiS_DDC_Index = 0x11;
9344 flag = 0xff;
9346 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9348 #if 0
9349 if(VBFlags & VB_SISBRIDGE) {
9350 if(myadaptnum == 0) {
9351 if(!(cr32 & 0x20)) {
9352 myadaptnum = 2;
9353 if(!(cr32 & 0x10)) {
9354 myadaptnum = 1;
9355 if(!(cr32 & 0x08)) {
9356 myadaptnum = 0;
9362 #endif
9364 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9366 if(myadaptnum != 0) {
9367 flag = 0;
9368 if(VBFlags & VB_SISBRIDGE) {
9369 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9370 SiS_Pr->SiS_DDC_Index = 0x0f;
9374 if(!(VBFlags & VB_301)) {
9375 if((cr32 & 0x80) && (checkcr32)) {
9376 if(myadaptnum >= 1) {
9377 if(!(cr32 & 0x08)) {
9378 myadaptnum = 1;
9379 if(!(cr32 & 0x10)) return 0xFFFF;
9385 temp = 4 - (myadaptnum * 2);
9386 if(flag) temp = 0;
9388 } else { /* 315/330 series */
9390 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9392 if(VBFlags & VB_SISBRIDGE) {
9393 if(myadaptnum == 2) {
9394 myadaptnum = 1;
9398 if(myadaptnum == 1) {
9399 flag = 0;
9400 if(VBFlags & VB_SISBRIDGE) {
9401 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9402 SiS_Pr->SiS_DDC_Index = 0x0f;
9406 if((cr32 & 0x80) && (checkcr32)) {
9407 if(myadaptnum >= 1) {
9408 if(!(cr32 & 0x08)) {
9409 myadaptnum = 1;
9410 if(!(cr32 & 0x10)) return 0xFFFF;
9415 temp = myadaptnum;
9416 if(myadaptnum == 1) {
9417 temp = 0;
9418 if(VBFlags & VB_LVDS) flag = 0xff;
9421 if(flag) temp = 0;
9424 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9425 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9427 SiS_SetupDDCN(SiS_Pr);
9429 #ifdef TWDEBUG
9430 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9431 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9432 #endif
9434 return 0;
9437 USHORT
9438 SiS_WriteDABDDC(SiS_Private *SiS_Pr)
9440 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9441 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9442 return 0xFFFF;
9444 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9445 return 0xFFFF;
9447 return(0);
9450 USHORT
9451 SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
9453 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9454 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9455 return 0xFFFF;
9457 return(0);
9460 USHORT
9461 SiS_PrepareDDC(SiS_Private *SiS_Pr)
9463 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9464 if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
9465 return(0);
9468 void
9469 SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
9471 SiS_SetSCLKLow(SiS_Pr);
9472 if(yesno) {
9473 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9474 SiS_Pr->SiS_DDC_Index,
9475 SiS_Pr->SiS_DDC_NData,
9476 SiS_Pr->SiS_DDC_Data);
9477 } else {
9478 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9479 SiS_Pr->SiS_DDC_Index,
9480 SiS_Pr->SiS_DDC_NData,
9483 SiS_SetSCLKHigh(SiS_Pr);
9486 USHORT
9487 SiS_DoProbeDDC(SiS_Private *SiS_Pr)
9489 unsigned char mask, value;
9490 USHORT temp, ret=0;
9491 BOOLEAN failed = FALSE;
9493 SiS_SetSwitchDDC2(SiS_Pr);
9494 if(SiS_PrepareDDC(SiS_Pr)) {
9495 SiS_SetStop(SiS_Pr);
9496 #ifdef TWDEBUG
9497 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9498 #endif
9499 return(0xFFFF);
9501 mask = 0xf0;
9502 value = 0x20;
9503 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9504 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9505 SiS_SendACK(SiS_Pr, 0);
9506 if(temp == 0) {
9507 mask = 0xff;
9508 value = 0xff;
9509 } else {
9510 failed = TRUE;
9511 ret = 0xFFFF;
9512 #ifdef TWDEBUG
9513 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9514 #endif
9517 if(failed == FALSE) {
9518 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9519 SiS_SendACK(SiS_Pr, 1);
9520 temp &= mask;
9521 if(temp == value) ret = 0;
9522 else {
9523 ret = 0xFFFF;
9524 #ifdef TWDEBUG
9525 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9526 #endif
9527 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9528 if(temp == 0x30) ret = 0;
9532 SiS_SetStop(SiS_Pr);
9533 return(ret);
9536 USHORT
9537 SiS_ProbeDDC(SiS_Private *SiS_Pr)
9539 USHORT flag;
9541 flag = 0x180;
9542 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9543 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9544 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9545 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9546 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9547 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9548 if(!(flag & 0x1a)) flag = 0;
9549 return(flag);
9552 USHORT
9553 SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9555 USHORT flag, length, i;
9556 unsigned char chksum,gotcha;
9558 if(DDCdatatype > 4) return 0xFFFF;
9560 flag = 0;
9561 SiS_SetSwitchDDC2(SiS_Pr);
9562 if(!(SiS_PrepareDDC(SiS_Pr))) {
9563 length = 127;
9564 if(DDCdatatype != 1) length = 255;
9565 chksum = 0;
9566 gotcha = 0;
9567 for(i=0; i<length; i++) {
9568 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9569 chksum += buffer[i];
9570 gotcha |= buffer[i];
9571 SiS_SendACK(SiS_Pr, 0);
9573 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9574 chksum += buffer[i];
9575 SiS_SendACK(SiS_Pr, 1);
9576 if(gotcha) flag = (USHORT)chksum;
9577 else flag = 0xFFFF;
9578 } else {
9579 flag = 0xFFFF;
9581 SiS_SetStop(SiS_Pr);
9582 return(flag);
9585 /* Our private DDC functions
9587 It complies somewhat with the corresponding VESA function
9588 in arguments and return values.
9590 Since this is probably called before the mode is changed,
9591 we use our pre-detected pSiS-values instead of SiS_Pr as
9592 regards chipset and video bridge type.
9594 Arguments:
9595 adaptnum: 0=CRT1, 1=LCD, 2=VGA2
9596 CRT2 DDC is only supported on SiS301, 301B, 302B.
9597 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9598 buffer: ptr to 256 data bytes which will be filled with read data.
9600 Returns 0xFFFF if error, otherwise
9601 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9602 if DDCdatatype = 0: Returns supported DDC modes
9605 USHORT
9606 SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9607 USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
9609 unsigned char sr1f,cr17=1;
9610 USHORT result;
9612 if(adaptnum > 2) return 0xFFFF;
9613 if(DDCdatatype > 4) return 0xFFFF;
9614 if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
9615 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
9617 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9618 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9619 if(VGAEngine == SIS_300_VGA) {
9620 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9621 if(!cr17) {
9622 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9623 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9624 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9627 if((sr1f) || (!cr17)) {
9628 SiS_WaitRetrace1(SiS_Pr);
9629 SiS_WaitRetrace1(SiS_Pr);
9630 SiS_WaitRetrace1(SiS_Pr);
9631 SiS_WaitRetrace1(SiS_Pr);
9634 if(DDCdatatype == 0) {
9635 result = SiS_ProbeDDC(SiS_Pr);
9636 } else {
9637 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9639 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9640 if(VGAEngine == SIS_300_VGA) {
9641 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9643 return result;
9646 #ifdef LINUX_XF86
9648 static BOOLEAN
9649 checkedid1(unsigned char *buffer)
9651 /* Check header */
9652 if((buffer[0] != 0x00) ||
9653 (buffer[1] != 0xff) ||
9654 (buffer[2] != 0xff) ||
9655 (buffer[3] != 0xff) ||
9656 (buffer[4] != 0xff) ||
9657 (buffer[5] != 0xff) ||
9658 (buffer[6] != 0xff) ||
9659 (buffer[7] != 0x00))
9660 return FALSE;
9662 /* Check EDID version and revision */
9663 if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
9665 /* Check week of manufacture for sanity */
9666 if(buffer[0x10] > 53) return FALSE;
9668 /* Check year of manufacture for sanity */
9669 if(buffer[0x11] > 40) return FALSE;
9671 return TRUE;
9674 static BOOLEAN
9675 checkedid2(unsigned char *buffer)
9677 USHORT year = buffer[6] | (buffer[7] << 8);
9679 /* Check EDID version */
9680 if((buffer[0] & 0xf0) != 0x20) return FALSE;
9682 /* Check week of manufacture for sanity */
9683 if(buffer[5] > 53) return FALSE;
9685 /* Check year of manufacture for sanity */
9686 if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
9688 return TRUE;
9691 /* Sense the LCD parameters (CR36, CR37) via DDC */
9692 /* SiS30x(B) only */
9693 USHORT
9694 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
9696 USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
9697 USHORT index, myindex, lumsize, numcodes, panelvendor, panelproduct;
9698 unsigned char cr37=0, seekcode;
9699 BOOLEAN checkexpand = FALSE;
9700 BOOLEAN havesync = FALSE;
9701 int retry, i;
9702 unsigned char buffer[256];
9704 for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
9705 SiS_Pr->CP_HaveCustomData = FALSE;
9706 SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
9707 SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
9708 SiS_Pr->CP_PreferredIndex = -1;
9709 SiS_Pr->CP_PrefClock = 0;
9710 SiS_Pr->PanelSelfDetected = FALSE;
9712 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
9713 if(pSiS->VBFlags & VB_30xBDH) return 0;
9715 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
9717 SiS_Pr->SiS_DDC_SecAddr = 0x00;
9719 /* Probe supported DA's */
9720 flag = SiS_ProbeDDC(SiS_Pr);
9721 #ifdef TWDEBUG
9722 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
9723 "CRT2 DDC capabilities 0x%x\n", flag);
9724 #endif
9725 if(flag & 0x10) {
9726 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
9727 DDCdatatype = 4;
9728 } else if(flag & 0x08) {
9729 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
9730 DDCdatatype = 3;
9731 } else if(flag & 0x02) {
9732 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
9733 DDCdatatype = 1;
9734 } else return 0; /* no DDC support (or no device attached) */
9736 /* Read the entire EDID */
9737 retry = 2;
9738 do {
9739 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
9740 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9741 "CRT2: DDC read failed (attempt %d), %s\n",
9742 (3-retry), (retry == 1) ? "giving up" : "retrying");
9743 retry--;
9744 if(retry == 0) return 0xFFFF;
9745 } else break;
9746 } while(1);
9748 #ifdef TWDEBUG
9749 for(i=0; i<256; i+=16) {
9750 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9751 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
9752 buffer[i], buffer[i+1], buffer[i+2], buffer[i+3],
9753 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
9754 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
9755 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
9757 #endif
9759 /* Analyze EDID and retrieve LCD panel information */
9760 paneltype = 0;
9761 switch(DDCdatatype) {
9762 case 1: /* Analyze EDID V1 */
9763 /* Catch a few clear cases: */
9764 if(!(checkedid1(buffer))) {
9765 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9766 "LCD sense: EDID corrupt\n");
9767 return 0;
9770 if(!(buffer[0x14] & 0x80)) {
9771 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9772 "LCD sense: Attached display expects analog input (0x%02x)\n",
9773 buffer[0x14]);
9774 return 0;
9777 if((buffer[0x18] & 0x18) != 0x08) {
9778 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9779 "LCD sense: Attached display is not of RGB but of %s type (0x%02x)\n",
9780 ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
9781 ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
9782 "undefined"),
9783 buffer[0x18]);
9784 return 0;
9787 /* Now analyze the first Detailed Timing Block and see
9788 * if the preferred timing mode is stored there. If so,
9789 * check if this is a standard panel for which we already
9790 * know the timing.
9793 paneltype = Panel_Custom;
9794 checkexpand = FALSE;
9796 panelvendor = buffer[9] | (buffer[8] << 8);
9797 panelproduct = buffer[10] | (buffer[11] << 8);
9799 if(buffer[0x18] & 0x02) {
9801 USHORT pclk = (buffer[0x36] | (buffer[0x37] << 8));
9802 USHORT phb = (buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8));
9803 USHORT pvb = (buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8));
9805 SiS_Pr->CP_PreferredX = xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
9806 SiS_Pr->CP_PreferredY = yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
9808 switch(xres) {
9809 #if 0 /* Treat as custom */
9810 case 800:
9811 if(yres == 600) {
9812 paneltype = Panel_800x600;
9813 checkexpand = TRUE;
9815 break;
9816 #endif
9817 case 1024:
9818 if(yres == 768) {
9819 paneltype = Panel_1024x768;
9820 checkexpand = TRUE;
9822 break;
9823 case 1280:
9824 if(yres == 1024) {
9825 paneltype = Panel_1280x1024;
9826 checkexpand = TRUE;
9827 } else if(yres == 960) {
9828 if(pSiS->VGAEngine == SIS_300_VGA) {
9829 paneltype = Panel300_1280x960;
9830 } else {
9831 paneltype = Panel310_1280x960;
9833 } else if(yres == 768) {
9834 if( (pclk == 8100) &&
9835 (phb == (1688 - 1280)) &&
9836 (pvb == (802 - 768)) ) {
9837 paneltype = Panel_1280x768;
9838 checkexpand = FALSE;
9839 cr37 |= 0x10;
9841 } else if(yres == 800) {
9842 if( (pclk == 6900) &&
9843 (phb == (1408 - 1280)) &&
9844 (pvb == (816 - 800)) ) {
9845 paneltype = Panel_1280x800;
9848 break;
9849 case 1400:
9850 if(pSiS->VGAEngine == SIS_315_VGA) {
9851 if(yres == 1050) {
9852 paneltype = Panel310_1400x1050;
9853 checkexpand = TRUE;
9856 break;
9857 case 1600:
9858 if(pSiS->VGAEngine == SIS_315_VGA) {
9859 if(pSiS->VBFlags & VB_301C) {
9860 if(yres == 1200) {
9861 paneltype = Panel310_1600x1200;
9862 checkexpand = TRUE;
9866 break;
9869 /* Save sync: This is used if "Pass 1:1" is off; in this case
9870 * we always use the panel's native mode = this "preferred mode"
9871 * we just have been analysing. Hence, we also need its sync.
9873 if((buffer[0x47] & 0x18) == 0x18) {
9874 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
9875 havesync = TRUE;
9876 } else {
9877 /* What now? There is no digital separate output timing... */
9878 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9879 "LCD sense: Unable to retrieve Sync polarity information\n");
9880 cr37 |= 0xc0; /* Default */
9885 /* Check against our database; Eg. Sanyo projector reports
9886 * 1024x768 as preferred mode, although it supports 1280x720
9887 * natively in non-HTCP mode. Treat such wrongly reporting
9888 * panels as custom and fixup actual maximum resolutions.
9890 if(paneltype != Panel_Custom) {
9891 int maxx, maxy;
9892 if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy))) {
9893 paneltype = Panel_Custom;
9894 SiS_Pr->CP_MaxX = maxx;
9895 SiS_Pr->CP_MaxY = maxy;
9896 /* Leave preferred unchanged (MUST contain a valid mode!) */
9900 /* If we still don't know what panel this is, we take it
9901 * as a custom panel and derive the timing data from the
9902 * detailed timing blocks
9904 if(paneltype == Panel_Custom) {
9906 int i, temp, base = 0x36;
9907 unsigned long estpack;
9908 const unsigned short estx[] = {
9909 720, 720, 640, 640, 640, 640, 800, 800,
9910 800, 800, 832,1024,1024,1024,1024,1280,
9911 1152
9913 const unsigned short esty[] = {
9914 400, 400, 480, 480, 480, 480, 600, 600,
9915 600, 600, 624, 768, 768, 768, 768,1024,
9918 const int estclk[] = {
9919 0, 0, 25100, 0, 31500, 31500, 36100, 40000,
9920 50100, 49500, 0, 0, 65100, 75200, 78700,135200,
9924 paneltype = 0;
9925 SiS_Pr->CP_Supports64048075 = TRUE;
9927 /* Find the maximum resolution */
9929 /* 1. From Established timings */
9930 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
9931 for(i=16; i>=0; i--) {
9932 if(estpack & (1 << i)) {
9933 if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
9934 if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
9935 if(estclk[16 - i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = estclk[16 - i];
9939 /* By default we drive the LCD at 75Hz in 640x480 mode; if
9940 * the panel does not provide this mode, use 60hz
9942 if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
9944 /* 2. From Standard Timings */
9945 for(i=0x26; i < 0x36; i+=2) {
9946 if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
9947 temp = (buffer[i] + 31) * 8;
9948 if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
9949 switch((buffer[i+1] & 0xc0) >> 6) {
9950 case 0x03: temp = temp * 9 / 16; break;
9951 case 0x02: temp = temp * 4 / 5; break;
9952 case 0x01: temp = temp * 3 / 4; break;
9954 if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
9958 /* Now extract the Detailed Timings and convert them into modes */
9960 for(i = 0; i < 4; i++, base += 18) {
9962 /* Is this a detailed timing block or a monitor descriptor? */
9963 if(buffer[base] || buffer[base+1] || buffer[base+2]) {
9965 xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
9966 yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
9968 SiS_Pr->CP_HDisplay[i] = xres;
9969 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
9970 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
9971 SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
9972 SiS_Pr->CP_HBlankStart[i] = xres + 1;
9973 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
9975 SiS_Pr->CP_VDisplay[i] = yres;
9976 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
9977 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
9978 SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
9979 SiS_Pr->CP_VBlankStart[i] = yres + 1;
9980 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
9982 SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
9984 SiS_Pr->CP_DataValid[i] = TRUE;
9986 /* Sort out invalid timings, interlace and too high clocks */
9987 if((SiS_Pr->CP_HDisplay[i] & 7) ||
9988 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
9989 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
9990 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
9991 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
9992 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
9993 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
9994 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
9995 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
9996 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
9997 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
9998 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
9999 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10000 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10001 ((!(pSiS->VBFlags & VB_301C)) &&
10002 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024)))) ||
10003 (buffer[base+17] & 0x80)) {
10005 SiS_Pr->CP_DataValid[i] = FALSE;
10007 } else {
10009 SiS_Pr->CP_HaveCustomData = TRUE;
10011 if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
10012 if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
10013 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10015 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10016 SiS_Pr->CP_PreferredIndex = i;
10017 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10018 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10021 /* Extract the sync polarisation information. This only works
10022 * if the Flags indicate a digital separate output.
10024 if((buffer[base+17] & 0x18) == 0x18) {
10025 SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
10026 SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
10027 SiS_Pr->CP_SyncValid[i] = TRUE;
10028 if((i == SiS_Pr->CP_PreferredIndex) && (!havesync)) {
10029 cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
10030 havesync = TRUE;
10032 } else {
10033 SiS_Pr->CP_SyncValid[i] = FALSE;
10038 } else if((!buffer[base]) && (!buffer[base+1]) && (!buffer[base+2]) && (!buffer[base+4])) {
10040 /* Maximum pixclock from Monitor Range Limits */
10041 if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) {
10042 int maxclk = buffer[base+9] * 10;
10043 /* More than 170 is not supported anyway */
10044 if(maxclk <= 170) SiS_Pr->CP_MaxClock = maxclk * 1000;
10051 if(SiS_Pr->CP_MaxX && SiS_Pr->CP_MaxY) {
10052 paneltype = Panel_Custom;
10053 checkexpand = FALSE;
10054 cr37 |= 0x10;
10055 SiS_Pr->CP_Vendor = panelvendor;
10056 SiS_Pr->CP_Product = panelproduct;
10061 if(paneltype && checkexpand) {
10062 /* If any of the Established low-res modes is supported, the
10063 * panel can scale automatically. For 800x600 panels, we only
10064 * check the even lower ones.
10066 if(paneltype == Panel_800x600) {
10067 if(buffer[0x23] & 0xfc) cr37 |= 0x10;
10068 } else {
10069 if(buffer[0x23]) cr37 |= 0x10;
10073 break;
10075 case 3: /* Analyze EDID V2 */
10076 case 4:
10077 index = 0;
10079 if(!(checkedid2(buffer))) {
10080 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10081 "LCD sense: EDID corrupt\n");
10082 return 0;
10085 if((buffer[0x41] & 0x0f) == 0x03) {
10086 index = 0x42 + 3;
10087 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10088 "LCD sense: Display supports TMDS input on primary interface\n");
10089 } else if((buffer[0x41] & 0xf0) == 0x30) {
10090 index = 0x46 + 3;
10091 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10092 "LCD sense: Display supports TMDS input on secondary interface\n");
10093 } else {
10094 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10095 "LCD sense: Display does not support TMDS video interface (0x%02x)\n",
10096 buffer[0x41]);
10097 return 0;
10100 SiS_Pr->CP_Vendor = panelvendor = buffer[2] | (buffer[1] << 8);
10101 SiS_Pr->CP_Product = panelproduct = buffer[3] | (buffer[4] << 8);
10103 paneltype = Panel_Custom;
10104 SiS_Pr->CP_MaxX = SiS_Pr->CP_PreferredX = xres = buffer[0x76] | (buffer[0x77] << 8);
10105 SiS_Pr->CP_MaxY = SiS_Pr->CP_PreferredY = yres = buffer[0x78] | (buffer[0x79] << 8);
10107 switch(xres) {
10108 #if 0
10109 case 800:
10110 if(yres == 600) {
10111 paneltype = Panel_800x600;
10112 checkexpand = TRUE;
10114 break;
10115 #endif
10116 case 1024:
10117 if(yres == 768) {
10118 paneltype = Panel_1024x768;
10119 checkexpand = TRUE;
10121 break;
10122 case 1280:
10123 if(yres == 960) {
10124 if(pSiS->VGAEngine == SIS_315_VGA) {
10125 paneltype = Panel310_1280x960;
10126 } else {
10127 paneltype = Panel300_1280x960;
10129 } else if(yres == 1024) {
10130 paneltype = Panel_1280x1024;
10131 checkexpand = TRUE;
10133 /* 1280x768 treated as custom here */
10134 break;
10135 case 1400:
10136 if(pSiS->VGAEngine == SIS_315_VGA) {
10137 if(yres == 1050) {
10138 paneltype = Panel310_1400x1050;
10139 checkexpand = TRUE;
10142 break;
10143 case 1600:
10144 if(pSiS->VGAEngine == SIS_315_VGA) {
10145 if(pSiS->VBFlags & VB_301C) {
10146 if(yres == 1200) {
10147 paneltype = Panel310_1600x1200;
10148 checkexpand = TRUE;
10152 break;
10155 /* Determine if RGB18 or RGB24 */
10156 if(index) {
10157 if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
10158 cr37 |= 0x01;
10162 if(checkexpand) {
10163 /* TODO - for now, we let the panel scale */
10164 cr37 |= 0x10;
10167 /* Now seek 4-Byte Timing codes and extract sync pol info */
10168 index = 0x80;
10169 if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
10170 lumsize = buffer[0x80] & 0x1f;
10171 if(buffer[0x80] & 0x80) lumsize *= 3;
10172 lumsize++; /* luminance header byte */
10173 index += lumsize;
10175 #if 0 /* "pixel rate" = pixel clock? */
10176 if(buffer[0x7e] & 0x1c) {
10177 for(i=0; i<((buffer[0x7e] & 0x1c) >> 2); i++) {
10178 if(buffer[index + (i*8) + 6] && (buffer[index + (i*8) + 7] & 0x0f)) {
10179 int clk = (buffer[index + (i*8) + 6] | ((buffer[index + (i*8) + 7] & 0x0f) << 4)) * 1000;
10180 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10184 #endif
10185 index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */
10186 if(buffer[0x7e] & 0x03) {
10187 for(i=0; i<(buffer[0x7e] & 0x03); i++) {
10188 if((buffer[index + (i*27) + 9]) || (buffer[index + (i*27) + 10])) {
10189 int clk = ((buffer[index + (i*27) + 9]) | ((buffer[index + (i*27) + 9]) << 8)) * 10;
10190 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10194 index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */
10195 numcodes = (buffer[0x7f] & 0xf8) >> 3;
10196 if(numcodes) {
10197 myindex = index;
10198 seekcode = (xres - 256) / 16;
10199 for(i=0; i<numcodes; i++) {
10200 if(buffer[myindex] == seekcode) break;
10201 myindex += 4;
10203 if(buffer[myindex] == seekcode) {
10204 cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
10205 havesync = TRUE;
10206 } else {
10207 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10208 "LCD sense: Unable to retrieve Sync polarity information\n");
10210 } else {
10211 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10212 "LCD sense: Unable to retrieve Sync polarity information\n");
10215 /* Check against our database; Eg. Sanyo projector reports
10216 * 1024x768 in non-HDPC mode, although it supports 1280x720.
10217 * Treat such wrongly reporting panels as custom.
10219 if(paneltype != Panel_Custom) {
10220 int maxx, maxy;
10221 if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy))) {
10222 paneltype = Panel_Custom;
10223 SiS_Pr->CP_MaxX = maxx;
10224 SiS_Pr->CP_MaxY = maxy;
10225 cr37 |= 0x10;
10226 /* Leave preferred unchanged (MUST be a valid mode!) */
10230 /* Now seek the detailed timing descriptions for custom panels */
10231 if(paneltype == Panel_Custom) {
10233 SiS_Pr->CP_Supports64048075 = TRUE;
10235 index += (numcodes * 4);
10236 numcodes = buffer[0x7f] & 0x07;
10237 for(i=0; i<numcodes; i++, index += 18) {
10238 xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
10239 yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
10241 SiS_Pr->CP_HDisplay[i] = xres;
10242 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
10243 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
10244 SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
10245 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10246 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10248 SiS_Pr->CP_VDisplay[i] = yres;
10249 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10250 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10251 SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10252 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10253 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10255 SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10257 SiS_Pr->CP_DataValid[i] = TRUE;
10259 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10260 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10261 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10262 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10263 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10264 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10265 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10266 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10267 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10268 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10269 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10270 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10271 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10272 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10273 ((!(pSiS->VBFlags & VB_301C)) &&
10274 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024)))) ||
10275 (buffer[index + 17] & 0x80)) {
10277 SiS_Pr->CP_DataValid[i] = FALSE;
10279 } else {
10281 SiS_Pr->CP_HaveCustomData = TRUE;
10283 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10285 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10286 SiS_Pr->CP_PreferredIndex = i;
10287 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10288 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10289 if(!havesync) {
10290 cr37 |= ((((buffer[index + 17] & 0x06) ^ 0x06) << 5) | 0x20);
10291 havesync = TRUE;
10295 SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10296 SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10297 SiS_Pr->CP_SyncValid[i] = TRUE;
10302 cr37 |= 0x10;
10306 break;
10310 /* 1280x960 panels are always RGB24, unable to scale and use
10311 * high active sync polarity
10313 if(pSiS->VGAEngine == SIS_315_VGA) {
10314 if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10315 } else {
10316 if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10319 for(i = 0; i < 7; i++) {
10320 if(SiS_Pr->CP_DataValid[i]) {
10321 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10322 "Non-standard LCD/DVI-D timing data no. %d:\n", i);
10323 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10324 " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10325 SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10326 SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10327 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10328 " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10329 SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10330 SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10331 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10332 " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10333 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10334 " To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10335 SiS_Pr->CP_HDisplay[i],
10336 SiS_Pr->CP_VDisplay[i]);
10340 if(paneltype) {
10341 if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10342 if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10343 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10344 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
10345 cr37 &= 0xf1;
10346 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
10347 SiS_Pr->PanelSelfDetected = TRUE;
10348 #ifdef TWDEBUG
10349 xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
10350 "LCD sense: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10351 #endif
10352 } else {
10353 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
10354 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
10356 return 0;
10359 USHORT
10360 SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10362 USHORT DDCdatatype,flag;
10363 BOOLEAN foundcrt = FALSE;
10364 int retry;
10365 unsigned char buffer[256];
10367 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10369 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10371 SiS_Pr->SiS_DDC_SecAddr = 0x00;
10373 /* Probe supported DA's */
10374 flag = SiS_ProbeDDC(SiS_Pr);
10375 if(flag & 0x10) {
10376 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
10377 DDCdatatype = 4;
10378 } else if(flag & 0x08) {
10379 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
10380 DDCdatatype = 3;
10381 } else if(flag & 0x02) {
10382 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
10383 DDCdatatype = 1;
10384 } else {
10385 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10386 "VGA2 sense: Do DDC answer\n");
10387 return 0; /* no DDC support (or no device attached) */
10390 /* Read the entire EDID */
10391 retry = 2;
10392 do {
10393 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10394 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10395 "VGA2 sense: DDC read failed (attempt %d), %s\n",
10396 (3-retry), (retry == 1) ? "giving up" : "retrying");
10397 retry--;
10398 if(retry == 0) return 0xFFFF;
10399 } else break;
10400 } while(1);
10402 /* Analyze EDID. We don't have many chances to
10403 * distinguish a flat panel from a CRT...
10405 switch(DDCdatatype) {
10406 case 1:
10407 if(!(checkedid1(buffer))) {
10408 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10409 "VGA2 sense: EDID corrupt\n");
10410 return 0;
10412 if(buffer[0x14] & 0x80) { /* Display uses digital input */
10413 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10414 "VGA2 sense: Attached display expects digital input\n");
10415 return 0;
10417 SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10418 SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10419 foundcrt = TRUE;
10420 break;
10421 case 3:
10422 case 4:
10423 if(!(checkedid2(buffer))) {
10424 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10425 "VGA2 sense: EDID corrupt\n");
10426 return 0;
10428 if( ((buffer[0x41] & 0x0f) != 0x01) && /* Display does not support analog input */
10429 ((buffer[0x41] & 0x0f) != 0x02) &&
10430 ((buffer[0x41] & 0xf0) != 0x10) &&
10431 ((buffer[0x41] & 0xf0) != 0x20) ) {
10432 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10433 "VGA2 sense: Attached display does not support analog input (0x%02x)\n",
10434 buffer[0x41]);
10435 return 0;
10437 SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10438 SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10439 foundcrt = TRUE;
10440 break;
10443 if(foundcrt) {
10444 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10446 return(0);
10449 #endif
10451 void
10452 SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10454 USHORT tempbl;
10456 tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10457 tempbl = (((tempbl & tempbh) << 8) | tempax);
10458 SiS_SetCH70xx(SiS_Pr,tempbl);
10461 /* Generic I2C functions for Chrontel & DDC --------- */
10463 void
10464 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10466 SiS_SetSCLKHigh(SiS_Pr);
10467 SiS_WaitRetrace1(SiS_Pr);
10469 SiS_SetSCLKLow(SiS_Pr);
10470 SiS_WaitRetrace1(SiS_Pr);
10473 USHORT
10474 SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
10476 SiS_WaitRetrace1(SiS_Pr);
10477 return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10480 /* Set I2C start condition */
10481 /* This is done by a SD high-to-low transition while SC is high */
10482 USHORT
10483 SiS_SetStart(SiS_Private *SiS_Pr)
10485 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10486 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10487 SiS_Pr->SiS_DDC_Index,
10488 SiS_Pr->SiS_DDC_NData,
10489 SiS_Pr->SiS_DDC_Data); /* SD->high */
10490 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10491 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10492 SiS_Pr->SiS_DDC_Index,
10493 SiS_Pr->SiS_DDC_NData,
10494 0x00); /* SD->low = start condition */
10495 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10496 return 0;
10499 /* Set I2C stop condition */
10500 /* This is done by a SD low-to-high transition while SC is high */
10501 USHORT
10502 SiS_SetStop(SiS_Private *SiS_Pr)
10504 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10505 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10506 SiS_Pr->SiS_DDC_Index,
10507 SiS_Pr->SiS_DDC_NData,
10508 0x00); /* SD->low */
10509 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10510 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10511 SiS_Pr->SiS_DDC_Index,
10512 SiS_Pr->SiS_DDC_NData,
10513 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
10514 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
10515 return 0;
10518 /* Write 8 bits of data */
10519 USHORT
10520 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10522 USHORT i,flag,temp;
10524 flag = 0x80;
10525 for(i=0; i<8; i++) {
10526 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
10527 if(tempax & flag) {
10528 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10529 SiS_Pr->SiS_DDC_Index,
10530 SiS_Pr->SiS_DDC_NData,
10531 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
10532 } else {
10533 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10534 SiS_Pr->SiS_DDC_Index,
10535 SiS_Pr->SiS_DDC_NData,
10536 0x00); /* Write bit (0) to SD */
10538 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
10539 flag >>= 1;
10541 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
10542 return(temp);
10545 USHORT
10546 SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10548 USHORT i,temp,getdata;
10550 getdata=0;
10551 for(i=0; i<8; i++) {
10552 getdata <<= 1;
10553 SiS_SetSCLKLow(SiS_Pr);
10554 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10555 SiS_Pr->SiS_DDC_Index,
10556 SiS_Pr->SiS_DDC_NData,
10557 SiS_Pr->SiS_DDC_Data);
10558 SiS_SetSCLKHigh(SiS_Pr);
10559 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10560 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
10562 return(getdata);
10565 USHORT
10566 SiS_SetSCLKLow(SiS_Private *SiS_Pr)
10568 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10569 SiS_Pr->SiS_DDC_Index,
10570 SiS_Pr->SiS_DDC_NClk,
10571 0x00); /* SetSCLKLow() */
10572 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10573 return 0;
10576 USHORT
10577 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
10579 USHORT temp, watchdog=1000;
10581 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10582 SiS_Pr->SiS_DDC_Index,
10583 SiS_Pr->SiS_DDC_NClk,
10584 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
10585 do {
10586 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10587 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
10588 if (!watchdog) {
10589 #ifdef TWDEBUG
10590 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
10591 #endif
10592 return 0xFFFF;
10594 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10595 return 0;
10598 /* Check I2C acknowledge */
10599 /* Returns 0 if ack ok, non-0 if ack not ok */
10600 USHORT
10601 SiS_CheckACK(SiS_Private *SiS_Pr)
10603 USHORT tempah;
10605 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
10606 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10607 SiS_Pr->SiS_DDC_Index,
10608 SiS_Pr->SiS_DDC_NData,
10609 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
10610 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
10611 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
10612 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
10613 if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */
10614 else return(0);
10617 /* End of I2C functions ----------------------- */
10620 /* =============== SiS 315/330 O.E.M. ================= */
10622 #ifdef SIS315H
10624 static USHORT
10625 GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10627 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10628 USHORT romptr;
10630 if(HwInfo->jChipType < SIS_330) {
10631 romptr = SISGETROMW(0x128);
10632 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10633 romptr = SISGETROMW(0x12a);
10634 } else {
10635 romptr = SISGETROMW(0x1a8);
10636 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10637 romptr = SISGETROMW(0x1aa);
10639 return(romptr);
10642 static USHORT
10643 GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10645 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10646 USHORT romptr;
10648 if(HwInfo->jChipType < SIS_330) {
10649 romptr = SISGETROMW(0x120);
10650 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10651 romptr = SISGETROMW(0x122);
10652 } else {
10653 romptr = SISGETROMW(0x1a0);
10654 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10655 romptr = SISGETROMW(0x1a2);
10657 return(romptr);
10660 static USHORT
10661 GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10663 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10664 USHORT romptr;
10666 if(HwInfo->jChipType < SIS_330) {
10667 romptr = SISGETROMW(0x114);
10668 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10669 romptr = SISGETROMW(0x11a);
10670 } else {
10671 romptr = SISGETROMW(0x194);
10672 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10673 romptr = SISGETROMW(0x19a);
10675 return(romptr);
10678 static USHORT
10679 GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10681 USHORT index;
10683 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10684 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
10685 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
10686 index >>= 4;
10687 index *= 3;
10688 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10689 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10690 return index;
10695 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
10696 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
10697 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
10698 index--;
10699 index *= 3;
10700 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10701 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10702 return index;
10705 static USHORT
10706 GetLCDPtrIndex(SiS_Private *SiS_Pr)
10708 USHORT index;
10710 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
10711 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10712 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10713 return index;
10716 static USHORT
10717 GetTVPtrIndex(SiS_Private *SiS_Pr)
10719 USHORT index;
10721 index = 0;
10722 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10723 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
10725 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
10727 index <<= 1;
10729 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
10730 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10731 index++;
10734 return index;
10737 static ULONG
10738 GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10740 USHORT index = 0, temp = 0;
10742 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10743 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
10744 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
10745 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
10746 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
10747 index = 4;
10748 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
10749 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
10752 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10753 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
10754 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10755 index += addme;
10756 temp++;
10758 temp += 0x0100;
10760 return(ULONG)(index | (temp << 16));
10763 static ULONG
10764 GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
10766 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
10769 #if 0
10770 static ULONG
10771 GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
10773 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
10775 #endif
10777 static int
10778 GetOEMTVPtr661(SiS_Private *SiS_Pr)
10780 int index = 0;
10782 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
10783 if(SiS_Pr->SiS_ROMNew) {
10784 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
10785 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
10786 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
10787 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
10788 } else {
10789 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
10790 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
10791 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
10792 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
10795 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
10797 return index;
10800 static void
10801 SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10803 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10804 USHORT delay=0,index,myindex,temp,romptr=0;
10805 BOOLEAN dochiptest = TRUE;
10807 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10808 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
10809 } else {
10810 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
10813 /* Find delay (from ROM, internal tables, PCI subsystem) */
10815 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
10817 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10818 romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
10820 if(romptr) delay = ROMAddr[romptr];
10821 else {
10822 delay = 0x04;
10823 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10824 if(IS_SIS650) {
10825 delay = 0x0a;
10826 } else if(IS_SIS740) {
10827 delay = 0x00;
10828 } else if(HwInfo->jChipType < SIS_330) {
10829 delay = 0x0c;
10830 } else {
10831 delay = 0x0c;
10833 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10834 delay = 0x00;
10838 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
10840 BOOLEAN gotitfrompci = FALSE;
10842 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
10844 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10845 if(SiS_Pr->PDC != -1) {
10846 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
10847 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
10848 return;
10850 } else {
10851 if(SiS_Pr->PDCA != -1) {
10852 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10853 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10854 return;
10858 /* Custom Panel? */
10860 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10861 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10862 delay = 0x00;
10863 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10864 delay = 0x20;
10866 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10867 } else {
10868 delay = 0x0c;
10869 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
10870 else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10871 if(IS_SIS740) delay = 0x01;
10872 else delay = 0x03;
10874 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10876 return;
10879 /* This is a piece of typical SiS crap: They code the OEM LCD
10880 * delay into the code, at no defined place in the BIOS.
10881 * We now have to start doing a PCI subsystem check here.
10884 switch(SiS_Pr->SiS_CustomT) {
10885 case CUT_COMPAQ1280:
10886 case CUT_COMPAQ12802:
10887 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10888 gotitfrompci = TRUE;
10889 dochiptest = FALSE;
10890 delay = 0x03;
10892 break;
10893 case CUT_CLEVO1400:
10894 case CUT_CLEVO14002:
10895 gotitfrompci = TRUE;
10896 dochiptest = FALSE;
10897 delay = 0x02;
10898 break;
10899 case CUT_CLEVO1024:
10900 case CUT_CLEVO10242:
10901 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10902 gotitfrompci = TRUE;
10903 dochiptest = FALSE;
10904 delay = 0x33;
10905 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10906 delay &= 0x0f;
10908 break;
10911 /* Could we find it through the PCI ID? If no, use ROM or table */
10913 if(!gotitfrompci) {
10915 index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
10916 myindex = GetLCDPtrIndex(SiS_Pr);
10918 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10920 if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
10922 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10923 /* Always use the second pointer on 650; some BIOSes */
10924 /* still carry old 301 data at the first location */
10925 /* romptr = SISGETROMW(0x120); */
10926 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10927 romptr = SISGETROMW(0x122);
10928 if(!romptr) return;
10929 delay = ROMAddr[(romptr + index)];
10930 } else {
10931 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10934 } else {
10936 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10937 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10938 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10942 } else if(SiS_Pr->SiS_UseROM &&
10943 (!(SiS_Pr->SiS_ROMNew)) &&
10944 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10945 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10946 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
10948 /* Data for 1280x1024 wrong in 301B BIOS */
10949 romptr = GetLCDromptr(SiS_Pr, HwInfo);
10950 if(!romptr) return;
10951 delay = ROMAddr[(romptr + index)];
10953 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10955 if(IS_SIS740) delay = 0x03;
10956 else delay = 0x00;
10958 } else {
10960 delay = SiS310_LCDDelayCompensation_301[myindex];
10961 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10962 if(IS_SIS740) delay = 0x01;
10963 else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10964 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10965 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10966 if(IS_SIS740) delay = 0x01; /* ? */
10967 else delay = 0x03;
10968 } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10969 if(IS_SIS740) delay = 0x01;
10970 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10975 } /* got it from PCI */
10977 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10978 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10979 dochiptest = FALSE;
10982 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10984 index = GetTVPtrIndex(SiS_Pr);
10986 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10988 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
10990 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10991 /* Always use the second pointer on 650; some BIOSes */
10992 /* still carry old 301 data at the first location */
10993 /* romptr = SISGETROMW(0x114); */
10994 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10995 romptr = SISGETROMW(0x11a);
10996 if(!romptr) return;
10997 delay = ROMAddr[romptr + index];
10999 } else {
11001 delay = SiS310_TVDelayCompensation_301B[index];
11005 } else {
11007 switch(SiS_Pr->SiS_CustomT) {
11008 case CUT_COMPAQ1280:
11009 case CUT_COMPAQ12802:
11010 case CUT_CLEVO1400:
11011 case CUT_CLEVO14002:
11012 delay = 0x02;
11013 dochiptest = FALSE;
11014 break;
11015 case CUT_CLEVO1024:
11016 case CUT_CLEVO10242:
11017 delay = 0x03;
11018 dochiptest = FALSE;
11019 break;
11020 default:
11021 delay = SiS310_TVDelayCompensation_651301LV[index];
11022 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
11023 delay = SiS310_TVDelayCompensation_651302LV[index];
11028 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
11030 romptr = GetTVromptr(SiS_Pr, HwInfo);
11031 if(!romptr) return;
11032 delay = ROMAddr[romptr + index];
11034 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11036 delay = SiS310_TVDelayCompensation_LVDS[index];
11038 } else {
11040 delay = SiS310_TVDelayCompensation_301[index];
11041 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11042 if(IS_SIS740) {
11043 delay = SiS310_TVDelayCompensation_740301B[index];
11044 /* LV: use 301 data? BIOS bug? */
11045 } else {
11046 delay = SiS310_TVDelayCompensation_301B[index];
11047 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
11053 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
11054 delay &= 0x0f;
11055 dochiptest = FALSE;
11058 } else return;
11060 /* Write delay */
11062 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11064 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
11066 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
11067 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
11068 delay &= 0x0f;
11069 delay |= 0xb0;
11070 } else if(temp == 6) {
11071 delay &= 0x0f;
11072 delay |= 0xc0;
11073 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
11074 delay = 0x35;
11076 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
11078 } else {
11080 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11084 } else { /* LVDS */
11086 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11087 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11088 } else {
11089 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
11090 delay <<= 4;
11091 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
11092 } else {
11093 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11101 static void
11102 SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11103 USHORT ModeNo,USHORT ModeIdIndex)
11105 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11106 USHORT index,temp,temp1,romptr=0;
11108 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
11110 if(ModeNo<=0x13)
11111 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
11112 else
11113 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
11115 temp = GetTVPtrIndex(SiS_Pr);
11116 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11117 temp1 = temp;
11119 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11120 if(HwInfo->jChipType >= SIS_661) {
11121 temp1 = GetOEMTVPtr661(SiS_Pr);
11122 temp1 >>= 1;
11123 romptr = SISGETROMW(0x260);
11124 if(HwInfo->jChipType >= SIS_760) {
11125 romptr = SISGETROMW(0x360);
11127 } else if(HwInfo->jChipType >= SIS_330) {
11128 romptr = SISGETROMW(0x192);
11129 } else {
11130 romptr = SISGETROMW(0x112);
11134 if(romptr) {
11135 temp1 <<= 1;
11136 temp = ROMAddr[romptr + temp1 + index];
11137 } else {
11138 temp = SiS310_TVAntiFlick1[temp][index];
11140 temp <<= 4;
11142 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
11145 static void
11146 SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11147 USHORT ModeNo,USHORT ModeIdIndex)
11149 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11150 USHORT index,temp,temp1,romptr=0;
11152 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11154 if(ModeNo <= 0x13)
11155 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
11156 else
11157 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
11159 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11160 if(HwInfo->jChipType >= SIS_661) {
11161 romptr = SISGETROMW(0x26c);
11162 if(HwInfo->jChipType >= SIS_760) {
11163 romptr = SISGETROMW(0x36c);
11165 temp1 = GetOEMTVPtr661(SiS_Pr);
11166 temp1 >>= 1;
11167 } else if(HwInfo->jChipType >= SIS_330) {
11168 romptr = SISGETROMW(0x1a4);
11169 } else {
11170 romptr = SISGETROMW(0x124);
11174 if(romptr) {
11175 temp1 <<= 1;
11176 temp = ROMAddr[romptr + temp1 + index];
11177 } else {
11178 temp = SiS310_TVEdge1[temp][index];
11180 temp <<= 5;
11181 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
11184 static void
11185 SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11186 USHORT ModeNo,USHORT ModeIdIndex)
11188 USHORT index, temp, i, j;
11190 if(ModeNo <= 0x13) {
11191 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
11192 } else {
11193 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
11196 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11198 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
11199 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
11200 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
11201 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
11203 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11204 for(i=0x35, j=0; i<=0x38; i++, j++) {
11205 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11207 for(i=0x48; i<=0x4A; i++, j++) {
11208 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11210 } else {
11211 for(i=0x35, j=0; i<=0x38; i++, j++) {
11212 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
11217 static void
11218 SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11219 USHORT ModeNo,USHORT ModeIdIndex)
11221 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11222 USHORT index,temp,i,j,resinfo,romptr=0;
11223 ULONG lindex;
11225 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
11227 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
11228 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
11230 if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
11231 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
11232 lindex <<= 2;
11233 for(j=0, i=0x31; i<=0x34; i++, j++) {
11234 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
11236 return;
11239 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
11240 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
11242 if(ModeNo<=0x13) {
11243 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11244 } else {
11245 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11248 temp = GetTVPtrIndex(SiS_Pr);
11249 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
11250 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
11252 if(SiS_Pr->SiS_UseROM) {
11253 romptr = SISGETROMW(0x116);
11254 if(HwInfo->jChipType >= SIS_330) {
11255 romptr = SISGETROMW(0x196);
11257 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11258 romptr = SISGETROMW(0x11c);
11259 if(HwInfo->jChipType >= SIS_330) {
11260 romptr = SISGETROMW(0x19c);
11262 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11263 romptr = SISGETROMW(0x116);
11264 if(HwInfo->jChipType >= SIS_330) {
11265 romptr = SISGETROMW(0x196);
11270 if(romptr) {
11271 romptr += (temp << 2);
11272 for(j=0, i=0x31; i<=0x34; i++, j++) {
11273 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11275 } else {
11276 index = temp % 2;
11277 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
11278 for(j=0, i=0x31; i<=0x34; i++, j++) {
11279 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
11280 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11281 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11282 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
11283 else
11284 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11288 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11289 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11290 if((resinfo == SIS_RI_640x480) ||
11291 (resinfo == SIS_RI_800x600)) {
11292 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
11293 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
11294 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
11295 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
11296 } else if(resinfo == SIS_RI_1024x768) {
11297 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
11298 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
11299 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
11300 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
11306 static void
11307 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11308 USHORT ModeIdIndex, USHORT RTI)
11310 USHORT delay = 0, romptr = 0, index, lcdpdcindex;
11311 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11313 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11314 return;
11316 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
11317 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
11319 if(SiS_Pr->SiS_ROMNew) {
11320 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
11321 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
11322 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
11323 index = 25;
11324 if(SiS_Pr->UseCustomMode) {
11325 index = SiS_Pr->CSRClock;
11326 } else if(ModeNo > 0x13) {
11327 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
11328 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
11330 if(index < 25) index = 25;
11331 index = ((index / 25) - 1) << 1;
11332 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
11333 index++;
11335 romptr = SISGETROMW(0x104);
11336 delay = ROMAddr[romptr + index];
11337 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
11338 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11339 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11340 } else {
11341 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11342 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11344 return;
11348 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
11350 if(SiS_Pr->UseCustomMode) delay = 0x04;
11351 else if(ModeNo <= 0x13) delay = 0x04;
11352 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
11353 delay |= (delay << 8);
11355 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11357 /* 3. TV */
11359 index = GetOEMTVPtr661(SiS_Pr);
11360 if(SiS_Pr->SiS_ROMNew) {
11361 romptr = SISGETROMW(0x106);
11362 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
11363 delay = ROMAddr[romptr + index];
11364 } else {
11365 delay = 0x04;
11366 if(index > 3) delay = 0;
11369 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11371 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
11373 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
11374 ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
11376 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
11378 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
11379 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
11380 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
11382 } else {
11384 /* TMDS: Set our own, since BIOS has no idea */
11385 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
11386 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11387 switch(SiS_Pr->SiS_LCDResInfo) {
11388 case Panel_1024x768: delay = 0x0008; break;
11389 case Panel_1280x720: delay = 0x0004; break;
11390 case Panel_1280x768:
11391 case Panel_1280x768_2:delay = 0x0004; break;
11392 case Panel_1280x800:
11393 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
11394 case Panel_1280x1024: delay = 0x1e04; break;
11395 case Panel_1400x1050: delay = 0x0004; break;
11396 case Panel_1600x1200: delay = 0x0400; break;
11397 case Panel_1680x1050: delay = 0x0e04; break;
11398 default:
11399 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
11400 delay = 0x0008;
11401 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
11402 delay = 0x1e04;
11403 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
11404 delay = 0x0004;
11405 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
11406 delay = 0x0400;
11407 } else
11408 delay = 0x0e04;
11409 break;
11413 /* Override by detected or user-set values */
11414 /* (but only if, for some reason, we can't read value from BIOS) */
11415 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
11416 delay = SiS_Pr->PDC & 0x1f;
11418 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
11419 delay = (SiS_Pr->PDCA & 0x1f) << 8;
11426 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11427 delay >>= 8;
11428 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11429 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11430 } else {
11431 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11432 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11436 static void
11437 SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
11439 USHORT infoflag;
11440 UCHAR temp;
11442 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11444 if(ModeNo <= 0x13) {
11445 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
11446 } else if(SiS_Pr->UseCustomMode) {
11447 infoflag = SiS_Pr->CInfoFlag;
11448 } else {
11449 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
11452 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11453 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
11456 infoflag &= 0xc0;
11458 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11459 temp = (infoflag >> 6) | 0x0c;
11460 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
11461 temp ^= 0x04;
11462 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
11464 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
11465 } else {
11466 temp = 0x30;
11467 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
11468 temp |= infoflag;
11469 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
11470 temp = 0;
11471 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
11472 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
11474 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
11480 static void
11481 SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11483 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11484 USHORT romptr, temp1, temp2;
11486 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11487 if(SiS_Pr->LVDSHL != -1) {
11488 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11492 if(SiS_Pr->SiS_ROMNew) {
11494 if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
11495 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11496 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
11497 temp2 = 0xfc;
11498 if(SiS_Pr->LVDSHL != -1) {
11499 temp1 &= 0xfc;
11500 temp2 = 0xf3;
11502 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
11504 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11505 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
11506 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
11513 void
11514 SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11515 USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)
11517 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
11518 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11519 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11520 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11521 SetPanelParms661(SiS_Pr,HwInfo);
11523 } else {
11524 SetDelayComp(SiS_Pr,HwInfo,ModeNo);
11527 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11528 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11529 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11530 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11531 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11532 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11537 void
11538 SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11539 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
11541 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11543 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11545 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11546 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11547 SetPanelParms661(SiS_Pr,HwInfo);
11550 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11551 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11552 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11553 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11554 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11555 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11561 /* FinalizeLCD
11562 * This finalizes some CRT2 registers for the very panel used.
11563 * If we have a backup if these registers, we use it; otherwise
11564 * we set the register according to most BIOSes. However, this
11565 * function looks quite different in every BIOS, so you better
11566 * pray that we have a backup...
11568 void
11569 SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11570 PSIS_HW_INFO HwInfo)
11572 USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
11573 USHORT resinfo,modeflag;
11575 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
11576 if(SiS_Pr->SiS_ROMNew) return;
11578 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11579 if(SiS_Pr->LVDSHL != -1) {
11580 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11584 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11585 if(SiS_Pr->UseCustomMode) return;
11587 switch(SiS_Pr->SiS_CustomT) {
11588 case CUT_COMPAQ1280:
11589 case CUT_COMPAQ12802:
11590 case CUT_CLEVO1400:
11591 case CUT_CLEVO14002:
11592 return;
11595 if(ModeNo <= 0x13) {
11596 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11597 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11598 } else {
11599 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11600 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11603 if(IS_SIS650) {
11604 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
11605 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11606 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
11607 } else {
11608 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
11613 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11614 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11615 /* Maybe all panels? */
11616 if(SiS_Pr->LVDSHL == -1) {
11617 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11619 return;
11623 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
11624 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11625 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11626 if(SiS_Pr->LVDSHL == -1) {
11627 /* Maybe all panels? */
11628 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11630 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11631 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11632 if(tempch == 3) {
11633 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11634 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11635 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11636 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11639 return;
11644 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11645 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11646 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
11647 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
11648 #ifdef SET_EMI
11649 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
11650 #endif
11651 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
11653 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
11654 if(SiS_Pr->LVDSHL == -1) {
11655 /* Maybe ACER only? */
11656 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11659 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11660 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11661 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
11662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
11663 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11664 if(tempch == 0x03) {
11665 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11666 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11667 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11668 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11670 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
11671 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
11672 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
11673 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
11674 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
11675 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
11676 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
11677 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
11678 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
11679 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
11680 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
11681 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
11682 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
11683 if(ModeNo <= 0x13) {
11684 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
11685 if((resinfo == 0) || (resinfo == 2)) return;
11686 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
11687 if((resinfo == 1) || (resinfo == 3)) return;
11689 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11690 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
11691 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
11692 #if 0
11693 tempbx = 806; /* 0x326 */ /* other older BIOSes */
11694 tempbx--;
11695 temp = tempbx & 0xff;
11696 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
11697 temp = (tempbx >> 8) & 0x03;
11698 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
11699 #endif
11701 } else if(ModeNo <= 0x13) {
11702 if(ModeNo <= 1) {
11703 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
11704 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
11705 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11706 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11708 if(!(modeflag & HalfDCLK)) {
11709 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
11710 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
11711 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
11712 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
11713 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
11714 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11715 if(ModeNo == 0x12) {
11716 switch(tempch) {
11717 case 0:
11718 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11719 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11720 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
11721 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11722 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
11723 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11724 break;
11725 case 2:
11726 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11727 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11728 break;
11729 case 3:
11730 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11731 break;
11737 } else {
11738 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
11739 tempcl &= 0x0f;
11740 tempbh &= 0x70;
11741 tempbh >>= 4;
11742 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
11743 tempbx = (tempbh << 8) | tempbl;
11744 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11745 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
11746 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
11747 tempbx = 770;
11748 } else {
11749 if(tempbx > 770) tempbx = 770;
11750 if(SiS_Pr->SiS_VGAVDE < 600) {
11751 tempax = 768 - SiS_Pr->SiS_VGAVDE;
11752 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
11753 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
11754 tempbx -= tempax;
11757 } else return;
11759 temp = tempbx & 0xff;
11760 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
11761 temp = ((tempbx & 0xff00) >> 4) | tempcl;
11762 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
11767 #endif
11769 /* ================= SiS 300 O.E.M. ================== */
11771 #ifdef SIS300
11773 void
11774 SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11775 USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
11777 USHORT crt2crtc=0, modeflag, myindex=0;
11778 UCHAR temp;
11779 int i;
11781 if(ModeNo <= 0x13) {
11782 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11783 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
11784 } else {
11785 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11786 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
11789 crt2crtc &= 0x3f;
11791 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
11792 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
11795 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
11796 if(modeflag & HalfDCLK) myindex = 1;
11798 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
11799 for(i=0; i<7; i++) {
11800 if(barco_p1[myindex][crt2crtc][i][0]) {
11801 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
11802 barco_p1[myindex][crt2crtc][i][0],
11803 barco_p1[myindex][crt2crtc][i][2],
11804 barco_p1[myindex][crt2crtc][i][1]);
11808 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
11809 if(temp & 0x80) {
11810 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
11811 temp++;
11812 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
11817 static USHORT
11818 GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
11820 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11821 USHORT tempbx=0,romptr=0;
11822 UCHAR customtable300[] = {
11823 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11824 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11826 UCHAR customtable630[] = {
11827 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11828 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11831 if(HwInfo->jChipType == SIS_300) {
11833 tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
11834 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11835 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11836 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11838 if(SiS_Pr->SiS_UseROM) {
11839 if(ROMAddr[0x235] & 0x80) {
11840 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11841 if(Flag) {
11842 romptr = SISGETROMW(0x255);
11843 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11844 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11845 if(tempbx == 0xFF) return 0xFFFF;
11847 tempbx <<= 1;
11848 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11852 } else {
11854 if(Flag) {
11855 if(SiS_Pr->SiS_UseROM) {
11856 romptr = SISGETROMW(0x255);
11857 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11858 else tempbx = 0xff;
11859 } else {
11860 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11862 if(tempbx == 0xFF) return 0xFFFF;
11863 tempbx <<= 2;
11864 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11865 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11866 return tempbx;
11868 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11869 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11870 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11872 return tempbx;
11875 static void
11876 SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11877 USHORT ModeNo,USHORT ModeIdIndex)
11879 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11880 USHORT index,temp,romptr=0;
11882 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11884 if(SiS_Pr->SiS_UseROM) {
11885 if(!(ROMAddr[0x237] & 0x01)) return;
11886 if(!(ROMAddr[0x237] & 0x02)) return;
11887 romptr = SISGETROMW(0x24b);
11890 /* The Panel Compensation Delay should be set according to tables
11891 * here. Unfortunately, various BIOS versions don't case about
11892 * a uniform way using eg. ROM byte 0x220, but use different
11893 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11894 * Thus we don't set this if the user select a custom pdc or if
11895 * we otherwise detected a valid pdc.
11897 if(SiS_Pr->PDC != -1) return;
11899 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
11901 if(SiS_Pr->UseCustomMode)
11902 index = 0;
11903 else
11904 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11906 if(HwInfo->jChipType != SIS_300) {
11907 if(romptr) {
11908 romptr += (temp * 2);
11909 romptr = SISGETROMW(romptr);
11910 romptr += index;
11911 temp = ROMAddr[romptr];
11912 } else {
11913 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11914 temp = SiS300_OEMLCDDelay2[temp][index];
11915 } else {
11916 temp = SiS300_OEMLCDDelay3[temp][index];
11919 } else {
11920 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11921 if(romptr) {
11922 romptr += (temp * 2);
11923 romptr = SISGETROMW(romptr);
11924 romptr += index;
11925 temp = ROMAddr[romptr];
11926 } else {
11927 temp = SiS300_OEMLCDDelay5[temp][index];
11929 } else {
11930 if(SiS_Pr->SiS_UseROM) {
11931 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11932 if(romptr) {
11933 romptr += (temp * 2);
11934 romptr = SISGETROMW(romptr);
11935 romptr += index;
11936 temp = ROMAddr[romptr];
11937 } else {
11938 temp = SiS300_OEMLCDDelay4[temp][index];
11940 } else {
11941 temp = SiS300_OEMLCDDelay4[temp][index];
11945 temp &= 0x3c;
11946 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11949 static void
11950 SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11951 USHORT ModeNo,USHORT ModeIdIndex)
11953 #if 0 /* Unfinished; Data table missing */
11954 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11955 USHORT index,temp;
11957 if((SiS_Pr->SiS_UseROM) {
11958 if(!(ROMAddr[0x237] & 0x01)) return;
11959 if(!(ROMAddr[0x237] & 0x04)) return;
11960 /* No rom pointer in BIOS header! */
11963 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
11964 if(temp = 0xFFFF) return;
11966 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11967 for(i=0x14, j=0; i<=0x17; i++, j++) {
11968 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11970 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11972 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11973 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11974 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11975 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11976 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11977 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11979 #endif
11982 static USHORT
11983 GetOEMTVPtr(SiS_Private *SiS_Pr)
11985 USHORT index;
11987 index = 0;
11988 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11989 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11990 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11991 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11992 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11993 } else {
11994 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11995 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11997 return index;
12000 static void
12001 SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12002 USHORT ModeNo,USHORT ModeIdIndex)
12004 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12005 USHORT index,temp,romptr=0;
12007 if(SiS_Pr->SiS_UseROM) {
12008 if(!(ROMAddr[0x238] & 0x01)) return;
12009 if(!(ROMAddr[0x238] & 0x02)) return;
12010 romptr = SISGETROMW(0x241);
12013 temp = GetOEMTVPtr(SiS_Pr);
12015 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
12017 if(romptr) {
12018 romptr += (temp * 2);
12019 romptr = SISGETROMW(romptr);
12020 romptr += index;
12021 temp = ROMAddr[romptr];
12022 } else {
12023 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12024 temp = SiS300_OEMTVDelay301[temp][index];
12025 } else {
12026 temp = SiS300_OEMTVDelayLVDS[temp][index];
12029 temp &= 0x3c;
12030 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
12033 static void
12034 SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12035 USHORT ModeNo, USHORT ModeIdIndex)
12037 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12038 USHORT index,temp,romptr=0;
12040 if(SiS_Pr->SiS_UseROM) {
12041 if(!(ROMAddr[0x238] & 0x01)) return;
12042 if(!(ROMAddr[0x238] & 0x04)) return;
12043 romptr = SISGETROMW(0x243);
12046 temp = GetOEMTVPtr(SiS_Pr);
12048 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
12050 if(romptr) {
12051 romptr += (temp * 2);
12052 romptr = SISGETROMW(romptr);
12053 romptr += index;
12054 temp = ROMAddr[romptr];
12055 } else {
12056 temp = SiS300_OEMTVFlicker[temp][index];
12058 temp &= 0x70;
12059 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
12062 static void
12063 SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12064 USHORT ModeNo,USHORT ModeIdIndex)
12066 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12067 USHORT index,i,j,temp,romptr=0;
12069 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
12071 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
12073 if(SiS_Pr->SiS_UseROM) {
12074 if(!(ROMAddr[0x238] & 0x01)) return;
12075 if(!(ROMAddr[0x238] & 0x08)) return;
12076 romptr = SISGETROMW(0x245);
12079 temp = GetOEMTVPtr(SiS_Pr);
12081 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
12083 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12084 for(i=0x31, j=0; i<=0x34; i++, j++) {
12085 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
12087 } else {
12088 if(romptr) {
12089 romptr += (temp * 2);
12090 romptr = SISGETROMW(romptr);
12091 romptr += (index * 4);
12092 for(i=0x31, j=0; i<=0x34; i++, j++) {
12093 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12095 } else {
12096 for(i=0x31, j=0; i<=0x34; i++, j++) {
12097 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
12103 static void
12104 SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12105 USHORT ModeNo,USHORT ModeIdIndex)
12107 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12108 USHORT index,temp,i,j,romptr=0;
12110 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
12112 if(SiS_Pr->SiS_UseROM) {
12113 if(!(ROMAddr[0x238] & 0x01)) return;
12114 if(!(ROMAddr[0x238] & 0x10)) return;
12115 romptr = SISGETROMW(0x247);
12118 temp = GetOEMTVPtr(SiS_Pr);
12120 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
12121 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
12122 /* NTSCJ uses NTSC filters */
12124 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
12126 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12127 for(i=0x35, j=0; i<=0x38; i++, j++) {
12128 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12130 for(i=0x48; i<=0x4A; i++, j++) {
12131 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12133 } else {
12134 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
12135 romptr += (temp * 2);
12136 romptr = SISGETROMW(romptr);
12137 romptr += (index * 4);
12138 for(i=0x35, j=0; i<=0x38; i++, j++) {
12139 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12141 } else {
12142 for(i=0x35, j=0; i<=0x38; i++, j++) {
12143 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
12149 static USHORT
12150 SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
12152 USHORT ModeIdIndex;
12153 UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
12155 if(*ModeNo <= 5) *ModeNo |= 1;
12157 for(ModeIdIndex=0; ; ModeIdIndex++) {
12158 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
12159 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
12162 if(*ModeNo != 0x07) {
12163 if(*ModeNo > 0x03) return ModeIdIndex;
12164 if(VGAINFO & 0x80) return ModeIdIndex;
12165 ModeIdIndex++;
12168 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
12169 /* else 350 lines */
12170 return ModeIdIndex;
12173 void
12174 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12175 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
12177 USHORT OEMModeIdIndex=0;
12179 if(!SiS_Pr->UseCustomMode) {
12180 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
12181 if(!(OEMModeIdIndex)) return;
12184 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
12185 SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12186 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
12187 SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12190 if(SiS_Pr->UseCustomMode) return;
12191 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
12192 SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
12193 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12194 SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12195 SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12196 SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12200 #endif