[PATCH] W1: w1_netlink: New init/fini netlink callbacks.
[linux-2.6/verdex.git] / drivers / video / sis / init301.c
blob274dacd54bb82d269f982333ad1c2bdf79e1d5fc
1 /* $XFree86$ */
2 /* $XdotOrg$ */
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);
89 static void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx);
91 /*********************************************/
92 /* HELPER: Lock/Unlock CRT2 */
93 /*********************************************/
95 void
96 SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
98 if(HwInfo->jChipType >= SIS_315H)
99 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
100 else
101 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
104 static void
105 SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
107 if(HwInfo->jChipType >= SIS_315H)
108 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
109 else
110 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
113 /*********************************************/
114 /* HELPER: Write SR11 */
115 /*********************************************/
117 static void
118 SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
120 if(HwInfo->jChipType >= SIS_661) {
121 DataAND &= 0x0f;
122 DataOR &= 0x0f;
124 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
127 /*********************************************/
128 /* HELPER: Get Pointer to LCD structure */
129 /*********************************************/
131 #ifdef SIS315H
132 static UCHAR *
133 GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
135 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
136 UCHAR *myptr = NULL;
137 USHORT romindex = 0, reg = 0, idx = 0;
139 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
140 * due to the variaty of panels the BIOS doesn't know about.
141 * Exception: If the BIOS has better knowledge (such as in case
142 * of machines with a 301C and a panel that does not support DDC)
143 * use the BIOS data as well.
146 if((SiS_Pr->SiS_ROMNew) &&
147 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
149 if(HwInfo->jChipType < SIS_661) reg = 0x3c;
150 else reg = 0x7d;
152 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
154 if(idx < (8*26)) {
155 myptr = (UCHAR *)&SiS_LCDStruct661[idx];
157 romindex = SISGETROMW(0x100);
158 if(romindex) {
159 romindex += idx;
160 myptr = &ROMAddr[romindex];
163 return myptr;
166 static USHORT
167 GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
169 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
170 USHORT romptr = 0;
172 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
173 * due to the variaty of panels the BIOS doesn't know about.
174 * Exception: If the BIOS has better knowledge (such as in case
175 * of machines with a 301C and a panel that does not support DDC)
176 * use the BIOS data as well.
179 if((SiS_Pr->SiS_ROMNew) &&
180 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
181 romptr = SISGETROMW(0x102);
182 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
185 return(romptr);
187 #endif
189 /*********************************************/
190 /* Adjust Rate for CRT2 */
191 /*********************************************/
193 static BOOLEAN
194 SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
195 USHORT RRTI, USHORT *i, PSIS_HW_INFO HwInfo)
197 USHORT checkmask=0,modeid,infoflag;
199 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
201 if(SiS_Pr->SiS_VBType & VB_SISVB) {
203 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
205 checkmask |= SupportRAMDAC2;
206 if(HwInfo->jChipType >= SIS_315H) {
207 checkmask |= SupportRAMDAC2_135;
208 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
209 checkmask |= SupportRAMDAC2_162;
210 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
211 checkmask |= SupportRAMDAC2_202;
216 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
218 checkmask |= SupportLCD;
219 if(HwInfo->jChipType >= SIS_315H) {
220 if(SiS_Pr->SiS_VBType & VB_SISVB) {
221 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
222 if(modeid == 0x2e) checkmask |= Support64048060Hz;
227 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
229 checkmask |= SupportHiVision;
231 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
233 checkmask |= SupportTV;
234 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
235 checkmask |= SupportTV1024;
236 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
237 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
238 checkmask |= SupportYPbPr750p;
245 } else { /* LVDS */
247 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
248 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
249 checkmask |= SupportCHTV;
253 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
254 checkmask |= SupportLCD;
259 /* Look backwards in table for matching CRT2 mode */
260 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
261 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
262 if(infoflag & checkmask) return TRUE;
263 if((*i) == 0) break;
266 /* Look through the whole mode-section of the table from the beginning
267 * for a matching CRT2 mode if no mode was found yet.
269 for((*i) = 0; ; (*i)++) {
270 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
271 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
272 if(infoflag & checkmask) return TRUE;
274 return FALSE;
277 /*********************************************/
278 /* Get rate index */
279 /*********************************************/
281 USHORT
282 SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
283 PSIS_HW_INFO HwInfo)
285 SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
286 0x01, 0x01, 0x01, 0x01,
287 0x01, 0x01, 0x01, 0x01,
288 0x01, 0x01, 0x01, 0x01,
289 0x00, 0x00, 0x00, 0x00 };
290 USHORT RRTI,i,backup_i;
291 USHORT modeflag,index,temp,backupindex;
293 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
294 if(ModeNo == 0xfe) return 0;
296 if(ModeNo <= 0x13) {
297 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
298 } else {
299 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
302 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
303 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
304 if(modeflag & HalfDCLK) return 0;
308 if(ModeNo < 0x14) return 0xFFFF;
310 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
311 backupindex = index;
313 if(index > 0) index--;
315 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
316 if(SiS_Pr->SiS_VBType & VB_SISVB) {
317 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
318 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
319 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
321 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
322 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
323 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
324 if(index > temp) index = temp;
327 } else {
328 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
329 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
330 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
335 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
336 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
338 if(HwInfo->jChipType >= SIS_315H) {
339 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
340 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
341 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
342 if(backupindex <= 1) RRTI++;
347 i = 0;
348 do {
349 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
350 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
351 temp &= ModeTypeMask;
352 if(temp < SiS_Pr->SiS_ModeType) break;
353 i++;
354 index--;
355 } while(index != 0xFFFF);
357 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
358 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
359 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
360 if(temp & InterlaceMode) i++;
364 i--;
366 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
367 backup_i = i;
368 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i, HwInfo))) {
369 i = backup_i;
373 return(RRTI + i);
376 /*********************************************/
377 /* STORE CRT2 INFO in CR34 */
378 /*********************************************/
380 static void
381 SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
383 USHORT temp1,temp2;
385 /* Store CRT1 ModeNo in CR34 */
386 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
387 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
388 temp2 = ~(SetInSlaveMode >> 8);
389 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
392 /*********************************************/
393 /* HELPER: GET SOME DATA FROM BIOS ROM */
394 /*********************************************/
396 #ifdef SIS300
397 static BOOLEAN
398 SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
400 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
401 USHORT temp,temp1;
403 if(SiS_Pr->SiS_UseROM) {
404 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
405 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
406 temp1 = SISGETROMW(0x23b);
407 if(temp1 & temp) return TRUE;
410 return FALSE;
413 static BOOLEAN
414 SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
416 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
417 USHORT temp,temp1;
419 if(SiS_Pr->SiS_UseROM) {
420 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
421 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
422 temp1 = SISGETROMW(0x23d);
423 if(temp1 & temp) return TRUE;
426 return FALSE;
428 #endif
430 /*********************************************/
431 /* HELPER: DELAY FUNCTIONS */
432 /*********************************************/
434 void
435 SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
437 USHORT i, j;
439 for(i=0; i<delaytime; i++) {
440 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
444 #if defined(SIS300) || defined(SIS315H)
445 static void
446 SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
448 USHORT temp,flag;
450 flag = SiS_GetRegByte(0x61) & 0x10;
452 while(delay) {
453 temp = SiS_GetRegByte(0x61) & 0x10;
454 if(temp == flag) continue;
455 flag = temp;
456 delay--;
459 #endif
461 #ifdef SIS315H
462 static void
463 SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
465 while(delay--) {
466 SiS_GenericDelay(SiS_Pr,0x19df);
469 #endif
471 #if defined(SIS300) || defined(SIS315H)
472 static void
473 SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
475 while(delay--) {
476 SiS_GenericDelay(SiS_Pr,0x42);
479 #endif
481 static void
482 SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
484 #if defined(SIS300) || defined(SIS315H)
485 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
486 USHORT PanelID, DelayIndex, Delay=0;
487 #endif
489 if(HwInfo->jChipType < SIS_315H) {
491 #ifdef SIS300
493 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
494 if(SiS_Pr->SiS_VBType & VB_SISVB) {
495 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
496 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
498 DelayIndex = PanelID >> 4;
499 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
500 Delay = 3;
501 } else {
502 if(DelayTime >= 2) DelayTime -= 2;
503 if(!(DelayTime & 0x01)) {
504 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
505 } else {
506 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
508 if(SiS_Pr->SiS_UseROM) {
509 if(ROMAddr[0x220] & 0x40) {
510 if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
511 else Delay = (USHORT)ROMAddr[0x226];
515 SiS_ShortDelay(SiS_Pr, Delay);
517 #endif /* SIS300 */
519 } else {
521 #ifdef SIS315H
523 if((HwInfo->jChipType >= SIS_661) ||
524 (HwInfo->jChipType <= SIS_315PRO) ||
525 (HwInfo->jChipType == SIS_330) ||
526 (SiS_Pr->SiS_ROMNew)) {
528 if(!(DelayTime & 0x01)) {
529 SiS_DDC2Delay(SiS_Pr, 0x1000);
530 } else {
531 SiS_DDC2Delay(SiS_Pr, 0x4000);
534 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
535 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
536 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
538 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
539 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
540 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
541 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
543 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
544 DelayIndex = PanelID & 0x0f;
545 } else {
546 DelayIndex = PanelID >> 4;
548 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
549 Delay = 3;
550 } else {
551 if(DelayTime >= 2) DelayTime -= 2;
552 if(!(DelayTime & 0x01)) {
553 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
554 } else {
555 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
557 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
558 if(ROMAddr[0x13c] & 0x40) {
559 if(!(DelayTime & 0x01)) {
560 Delay = (USHORT)ROMAddr[0x17e];
561 } else {
562 Delay = (USHORT)ROMAddr[0x17f];
567 SiS_ShortDelay(SiS_Pr, Delay);
570 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
572 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
573 if(!(DelayTime & 0x01)) {
574 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
575 } else {
576 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
578 Delay <<= 8;
579 SiS_DDC2Delay(SiS_Pr, Delay);
583 #endif /* SIS315H */
588 #ifdef SIS315H
589 static void
590 SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
591 USHORT DelayTime, USHORT DelayLoop)
593 int i;
594 for(i=0; i<DelayLoop; i++) {
595 SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
598 #endif
600 /*********************************************/
601 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
602 /*********************************************/
604 void
605 SiS_WaitRetrace1(SiS_Private *SiS_Pr)
607 USHORT watchdog;
609 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
610 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
612 watchdog = 65535;
613 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
614 watchdog = 65535;
615 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
618 #if defined(SIS300) || defined(SIS315H)
619 static void
620 SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
622 USHORT watchdog;
624 watchdog = 65535;
625 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
626 watchdog = 65535;
627 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
629 #endif
631 static void
632 SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
634 if(HwInfo->jChipType < SIS_315H) {
635 #ifdef SIS300
636 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
637 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
639 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
640 SiS_WaitRetrace1(SiS_Pr);
641 } else {
642 SiS_WaitRetrace2(SiS_Pr, 0x25);
644 #endif
645 } else {
646 #ifdef SIS315H
647 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
648 SiS_WaitRetrace1(SiS_Pr);
649 } else {
650 SiS_WaitRetrace2(SiS_Pr, 0x30);
652 #endif
656 static void
657 SiS_VBWait(SiS_Private *SiS_Pr)
659 USHORT tempal,temp,i,j;
661 temp = 0;
662 for(i=0; i<3; i++) {
663 for(j=0; j<100; j++) {
664 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
665 if(temp & 0x01) {
666 if((tempal & 0x08)) continue;
667 else break;
668 } else {
669 if(!(tempal & 0x08)) continue;
670 else break;
673 temp ^= 0x01;
677 static void
678 SiS_VBLongWait(SiS_Private *SiS_Pr)
680 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
681 SiS_VBWait(SiS_Pr);
682 } else {
683 SiS_WaitRetrace1(SiS_Pr);
687 /*********************************************/
688 /* HELPER: MISC */
689 /*********************************************/
691 #ifdef SIS300
692 static BOOLEAN
693 SiS_Is301B(SiS_Private *SiS_Pr)
695 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
696 return FALSE;
698 #endif
700 static BOOLEAN
701 SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
703 USHORT flag;
705 if(HwInfo->jChipType == SIS_730) {
706 flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
707 if(flag & 0x20) return TRUE;
709 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
710 if(flag & 0x20) return TRUE;
711 return FALSE;
714 BOOLEAN
715 SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
717 #ifdef SIS315H
718 USHORT flag;
720 if(HwInfo->jChipType >= SIS_315H) {
721 if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
722 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
723 if(flag & EnableDualEdge) return TRUE;
726 #endif
727 return FALSE;
730 BOOLEAN
731 SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
733 #ifdef SIS315H
734 USHORT flag;
736 if(HwInfo->jChipType >= SIS_315H) {
737 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
738 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
740 #endif
741 return FALSE;
744 #ifdef SIS315H
745 static BOOLEAN
746 SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
748 if(SiS_IsVAMode(SiS_Pr,HwInfo)) return TRUE;
749 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
750 return FALSE;
752 #endif
754 static BOOLEAN
755 SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
757 #ifdef SIS315H
758 if(HwInfo->jChipType >= SIS_315H) {
759 if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
760 (SiS_IsVAMode(SiS_Pr, HwInfo))) {
761 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
764 #endif
765 return FALSE;
768 #ifdef SIS315H
769 static BOOLEAN
770 SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
772 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
773 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
774 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
776 return FALSE;
778 #endif
780 #ifdef SIS315H
781 static BOOLEAN
782 SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
784 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
785 return FALSE;
787 #endif
789 #ifdef SIS315H
790 static BOOLEAN
791 SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
793 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
794 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
796 return FALSE;
798 #endif
800 #ifdef SIS315H
801 static BOOLEAN
802 SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
804 USHORT flag;
806 if(HwInfo->jChipType == SIS_650) {
807 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
808 flag &= 0xF0;
809 /* Check for revision != A0 only */
810 if((flag == 0xe0) || (flag == 0xc0) ||
811 (flag == 0xb0) || (flag == 0x90)) return FALSE;
812 } else if(HwInfo->jChipType >= SIS_661) return FALSE;
813 return TRUE;
815 #endif
817 #ifdef SIS315H
818 static BOOLEAN
819 SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
821 USHORT flag;
823 if(HwInfo->jChipType >= SIS_315H) {
824 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
825 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
827 return FALSE;
829 #endif
831 #ifdef SIS315H
832 static BOOLEAN
833 SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
835 USHORT flag;
837 if(HwInfo->jChipType >= SIS_315H) {
838 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
839 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 */
841 return FALSE;
843 #endif
845 #ifdef SIS315H
846 static BOOLEAN
847 SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
849 USHORT flag;
851 if(HwInfo->jChipType >= SIS_315H) {
852 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
853 if(flag & SetCRT2ToTV) return TRUE;
854 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
855 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
856 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
857 } else {
858 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
859 if(flag & SetCRT2ToTV) return TRUE;
861 return FALSE;
863 #endif
865 #ifdef SIS315H
866 static BOOLEAN
867 SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
869 USHORT flag;
871 if(HwInfo->jChipType >= SIS_315H) {
872 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
873 if(flag & SetCRT2ToLCD) return TRUE;
874 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
875 if(flag & SetToLCDA) return TRUE;
876 } else {
877 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
878 if(flag & SetCRT2ToLCD) return TRUE;
880 return FALSE;
882 #endif
884 static BOOLEAN
885 SiS_BridgeIsOn(SiS_Private *SiS_Pr)
887 USHORT flag;
889 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
890 return TRUE;
891 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
892 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
893 if((flag == 1) || (flag == 2)) return TRUE;
895 return FALSE;
898 static BOOLEAN
899 SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
901 USHORT flag;
903 if(SiS_BridgeIsOn(SiS_Pr)) {
904 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
905 if(HwInfo->jChipType < SIS_315H) {
906 flag &= 0xa0;
907 if((flag == 0x80) || (flag == 0x20)) return TRUE;
908 } else {
909 flag &= 0x50;
910 if((flag == 0x40) || (flag == 0x10)) return TRUE;
913 return FALSE;
916 static BOOLEAN
917 SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
919 USHORT flag1;
921 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
922 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
923 return FALSE;
926 /*********************************************/
927 /* GET VIDEO BRIDGE CONFIG INFO */
928 /*********************************************/
930 /* Setup general purpose IO for Chrontel communication */
931 void
932 SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
934 unsigned long acpibase;
935 unsigned short temp;
937 if(!(SiS_Pr->SiS_ChSW)) return;
939 #ifdef LINUX_KERNEL
940 SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */
941 acpibase = SiS_GetRegLong(0xcfc);
942 #else
943 acpibase = pciReadLong(0x00000800, 0x74);
944 #endif
945 acpibase &= 0xFFFF;
946 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
947 temp &= 0xFEFF;
948 SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
949 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
950 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
951 temp &= 0xFEFF;
952 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
953 SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
954 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
957 void
958 SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
959 PSIS_HW_INFO HwInfo, int checkcrt2mode)
961 USHORT tempax,tempbx,temp;
962 USHORT modeflag, resinfo=0;
964 if(ModeNo <= 0x13) {
965 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
966 } else if(SiS_Pr->UseCustomMode) {
967 modeflag = SiS_Pr->CModeFlag;
968 } else {
969 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
970 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
973 SiS_Pr->SiS_SetFlag = 0;
975 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
977 tempbx = 0;
978 if(SiS_BridgeIsOn(SiS_Pr)) {
979 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
980 #if 0
981 if(HwInfo->jChipType < SIS_661) {
982 /* NO - YPbPr not set yet ! */
983 if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
984 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
985 temp |= SetCRT2ToHiVision; /* 0x80 */
987 if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
988 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
989 temp |= SetCRT2ToSVIDEO; /* 0x08 */
992 #endif
993 tempbx |= temp;
994 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
995 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
996 tempbx |= tempax;
998 #ifdef SIS315H
999 if(HwInfo->jChipType >= SIS_315H) {
1000 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1001 if(ModeNo == 0x03) {
1002 /* Mode 0x03 is never in driver mode */
1003 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1005 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1006 /* Reset LCDA setting if not driver mode */
1007 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1009 if(IS_SIS650) {
1010 if(SiS_Pr->SiS_UseLCDA) {
1011 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1012 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1013 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1018 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1019 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1020 tempbx |= SetCRT2ToLCDA;
1024 if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1025 tempbx &= ~(SetCRT2ToRAMDAC);
1028 if(HwInfo->jChipType >= SIS_661) {
1029 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1030 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1031 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1032 if(temp & 0x04) {
1033 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1034 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1035 else tempbx |= SetCRT2ToYPbPr525750;
1037 } else if(SiS_Pr->SiS_VBType & VB_SISHIVISION) {
1038 if(temp & 0x04) {
1039 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1040 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1045 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1046 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1047 if(temp & SetToLCDA) {
1048 tempbx |= SetCRT2ToLCDA;
1050 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1051 if(temp & EnableCHYPbPr) {
1052 tempbx |= SetCRT2ToCHYPbPr;
1058 #endif /* SIS315H */
1060 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1061 temp = SetCRT2ToSVIDEO |
1062 SetCRT2ToAVIDEO |
1063 SetCRT2ToSCART |
1064 SetCRT2ToLCDA |
1065 SetCRT2ToLCD |
1066 SetCRT2ToRAMDAC |
1067 SetCRT2ToHiVision |
1068 SetCRT2ToYPbPr525750;
1069 } else {
1070 if(HwInfo->jChipType >= SIS_315H) {
1071 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1072 temp = SetCRT2ToAVIDEO |
1073 SetCRT2ToSVIDEO |
1074 SetCRT2ToSCART |
1075 SetCRT2ToLCDA |
1076 SetCRT2ToLCD |
1077 SetCRT2ToCHYPbPr;
1078 } else {
1079 temp = SetCRT2ToLCDA |
1080 SetCRT2ToLCD;
1082 } else {
1083 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1084 temp = SetCRT2ToTV | SetCRT2ToLCD;
1085 } else {
1086 temp = SetCRT2ToLCD;
1091 if(!(tempbx & temp)) {
1092 tempax = DisableCRT2Display;
1093 tempbx = 0;
1096 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1097 USHORT clearmask = ( DriverMode |
1098 DisableCRT2Display |
1099 LoadDACFlag |
1100 SetNotSimuMode |
1101 SetInSlaveMode |
1102 SetPALTV |
1103 SwitchCRT2 |
1104 SetSimuScanMode );
1105 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1106 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1107 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1108 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1109 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1110 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1111 } else {
1112 if(HwInfo->jChipType >= SIS_315H) {
1113 if(tempbx & SetCRT2ToLCDA) {
1114 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1117 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1118 if(tempbx & SetCRT2ToTV) {
1119 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1122 if(tempbx & SetCRT2ToLCD) {
1123 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1125 if(HwInfo->jChipType >= SIS_315H) {
1126 if(tempbx & SetCRT2ToLCDA) {
1127 tempbx |= SetCRT2ToLCD;
1132 if(tempax & DisableCRT2Display) {
1133 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1134 tempbx = SetSimuScanMode | DisableCRT2Display;
1138 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1140 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1141 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1142 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1143 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1144 modeflag &= (~CRT2Mode);
1148 if(!(tempbx & SetSimuScanMode)) {
1149 if(tempbx & SwitchCRT2) {
1150 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1151 if( (HwInfo->jChipType >= SIS_315H) &&
1152 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1153 if(resinfo != SIS_RI_1600x1200) {
1154 tempbx |= SetSimuScanMode;
1156 } else {
1157 tempbx |= SetSimuScanMode;
1160 } else {
1161 if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
1162 if(!(tempbx & DriverMode)) {
1163 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1164 tempbx |= SetSimuScanMode;
1171 if(!(tempbx & DisableCRT2Display)) {
1172 if(tempbx & DriverMode) {
1173 if(tempbx & SetSimuScanMode) {
1174 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1175 if( (HwInfo->jChipType >= SIS_315H) &&
1176 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1177 if(resinfo != SIS_RI_1600x1200) {
1178 tempbx |= SetInSlaveMode;
1180 } else {
1181 tempbx |= SetInSlaveMode;
1185 } else {
1186 tempbx |= SetInSlaveMode;
1192 SiS_Pr->SiS_VBInfo = tempbx;
1194 if(HwInfo->jChipType == SIS_630) {
1195 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1198 #ifdef TWDEBUG
1199 #ifdef LINUX_KERNEL
1200 printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1201 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1202 #endif
1203 #ifdef LINUX_XF86
1204 xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1205 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1206 #endif
1207 #endif
1210 /*********************************************/
1211 /* DETERMINE YPbPr MODE */
1212 /*********************************************/
1214 void
1215 SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1218 UCHAR temp;
1220 /* Note: This variable is only used on 30xLV systems.
1221 * CR38 has a different meaning on LVDS/CH7019 systems.
1222 * On 661 and later, these bits moved to CR35.
1224 * On 301, 301B, only HiVision 1080i is supported.
1225 * On 30xLV, 301C, only YPbPr 1080i is supported.
1228 SiS_Pr->SiS_YPbPr = 0;
1229 if(HwInfo->jChipType >= SIS_661) return;
1231 if(SiS_Pr->SiS_VBType) {
1232 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1233 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1237 if(HwInfo->jChipType >= SIS_315H) {
1238 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
1239 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1240 if(temp & 0x08) {
1241 switch((temp >> 4)) {
1242 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1243 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1244 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1245 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1253 /*********************************************/
1254 /* DETERMINE TVMode flag */
1255 /*********************************************/
1257 void
1258 SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
1260 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1261 USHORT temp, temp1, resinfo = 0, romindex = 0;
1262 UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1264 SiS_Pr->SiS_TVMode = 0;
1266 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1267 if(SiS_Pr->UseCustomMode) return;
1269 if(ModeNo > 0x13) {
1270 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1273 if(HwInfo->jChipType < SIS_661) {
1275 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1277 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1278 temp = 0;
1279 if((HwInfo->jChipType == SIS_630) ||
1280 (HwInfo->jChipType == SIS_730)) {
1281 temp = 0x35;
1282 romindex = 0xfe;
1283 } else if(HwInfo->jChipType >= SIS_315H) {
1284 temp = 0x38;
1285 romindex = 0xf3;
1286 if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
1288 if(temp) {
1289 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1290 OutputSelect = ROMAddr[romindex];
1291 if(!(OutputSelect & EnablePALMN)) {
1292 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1295 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1296 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1297 if(temp1 & EnablePALM) { /* 0x40 */
1298 SiS_Pr->SiS_TVMode |= TVSetPALM;
1299 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1300 } else if(temp1 & EnablePALN) { /* 0x80 */
1301 SiS_Pr->SiS_TVMode |= TVSetPALN;
1303 } else {
1304 if(temp1 & EnableNTSCJ) { /* 0x40 */
1305 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1309 /* Translate HiVision/YPbPr to our new flags */
1310 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1311 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1312 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1313 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1314 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1315 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1316 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1317 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1318 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1319 SiS_Pr->SiS_TVMode |= TVSetPAL;
1322 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1323 if(SiS_Pr->SiS_CHOverScan) {
1324 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1325 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1326 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1327 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1329 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1330 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1331 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1332 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1335 if(SiS_Pr->SiS_CHSOverScan) {
1336 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1339 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1340 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1341 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1342 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1343 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1344 } else {
1345 if(temp & EnableNTSCJ) {
1346 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1352 } else { /* 661 and later */
1354 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1355 if(temp1 & 0x01) {
1356 SiS_Pr->SiS_TVMode |= TVSetPAL;
1357 if(temp1 & 0x08) {
1358 SiS_Pr->SiS_TVMode |= TVSetPALN;
1359 } else if(temp1 & 0x04) {
1360 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1361 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1363 SiS_Pr->SiS_TVMode |= TVSetPALM;
1365 } else {
1366 if(temp1 & 0x02) {
1367 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1370 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1371 if(SiS_Pr->SiS_CHOverScan) {
1372 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1373 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1377 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1378 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1379 temp1 &= 0xe0;
1380 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1381 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1382 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1383 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1384 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1386 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1387 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1388 SiS_Pr->SiS_TVMode |= TVAspect169;
1389 } else {
1390 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1391 if(temp1 & 0x02) {
1392 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1393 SiS_Pr->SiS_TVMode |= TVAspect169;
1394 } else {
1395 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1397 } else {
1398 SiS_Pr->SiS_TVMode |= TVAspect43;
1405 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1407 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1409 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1410 SiS_Pr->SiS_TVMode |= TVSetPAL;
1411 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1412 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1413 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1414 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1418 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1419 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1420 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1424 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1425 /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
1426 if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
1427 if(resinfo == SIS_RI_1024x768) {
1428 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1433 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1434 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1435 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1436 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1437 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1438 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1439 } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
1440 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1441 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1447 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1449 #ifdef TWDEBUG
1450 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1451 #endif
1454 /*********************************************/
1455 /* GET LCD INFO */
1456 /*********************************************/
1458 static USHORT
1459 SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
1461 USHORT temp = SiS_Pr->SiS_LCDResInfo;
1462 /* Translate my LCDResInfo to BIOS value */
1463 if(temp == Panel_1280x768_2) temp = Panel_1280x768;
1464 if(temp == Panel_1280x800_2) temp = Panel_1280x800;
1465 return temp;
1468 static void
1469 SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1471 #ifdef SIS315H
1472 UCHAR *ROMAddr;
1473 USHORT temp;
1475 #ifdef TWDEBUG
1476 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1477 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1478 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1479 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1480 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1481 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1482 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1483 #endif
1485 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1486 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1487 SiS_Pr->SiS_NeedRomModeData = TRUE;
1488 SiS_Pr->PanelHT = temp;
1490 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1491 SiS_Pr->SiS_NeedRomModeData = TRUE;
1492 SiS_Pr->PanelVT = temp;
1494 SiS_Pr->PanelHRS = SISGETROMW(10);
1495 SiS_Pr->PanelHRE = SISGETROMW(12);
1496 SiS_Pr->PanelVRS = SISGETROMW(14);
1497 SiS_Pr->PanelVRE = SISGETROMW(16);
1498 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1499 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1500 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
1501 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1502 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1503 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1504 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1506 #ifdef TWDEBUG
1507 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1508 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1509 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1510 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1511 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1512 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1513 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1514 #endif
1517 #endif
1520 static void
1521 SiS_CheckScaling(SiS_Private *SiS_Pr, USHORT resinfo, const UCHAR *nonscalingmodes)
1523 int i = 0;
1524 while(nonscalingmodes[i] != 0xff) {
1525 if(nonscalingmodes[i++] == resinfo) {
1526 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1527 (SiS_Pr->UsePanelScaler == -1)) {
1528 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1530 break;
1535 void
1536 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1537 PSIS_HW_INFO HwInfo)
1539 #ifdef SIS300
1540 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1541 const unsigned char SiS300SeriesLCDRes[] =
1542 { 0, 1, 2, 3, 7, 4, 5, 8,
1543 0, 0, 10, 0, 0, 0, 0, 15 };
1544 #endif
1545 #ifdef SIS315H
1546 UCHAR *myptr = NULL;
1547 #endif
1548 USHORT temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1549 BOOLEAN panelcanscale = FALSE;
1551 SiS_Pr->SiS_LCDResInfo = 0;
1552 SiS_Pr->SiS_LCDTypeInfo = 0;
1553 SiS_Pr->SiS_LCDInfo = 0;
1554 SiS_Pr->PanelHRS = 999; /* HSync start */
1555 SiS_Pr->PanelHRE = 999; /* HSync end */
1556 SiS_Pr->PanelVRS = 999; /* VSync start */
1557 SiS_Pr->PanelVRE = 999; /* VSync end */
1558 SiS_Pr->SiS_NeedRomModeData = FALSE;
1560 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1562 if(ModeNo <= 0x13) {
1563 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1564 } else if(SiS_Pr->UseCustomMode) {
1565 modeflag = SiS_Pr->CModeFlag;
1566 } else {
1567 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1568 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1569 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1570 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1573 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1575 /* For broken BIOSes: Assume 1024x768 */
1576 if(temp == 0) temp = 0x02;
1578 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1579 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1580 } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
1581 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1582 } else {
1583 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1585 temp &= 0x0f;
1586 #ifdef SIS300
1587 if(HwInfo->jChipType < SIS_315H) {
1588 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1589 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1590 if(temp < 0x0f) temp &= 0x07;
1592 /* Translate 300 series LCDRes to 315 series for unified usage */
1593 temp = SiS300SeriesLCDRes[temp];
1595 #endif
1597 /* Translate to our internal types */
1598 if(HwInfo->jChipType == SIS_550) {
1599 if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
1600 if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
1603 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1604 if(temp == Panel310_1280x768) {
1605 temp = Panel_1280x768_2;
1607 if(SiS_Pr->SiS_ROMNew) {
1608 if(temp == Panel661_1280x800) {
1609 temp = Panel_1280x800_2;
1614 SiS_Pr->SiS_LCDResInfo = temp;
1616 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1617 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1618 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1619 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1620 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1624 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1625 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1626 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1627 } else {
1628 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1629 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1632 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1633 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1634 /* Need temp below! */
1636 /* These can't scale no matter what */
1637 switch(SiS_Pr->SiS_LCDResInfo) {
1638 case Panel_1280x960:
1639 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1642 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
1644 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1645 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1647 /* Dual link, Pass 1:1 BIOS default, etc. */
1648 #ifdef SIS315H
1649 if(HwInfo->jChipType >= SIS_661) {
1650 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1651 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1653 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1654 if(SiS_Pr->SiS_ROMNew) {
1655 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1656 } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1657 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1660 } else if(HwInfo->jChipType >= SIS_315H) {
1661 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1662 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1664 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1665 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1666 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1667 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1668 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1669 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1671 } else if(!(SiS_Pr->SiS_ROMNew)) {
1672 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1673 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1674 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1675 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1677 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1678 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1679 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1680 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1681 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1686 #endif
1688 /* Pass 1:1 */
1689 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1690 /* Always center screen on LVDS (if scaling is disabled) */
1691 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1692 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1693 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1694 /* Always center screen on SiS LVDS (if scaling is disabled) */
1695 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1696 } else {
1697 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1698 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1699 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1703 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1704 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1706 switch(SiS_Pr->SiS_LCDResInfo) {
1707 case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480;
1708 SiS_Pr->PanelHT = 400; SiS_Pr->PanelVT = 525;
1709 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1710 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1711 break;
1712 case Panel_640x480_2:
1713 case Panel_640x480_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1714 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1715 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1716 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1717 break;
1718 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1719 SiS_Pr->PanelVRE = 3;
1720 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1721 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1722 break;
1723 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1724 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1725 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1726 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1727 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1728 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1729 break;
1730 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1731 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1732 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1733 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1734 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1735 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1736 break;
1737 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1738 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1739 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
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 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1748 break;
1749 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1750 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1751 SiS_Pr->PanelHRS = 24;
1752 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1753 if(HwInfo->jChipType < SIS_315H) {
1754 SiS_Pr->PanelHRS = 23;
1755 SiS_Pr->PanelVRE = 5;
1757 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1758 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1759 break;
1760 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1761 break;
1762 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1763 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1764 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1765 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1766 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1767 /* Data above for TMDS (projector); get from BIOS for LVDS */
1768 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1769 break;
1770 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1771 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1772 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1773 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1774 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1775 } else {
1776 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1777 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1778 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1779 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1780 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1782 break;
1783 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1784 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1785 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1786 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1787 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1788 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1789 break;
1790 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1791 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1792 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1793 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1794 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1795 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1796 break;
1797 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1798 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1799 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1800 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1801 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1802 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1803 break;
1804 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1805 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1806 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1807 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1808 if(resinfo == SIS_RI_1280x1024) {
1809 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1810 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1812 break;
1813 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1814 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1815 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1816 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1817 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1818 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1819 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1820 break;
1821 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1822 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1823 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; /* HRE OK for LVDS, not for LCDA */
1824 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1825 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1826 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1827 break;
1828 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1829 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1830 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1831 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1832 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1833 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1834 break;
1835 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1836 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1837 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1838 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1839 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1840 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1841 break;
1842 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1843 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1844 break;
1845 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1846 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1847 break;
1848 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1849 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1850 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1851 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1852 if(SiS_Pr->CP_PreferredIndex != -1) {
1853 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1854 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1855 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1856 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1857 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1858 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1859 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1860 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1861 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1862 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1863 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1864 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1865 if(SiS_Pr->CP_PrefClock) {
1866 int idx;
1867 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1868 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1869 if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1870 else idx = VCLK_CUSTOM_315;
1871 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1872 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1873 SiS_Pr->SiS_VCLKData[idx].SR2B =
1874 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1875 SiS_Pr->SiS_VCLKData[idx].SR2C =
1876 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1879 break;
1880 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1881 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1882 break;
1885 /* Special cases */
1886 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1887 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1888 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1889 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1890 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1891 SiS_Pr->PanelHRS = 999;
1892 SiS_Pr->PanelHRE = 999;
1895 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1896 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1897 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1898 SiS_Pr->PanelVRS = 999;
1899 SiS_Pr->PanelVRE = 999;
1902 /* DontExpand overrule */
1903 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1905 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1906 /* No scaling for this mode on any panel (LCD=CRT2)*/
1907 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1910 switch(SiS_Pr->SiS_LCDResInfo) {
1912 case Panel_Custom:
1913 case Panel_1152x864:
1914 case Panel_1280x768: /* TMDS only */
1915 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1916 break;
1918 case Panel_800x600: {
1919 static const UCHAR nonscalingmodes[] = {
1920 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1922 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1923 break;
1925 case Panel_1024x768: {
1926 static const UCHAR nonscalingmodes[] = {
1927 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1928 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1929 0xff
1931 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1932 break;
1934 case Panel_1280x720: {
1935 static const UCHAR nonscalingmodes[] = {
1936 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1937 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1938 0xff
1940 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1941 if(SiS_Pr->PanelHT == 1650) {
1942 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1944 break;
1946 case Panel_1280x768_2: { /* LVDS only */
1947 static const UCHAR nonscalingmodes[] = {
1948 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1949 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1950 SIS_RI_1152x768,0xff
1952 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1953 switch(resinfo) {
1954 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1955 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1957 break;
1959 break;
1961 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1962 static const UCHAR nonscalingmodes[] = {
1963 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1964 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1965 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1967 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1968 break;
1970 case Panel_1280x800_2: { /* SiS LVDS */
1971 static const UCHAR nonscalingmodes[] = {
1972 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1973 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1974 SIS_RI_1152x768,0xff
1976 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1977 switch(resinfo) {
1978 case SIS_RI_1280x720:
1979 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1980 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1982 break;
1984 break;
1986 case Panel_1280x960: {
1987 static const UCHAR nonscalingmodes[] = {
1988 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1989 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1990 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1991 0xff
1993 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1994 break;
1996 case Panel_1280x1024: {
1997 static const UCHAR nonscalingmodes[] = {
1998 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1999 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2000 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2001 SIS_RI_1280x960,0xff
2003 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2004 break;
2006 case Panel_1400x1050: {
2007 static const UCHAR nonscalingmodes[] = {
2008 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2009 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2010 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960,
2011 0xff
2013 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2014 switch(resinfo) {
2015 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2016 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2018 break;
2019 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2020 break;
2022 break;
2024 case Panel_1600x1200: {
2025 static const UCHAR nonscalingmodes[] = {
2026 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2027 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2028 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2029 SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2031 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2032 break;
2034 case Panel_1680x1050: {
2035 static const UCHAR nonscalingmodes[] = {
2036 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2037 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2038 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,
2039 0xff
2041 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2042 break;
2047 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2048 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2049 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2053 #ifdef SIS300
2054 if(HwInfo->jChipType < SIS_315H) {
2055 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2056 if(SiS_Pr->SiS_UseROM) {
2057 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2058 if(!(ROMAddr[0x235] & 0x02)) {
2059 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2063 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2064 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2065 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2069 #endif
2071 /* Special cases */
2073 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2074 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2077 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2078 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2081 switch(SiS_Pr->SiS_LCDResInfo) {
2082 case Panel_640x480:
2083 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2084 break;
2085 case Panel_1280x800:
2086 /* Don't pass 1:1 by default (TMDS special) */
2087 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2088 break;
2089 case Panel_1280x960:
2090 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2091 break;
2092 case Panel_Custom:
2093 if((!SiS_Pr->CP_PrefClock) ||
2094 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2095 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2097 break;
2100 if(SiS_Pr->UseCustomMode) {
2101 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2104 /* (In)validate LCDPass11 flag */
2105 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2106 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2109 /* LVDS DDA */
2110 if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2112 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2113 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2114 if(ModeNo == 0x12) {
2115 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2116 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2118 } else if(ModeNo > 0x13) {
2119 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2120 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2121 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2122 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2130 if(modeflag & HalfDCLK) {
2131 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2132 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2133 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2134 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2135 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2136 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2137 } else if(ModeNo > 0x13) {
2138 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2139 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2140 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2141 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2148 /* VESA timing */
2149 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2150 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2151 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2153 } else {
2154 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2157 #ifdef LINUX_KERNEL
2158 #ifdef TWDEBUG
2159 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2160 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2161 #endif
2162 #endif
2163 #ifdef LINUX_XF86
2164 xf86DrvMsgVerb(0, X_PROBED, 4,
2165 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2166 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2167 #endif
2170 /*********************************************/
2171 /* GET VCLK */
2172 /*********************************************/
2174 USHORT
2175 SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2176 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
2178 USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
2179 USHORT modeflag,resinfo,tempbx;
2180 const UCHAR *CHTVVCLKPtr = NULL;
2182 if(ModeNo <= 0x13) {
2183 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2184 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2185 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2186 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2187 } else {
2188 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2189 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2190 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2191 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2192 if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
2195 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2197 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2199 CRT2Index >>= 6;
2200 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2202 if(HwInfo->jChipType < SIS_315H) {
2203 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2204 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2205 VCLKIndex = VCLKIndexGEN;
2207 } else {
2208 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2209 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2210 switch(resinfo) {
2211 /* Only those whose IndexGEN doesn't match VBVCLK array */
2212 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2213 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2214 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2215 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2216 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2217 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2218 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2219 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2220 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2221 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2222 default: VCLKIndex = VCLKIndexGEN;
2225 if(ModeNo <= 0x13) {
2226 if(HwInfo->jChipType <= SIS_315PRO) {
2227 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2228 } else {
2229 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2232 if(HwInfo->jChipType <= SIS_315PRO) {
2233 if(VCLKIndex == 0) VCLKIndex = 0x41;
2234 if(VCLKIndex == 1) VCLKIndex = 0x43;
2235 if(VCLKIndex == 4) VCLKIndex = 0x44;
2240 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2242 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2243 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2244 else VCLKIndex = HiTVVCLK;
2245 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
2246 if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
2247 else VCLKIndex = HiTVTextVCLK;
2249 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2250 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2251 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2252 else VCLKIndex = TVVCLK;
2254 if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2255 else VCLKIndex += TVCLKBASE_315;
2257 } else { /* VGA2 */
2259 VCLKIndex = VCLKIndexGEN;
2260 if(HwInfo->jChipType < SIS_315H) {
2261 if(ModeNo > 0x13) {
2262 if( (HwInfo->jChipType == SIS_630) &&
2263 (HwInfo->jChipRevision >= 0x30)) {
2264 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2266 /* Better VGA2 clock for 1280x1024@75 */
2267 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2272 } else { /* If not programming CRT2 */
2274 VCLKIndex = VCLKIndexGEN;
2275 if(HwInfo->jChipType < SIS_315H) {
2276 if(ModeNo > 0x13) {
2277 if( (HwInfo->jChipType != SIS_630) &&
2278 (HwInfo->jChipType != SIS_300) ) {
2279 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2285 } else { /* LVDS */
2287 VCLKIndex = CRT2Index;
2289 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2291 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2293 VCLKIndex &= 0x1f;
2294 tempbx = 0;
2295 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2296 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2297 tempbx += 2;
2298 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2299 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2301 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2302 tempbx = 4;
2303 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2304 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2305 tempbx = 6;
2306 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2309 switch(tempbx) {
2310 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2311 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2312 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2313 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2314 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2315 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2316 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2317 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2318 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2319 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2321 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2323 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2325 if(HwInfo->jChipType < SIS_315H) {
2326 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2327 } else {
2328 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2331 /* Special Timing: Barco iQ Pro R series */
2332 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2334 /* Special Timing: 848x480 parallel lvds */
2335 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2336 if(HwInfo->jChipType < SIS_315H) {
2337 VCLKIndex = VCLK34_300;
2338 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2339 } else {
2340 VCLKIndex = VCLK34_315;
2341 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2345 } else {
2347 VCLKIndex = VCLKIndexGEN;
2348 if(HwInfo->jChipType < SIS_315H) {
2349 if(ModeNo > 0x13) {
2350 if( (HwInfo->jChipType == SIS_630) &&
2351 (HwInfo->jChipRevision >= 0x30) ) {
2352 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2358 } else { /* if not programming CRT2 */
2360 VCLKIndex = VCLKIndexGEN;
2361 if(HwInfo->jChipType < SIS_315H) {
2362 if(ModeNo > 0x13) {
2363 if( (HwInfo->jChipType != SIS_630) &&
2364 (HwInfo->jChipType != SIS_300) ) {
2365 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2367 #if 0
2368 if(HwInfo->jChipType == SIS_730) {
2369 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2370 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2372 #endif
2380 #ifdef TWDEBUG
2381 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2382 #endif
2384 return(VCLKIndex);
2387 /*********************************************/
2388 /* SET CRT2 MODE TYPE REGISTERS */
2389 /*********************************************/
2391 static void
2392 SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2393 PSIS_HW_INFO HwInfo)
2395 USHORT i,j,modeflag;
2396 USHORT tempcl,tempah=0;
2397 #if defined(SIS300) || defined(SIS315H)
2398 USHORT tempbl;
2399 #endif
2400 #ifdef SIS315H
2401 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
2402 USHORT tempah2, tempbl2;
2403 #endif
2405 if(ModeNo <= 0x13) {
2406 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2407 } else if(SiS_Pr->UseCustomMode) {
2408 modeflag = SiS_Pr->CModeFlag;
2409 } else {
2410 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2413 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2415 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2416 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2418 } else {
2420 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2421 if(HwInfo->jChipType >= SIS_315H) {
2422 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2425 tempcl = SiS_Pr->SiS_ModeType;
2427 if(HwInfo->jChipType < SIS_315H) {
2429 #ifdef SIS300 /* ---- 300 series ---- */
2431 /* For 301BDH: (with LCD via LVDS) */
2432 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2433 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2434 tempbl &= 0xef;
2435 tempbl |= 0x02;
2436 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2437 tempbl |= 0x10;
2438 tempbl &= 0xfd;
2440 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2443 if(ModeNo > 0x13) {
2444 tempcl -= ModeVGA;
2445 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2446 tempah = ((0x10 >> tempcl) | 0x80);
2448 } else tempah = 0x80;
2450 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2452 #endif /* SIS300 */
2454 } else {
2456 #ifdef SIS315H /* ------- 315/330 series ------ */
2458 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2459 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2460 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2464 if(ModeNo > 0x13) {
2465 tempcl -= ModeVGA;
2466 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2467 tempah = (0x08 >> tempcl);
2468 if (tempah == 0) tempah = 1;
2469 tempah |= 0x40;
2471 } else tempah = 0x40;
2473 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2475 #endif /* SIS315H */
2479 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2481 if(HwInfo->jChipType < SIS_315H) {
2482 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2483 } else {
2484 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2485 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2486 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2487 if(IS_SIS740) {
2488 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2489 } else {
2490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2495 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2497 tempah = 0x01;
2498 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2499 tempah |= 0x02;
2501 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2502 tempah ^= 0x05;
2503 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2504 tempah ^= 0x01;
2508 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2510 if(HwInfo->jChipType < SIS_315H) {
2512 tempah = (tempah << 5) & 0xFF;
2513 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2514 tempah = (tempah >> 5) & 0xFF;
2516 } else {
2518 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2522 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2523 tempah |= 0x10;
2526 tempah |= 0x80;
2527 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2528 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2531 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2532 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2533 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2534 tempah |= 0x20;
2539 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2541 tempah = 0x80;
2542 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2543 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2546 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
2548 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2549 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2550 tempah |= 0x40;
2554 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2556 } else { /* LVDS */
2558 if(HwInfo->jChipType >= SIS_315H) {
2560 #ifdef SIS315H
2561 /* LVDS can only be slave in 8bpp modes */
2562 tempah = 0x80;
2563 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2564 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2565 tempah |= 0x02;
2569 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2570 tempah |= 0x02;
2573 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2574 tempah ^= 0x01;
2577 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2578 tempah = 1;
2581 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2582 #endif
2584 } else {
2586 #ifdef SIS300
2587 tempah = 0;
2588 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2589 tempah |= 0x02;
2591 tempah <<= 5;
2593 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2595 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2596 #endif
2602 } /* LCDA */
2604 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2606 if(HwInfo->jChipType >= SIS_315H) {
2608 #ifdef SIS315H
2609 unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
2611 /* The following is nearly unpreditable and varies from machine
2612 * to machine. Especially the 301DH seems to be a real trouble
2613 * maker. Some BIOSes simply set the registers (like in the
2614 * NoLCD-if-statements here), some set them according to the
2615 * LCDA stuff. It is very likely that some machines are not
2616 * treated correctly in the following, very case-orientated
2617 * code. What do I do then...?
2620 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2622 if(!(IS_SIS740)) {
2623 tempah = 0x04; /* For all bridges */
2624 tempbl = 0xfb;
2625 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2626 tempah = 0x00;
2627 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2628 tempbl = 0xff;
2631 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2634 /* The following two are responsible for eventually wrong colors
2635 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2636 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2637 * in a 650 box (Jake). What is the criteria?
2640 if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2641 tempah = 0x30;
2642 tempbl = 0xc0;
2643 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2644 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2645 tempah = 0x00;
2646 tempbl = 0x00;
2648 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2649 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2650 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2651 /* Fixes "TV-blue-bug" on 315+301 */
2652 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2653 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2654 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2655 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2656 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2657 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2658 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */
2659 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2660 } else {
2661 tempah = 0x30; tempah2 = 0xc0; /* For 30xB (and 301BDH rev b1) */
2662 tempbl = 0xcf; tempbl2 = 0x3f;
2663 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2664 tempah = tempah2 = 0x00;
2665 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2666 tempbl = tempbl2 = 0xff;
2669 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2670 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2673 if(IS_SIS740) {
2674 tempah = 0x80;
2675 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2676 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2677 } else {
2678 tempah = 0x00;
2679 tempbl = 0x7f;
2680 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2681 tempbl = 0xff;
2682 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
2684 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2687 #endif /* SIS315H */
2689 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2691 #ifdef SIS300
2692 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2694 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2695 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2696 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2697 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2698 } else {
2699 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2701 #endif
2705 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2706 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2707 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
2708 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2712 } else { /* LVDS */
2714 #ifdef SIS315H
2715 if(HwInfo->jChipType >= SIS_315H) {
2717 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2719 tempah = 0x04;
2720 tempbl = 0xfb;
2721 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2722 tempah = 0x00;
2723 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
2725 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2727 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2728 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2731 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2733 } else if(HwInfo->jChipType == SIS_550) {
2735 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2736 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2741 #endif
2747 /*********************************************/
2748 /* GET RESOLUTION DATA */
2749 /*********************************************/
2751 USHORT
2752 SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
2754 if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2755 else return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2758 static void
2759 SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2760 PSIS_HW_INFO HwInfo)
2762 USHORT xres,yres,modeflag=0,resindex;
2764 if(SiS_Pr->UseCustomMode) {
2765 xres = SiS_Pr->CHDisplay;
2766 if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
2767 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2768 yres = SiS_Pr->CVDisplay;
2769 if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
2770 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2771 return;
2774 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2776 if(ModeNo <= 0x13) {
2777 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2778 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2779 } else {
2780 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2781 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2782 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2785 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2787 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2788 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2789 if(yres == 350) yres = 400;
2791 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2792 if(ModeNo == 0x12) yres = 400;
2796 if(modeflag & HalfDCLK) xres *= 2;
2797 if(modeflag & DoubleScanMode) yres *= 2;
2801 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2803 #if 0
2804 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
2805 if(xres == 720) xres = 640;
2807 #endif
2809 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2810 switch(SiS_Pr->SiS_LCDResInfo) {
2811 case Panel_1024x768:
2812 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2813 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2814 if(yres == 350) yres = 357;
2815 if(yres == 400) yres = 420;
2816 if(yres == 480) yres = 525;
2819 break;
2820 case Panel_1280x1024:
2821 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2822 /* BIOS bug - does this regardless of scaling */
2823 if(yres == 400) yres = 405;
2825 if(yres == 350) yres = 360;
2826 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2827 if(yres == 360) yres = 375;
2829 break;
2830 case Panel_1600x1200:
2831 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2832 if(yres == 1024) yres = 1056;
2834 break;
2838 } else {
2840 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2841 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2842 if(xres == 720) xres = 640;
2844 } else if(xres == 720) xres = 640;
2846 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2847 yres = 400;
2848 if(HwInfo->jChipType >= SIS_315H) {
2849 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2850 } else {
2851 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2853 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2857 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2858 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2861 /*********************************************/
2862 /* GET CRT2 TIMING DATA */
2863 /*********************************************/
2865 static BOOLEAN
2866 SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2867 USHORT RefreshRateTableIndex, USHORT *ResIndex,
2868 USHORT *DisplayType)
2870 USHORT modeflag=0;
2872 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2873 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2874 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2876 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2877 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2878 } else
2879 return FALSE;
2881 if(ModeNo <= 0x13) {
2882 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2883 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2884 } else {
2885 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2886 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2889 (*ResIndex) &= 0x3F;
2891 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2892 (*DisplayType) = 18;
2893 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2894 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2895 (*DisplayType) += 2;
2896 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2897 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
2899 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2900 (*DisplayType) = 18; /* PALM uses NTSC data */
2901 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2902 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2903 (*DisplayType) = 20; /* PALN uses PAL data */
2904 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2907 } else {
2908 switch(SiS_Pr->SiS_LCDResInfo) {
2909 case Panel_640x480: (*DisplayType) = 50; break;
2910 case Panel_640x480_2: (*DisplayType) = 52; break;
2911 case Panel_640x480_3: (*DisplayType) = 54; break;
2912 case Panel_800x600: (*DisplayType) = 0; break;
2913 case Panel_1024x600: (*DisplayType) = 23; break;
2914 case Panel_1024x768: (*DisplayType) = 4; break;
2915 case Panel_1152x768: (*DisplayType) = 27; break;
2916 case Panel_1280x768: (*DisplayType) = 40; break;
2917 case Panel_1280x1024: (*DisplayType) = 8; break;
2918 case Panel_1400x1050: (*DisplayType) = 14; break;
2919 case Panel_1600x1200: (*DisplayType) = 36; break;
2920 default: return FALSE;
2923 if(modeflag & HalfDCLK) (*DisplayType)++;
2925 switch(SiS_Pr->SiS_LCDResInfo) {
2926 case Panel_640x480:
2927 case Panel_640x480_2:
2928 case Panel_640x480_3:
2929 break;
2930 default:
2931 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
2934 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2935 (*DisplayType) = 12;
2936 if(modeflag & HalfDCLK) (*DisplayType)++;
2940 #if 0
2941 if(SiS_Pr->SiS_IF_DEF_FSTN) {
2942 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2943 (*DisplayType) = 22;
2946 #endif
2948 return TRUE;
2951 static void
2952 SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2953 USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
2954 PSIS_HW_INFO HwInfo)
2956 USHORT tempbx=0,tempal=0,resinfo=0;
2958 if(ModeNo <= 0x13) {
2959 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2960 } else {
2961 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2962 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2965 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2967 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2969 tempbx = SiS_Pr->SiS_LCDResInfo;
2970 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2972 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2973 if (resinfo == SIS_RI_1280x800) tempal = 9;
2974 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2975 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2976 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2)) {
2977 if (resinfo == SIS_RI_1280x768) tempal = 9;
2980 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2981 /* Pass 1:1 only (center-screen handled outside) */
2982 /* This is never called for the panel's native resolution */
2983 /* since Pass1:1 will not be set in this case */
2984 tempbx = 100;
2985 if(ModeNo >= 0x13) {
2986 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2990 #ifdef SIS315H
2991 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2992 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2993 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2994 tempbx = 200;
2995 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2999 #endif
3001 } else { /* TV */
3003 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3004 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3005 tempbx = 2;
3006 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3007 tempbx = 13;
3008 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3010 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3011 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
3012 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3013 else tempbx = 5;
3014 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3015 } else {
3016 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3017 else tempbx = 4;
3018 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3023 tempal &= 0x3F;
3025 if(ModeNo > 0x13) {
3026 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3027 if(tempal == 6) tempal = 7;
3028 if((resinfo == SIS_RI_720x480) ||
3029 (resinfo == SIS_RI_720x576) ||
3030 (resinfo == SIS_RI_768x576)) {
3031 tempal = 6;
3032 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
3033 if(resinfo == SIS_RI_720x480) tempal = 9;
3036 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3037 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3038 if(resinfo == SIS_RI_1024x768) tempal = 8;
3040 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3041 if((resinfo == SIS_RI_720x576) ||
3042 (resinfo == SIS_RI_768x576)) {
3043 tempal = 8;
3045 if(resinfo == SIS_RI_1280x720) tempal = 9;
3051 *CRT2Index = tempbx;
3052 *ResIndex = tempal;
3054 } else { /* LVDS, 301B-DH (if running on LCD) */
3056 tempbx = 0;
3057 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3059 tempbx = 10;
3060 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3061 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3062 tempbx += 2;
3063 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3064 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3066 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
3067 tempbx = 90;
3068 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3069 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
3070 tempbx = 92;
3071 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3075 } else {
3077 switch(SiS_Pr->SiS_LCDResInfo) {
3078 case Panel_640x480: tempbx = 6; break;
3079 case Panel_640x480_2:
3080 case Panel_640x480_3: tempbx = 30; break;
3081 case Panel_800x600: tempbx = 0; break;
3082 case Panel_1024x600: tempbx = 15; break;
3083 case Panel_1024x768: tempbx = 2; break;
3084 case Panel_1152x768: tempbx = 17; break;
3085 case Panel_1280x768: tempbx = 18; break;
3086 case Panel_1280x1024: tempbx = 4; break;
3087 case Panel_1400x1050: tempbx = 8; break;
3088 case Panel_1600x1200: tempbx = 21; break;
3089 case Panel_Barco1366: tempbx = 80; break;
3092 switch(SiS_Pr->SiS_LCDResInfo) {
3093 case Panel_640x480:
3094 case Panel_640x480_2:
3095 case Panel_640x480_3:
3096 break;
3097 default:
3098 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3101 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
3103 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3104 tempbx = 82;
3105 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3106 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
3107 tempbx = 84;
3108 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3111 if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
3112 (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
3113 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3114 (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3115 tempal = 0;
3121 (*CRT2Index) = tempbx;
3122 (*ResIndex) = tempal & 0x1F;
3126 static void
3127 SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3128 USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
3130 USHORT tempax=0,tempbx=0;
3131 USHORT temp1=0,modeflag=0,tempcx=0;
3132 USHORT index;
3134 SiS_Pr->SiS_RVBHCMAX = 1;
3135 SiS_Pr->SiS_RVBHCFACT = 1;
3137 if(ModeNo <= 0x13) {
3139 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3140 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3142 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3143 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3144 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3146 } else {
3148 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3149 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3151 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3152 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3153 tempax &= 0x03FF;
3154 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3155 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3156 tempcx &= 0x0100;
3157 tempcx <<= 2;
3158 tempbx |= tempcx;
3159 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3163 if(temp1 & 0x01) tempbx |= 0x0100;
3164 if(temp1 & 0x20) tempbx |= 0x0200;
3166 tempax += 5;
3168 /* Charx8Dot is no more used (and assumed), so we set it */
3169 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3170 modeflag |= Charx8Dot;
3173 if(modeflag & Charx8Dot) tempax *= 8;
3174 else tempax *= 9;
3176 if(modeflag & HalfDCLK) tempax <<= 1;
3178 tempbx++;
3180 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3181 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3184 static void
3185 SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3186 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3188 USHORT CRT2Index, ResIndex;
3189 const SiS_LVDSDataStruct *LVDSData = NULL;
3191 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3193 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3194 SiS_Pr->SiS_RVBHCMAX = 1;
3195 SiS_Pr->SiS_RVBHCFACT = 1;
3196 SiS_Pr->SiS_NewFlickerMode = 0;
3197 SiS_Pr->SiS_RVBHRS = 50;
3198 SiS_Pr->SiS_RY1COE = 0;
3199 SiS_Pr->SiS_RY2COE = 0;
3200 SiS_Pr->SiS_RY3COE = 0;
3201 SiS_Pr->SiS_RY4COE = 0;
3204 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3206 #ifdef SIS315H
3207 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3208 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3209 if(SiS_Pr->UseCustomMode) {
3210 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3211 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3212 } else {
3213 if(ModeNo < 0x13) {
3214 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3215 } else {
3216 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3218 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3219 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3220 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3221 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3223 } else {
3224 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3225 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3227 } else {
3228 /* This handles custom modes and custom panels */
3229 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3230 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3231 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3232 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3233 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3234 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3237 SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
3239 #endif
3241 } else {
3243 /* 301BDH needs LVDS Data */
3244 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3245 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3248 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3249 &CRT2Index, &ResIndex, HwInfo);
3251 /* 301BDH needs LVDS Data */
3252 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3253 SiS_Pr->SiS_IF_DEF_LVDS = 0;
3256 switch (CRT2Index) {
3257 case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3258 case 1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
3259 case 2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3260 case 3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
3261 case 4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
3262 case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
3263 case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3264 case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
3265 case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
3266 case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
3267 case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3268 case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3269 case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3270 case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3271 case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
3272 case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3273 case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
3274 case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
3275 case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
3276 case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
3277 case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
3278 case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
3279 case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
3280 case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
3281 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3282 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3283 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3284 case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
3285 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3286 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3287 case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3288 case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3289 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3290 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3291 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
3292 default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3295 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3296 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3297 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3298 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3300 if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
3301 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3302 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3303 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3304 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3305 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3306 if(ResIndex < 0x08) {
3307 SiS_Pr->SiS_HDE = 1280;
3308 SiS_Pr->SiS_VDE = 1024;
3317 static void
3318 SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3319 USHORT RefreshRateTableIndex,
3320 PSIS_HW_INFO HwInfo)
3322 UCHAR *ROMAddr = NULL;
3323 USHORT tempax,tempbx,modeflag,romptr=0;
3324 USHORT resinfo,CRT2Index,ResIndex;
3325 const SiS_LCDDataStruct *LCDPtr = NULL;
3326 const SiS_TVDataStruct *TVPtr = NULL;
3327 #ifdef SIS315H
3328 SHORT resinfo661;
3329 #endif
3331 if(ModeNo <= 0x13) {
3332 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3333 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3334 } else if(SiS_Pr->UseCustomMode) {
3335 modeflag = SiS_Pr->CModeFlag;
3336 resinfo = 0;
3337 } else {
3338 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3339 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3340 #ifdef SIS315H
3341 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3342 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3343 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3344 (resinfo661 >= 0) &&
3345 (SiS_Pr->SiS_NeedRomModeData) ) {
3346 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
3347 if((romptr = (SISGETROMW(21)))) {
3348 romptr += (resinfo661 * 10);
3349 ROMAddr = HwInfo->pjVirtualRomBase;
3353 #endif
3356 SiS_Pr->SiS_NewFlickerMode = 0;
3357 SiS_Pr->SiS_RVBHRS = 50;
3358 SiS_Pr->SiS_RY1COE = 0;
3359 SiS_Pr->SiS_RY2COE = 0;
3360 SiS_Pr->SiS_RY3COE = 0;
3361 SiS_Pr->SiS_RY4COE = 0;
3363 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
3365 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
3367 if(SiS_Pr->UseCustomMode) {
3369 SiS_Pr->SiS_RVBHCMAX = 1;
3370 SiS_Pr->SiS_RVBHCFACT = 1;
3371 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3372 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3373 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3374 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3375 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3376 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3378 } else {
3380 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3384 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3386 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3387 &CRT2Index,&ResIndex,HwInfo);
3389 switch(CRT2Index) {
3390 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3391 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3392 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3393 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3394 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3395 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3396 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3397 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3398 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3399 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3400 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3401 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3402 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3403 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3406 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3407 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3408 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3409 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3410 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3411 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3412 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3413 SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3414 if(modeflag & HalfDCLK) {
3415 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3418 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3420 if((resinfo == SIS_RI_1024x768) ||
3421 (resinfo == SIS_RI_1280x1024) ||
3422 (resinfo == SIS_RI_1280x720)) {
3423 SiS_Pr->SiS_NewFlickerMode = 0x40;
3426 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3428 SiS_Pr->SiS_HT = ExtHiTVHT;
3429 SiS_Pr->SiS_VT = ExtHiTVVT;
3430 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3431 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3432 SiS_Pr->SiS_HT = StHiTVHT;
3433 SiS_Pr->SiS_VT = StHiTVVT;
3434 #if 0
3435 if(!(modeflag & Charx8Dot)) {
3436 SiS_Pr->SiS_HT = StHiTextTVHT;
3437 SiS_Pr->SiS_VT = StHiTextTVVT;
3439 #endif
3443 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3445 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3446 SiS_Pr->SiS_HT = 1650;
3447 SiS_Pr->SiS_VT = 750;
3448 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3449 SiS_Pr->SiS_HT = NTSCHT;
3450 SiS_Pr->SiS_VT = NTSCVT;
3451 } else {
3452 SiS_Pr->SiS_HT = NTSCHT;
3453 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3454 SiS_Pr->SiS_VT = NTSCVT;
3457 } else {
3459 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3460 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3461 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3462 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3464 if(modeflag & HalfDCLK) {
3465 SiS_Pr->SiS_RY1COE = 0x00;
3466 SiS_Pr->SiS_RY2COE = 0xf4;
3467 SiS_Pr->SiS_RY3COE = 0x10;
3468 SiS_Pr->SiS_RY4COE = 0x38;
3471 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3472 SiS_Pr->SiS_HT = NTSCHT;
3473 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3474 SiS_Pr->SiS_VT = NTSCVT;
3475 } else {
3476 SiS_Pr->SiS_HT = PALHT;
3477 SiS_Pr->SiS_VT = PALVT;
3482 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3484 SiS_Pr->SiS_RVBHCMAX = 1;
3485 SiS_Pr->SiS_RVBHCFACT = 1;
3487 if(SiS_Pr->UseCustomMode) {
3489 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3490 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3491 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3492 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3493 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3494 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3496 } else {
3498 BOOLEAN gotit = FALSE;
3500 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3502 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3503 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3504 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3505 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3506 gotit = TRUE;
3508 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3510 #ifdef SIS315H
3511 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3512 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3513 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3514 SiS_Pr->SiS_VGAVT = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
3515 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3516 SiS_Pr->SiS_VT = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
3517 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3518 else {
3519 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3520 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3521 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3522 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3523 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3524 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3525 gotit = TRUE;
3527 #endif
3531 if(!gotit) {
3533 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3534 &CRT2Index,&ResIndex,HwInfo);
3536 switch(CRT2Index) {
3537 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3538 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3539 case Panel_1280x720 :
3540 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3541 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3542 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3543 case Panel_1280x800 :
3544 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3545 case Panel_1280x800_2 :
3546 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3547 case Panel_1280x960 :
3548 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3549 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3550 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3551 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3552 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3553 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3554 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3555 case Panel_1680x1050 :
3556 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3557 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3558 #ifdef SIS315H
3559 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3560 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3561 #endif
3562 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3565 #ifdef TWDEBUG
3566 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3567 #endif
3569 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3570 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3571 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3572 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3573 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3574 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3578 tempax = SiS_Pr->PanelXRes;
3579 tempbx = SiS_Pr->PanelYRes;
3581 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3582 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3583 if(HwInfo->jChipType < SIS_315H) {
3584 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3585 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3587 } else {
3588 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3589 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3590 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3591 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3592 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3593 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3595 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
3596 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3597 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3598 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3599 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3600 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3601 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3602 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3603 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
3604 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3605 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3606 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3610 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3611 tempax = SiS_Pr->SiS_VGAHDE;
3612 tempbx = SiS_Pr->SiS_VGAVDE;
3615 SiS_Pr->SiS_HDE = tempax;
3616 SiS_Pr->SiS_VDE = tempbx;
3621 static void
3622 SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3623 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3626 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3628 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3629 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3630 } else {
3631 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3632 /* Need LVDS Data for LCD on 301B-DH */
3633 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3634 } else {
3635 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3639 } else {
3641 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3646 /*********************************************/
3647 /* GET LVDS DES (SKEW) DATA */
3648 /*********************************************/
3650 static void
3651 SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3652 USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3653 USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3655 USHORT modeflag;
3657 if(ModeNo <= 0x13) {
3658 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3659 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3660 } else {
3661 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3662 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3665 (*ResIndex) &= 0x1F;
3666 (*PanelIndex) = 0;
3668 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3669 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3670 (*PanelIndex) = 50;
3671 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
3672 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
3673 /* Nothing special needed for SOverscan */
3674 /* PALM uses NTSC data, PALN uses PAL data */
3678 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3679 *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
3680 if(HwInfo->jChipType >= SIS_661) {
3681 /* As long as we don's use the BIOS tables, we
3682 * need to convert the TypeInfo as for 315 series
3684 (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
3686 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3687 (*PanelIndex) += 16;
3688 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3689 (*PanelIndex) = 32;
3690 if(modeflag & HalfDCLK) (*PanelIndex)++;
3695 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3696 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
3697 (*ResIndex) = 7;
3698 if(HwInfo->jChipType < SIS_315H) {
3699 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
3705 static void
3706 SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3707 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3709 USHORT modeflag;
3710 USHORT PanelIndex,ResIndex;
3711 const SiS_LVDSDesStruct *PanelDesPtr = NULL;
3713 SiS_Pr->SiS_LCDHDES = 0;
3714 SiS_Pr->SiS_LCDVDES = 0;
3716 if( (SiS_Pr->UseCustomMode) ||
3717 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3718 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3719 ((SiS_Pr->SiS_VBType & VB_SISVB) &&
3720 (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3721 (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3722 return;
3725 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3727 #ifdef SIS315H
3728 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3729 /* non-pass 1:1 only, see above */
3730 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3731 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3733 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3734 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3737 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3738 switch(SiS_Pr->SiS_CustomT) {
3739 case CUT_UNIWILL1024:
3740 case CUT_UNIWILL10242:
3741 case CUT_CLEVO1400:
3742 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3743 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3745 break;
3747 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3748 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3749 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3753 #endif
3755 } else {
3757 SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3758 &PanelIndex, &ResIndex, HwInfo);
3760 switch(PanelIndex) {
3761 case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */
3762 case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break;
3763 case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break;
3764 case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break;
3765 case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break;
3766 case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break;
3767 case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break;
3768 case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break;
3769 case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break;
3770 case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break;
3771 case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break;
3772 case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break;
3773 case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break;
3774 case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break;
3775 case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break;
3776 case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break;
3777 case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */
3778 case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break;
3779 case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break;
3780 case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break;
3781 case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break;
3782 case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break;
3783 case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break;
3784 case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break;
3785 case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break;
3786 case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break;
3787 case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break;
3788 case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break;
3789 case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break;
3790 case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break;
3791 case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break;
3792 case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break;
3793 case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */
3794 case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break;
3795 case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */
3796 case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
3797 case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
3798 case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
3799 default: return;
3802 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3803 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3805 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3806 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3807 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3808 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3809 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3810 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3811 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3812 if(HwInfo->jChipType < SIS_315H) {
3813 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3814 } else {
3815 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3816 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3817 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3818 if(!(modeflag & HalfDCLK)) {
3819 SiS_Pr->SiS_LCDHDES = 320;
3820 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3821 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3831 /*********************************************/
3832 /* DISABLE VIDEO BRIDGE */
3833 /*********************************************/
3835 /* NEVER use any variables (VBInfo), this will be called
3836 * from outside the context of modeswitch!
3837 * MUST call getVBType before calling this
3839 void
3840 SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3842 #ifdef SIS315H
3843 USHORT tempah,pushax=0,modenum;
3844 #endif
3845 USHORT temp=0;
3847 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3849 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
3851 if(HwInfo->jChipType < SIS_315H) {
3853 #ifdef SIS300 /* 300 series */
3855 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3856 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3857 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3858 } else {
3859 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3861 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3863 if(SiS_Is301B(SiS_Pr)) {
3864 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3865 SiS_ShortDelay(SiS_Pr,1);
3867 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3868 SiS_DisplayOff(SiS_Pr);
3869 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3870 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3871 SiS_UnLockCRT2(SiS_Pr,HwInfo);
3872 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
3873 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3874 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3876 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3877 (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3878 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3879 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3880 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3881 } else {
3882 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3886 #endif /* SIS300 */
3888 } else {
3890 #ifdef SIS315H /* 315 series */
3892 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3893 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3895 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3897 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3899 #ifdef SET_EMI
3900 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3901 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3902 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3905 #endif
3906 if( (modenum <= 0x13) ||
3907 (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3908 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
3909 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3910 if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3913 if(!custom1) {
3914 SiS_DDC2Delay(SiS_Pr,0xff00);
3915 SiS_DDC2Delay(SiS_Pr,0xe000);
3916 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3917 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3918 if(IS_SIS740) {
3919 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3921 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3926 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
3927 if(HwInfo->jChipType < SIS_340) {
3928 tempah = 0xef;
3929 if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
3930 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3934 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3935 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3938 tempah = 0x3f;
3939 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3940 tempah = 0x7f;
3941 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
3943 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3945 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3946 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3948 SiS_DisplayOff(SiS_Pr);
3949 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3950 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3952 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3953 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3957 if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
3958 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3960 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3961 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3962 SiS_DisplayOff(SiS_Pr);
3964 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3966 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3967 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3970 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3971 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3972 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3973 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3974 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3978 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
3979 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3982 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3984 if(!custom1) {
3986 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3987 if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3988 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3989 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3994 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3996 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3997 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
3998 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
4002 } else {
4004 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4005 (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
4006 if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
4007 (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
4008 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4009 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4010 SiS_PanelDelay(SiS_Pr, HwInfo, 4);
4017 #endif /* SIS315H */
4021 } else { /* ============ For 301 ================ */
4023 if(HwInfo->jChipType < SIS_315H) {
4024 #ifdef SIS300
4025 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4026 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4027 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4029 #endif
4032 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4033 SiS_DisplayOff(SiS_Pr);
4035 if(HwInfo->jChipType >= SIS_315H) {
4036 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4039 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4041 if(HwInfo->jChipType >= SIS_315H) {
4042 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4043 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4044 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4045 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4046 } else {
4047 #ifdef SIS300
4048 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4049 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4050 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4051 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4052 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4054 #endif
4059 } else { /* ============ For LVDS =============*/
4061 if(HwInfo->jChipType < SIS_315H) {
4063 #ifdef SIS300 /* 300 series */
4065 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4066 SiS_SetCH700x(SiS_Pr,0x090E);
4069 if(HwInfo->jChipType == SIS_730) {
4070 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4071 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4073 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4074 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4075 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4077 } else {
4078 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4079 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4080 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4081 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4082 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4083 SiS_DisplayOff(SiS_Pr);
4085 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4086 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4092 SiS_DisplayOff(SiS_Pr);
4094 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4096 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4097 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4098 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4099 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4101 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4102 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4103 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4104 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4107 #endif /* SIS300 */
4109 } else {
4111 #ifdef SIS315H /* 315 series */
4113 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4114 if(HwInfo->jChipType < SIS_340) {
4115 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4119 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4121 if(HwInfo->jChipType == SIS_740) {
4122 temp = SiS_GetCH701x(SiS_Pr,0x61);
4123 if(temp < 1) {
4124 SiS_SetCH701x(SiS_Pr,0xac76);
4125 SiS_SetCH701x(SiS_Pr,0x0066);
4128 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4129 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4130 SiS_SetCH701x(SiS_Pr,0x3e49);
4134 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4135 (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
4136 SiS_Chrontel701xBLOff(SiS_Pr);
4137 SiS_Chrontel701xOff(SiS_Pr,HwInfo);
4140 if(HwInfo->jChipType != SIS_740) {
4141 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4142 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4143 SiS_SetCH701x(SiS_Pr,0x0149);
4149 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4150 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4151 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4154 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4155 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4156 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
4157 SiS_DisplayOff(SiS_Pr);
4160 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4161 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4162 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4163 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4166 if(HwInfo->jChipType == SIS_740) {
4167 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4170 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4172 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4173 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4174 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4175 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4178 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4179 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4180 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4181 if(HwInfo->jChipType == SIS_550) {
4182 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4183 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4186 } else {
4187 if(HwInfo->jChipType == SIS_740) {
4188 if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
4189 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4191 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4192 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4196 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4197 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4198 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4199 } else {
4200 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4204 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4206 if(HwInfo->jChipType == SIS_550) {
4207 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4208 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4209 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4210 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4211 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4212 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4215 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4216 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4217 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4218 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4219 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4224 #endif /* SIS315H */
4226 } /* 315 series */
4228 } /* LVDS */
4232 /*********************************************/
4233 /* ENABLE VIDEO BRIDGE */
4234 /*********************************************/
4236 /* NEVER use any variables (VBInfo), this will be called
4237 * from outside the context of a mode switch!
4238 * MUST call getVBType before calling this
4240 static void
4241 SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4243 USHORT temp=0,tempah;
4244 #ifdef SIS315H
4245 USHORT temp1,pushax=0;
4246 BOOLEAN delaylong = FALSE;
4247 #endif
4249 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4251 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */
4253 if(HwInfo->jChipType < SIS_315H) {
4255 #ifdef SIS300 /* 300 series */
4257 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4258 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4259 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4260 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4261 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4263 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
4264 if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
4265 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4270 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4271 (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4273 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4274 SiS_DisplayOn(SiS_Pr);
4275 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4276 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4277 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4278 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4279 } else {
4280 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4282 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4283 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4284 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4285 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4287 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4288 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4292 } else {
4294 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4295 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4296 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4297 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4299 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4300 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4301 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4302 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4303 SiS_DisplayOn(SiS_Pr);
4304 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4305 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4306 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4307 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4308 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4310 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4318 #endif /* SIS300 */
4320 } else {
4322 #ifdef SIS315H /* 315 series */
4324 #ifdef SET_EMI
4325 UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
4326 /* USHORT emidelay=0; */
4327 #endif
4329 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4330 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4331 #ifdef SET_EMI
4332 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4333 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4335 #endif
4338 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
4339 if(HwInfo->jChipType < SIS_340) {
4340 tempah = 0x10;
4341 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4342 if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4343 else tempah = 0x08;
4345 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4349 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4351 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4352 SiS_DisplayOff(SiS_Pr);
4353 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4354 if(IS_SIS740) {
4355 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4358 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4359 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4360 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4361 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4362 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4363 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4364 SiS_GenericDelay(SiS_Pr, 0x4500);
4369 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4370 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4371 delaylong = TRUE;
4376 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4378 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4379 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4380 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4381 if(!(tempah & SetCRT2ToRAMDAC)) {
4382 if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
4385 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4387 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4389 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4390 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4392 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4393 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4396 } else {
4398 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4402 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4403 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4405 tempah = 0xc0;
4406 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
4407 tempah = 0x80;
4408 if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
4410 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4412 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4414 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4416 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4417 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4419 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4420 #ifdef SET_EMI
4421 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4422 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4423 SiS_GenericDelay(SiS_Pr, 0x500);
4425 #endif
4426 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4428 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4429 #ifdef SET_EMI
4430 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4432 if(SiS_Pr->SiS_ROMNew) {
4433 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4434 USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
4435 if(romptr) {
4436 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4437 SiS_Pr->EMI_30 = 0;
4438 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4439 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4440 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4441 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4442 /* emidelay = SISGETROMW((romptr + 0x22)); */
4443 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4447 /* (P4_30|0x40) */
4448 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4449 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4450 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4451 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4452 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4453 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4454 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4455 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4456 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4458 if(SiS_Pr->HaveEMI) {
4459 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4460 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4461 } else {
4462 r30 = 0;
4465 /* EMI_30 is read at driver start; however, the BIOS sets this
4466 * (if it is used) only if the LCD is in use. In case we caught
4467 * the machine while on TV output, this bit is not set and we
4468 * don't know if it should be set - hence our detection is wrong.
4469 * Work-around this here:
4472 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4473 switch((cr36 & 0x0f)) {
4474 case 2:
4475 r30 |= 0x40;
4476 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4477 if(!SiS_Pr->HaveEMI) {
4478 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4479 if((cr36 & 0xf0) == 0x30) {
4480 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4483 break;
4484 case 3: /* 1280x1024 */
4485 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4486 if(!SiS_Pr->HaveEMI) {
4487 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4488 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4489 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4492 break;
4493 case 9: /* 1400x1050 */
4494 r30 |= 0x40;
4495 if(!SiS_Pr->HaveEMI) {
4496 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4497 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4498 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4501 break;
4502 case 11: /* 1600x1200 - unknown */
4503 r30 |= 0x40;
4504 if(!SiS_Pr->HaveEMI) {
4505 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4510 /* BIOS values don't work so well sometimes */
4511 if(!SiS_Pr->OverruleEMI) {
4512 #ifdef COMPAL_HACK
4513 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4514 if((cr36 & 0x0f) == 0x09) {
4515 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4518 #endif
4519 #ifdef COMPAQ_HACK
4520 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4521 if((cr36 & 0x0f) == 0x03) {
4522 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4525 #endif
4526 #ifdef ASUS_HACK
4527 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4528 if((cr36 & 0x0f) == 0x02) {
4529 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4530 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4531 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4532 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4535 #endif
4538 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4539 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4540 SiS_GenericDelay(SiS_Pr, 0x500);
4542 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4543 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4544 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4545 #endif /* SET_EMI */
4547 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4549 #ifdef SET_EMI
4550 if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
4551 (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4552 if(r30 & 0x40) {
4553 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4554 if(delaylong) {
4555 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4556 delaylong = FALSE;
4558 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4559 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4560 SiS_GenericDelay(SiS_Pr, 0x500);
4562 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4565 #endif
4569 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4570 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4571 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4572 if(delaylong) {
4573 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4575 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4576 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4577 SiS_GenericDelay(SiS_Pr, 0x500);
4579 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4583 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4584 SiS_DisplayOn(SiS_Pr);
4585 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4589 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4590 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4593 #endif /* SIS315H */
4597 } else { /* ============ For 301 ================ */
4599 if(HwInfo->jChipType < SIS_315H) {
4600 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4601 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4602 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4606 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4607 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4608 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4609 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4611 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4613 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4615 if(HwInfo->jChipType >= SIS_315H) {
4616 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4617 if(!(temp & 0x80)) {
4618 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4622 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4624 SiS_VBLongWait(SiS_Pr);
4625 SiS_DisplayOn(SiS_Pr);
4626 if(HwInfo->jChipType >= SIS_315H) {
4627 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4629 SiS_VBLongWait(SiS_Pr);
4631 if(HwInfo->jChipType < SIS_315H) {
4632 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4633 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4634 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4640 } else { /* =================== For LVDS ================== */
4642 if(HwInfo->jChipType < SIS_315H) {
4644 #ifdef SIS300 /* 300 series */
4646 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4647 if(HwInfo->jChipType == SIS_730) {
4648 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4649 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4650 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4652 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4653 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4654 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4658 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4659 SiS_DisplayOn(SiS_Pr);
4660 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4661 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4662 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4663 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4664 } else {
4665 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4668 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4669 if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4670 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4671 SiS_SetCH700x(SiS_Pr,0x0B0E);
4675 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4676 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4677 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4678 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4679 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4680 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4682 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4683 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4688 #endif /* SIS300 */
4690 } else {
4692 #ifdef SIS315H /* 315 series */
4694 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4695 if(HwInfo->jChipType < SIS_340) {
4696 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4700 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4701 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4702 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4703 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4707 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4708 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4710 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4712 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4713 temp = SiS_GetCH701x(SiS_Pr,0x66);
4714 temp &= 0x20;
4715 SiS_Chrontel701xBLOff(SiS_Pr);
4718 if(HwInfo->jChipType != SIS_550) {
4719 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4722 if(HwInfo->jChipType == SIS_740) {
4723 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4724 if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
4725 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4730 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4731 if(!(temp1 & 0x80)) {
4732 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4735 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4736 if(temp) {
4737 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4741 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4742 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4743 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4744 if(HwInfo->jChipType == SIS_550) {
4745 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4746 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4749 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4750 if(HwInfo->jChipType != SIS_740) {
4751 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4755 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4756 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4759 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4760 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
4761 SiS_Chrontel701xOn(SiS_Pr,HwInfo);
4763 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4764 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4765 SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
4769 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4770 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4771 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4772 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4773 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4774 SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
4777 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4778 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4779 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4780 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4781 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4786 #endif /* SIS315H */
4788 } /* 310 series */
4790 } /* LVDS */
4794 /*********************************************/
4795 /* SET PART 1 REGISTER GROUP */
4796 /*********************************************/
4798 /* Set CRT2 OFFSET / PITCH */
4799 static void
4800 SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
4801 USHORT RRTI, PSIS_HW_INFO HwInfo)
4803 USHORT offset;
4804 UCHAR temp;
4806 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4808 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
4810 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
4811 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
4812 offset >>= 1;
4815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4817 temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
4818 if(offset % 8) temp++;
4819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4822 /* Set CRT2 sync and PanelLink mode */
4823 static void
4824 SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
4825 PSIS_HW_INFO HwInfo)
4827 USHORT tempah=0,tempbl,infoflag;
4829 tempbl = 0xC0;
4831 if(SiS_Pr->UseCustomMode) {
4832 infoflag = SiS_Pr->CInfoFlag;
4833 } else {
4834 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4837 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4839 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4840 tempah = 0;
4841 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4842 tempah = SiS_Pr->SiS_LCDInfo;
4843 } else tempah = infoflag >> 8;
4844 tempah &= 0xC0;
4845 tempah |= 0x20;
4846 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4847 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4848 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4849 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4850 tempah |= 0xf0;
4852 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4853 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4854 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4855 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
4856 tempah |= 0x30;
4859 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4860 if(HwInfo->jChipType >= SIS_315H) {
4861 tempah >>= 3;
4862 tempah &= 0x18;
4863 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4864 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4865 } else {
4866 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4868 } else {
4869 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4872 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4874 if(HwInfo->jChipType < SIS_315H) {
4876 #ifdef SIS300 /* ---- 300 series --- */
4878 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */
4880 tempah = infoflag >> 8;
4881 tempbl = 0;
4882 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4883 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4884 tempah = SiS_Pr->SiS_LCDInfo;
4885 tempbl = (tempah >> 6) & 0x03;
4888 tempah &= 0xC0;
4889 tempah |= 0x20;
4890 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4891 tempah |= 0xc0;
4892 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4893 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4894 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4897 } else { /* 630 - 301 */
4899 tempah = infoflag >> 8;
4900 tempah &= 0xC0;
4901 tempah |= 0x20;
4902 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4903 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4907 #endif /* SIS300 */
4909 } else {
4911 #ifdef SIS315H /* ------- 315 series ------ */
4913 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - LVDS */
4915 tempbl = 0;
4916 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4917 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4918 tempah = infoflag >> 8;
4919 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4920 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4922 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4923 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4924 tempah = infoflag >> 8;
4925 tempbl = 0x03;
4926 } else {
4927 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4928 tempbl = (tempah >> 6) & 0x03;
4929 tempbl |= 0x08;
4930 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4932 tempah &= 0xC0;
4933 tempah |= 0x20;
4934 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4935 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4936 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4937 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4938 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4939 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4943 } else { /* 315 - TMDS */
4945 tempah = tempbl = infoflag >> 8;
4946 if(!SiS_Pr->UseCustomMode) {
4947 tempbl = 0;
4948 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4949 if(ModeNo <= 0x13) {
4950 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4953 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4954 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4955 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4956 tempah = SiS_Pr->SiS_LCDInfo;
4957 tempbl = (tempah >> 6) & 0x03;
4962 tempah &= 0xC0;
4963 tempah |= 0x20;
4964 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4965 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4966 /* Imitate BIOS bug */
4967 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4969 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4970 tempah >>= 3;
4971 tempah &= 0x18;
4972 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4973 } else {
4974 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4975 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4976 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4977 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4983 #endif /* SIS315H */
4988 /* Set CRT2 FIFO on 300/630/730 */
4989 #ifdef SIS300
4990 static void
4991 SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
4992 PSIS_HW_INFO HwInfo)
4994 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4995 USHORT temp,index;
4996 USHORT modeidindex,refreshratetableindex;
4997 USHORT VCLK=0,MCLK,colorth=0,data2=0;
4998 USHORT tempal, tempah, tempbx, tempcl, tempax;
4999 USHORT CRT1ModeNo,CRT2ModeNo;
5000 USHORT SelectRate_backup;
5001 ULONG data,eax;
5002 const UCHAR LatencyFactor[] = {
5003 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
5004 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
5005 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
5006 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
5007 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
5008 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
5009 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
5010 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
5012 const UCHAR LatencyFactor730[] = {
5013 69, 63, 61,
5014 86, 79, 77,
5015 103, 96, 94,
5016 120,113,111,
5017 137,130,128, /* <-- last entry, data below */
5018 137,130,128, /* to avoid using illegal values */
5019 137,130,128,
5020 137,130,128,
5021 137,130,128,
5022 137,130,128,
5023 137,130,128,
5024 137,130,128,
5025 137,130,128,
5026 137,130,128,
5027 137,130,128,
5028 137,130,128,
5030 const UCHAR ThLowB[] = {
5031 81, 4, 72, 6, 88, 8,120,12,
5032 55, 4, 54, 6, 66, 8, 90,12,
5033 42, 4, 45, 6, 55, 8, 75,12
5035 const UCHAR ThTiming[] = {
5036 1, 2, 2, 3, 0, 1, 1, 2
5039 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5041 if(!SiS_Pr->CRT1UsesCustomMode) {
5043 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5044 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5045 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5046 SiS_Pr->SiS_SelectCRT2Rate = 0;
5047 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
5049 if(CRT1ModeNo >= 0x13) {
5050 index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
5051 index &= 0x3F;
5052 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5054 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); /* Get colordepth */
5055 colorth >>= 1;
5056 if(!colorth) colorth++;
5059 } else {
5061 CRT1ModeNo = 0xfe;
5062 VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
5063 data2 = (SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2;
5064 switch(data2) { /* Get color depth */
5065 case 0 : colorth = 1; break;
5066 case 1 : colorth = 1; break;
5067 case 2 : colorth = 2; break;
5068 case 3 : colorth = 2; break;
5069 case 4 : colorth = 3; break;
5070 case 5 : colorth = 4; break;
5071 default: colorth = 2;
5076 if(CRT1ModeNo >= 0x13) {
5077 if(HwInfo->jChipType == SIS_300) {
5078 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5079 } else {
5080 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5082 index &= 0x07;
5083 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
5085 data2 = (colorth * VCLK) / MCLK;
5087 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5088 temp = ((temp & 0x00FF) >> 6) << 1;
5089 if(temp == 0) temp = 1;
5090 temp <<= 2;
5091 temp &= 0xff;
5093 data2 = temp - data2;
5095 if((28 * 16) % data2) {
5096 data2 = (28 * 16) / data2;
5097 data2++;
5098 } else {
5099 data2 = (28 * 16) / data2;
5102 if(HwInfo->jChipType == SIS_300) {
5104 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
5105 tempah &= 0x62;
5106 tempah >>= 1;
5107 tempal = tempah;
5108 tempah >>= 3;
5109 tempal |= tempah;
5110 tempal &= 0x07;
5111 tempcl = ThTiming[tempal];
5112 tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
5113 tempbx >>= 6;
5114 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5115 tempah >>= 4;
5116 tempah &= 0x0c;
5117 tempbx |= tempah;
5118 tempbx <<= 1;
5119 tempal = ThLowB[tempbx + 1];
5120 tempal *= tempcl;
5121 tempal += ThLowB[tempbx];
5122 data = tempal;
5124 } else if(HwInfo->jChipType == SIS_730) {
5126 #ifdef LINUX_KERNEL
5127 SiS_SetRegLong(0xcf8,0x80000050);
5128 eax = SiS_GetRegLong(0xcfc);
5129 #else
5130 eax = pciReadLong(0x00000000, 0x50);
5131 #endif
5132 tempal = (USHORT)(eax >> 8);
5133 tempal &= 0x06;
5134 tempal <<= 5;
5136 #ifdef LINUX_KERNEL
5137 SiS_SetRegLong(0xcf8,0x800000A0);
5138 eax = SiS_GetRegLong(0xcfc);
5139 #else
5140 eax = pciReadLong(0x00000000, 0xA0);
5141 #endif
5142 temp = (USHORT)(eax >> 28);
5143 temp &= 0x0F;
5144 tempal |= temp;
5146 tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5147 tempbx = 0; /* -- do it like the BIOS anyway... */
5148 tempax = tempbx;
5149 tempbx &= 0xc0;
5150 tempbx >>= 6;
5151 tempax &= 0x0f;
5152 tempax *= 3;
5153 tempbx += tempax;
5155 data = LatencyFactor730[tempbx];
5156 data += 15;
5157 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5158 if(!(temp & 0x80)) data += 5;
5160 } else {
5162 index = 0;
5163 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5164 if(temp & 0x0080) index += 12;
5166 #ifdef LINUX_KERNEL
5167 SiS_SetRegLong(0xcf8,0x800000A0);
5168 eax = SiS_GetRegLong(0xcfc);
5169 #else
5170 /* We use pci functions X offers. We use tag 0, because
5171 * we want to read/write to the host bridge (which is always
5172 * 00:00.0 on 630, 730 and 540), not the VGA device.
5174 eax = pciReadLong(0x00000000, 0xA0);
5175 #endif
5176 temp = (USHORT)(eax >> 24);
5177 if(!(temp&0x01)) index += 24;
5179 #ifdef LINUX_KERNEL
5180 SiS_SetRegLong(0xcf8,0x80000050);
5181 eax = SiS_GetRegLong(0xcfc);
5182 #else
5183 eax = pciReadLong(0x00000000, 0x50);
5184 #endif
5185 temp=(USHORT)(eax >> 24);
5186 if(temp & 0x01) index += 6;
5188 temp = (temp & 0x0F) >> 1;
5189 index += temp;
5191 data = LatencyFactor[index];
5192 data += 15;
5193 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5194 if(!(temp & 0x80)) data += 5;
5197 data += data2; /* CRT1 Request Period */
5199 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5200 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5202 if(!SiS_Pr->UseCustomMode) {
5204 CRT2ModeNo = ModeNo;
5205 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5207 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
5209 index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
5210 refreshratetableindex,HwInfo);
5211 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5213 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5214 if(SiS_Pr->SiS_UseROM) {
5215 if(ROMAddr[0x220] & 0x01) {
5216 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5221 } else {
5223 CRT2ModeNo = 0xfe;
5224 VCLK = SiS_Pr->CSRClock; /* Get VCLK */
5228 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
5229 colorth >>= 1;
5230 if(!colorth) colorth++;
5232 data = data * VCLK * colorth;
5233 if(data % (MCLK << 4)) {
5234 data = data / (MCLK << 4);
5235 data++;
5236 } else {
5237 data = data / (MCLK << 4);
5240 if(data <= 6) data = 6;
5241 if(data > 0x14) data = 0x14;
5243 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
5244 if(HwInfo->jChipType == SIS_300) {
5245 if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
5246 else temp = (temp & (~0x1F)) | 0x16;
5247 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
5248 temp = (temp & (~0x1F)) | 0x13;
5250 } else {
5251 if( ( (HwInfo->jChipType == SIS_630) ||
5252 (HwInfo->jChipType == SIS_730) ) &&
5253 (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5255 temp = (temp & (~0x1F)) | 0x1b;
5256 } else {
5257 temp = (temp & (~0x1F)) | 0x16;
5260 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5262 if( (HwInfo->jChipType == SIS_630) &&
5263 (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
5265 if(data > 0x13) data = 0x13;
5267 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5269 } else { /* If mode <= 0x13, we just restore everything */
5271 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5272 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5276 #endif
5278 /* Set CRT2 FIFO on 315/330 series */
5279 #ifdef SIS315H
5280 static void
5281 SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
5283 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5284 if( (HwInfo->jChipType == SIS_760) &&
5285 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5286 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5287 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5288 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5289 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5290 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5291 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5292 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5293 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5294 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5295 } else {
5296 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5300 #endif
5302 static USHORT
5303 SiS_GetVGAHT2(SiS_Private *SiS_Pr)
5305 ULONG tempax,tempbx;
5307 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5308 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5309 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5310 return((USHORT)tempax);
5313 /* Set Part 1 / SiS bridge slave mode */
5314 static void
5315 SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5316 PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
5318 USHORT push1,push2;
5319 USHORT tempax,tempbx,tempcx,temp;
5320 USHORT resinfo,modeflag,xres=0;
5321 unsigned char p1_7, p1_8;
5323 if(ModeNo <= 0x13) {
5324 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5325 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5326 } else if(SiS_Pr->UseCustomMode) {
5327 modeflag = SiS_Pr->CModeFlag;
5328 resinfo = 0;
5329 xres = SiS_Pr->CHDisplay;
5330 } else {
5331 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5332 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5333 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5336 /* The following is only done if bridge is in slave mode: */
5338 if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
5339 if(xres >= 1600) {
5340 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5344 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
5346 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
5348 if(modeflag & Charx8Dot) tempcx = 0x08;
5349 else tempcx = 0x09;
5351 tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
5352 if(modeflag & HalfDCLK) tempax >>= 1;
5353 tempax = ((tempax / tempcx) - 1) & 0xff;
5354 tempbx = tempax;
5356 temp = tempax;
5357 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5359 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5360 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
5361 temp += 2;
5364 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5365 if(resinfo == SIS_RI_800x600) temp -= 2;
5367 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
5369 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
5371 tempax = 0xFFFF;
5372 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5373 if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5374 if(modeflag & HalfDCLK) tempax >>= 1;
5375 tempax = (tempax / tempcx) - 5;
5376 tempcx = tempax;
5378 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5379 temp = tempcx - 1;
5380 if(!(modeflag & HalfDCLK)) {
5381 temp -= 6;
5382 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5383 temp -= 2;
5384 if(ModeNo > 0x13) temp -= 10;
5387 } else {
5388 tempcx = (tempcx + tempbx) >> 1;
5389 temp = (tempcx & 0x00FF) + 2;
5390 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5391 temp--;
5392 if(!(modeflag & HalfDCLK)) {
5393 if((modeflag & Charx8Dot)) {
5394 temp += 4;
5395 if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5396 if(HwInfo->jChipType >= SIS_315H) {
5397 if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5401 } else {
5402 if(!(modeflag & HalfDCLK)) {
5403 temp -= 4;
5404 if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
5405 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
5406 if(SiS_Pr->SiS_VGAHDE >= 800) {
5407 temp -= 7;
5408 if(HwInfo->jChipType < SIS_315H) {
5409 if(SiS_Pr->SiS_ModeType == ModeEGA) {
5410 if(SiS_Pr->SiS_VGAVDE == 1024) {
5411 temp += 15;
5412 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
5413 temp += 7;
5417 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5418 if(SiS_Pr->SiS_VGAHDE >= 1280) {
5419 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5428 p1_7 = temp;
5429 p1_8 = 0x00;
5431 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5432 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5433 if(ModeNo <= 0x01) {
5434 p1_7 = 0x2a;
5435 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5436 else p1_8 = 0x41;
5437 } else if(SiS_Pr->SiS_ModeType == ModeText) {
5438 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5439 else p1_7 = 0x55;
5440 p1_8 = 0x00;
5441 } else if(ModeNo <= 0x13) {
5442 if(modeflag & HalfDCLK) {
5443 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5444 p1_7 = 0x30;
5445 p1_8 = 0x03;
5446 } else {
5447 p1_7 = 0x2f;
5448 p1_8 = 0x02;
5450 } else {
5451 p1_7 = 0x5b;
5452 p1_8 = 0x03;
5454 } else if( ((HwInfo->jChipType >= SIS_315H) &&
5455 ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5456 ((HwInfo->jChipType < SIS_315H) &&
5457 (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5458 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5459 p1_7 = 0x30,
5460 p1_8 = 0x03;
5461 } else {
5462 p1_7 = 0x2f;
5463 p1_8 = 0x03;
5469 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
5470 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
5471 p1_7 = 0x63;
5472 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
5474 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5475 if(!(modeflag & HalfDCLK)) {
5476 p1_7 = 0xb2;
5477 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
5478 p1_7 = 0xab;
5481 } else {
5482 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
5483 if(modeflag & HalfDCLK) p1_7 = 0x30;
5488 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */
5489 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */
5491 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */
5493 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
5495 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */
5497 tempcx = 0x121;
5498 tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */
5499 if (tempbx == 357) tempbx = 350;
5500 else if(tempbx == 360) tempbx = 350;
5501 else if(tempbx == 375) tempbx = 350;
5502 else if(tempbx == 405) tempbx = 400;
5503 else if(tempbx == 420) tempbx = 400;
5504 else if(tempbx == 525) tempbx = 480;
5505 push2 = tempbx;
5506 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5507 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5508 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5509 if (tempbx == 350) tempbx += 5;
5510 else if(tempbx == 480) tempbx += 5;
5514 tempbx -= 2;
5515 temp = tempbx & 0x00FF;
5516 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
5518 tempbx = push2;
5519 tempbx--;
5520 temp = tempbx & 0x00FF;
5521 #if 0
5522 /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5523 if(xxx()) {
5524 if(temp == 0xdf) temp = 0xda;
5526 #endif
5527 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5529 temp = 0;
5530 if(modeflag & DoubleScanMode) temp |= 0x80;
5531 if(HwInfo->jChipType >= SIS_661) {
5532 if(tempbx & 0x0200) temp |= 0x20;
5533 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5534 if(tempbx & 0x0100) tempcx |= 0x000a;
5535 if(tempbx & 0x0400) tempcx |= 0x1200;
5536 } else {
5537 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5538 if(tempbx & 0x0100) tempcx |= 0x0002;
5539 if(tempbx & 0x0400) tempcx |= 0x0600;
5542 if(tempbx & 0x0200) tempcx |= 0x0040;
5544 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */
5546 tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
5548 if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
5549 if(resinfo != SIS_RI_1280x1024) {
5550 tempbx += (tempax << 1);
5552 } else if(HwInfo->jChipType >= SIS_315H) {
5553 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5554 tempbx += (tempax << 1);
5558 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5559 tempbx -= 10;
5560 } else {
5561 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5562 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5563 tempbx += 40;
5564 if(HwInfo->jChipType >= SIS_315H) {
5565 if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5570 tempax >>= 2;
5571 tempax++;
5572 tempax += tempbx;
5573 push1 = tempax;
5574 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5575 if(tempbx <= 513) {
5576 if(tempax >= 513) tempbx = 513;
5579 temp = tempbx & 0x00FF;
5580 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */
5582 tempbx--;
5583 temp = tempbx & 0x00FF;
5584 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5586 if(tempbx & 0x0100) tempcx |= 0x0008;
5588 if(tempbx & 0x0200) {
5589 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5591 tempbx++;
5593 if(tempbx & 0x0100) tempcx |= 0x0004;
5594 if(tempbx & 0x0200) tempcx |= 0x0080;
5595 if(tempbx & 0x0400) {
5596 if(HwInfo->jChipType >= SIS_661) tempcx |= 0x0800;
5597 else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5598 else tempcx |= 0x0C00;
5601 tempbx = push1;
5602 temp = tempbx & 0x000F;
5603 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
5605 if(tempbx & 0x0010) tempcx |= 0x2000;
5607 temp = tempcx & 0x00FF;
5608 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
5610 temp = (tempcx & 0xFF00) >> 8;
5611 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */
5613 tempax = modeflag;
5614 temp = (tempax & 0xFF00) >> 8;
5615 temp = (temp >> 1) & 0x09;
5616 if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01; /* Always 8 dotclock */
5617 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
5619 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */
5621 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */
5623 temp = 0x00;
5624 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5625 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
5626 temp = 0x80;
5629 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
5631 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5632 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
5635 /* Setup panel link
5636 * This is used for LVDS, LCDA and Chrontel TV output
5637 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5639 static void
5640 SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5641 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5643 USHORT modeflag,resinfo;
5644 USHORT push2,tempax,tempbx,tempcx,temp;
5645 ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
5646 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5647 #ifdef SIS300
5648 USHORT crt2crtc;
5649 #endif
5650 #ifdef SIS315H
5651 USHORT pushcx;
5652 #endif
5654 if(ModeNo <= 0x13) {
5655 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5656 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5657 #ifdef SIS300
5658 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5659 #endif
5660 } else if(SiS_Pr->UseCustomMode) {
5661 modeflag = SiS_Pr->CModeFlag;
5662 resinfo = 0;
5663 #ifdef SIS300
5664 crt2crtc = 0;
5665 #endif
5666 } else {
5667 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5668 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5669 #ifdef SIS300
5670 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5671 #endif
5674 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5675 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5676 islvds = TRUE;
5679 /* is really sis if sis bridge, but not 301B-DH */
5680 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5681 issis = TRUE;
5684 if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5685 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5686 chkdclkfirst = TRUE;
5690 #ifdef SIS315H
5691 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5692 if(IS_SIS330) {
5693 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5694 } else if(IS_SIS740) {
5695 if(islvds) {
5696 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5697 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5698 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5699 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5701 } else {
5702 if(islvds) {
5703 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5704 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5705 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5706 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5707 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
5708 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5709 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5710 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5716 #endif
5718 /* Horizontal */
5720 tempax = SiS_Pr->SiS_LCDHDES;
5721 if(islvds) {
5722 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5723 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5724 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5725 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5726 tempax -= 8;
5732 temp = (tempax & 0x0007);
5733 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5734 temp = (tempax >> 3) & 0x00FF;
5735 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5737 tempbx = SiS_Pr->SiS_HDE;
5738 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5739 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
5740 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
5741 tempbx >>= 1;
5743 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5744 tempbx = SiS_Pr->PanelXRes;
5748 tempax += tempbx;
5749 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5751 temp = tempax;
5752 if(temp & 0x07) temp += 8;
5753 temp >>= 3;
5754 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5756 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5758 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5759 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5760 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5764 tempcx += tempax;
5765 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5767 temp = (tempcx >> 3) & 0x00FF;
5768 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5769 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5770 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5771 switch(ModeNo) {
5772 case 0x04:
5773 case 0x05:
5774 case 0x0d: temp = 0x56; break;
5775 case 0x10: temp = 0x60; break;
5776 case 0x13: temp = 0x5f; break;
5777 case 0x40:
5778 case 0x41:
5779 case 0x4f:
5780 case 0x43:
5781 case 0x44:
5782 case 0x62:
5783 case 0x56:
5784 case 0x53:
5785 case 0x5d:
5786 case 0x5e: temp = 0x54; break;
5791 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5793 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5794 temp += 2;
5795 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5796 temp += 8;
5797 if(SiS_Pr->PanelHRE != 999) {
5798 temp = tempcx + SiS_Pr->PanelHRE;
5799 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5800 temp >>= 3;
5803 } else {
5804 temp += 10;
5807 temp &= 0x1F;
5808 temp |= ((tempcx & 0x07) << 5);
5809 #if 0
5810 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
5811 #endif
5812 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5814 /* Vertical */
5816 tempax = SiS_Pr->SiS_VGAVDE;
5817 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5818 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5819 tempax = SiS_Pr->PanelYRes;
5823 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5824 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5826 push2 = tempbx;
5828 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5829 if(HwInfo->jChipType < SIS_315H) {
5830 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5831 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5832 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5836 if(islvds) tempcx >>= 1;
5837 else tempcx >>= 2;
5839 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5840 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5841 (SiS_Pr->PanelVRS != 999) ) {
5842 tempcx = SiS_Pr->PanelVRS;
5843 tempbx += tempcx;
5844 if(issis) tempbx++;
5845 } else {
5846 tempbx += tempcx;
5847 if(HwInfo->jChipType < SIS_315H) tempbx++;
5848 else if(issis) tempbx++;
5851 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; /* BPLVRS */
5853 temp = tempbx & 0x00FF;
5854 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5855 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5856 if(ModeNo == 0x10) temp = 0xa9;
5859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
5861 tempcx >>= 3;
5862 tempcx++;
5864 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5865 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5866 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5870 tempcx += tempbx;
5871 temp = tempcx & 0x000F;
5872 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5874 temp = ((tempbx >> 8) & 0x07) << 3;
5875 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5876 if(SiS_Pr->SiS_HDE != 640) {
5877 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5879 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5880 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5881 tempbx = 0x87;
5882 if((HwInfo->jChipType >= SIS_315H) ||
5883 (HwInfo->jChipRevision >= 0x30)) {
5884 tempbx = 0x07;
5885 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5886 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5888 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
5889 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5890 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5891 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5892 } else {
5893 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5897 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5899 tempbx = push2; /* BPLVDEE */
5901 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5903 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5904 switch(SiS_Pr->SiS_LCDResInfo) {
5905 case Panel_640x480:
5906 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5907 tempcx = SiS_Pr->SiS_VGAVDE;
5908 break;
5909 case Panel_800x600:
5910 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5911 if(resinfo == SIS_RI_800x600) tempcx++;
5913 break;
5914 case Panel_1024x600:
5915 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5916 if(resinfo == SIS_RI_1024x600) tempcx++;
5917 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5918 if(resinfo == SIS_RI_800x600) tempcx++;
5921 break;
5922 case Panel_1024x768:
5923 if(HwInfo->jChipType < SIS_315H) {
5924 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5925 if(resinfo == SIS_RI_1024x768) tempcx++;
5928 break;
5932 temp = ((tempbx >> 8) & 0x07) << 3;
5933 temp = temp | ((tempcx >> 8) & 0x07);
5934 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5935 /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++; */
5936 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5937 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5939 /* Vertical scaling */
5941 if(HwInfo->jChipType < SIS_315H) {
5943 #ifdef SIS300 /* 300 series */
5944 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5945 temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
5946 tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
5947 if(temp) tempeax++;
5949 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5951 temp = (USHORT)(tempeax & 0x00FF);
5952 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5953 tempvcfact = temp;
5954 #endif /* SIS300 */
5956 } else {
5958 #ifdef SIS315H /* 315 series */
5959 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5960 tempebx = SiS_Pr->SiS_VDE;
5961 temp = (tempeax % tempebx);
5962 tempeax = tempeax / tempebx;
5963 if(temp) tempeax++;
5964 tempvcfact = tempeax;
5966 temp = (USHORT)(tempeax & 0x00FF);
5967 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5968 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5969 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5970 temp = (USHORT)((tempeax & 0x00030000) >> 16);
5971 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5972 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5974 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
5975 temp = (USHORT)(tempeax & 0x00FF);
5976 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5977 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5978 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5979 temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
5980 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5981 temp = 0;
5982 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5983 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5985 #endif
5989 /* Horizontal scaling */
5991 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5992 if(chkdclkfirst) {
5993 if(modeflag & HalfDCLK) tempeax >>= 1;
5995 tempebx = tempeax << 16;
5996 if(SiS_Pr->SiS_HDE == tempeax) {
5997 tempecx = 0xFFFF;
5998 } else {
5999 tempecx = tempebx / SiS_Pr->SiS_HDE;
6000 if(HwInfo->jChipType >= SIS_315H) {
6001 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6005 if(HwInfo->jChipType >= SIS_315H) {
6006 tempeax = (tempebx / tempecx) - 1;
6007 } else {
6008 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6010 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6011 temp = (USHORT)(tempecx & 0x00FF);
6012 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6014 if(HwInfo->jChipType >= SIS_315H) {
6015 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6016 tempbx = (USHORT)(tempeax & 0xFFFF);
6017 } else {
6018 tempeax = SiS_Pr->SiS_VGAVDE << 6;
6019 tempbx = tempvcfact & 0x3f;
6020 if(tempbx == 0) tempbx = 64;
6021 tempeax /= tempbx;
6022 tempbx = (USHORT)(tempeax & 0xFFFF);
6024 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6025 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6026 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6027 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
6030 temp = ((tempbx >> 8) & 0x07) << 3;
6031 temp = temp | ((tempecx >> 8) & 0x07);
6032 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6033 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6035 tempecx >>= 16; /* BPLHCFACT */
6036 if(!chkdclkfirst) {
6037 if(modeflag & HalfDCLK) tempecx >>= 1;
6039 temp = (USHORT)((tempecx & 0xFF00) >> 8);
6040 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6041 temp = (USHORT)(tempecx & 0x00FF);
6042 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6044 #ifdef SIS315H
6045 if(HwInfo->jChipType >= SIS_315H) {
6046 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6047 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
6048 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6050 } else {
6051 if(islvds) {
6052 if(HwInfo->jChipType == SIS_740) {
6053 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6054 } else {
6055 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6060 #endif
6062 #ifdef SIS300
6063 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6064 int i;
6065 UCHAR TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
6066 UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6067 UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6069 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6070 for(i=0; i<5; i++) {
6071 SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
6073 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6074 if(ModeNo == 0x13) {
6075 for(i=0; i<4; i++) {
6076 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6078 } else if(ModeNo == 0x10) {
6079 for(i=0; i<4; i++) {
6080 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6081 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6085 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6087 #endif
6089 #ifdef SIS315H
6090 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6091 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6092 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6093 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6094 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6095 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6096 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6097 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6098 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6099 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6100 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6101 tempax += 64;
6102 temp = tempax & 0x00FF;
6103 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
6104 temp = ((tempax & 0xFF00) >> 8) << 3;
6105 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6106 tempax += 32; /* Blpe=lBlps+32 */
6107 temp = tempax & 0x00FF;
6108 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
6109 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
6110 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */
6111 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
6113 tempax = SiS_Pr->SiS_VDE;
6114 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6115 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6116 tempax >>= 1;
6117 temp = tempax & 0x00FF;
6118 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
6119 temp = ((tempax & 0xFF00) >> 8) << 3;
6120 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6122 tempeax = SiS_Pr->SiS_HDE;
6123 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6124 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
6125 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6126 tempebx = 128;
6127 temp = (USHORT)(tempeax % tempebx);
6128 tempeax = tempeax / tempebx;
6129 if(temp) tempeax++;
6130 temp = (USHORT)(tempeax & 0x003F);
6131 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
6132 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6133 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6134 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6135 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
6137 tempax = SiS_Pr->SiS_HDE;
6138 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6139 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6140 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6141 pushcx = tempax;
6142 temp = tempax & 0x00FF;
6143 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6144 temp = ((tempax & 0xFF00) >> 8) << 3;
6145 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
6147 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6148 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6149 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6150 tempeax = (tempax * pushcx);
6151 tempebx = 0x00100000 + tempeax;
6152 temp = (USHORT)tempebx & 0x000000FF;
6153 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6154 temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
6155 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6156 temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
6157 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6158 temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
6159 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6161 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6162 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6163 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6165 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6167 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6168 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6169 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6170 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6171 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6172 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6173 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6174 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6175 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6176 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6177 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6178 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6179 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6180 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6181 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6182 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6183 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6184 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6185 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6186 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6187 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6190 #endif /* SIS315H */
6193 /* Set Part 1 */
6194 static void
6195 SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6196 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
6198 #if defined(SIS300) || defined(SIS315H)
6199 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
6200 #endif
6201 USHORT temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6202 USHORT pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6203 #ifdef SIS315H
6204 USHORT tempbl=0;
6205 #endif
6207 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6208 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6209 return;
6212 if(ModeNo <= 0x13) {
6213 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6214 } else if(SiS_Pr->UseCustomMode) {
6215 modeflag = SiS_Pr->CModeFlag;
6216 } else {
6217 CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
6218 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6219 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6222 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
6224 if( ! ((HwInfo->jChipType >= SIS_315H) &&
6225 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6226 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6228 if(HwInfo->jChipType < SIS_315H ) {
6229 #ifdef SIS300
6230 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
6231 #endif
6232 } else {
6233 #ifdef SIS315H
6234 SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
6235 #endif
6238 /* 1. Horizontal setup */
6240 if(HwInfo->jChipType < SIS_315H ) {
6242 #ifdef SIS300 /* ------------- 300 series --------------*/
6244 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6245 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6247 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6248 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6250 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6251 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6253 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6254 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6255 tempbx = pushbx + tempcx;
6256 tempcx <<= 1;
6257 tempcx += tempbx;
6259 bridgeadd = 12;
6261 #endif /* SIS300 */
6263 } else {
6265 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6267 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6268 if(modeflag & HalfDCLK) {
6269 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6270 tempcx >>= 1;
6271 } else {
6272 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6273 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6274 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6275 tempcx = SiS_Pr->SiS_HT - tempax;
6279 tempcx--;
6280 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6281 temp = (tempcx >> 4) & 0xF0;
6282 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6284 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6285 tempbx = SiS_Pr->SiS_VGAHDE;
6286 tempcx -= tempbx;
6287 tempcx >>= 2;
6288 if(modeflag & HalfDCLK) {
6289 tempbx >>= 1;
6290 tempcx >>= 1;
6292 tempbx += 16;
6294 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6296 pushbx = tempbx;
6297 tempcx >>= 1;
6298 tempbx += tempcx;
6299 tempcx += tempbx;
6301 bridgeadd = 16;
6303 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6304 if(HwInfo->jChipType >= SIS_661) {
6305 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6306 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6307 if(resinfo == SIS_RI_1280x1024) {
6308 tempcx = (tempcx & 0xff00) | 0x30;
6309 } else if(resinfo == SIS_RI_1600x1200) {
6310 tempcx = (tempcx & 0xff00) | 0xff;
6316 #endif /* SIS315H */
6318 } /* 315/330 series */
6320 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6322 if(SiS_Pr->UseCustomMode) {
6323 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6324 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6325 tempax = SiS_Pr->SiS_VGAHT;
6326 if(modeflag & HalfDCLK) tempax >>= 1;
6327 tempax--;
6328 if(tempcx > tempax) tempcx = tempax;
6331 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6332 unsigned char cr4, cr14, cr5, cr15;
6333 if(SiS_Pr->UseCustomMode) {
6334 cr4 = SiS_Pr->CCRT1CRTC[4];
6335 cr14 = SiS_Pr->CCRT1CRTC[14];
6336 cr5 = SiS_Pr->CCRT1CRTC[5];
6337 cr15 = SiS_Pr->CCRT1CRTC[15];
6338 } else {
6339 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6340 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6341 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6342 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6344 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6345 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6346 tempcx &= 0x00FF;
6347 tempcx |= (tempbx & 0xFF00);
6348 tempbx += bridgeadd;
6349 tempcx += bridgeadd;
6350 tempax = SiS_Pr->SiS_VGAHT;
6351 if(modeflag & HalfDCLK) tempax >>= 1;
6352 tempax--;
6353 if(tempcx > tempax) tempcx = tempax;
6356 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6357 tempbx = 1040;
6358 tempcx = 1044; /* HWCursor bug! */
6363 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6365 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6367 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6368 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6370 /* 2. Vertical setup */
6372 tempcx = SiS_Pr->SiS_VGAVT - 1;
6373 temp = tempcx & 0x00FF;
6375 if(HwInfo->jChipType < SIS_661) {
6376 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6377 if(HwInfo->jChipType < SIS_315H) {
6378 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6379 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6380 temp--;
6383 } else {
6384 temp--;
6386 } else if(HwInfo->jChipType >= SIS_315H) {
6387 temp--;
6390 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6392 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6393 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6395 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6396 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6398 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
6399 tempbx++;
6400 tempax = tempbx;
6401 tempcx++;
6402 tempcx -= tempax;
6403 tempcx >>= 2;
6404 tempbx += tempcx;
6405 if(tempcx < 4) tempcx = 4;
6406 tempcx >>= 2;
6407 tempcx += tempbx;
6408 tempcx++;
6409 } else {
6410 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6411 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6414 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6415 if(SiS_Pr->UseCustomMode) {
6416 tempbx = SiS_Pr->CVSyncStart;
6417 tempcx = SiS_Pr->CVSyncEnd;
6419 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6420 unsigned char cr8, cr7, cr13;
6421 if(SiS_Pr->UseCustomMode) {
6422 cr8 = SiS_Pr->CCRT1CRTC[8];
6423 cr7 = SiS_Pr->CCRT1CRTC[7];
6424 cr13 = SiS_Pr->CCRT1CRTC[13];
6425 tempcx = SiS_Pr->CCRT1CRTC[9];
6426 } else {
6427 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6428 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6429 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6430 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6432 tempbx = cr8;
6433 if(cr7 & 0x04) tempbx |= 0x0100;
6434 if(cr7 & 0x80) tempbx |= 0x0200;
6435 if(cr13 & 0x08) tempbx |= 0x0400;
6438 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6440 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6441 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6443 /* 3. Panel delay compensation */
6445 if(HwInfo->jChipType < SIS_315H) {
6447 #ifdef SIS300 /* ---------- 300 series -------------- */
6449 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6450 temp = 0x20;
6451 if(HwInfo->jChipType == SIS_300) {
6452 temp = 0x10;
6453 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6454 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6456 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6457 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6459 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6460 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6461 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6462 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6463 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6464 else temp = 0x20;
6466 if(SiS_Pr->SiS_UseROM) {
6467 if(ROMAddr[0x220] & 0x80) {
6468 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6469 temp = ROMAddr[0x221];
6470 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6471 temp = ROMAddr[0x222];
6472 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6473 temp = ROMAddr[0x223];
6474 else
6475 temp = ROMAddr[0x224];
6476 temp &= 0x3c;
6479 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6480 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6483 } else {
6484 temp = 0x20;
6485 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6486 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6488 if(SiS_Pr->SiS_UseROM) {
6489 if(ROMAddr[0x220] & 0x80) {
6490 temp = ROMAddr[0x220] & 0x3c;
6493 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6494 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6498 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6500 #endif /* SIS300 */
6502 } else {
6504 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6506 if(HwInfo->jChipType < SIS_661) {
6508 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6510 if(HwInfo->jChipType == SIS_740) temp = 0x03;
6511 else temp = 0x00;
6513 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6514 tempbl = 0xF0;
6515 if(HwInfo->jChipType == SIS_650) {
6516 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6517 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6521 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6522 temp = 0x08;
6523 tempbl = 0;
6524 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6525 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6529 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6532 } /* < 661 */
6534 tempax = 0;
6535 if(modeflag & DoubleScanMode) tempax |= 0x80;
6536 if(modeflag & HalfDCLK) tempax |= 0x40;
6537 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6539 #endif /* SIS315H */
6543 } /* Slavemode */
6545 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6546 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6547 /* For 301BDH with LCD, we set up the Panel Link */
6548 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6549 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6550 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6552 } else {
6553 if(HwInfo->jChipType < SIS_315H) {
6554 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6555 } else {
6556 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6557 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6558 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6560 } else {
6561 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6567 /*********************************************/
6568 /* SET PART 2 REGISTER GROUP */
6569 /*********************************************/
6571 #ifdef SIS315H
6572 static UCHAR *
6573 SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
6575 const UCHAR *tableptr = NULL;
6576 USHORT a, b, p = 0;
6578 a = SiS_Pr->SiS_VGAHDE;
6579 b = SiS_Pr->SiS_HDE;
6580 if(tabletype) {
6581 a = SiS_Pr->SiS_VGAVDE;
6582 b = SiS_Pr->SiS_VDE;
6585 if(a < b) {
6586 tableptr = SiS_Part2CLVX_1;
6587 } else if(a == b) {
6588 tableptr = SiS_Part2CLVX_2;
6589 } else {
6590 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6591 tableptr = SiS_Part2CLVX_4;
6592 } else {
6593 tableptr = SiS_Part2CLVX_3;
6595 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6596 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6597 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6598 else tableptr = SiS_Part2CLVX_5;
6599 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6600 tableptr = SiS_Part2CLVX_6;
6602 do {
6603 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6604 p += 0x42;
6605 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6606 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6608 p += 2;
6609 return((UCHAR *)&tableptr[p]);
6612 static void
6613 SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6614 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
6616 UCHAR *tableptr;
6617 int i, j;
6618 UCHAR temp;
6620 if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
6622 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
6623 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6624 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6626 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6627 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
6628 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6629 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6632 temp = 0x10;
6633 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6634 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6637 static BOOLEAN
6638 SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
6639 USHORT RefreshRateTableIndex,USHORT *CRT2Index,
6640 USHORT *ResIndex,PSIS_HW_INFO HwInfo)
6643 if(HwInfo->jChipType < SIS_315H) return FALSE;
6645 if(ModeNo <= 0x13)
6646 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6647 else
6648 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6650 (*ResIndex) &= 0x3f;
6651 (*CRT2Index) = 0;
6653 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6654 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6655 (*CRT2Index) = 200;
6659 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6660 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6661 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6664 return(((*CRT2Index) != 0));
6666 #endif
6668 #ifdef SIS300
6669 static void
6670 SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
6672 USHORT tempcx;
6673 const UCHAR atable[] = {
6674 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6675 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6678 if(!SiS_Pr->UseCustomMode) {
6679 if( ( ( (HwInfo->jChipType == SIS_630) ||
6680 (HwInfo->jChipType == SIS_730) ) &&
6681 (HwInfo->jChipRevision > 2) ) &&
6682 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6683 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6684 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6685 if(ModeNo == 0x13) {
6686 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6687 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6688 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6689 } else {
6690 if((crt2crtc & 0x3F) == 4) {
6691 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6692 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6693 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6694 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6695 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6700 if(HwInfo->jChipType < SIS_315H) {
6701 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6702 crt2crtc &= 0x1f;
6703 tempcx = 0;
6704 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6705 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6706 tempcx += 7;
6709 tempcx += crt2crtc;
6710 if(crt2crtc >= 4) {
6711 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6714 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6715 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6716 if(crt2crtc == 4) {
6717 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6722 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6728 /* For ECS A907. Highly preliminary. */
6729 static void
6730 SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6731 USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
6732 USHORT ModeNo)
6734 USHORT crt2crtc, resindex;
6735 int i,j;
6736 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6738 if(HwInfo->jChipType != SIS_300) return;
6739 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6740 if(SiS_Pr->UseCustomMode) return;
6742 if(ModeNo <= 0x13) {
6743 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6744 } else {
6745 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6748 resindex = crt2crtc & 0x3F;
6749 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6750 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6752 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6753 if(ModeNo > 0x13) {
6754 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6755 resindex = 4;
6758 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6759 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6760 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6761 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6763 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6764 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6766 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6767 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6769 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6770 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6772 #endif
6774 static void
6775 SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
6777 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6778 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6779 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6781 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6782 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6783 const UCHAR specialtv[] = {
6784 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6785 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6786 0x58,0xe4,0x73,0xda,0x13
6788 int i, j;
6789 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6790 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6792 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6793 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6794 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6795 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6796 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6797 } else {
6798 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6799 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6803 } else {
6804 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6805 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6806 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6807 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6808 } else {
6809 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6810 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6815 static void
6816 SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6818 USHORT temp;
6820 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6821 if(SiS_Pr->SiS_VGAVDE == 525) {
6822 temp = 0xc3;
6823 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6824 temp++;
6825 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6828 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6829 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6830 temp = 0x4d;
6831 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6832 temp++;
6833 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
6835 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6839 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6840 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6841 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
6842 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6843 /* Not always for LV, see SetGrp2 */
6845 temp = 1;
6846 if(ModeNo <= 0x13) temp = 3;
6847 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6849 #if 0
6850 /* 651+301C, for 1280x768 - do I really need that? */
6851 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6852 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6853 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6854 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6855 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6856 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6857 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6858 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6859 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6860 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6861 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6862 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6863 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6864 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6865 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6866 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6870 #endif
6874 static void
6875 SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
6876 PSIS_HW_INFO HwInfo)
6878 USHORT i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6879 USHORT push2, modeflag, crt2crtc, bridgeoffset;
6880 ULONG longtemp;
6881 const UCHAR *PhasePoint;
6882 const UCHAR *TimingPoint;
6883 #ifdef SIS315H
6884 USHORT resindex, CRT2Index;
6885 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6887 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6888 #endif
6890 if(ModeNo <= 0x13) {
6891 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6892 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6893 } else if(SiS_Pr->UseCustomMode) {
6894 modeflag = SiS_Pr->CModeFlag;
6895 crt2crtc = 0;
6896 } else {
6897 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6898 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6901 temp = 0;
6902 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6903 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6904 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6905 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6907 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6909 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6911 PhasePoint = SiS_Pr->SiS_PALPhase;
6912 TimingPoint = SiS_Pr->SiS_PALTiming;
6914 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6916 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6917 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6918 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6919 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6920 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6921 #if 0
6922 if(!(modeflag & Charx8Dot)) TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
6923 #endif
6927 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6929 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) TimingPoint = &SiS_YPbPrTable[2][0];
6930 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
6931 else TimingPoint = &SiS_YPbPrTable[0][0];
6933 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6935 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6937 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6938 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6939 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6940 PhasePoint = SiS_Pr->SiS_PALPhase2;
6943 } else {
6945 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6946 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6947 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6948 PhasePoint = SiS_Pr->SiS_PALPhase;
6951 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6952 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6953 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6954 PhasePoint = SiS_Pr->SiS_NTSCPhase2;
6955 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6956 PhasePoint = SiS_Pr->SiS_PALPhase2;
6962 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6963 PhasePoint = SiS_Pr->SiS_PALMPhase;
6964 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6965 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6966 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6967 PhasePoint = SiS_Pr->SiS_PALMPhase2;
6971 if(SiS_Pr->SiS_TVMode & TVSetPALN) {
6972 PhasePoint = SiS_Pr->SiS_PALNPhase;
6973 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6974 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6975 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6976 PhasePoint = SiS_Pr->SiS_PALNPhase2;
6980 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6981 PhasePoint = SiS_Pr->SiS_SpecialPhase;
6982 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6983 PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
6984 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6985 PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
6989 for(i=0x31, j=0; i<=0x34; i++, j++) {
6990 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
6993 for(i=0x01, j=0; i<=0x2D; i++, j++) {
6994 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6996 for(i=0x39; i<=0x45; i++, j++) {
6997 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7000 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7001 if(SiS_Pr->SiS_ModeType != ModeText) {
7002 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7006 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7008 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7009 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7010 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7011 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7013 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
7014 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
7015 else tempax = 440; /* NTSC, YPbPr 525, 750 */
7017 if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
7018 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7019 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7021 tempax -= SiS_Pr->SiS_VDE;
7022 tempax >>= 2;
7023 tempax &= 0x00ff;
7025 temp = tempax + (USHORT)TimingPoint[0];
7026 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7028 temp = tempax + (USHORT)TimingPoint[1];
7029 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7031 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7032 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7033 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 19 */
7034 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 52 */
7035 } else {
7036 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7037 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7043 tempcx = SiS_Pr->SiS_HT;
7044 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7045 tempcx--;
7046 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
7047 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7048 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7050 tempcx = SiS_Pr->SiS_HT >> 1;
7051 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7052 tempcx += 7;
7053 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7054 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7056 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7057 tempbx += tempcx;
7058 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7059 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7061 tempbx += 8;
7062 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7063 tempbx -= 4;
7064 tempcx = tempbx;
7066 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7068 j += 2;
7069 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7070 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7071 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7073 tempcx += 8;
7074 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7075 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7077 tempcx = SiS_Pr->SiS_HT >> 1;
7078 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7079 j += 2;
7080 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7081 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7083 tempcx -= 11;
7084 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7085 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7087 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7089 tempbx = SiS_Pr->SiS_VDE;
7090 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7091 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7092 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7093 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7094 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7095 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7096 tempbx >>= 1;
7097 if(HwInfo->jChipType >= SIS_315H) {
7098 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7099 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7100 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7101 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7102 if(crt2crtc == 4) tempbx++;
7106 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7107 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7108 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7110 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7111 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7115 tempbx -= 2;
7116 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7118 temp = (tempcx >> 8) & 0x0F;
7119 temp |= ((tempbx >> 2) & 0xC0);
7120 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7121 temp |= 0x10;
7122 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7124 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7126 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
7127 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7130 #if 0
7131 /* TEST qqqq */
7132 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7133 for(i=0x01, j=0; i<=0x2D; i++, j++) {
7134 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7136 for(i=0x39; i<=0x45; i++, j++) {
7137 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7140 #endif
7142 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7143 tempbx = SiS_Pr->SiS_VDE;
7144 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7145 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7146 tempbx >>= 1;
7148 tempbx -= 3;
7149 temp = ((tempbx >> 3) & 0x60) | 0x18;
7150 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7151 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7153 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
7154 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7158 tempbx = 0;
7159 if(!(modeflag & HalfDCLK)) {
7160 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7161 tempax = 0;
7162 tempbx |= 0x20;
7166 tempch = tempcl = 0x01;
7167 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7168 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7169 if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
7170 tempch = 0x19;
7171 tempcl = 0x20;
7172 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7173 tempch = 0x14;
7174 tempbx &= ~0x20;
7180 if(!(tempbx & 0x20)) {
7181 if(modeflag & HalfDCLK) tempcl <<= 1;
7182 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7183 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
7184 tempax = longtemp / SiS_Pr->SiS_HDE;
7185 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7186 tempbx |= ((tempax >> 8) & 0x1F);
7187 tempcx = tempax >> 13;
7190 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7191 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7193 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7195 tempcx &= 0x07;
7196 if(tempbx & 0x20) tempcx = 0;
7197 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7199 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7200 tempbx = 0x0382;
7201 tempcx = 0x007e;
7202 } else {
7203 tempbx = 0x0369;
7204 tempcx = 0x0061;
7206 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7207 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7208 temp = (tempcx & 0x0300) >> 6;
7209 temp |= ((tempbx >> 8) & 0x03);
7210 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7211 temp |= 0x10;
7212 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7213 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7215 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7217 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7218 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7220 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7222 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
7223 temp = 0;
7224 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7225 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7230 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7231 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7232 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7233 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7235 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7238 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7239 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7240 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7244 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7246 /* From here: Part2 LCD setup */
7248 tempbx = SiS_Pr->SiS_HDE;
7249 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7250 tempbx--; /* RHACTE = HDE - 1 */
7251 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7252 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7254 temp = 0x01;
7255 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7256 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7257 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7258 temp = 0x02;
7259 if(HwInfo->jChipType >= SIS_315H) {
7260 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7261 temp = 0x01;
7267 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7269 tempbx = SiS_Pr->SiS_VDE - 1;
7270 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7271 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7273 tempcx = SiS_Pr->SiS_VT - 1;
7274 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7275 temp = (tempcx >> 3) & 0xE0;
7276 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7277 /* Enable dithering; only do this for 32bpp mode */
7278 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7279 temp |= 0x10;
7282 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7284 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7285 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7288 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7290 #ifdef SIS315H
7291 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7292 &CRT2Index, &resindex, HwInfo)) {
7293 switch(CRT2Index) {
7294 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7295 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7296 default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
7299 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7300 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7301 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7302 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7304 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7305 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7307 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7308 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7310 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7311 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7313 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7316 } else {
7317 #endif
7319 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7320 /* Clevo dual-link 1024x768 */
7321 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7322 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7324 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7325 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7326 tempbx = SiS_Pr->SiS_VDE - 1;
7327 tempcx = SiS_Pr->SiS_VT - 1;
7328 } else {
7329 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7330 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7332 } else {
7333 tempbx = SiS_Pr->PanelYRes;
7334 tempcx = SiS_Pr->SiS_VT;
7335 tempax = 1;
7336 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7337 tempax = SiS_Pr->PanelYRes;
7338 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7339 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7340 tempax = tempcx = 0;
7341 } else {
7342 tempax -= SiS_Pr->SiS_VDE;
7344 tempax >>= 1;
7346 tempcx -= tempax; /* lcdvdes */
7347 tempbx -= tempax; /* lcdvdee */
7350 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7352 #ifdef TWDEBUG
7353 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7354 #endif
7356 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7357 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7359 temp = (tempbx >> 5) & 0x38;
7360 temp |= ((tempcx >> 8) & 0x07);
7361 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7363 tempax = SiS_Pr->SiS_VDE;
7364 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7365 tempax = SiS_Pr->PanelYRes;
7367 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7368 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7369 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7370 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7374 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7375 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7376 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7377 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7378 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7379 if(tempax % 4) { tempax >>= 2; tempax++; }
7380 else { tempax >>= 2; }
7381 tempbx -= (tempax - 1);
7382 } else {
7383 tempbx -= 10;
7384 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7388 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7389 tempbx++;
7390 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7391 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7392 tempbx = 770;
7393 tempcx = 3;
7398 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7400 if(SiS_Pr->UseCustomMode) {
7401 tempbx = SiS_Pr->CVSyncStart;
7404 #ifdef TWDEBUG
7405 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7406 #endif
7408 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7410 temp = (tempbx >> 4) & 0xF0;
7411 tempbx += (tempcx + 1);
7412 temp |= (tempbx & 0x0F);
7414 if(SiS_Pr->UseCustomMode) {
7415 temp &= 0xf0;
7416 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7419 #ifdef TWDEBUG
7420 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7421 #endif
7423 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7425 #ifdef SIS300
7426 SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
7427 #endif
7429 bridgeoffset = 7;
7430 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) bridgeoffset += 2;
7431 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
7432 if(SiS_IsDualLink(SiS_Pr, HwInfo)) bridgeoffset++;
7434 temp = 0;
7435 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7436 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7437 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7438 if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
7441 temp += bridgeoffset;
7442 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7443 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7445 tempcx = SiS_Pr->SiS_HT;
7446 tempax = tempbx = SiS_Pr->SiS_HDE;
7447 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7448 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7449 tempax = SiS_Pr->PanelXRes;
7450 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7453 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7454 tempcx >>= 1;
7455 tempbx >>= 1;
7456 tempax >>= 1;
7459 #ifdef TWDEBUG
7460 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7461 #endif
7463 tempbx += bridgeoffset;
7465 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7466 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7468 tempcx = (tempcx - tempax) >> 2;
7470 tempbx += tempcx;
7471 push2 = tempbx;
7473 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7474 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7475 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7476 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7481 if(SiS_Pr->UseCustomMode) {
7482 tempbx = SiS_Pr->CHSyncStart;
7483 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7484 tempbx += bridgeoffset;
7487 #ifdef TWDEBUG
7488 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7489 #endif
7491 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7492 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7494 tempbx = push2;
7496 tempcx <<= 1;
7497 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7498 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7500 tempbx += tempcx;
7502 if(SiS_Pr->UseCustomMode) {
7503 tempbx = SiS_Pr->CHSyncEnd;
7504 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7505 tempbx += bridgeoffset;
7508 #ifdef TWDEBUG
7509 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7510 #endif
7512 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7514 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7516 #ifdef SIS300
7517 SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7518 #endif
7519 #ifdef SIS315H
7520 } /* CRT2-LCD from table */
7521 #endif
7524 /*********************************************/
7525 /* SET PART 3 REGISTER GROUP */
7526 /*********************************************/
7528 static void
7529 SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7530 PSIS_HW_INFO HwInfo)
7532 USHORT i;
7533 const UCHAR *tempdi;
7535 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7537 #ifndef SIS_CP
7538 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7539 #else
7540 SIS_CP_INIT301_CP
7541 #endif
7543 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7544 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7545 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7546 } else {
7547 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7548 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7551 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7552 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7553 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7554 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7557 tempdi = NULL;
7558 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7559 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7560 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7561 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7563 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7564 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7565 tempdi = SiS_HiTVGroup3_1;
7566 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7569 if(tempdi) {
7570 for(i=0; i<=0x3E; i++) {
7571 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7573 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
7574 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7575 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7580 #ifdef SIS_CP
7581 SIS_CP_INIT301_CP2
7582 #endif
7585 /*********************************************/
7586 /* SET PART 4 REGISTER GROUP */
7587 /*********************************************/
7589 #ifdef SIS315H
7590 static void
7591 SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
7593 USHORT temp, temp1, temp2;
7595 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7596 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7597 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7598 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7599 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7600 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7601 temp = (USHORT)((int)(temp) + shift);
7602 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7603 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7604 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7605 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7606 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7607 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7610 static void
7611 SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7612 USHORT ModeNo, USHORT ModeIdIndex)
7614 USHORT temp, temp1, resinfo = 0;
7616 if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
7617 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7619 if(ModeNo > 0x13) {
7620 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7623 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7624 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7625 if(!(temp & 0x01)) {
7626 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7627 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7628 if((HwInfo->jChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7629 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7631 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7632 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7633 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7634 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7635 else temp = 0x0402;
7636 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7637 temp1 = 0;
7638 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7639 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7640 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7641 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7642 } else {
7643 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7644 if(temp1 == 0x01) temp |= 0x01;
7645 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7646 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7648 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7649 if(ModeNo > 0x13) {
7650 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7653 if(HwInfo->jChipType >= SIS_661) { /* ? */
7654 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7655 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7656 if(resinfo == SIS_RI_1024x768) {
7657 SiS_ShiftXPos(SiS_Pr, 97);
7658 } else {
7659 SiS_ShiftXPos(SiS_Pr, 111);
7661 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7662 SiS_ShiftXPos(SiS_Pr, 136);
7668 #endif
7670 static void
7671 SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7672 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7674 USHORT vclkindex;
7675 USHORT temp, reg1, reg2;
7677 if(SiS_Pr->UseCustomMode) {
7678 reg1 = SiS_Pr->CSR2B;
7679 reg2 = SiS_Pr->CSR2C;
7680 } else {
7681 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7682 HwInfo);
7683 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7684 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7687 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7688 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7690 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7691 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7692 } else {
7693 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7694 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7696 } else {
7697 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7698 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7699 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7701 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7702 temp = 0x08;
7703 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7704 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7707 static void
7708 SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7709 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7711 USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
7712 ULONG tempebx,tempeax,templong;
7714 if(ModeNo <= 0x13) {
7715 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7716 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7717 } else if(SiS_Pr->UseCustomMode) {
7718 modeflag = SiS_Pr->CModeFlag;
7719 resinfo = 0;
7720 } else {
7721 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7722 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7725 if(HwInfo->jChipType >= SIS_315H) {
7726 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7727 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7728 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7733 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
7734 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7735 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7739 if(HwInfo->jChipType >= SIS_315H) {
7740 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7741 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7742 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7743 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7744 } else {
7745 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7748 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7749 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7750 #ifdef SET_EMI
7751 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7752 #endif
7753 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7756 return;
7760 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7762 tempbx = SiS_Pr->SiS_RVBHCMAX;
7763 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7765 temp = (tempbx >> 1) & 0x80;
7767 tempcx = SiS_Pr->SiS_VGAHT - 1;
7768 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7770 temp |= ((tempcx >> 5) & 0x78);
7772 tempcx = SiS_Pr->SiS_VGAVT - 1;
7773 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7774 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7776 temp |= ((tempcx >> 8) & 0x07);
7777 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7779 tempbx = SiS_Pr->SiS_VGAHDE;
7780 if(modeflag & HalfDCLK) tempbx >>= 1;
7781 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7783 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7784 temp = 0;
7785 if(tempbx > 800) temp = 0x60;
7786 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7787 temp = 0;
7788 if(tempbx == 1024) temp = 0xA0;
7789 else if(tempbx > 1024) temp = 0xC0;
7790 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7791 temp = 0;
7792 if(tempbx >= 1280) temp = 0x40;
7793 else if(tempbx >= 1024) temp = 0x20;
7794 } else {
7795 temp = 0x80;
7796 if(tempbx >= 1024) temp = 0xA0;
7799 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7800 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
7803 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7805 tempeax = SiS_Pr->SiS_VGAVDE;
7806 tempebx = SiS_Pr->SiS_VDE;
7807 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7808 if(!(temp & 0xE0)) tempebx >>=1;
7811 tempcx = SiS_Pr->SiS_RVBHRS;
7812 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7813 tempcx >>= 8;
7814 tempcx |= 0x40;
7816 if(tempeax <= tempebx) {
7817 tempcx ^= 0x40;
7818 } else {
7819 tempeax -= tempebx;
7822 tempeax *= (256 * 1024);
7823 templong = tempeax % tempebx;
7824 tempeax /= tempebx;
7825 if(templong) tempeax++;
7827 temp = (USHORT)(tempeax & 0x000000FF);
7828 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7829 temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
7830 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7831 temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
7832 temp |= (tempcx & 0x4F);
7833 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7835 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7837 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7839 /* Calc Linebuffer max address and set/clear decimode */
7840 tempbx = 0;
7841 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7842 tempax = SiS_Pr->SiS_VGAHDE;
7843 if(modeflag & HalfDCLK) tempax >>= 1;
7844 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
7845 if(tempax > 800) {
7846 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7847 tempax -= 800;
7848 } else { /* 651+301C: Only if TVNoHiviNoYPbPr */
7849 tempbx = 0x08;
7850 if(tempax == 1024) tempax *= 25;
7851 else tempax *= 20;
7852 temp = tempax % 32;
7853 tempax /= 32;
7854 if(temp) tempax++;
7855 tempax++;
7856 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
7857 (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7858 if(resinfo == SIS_RI_1024x768) {
7859 /* Otherwise white line at right edge */
7860 tempax = (tempax & 0xff00) | 0x20;
7865 tempax--;
7866 temp = ((tempax >> 4) & 0x30) | tempbx;
7867 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7868 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7870 temp = 0x0036; tempbx = 0xD0;
7871 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
7872 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7875 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7876 temp |= 0x01;
7877 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7878 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7879 temp &= ~0x01;
7884 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7886 tempbx = SiS_Pr->SiS_HT >> 1;
7887 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7888 tempbx -= 2;
7889 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7890 temp = (tempbx >> 5) & 0x38;
7891 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7893 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7894 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7895 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7896 /* LCD-too-dark-error-source, see FinalizeLCD() */
7898 if(HwInfo->jChipType >= SIS_315H) {
7899 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7900 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7901 } else {
7902 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7905 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7906 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7907 #ifdef SET_EMI
7908 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7909 #endif
7910 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7914 } /* 301B */
7916 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
7919 /*********************************************/
7920 /* SET PART 5 REGISTER GROUP */
7921 /*********************************************/
7923 static void
7924 SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7925 PSIS_HW_INFO HwInfo)
7928 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7930 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7931 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7932 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7933 SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
7938 /*********************************************/
7939 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7940 /*********************************************/
7942 static void
7943 SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7944 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7946 USHORT tempah,i,modeflag,j;
7947 USHORT ResIndex,DisplayType;
7948 const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
7950 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7951 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7953 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7954 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7955 (SiS_Pr->SiS_CustomT == CUT_PANEL848))
7956 return;
7958 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7959 &ResIndex, &DisplayType))) {
7960 return;
7963 if(HwInfo->jChipType < SIS_315H) {
7964 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7967 switch(DisplayType) {
7968 case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
7969 case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
7970 case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
7971 case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
7972 case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
7973 case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
7974 case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
7975 case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
7976 case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
7977 case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
7978 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
7979 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
7980 case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
7981 case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
7982 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
7983 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
7984 case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
7985 case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
7986 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7987 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7988 case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7989 case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7990 case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */
7991 case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7992 case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7993 case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7994 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7995 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break;
7996 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break;
7997 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break;
7998 case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break;
7999 case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break;
8000 case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break;
8001 case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break;
8002 case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break;
8003 case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1; break;
8004 case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break;
8005 case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break;
8006 case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break;
8007 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
8008 case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
8009 case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break;
8010 case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break;
8011 case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break;
8012 case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break;
8013 case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
8014 default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
8017 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8019 tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
8020 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
8022 for(i=0x02,j=1;i<=0x05;i++,j++){
8023 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8024 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8026 for(i=0x06,j=5;i<=0x07;i++,j++){
8027 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8028 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8030 for(i=0x10,j=7;i<=0x11;i++,j++){
8031 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8032 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8034 for(i=0x15,j=9;i<=0x16;i++,j++){
8035 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8036 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8038 for(i=0x0A,j=11;i<=0x0C;i++,j++){
8039 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8040 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8043 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8044 tempah &= 0xE0;
8045 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8047 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8048 tempah &= 0x01;
8049 tempah <<= 5;
8050 if(modeflag & DoubleScanMode) tempah |= 0x080;
8051 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8054 /*********************************************/
8055 /* SET CRT2 ECLK */
8056 /*********************************************/
8058 static void
8059 SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8060 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
8062 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8063 USHORT clkbase, vclkindex=0;
8064 UCHAR sr2b, sr2c;
8066 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8067 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8068 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
8069 RefreshRateTableIndex--;
8071 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8072 RefreshRateTableIndex, HwInfo);
8073 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8074 } else {
8075 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8076 RefreshRateTableIndex, HwInfo);
8079 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8080 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8082 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8083 if(SiS_Pr->SiS_UseROM) {
8084 if(ROMAddr[0x220] & 0x01) {
8085 sr2b = ROMAddr[0x227];
8086 sr2c = ROMAddr[0x228];
8091 clkbase = 0x02B;
8092 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8093 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8094 clkbase += 3;
8098 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8099 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8100 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8101 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8102 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8103 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8104 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8105 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8106 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8109 /*********************************************/
8110 /* SET UP CHRONTEL CHIPS */
8111 /*********************************************/
8113 static void
8114 SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8115 USHORT RefreshRateTableIndex)
8117 #if defined(SIS300) || defined(SIS315H)
8118 USHORT temp, tempbx;
8119 #endif
8120 USHORT tempcl;
8121 USHORT TVType, resindex;
8122 const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
8124 if(ModeNo <= 0x13)
8125 tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8126 else
8127 tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8129 TVType = 0;
8130 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8131 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8132 TVType += 2;
8133 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8134 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8136 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8137 TVType = 4;
8138 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8139 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8140 TVType = 6;
8141 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8144 switch(TVType) {
8145 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8146 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8147 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8148 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8149 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8150 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8151 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8152 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8153 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8154 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8156 resindex = tempcl & 0x3F;
8158 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8160 #ifdef SIS300
8162 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8164 /* We don't support modes >800x600 */
8165 if (resindex > 5) return;
8167 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8168 SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8169 SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/
8170 } else {
8171 SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8172 SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/
8175 temp = CHTVRegData[resindex].Reg[0];
8176 tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */
8177 SiS_SetCH700x(SiS_Pr,tempbx);
8178 temp = CHTVRegData[resindex].Reg[1];
8179 tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */
8180 SiS_SetCH700x(SiS_Pr,tempbx);
8181 temp = CHTVRegData[resindex].Reg[2];
8182 tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */
8183 SiS_SetCH700x(SiS_Pr,tempbx);
8184 temp = CHTVRegData[resindex].Reg[3];
8185 tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */
8186 SiS_SetCH700x(SiS_Pr,tempbx);
8187 temp = CHTVRegData[resindex].Reg[4];
8188 tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */
8189 SiS_SetCH700x(SiS_Pr,tempbx);
8191 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8192 minimum text enhancement (S3-2=10),
8193 maximum flicker filter for Chroma channel (S5-4=10)
8194 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8196 SiS_SetCH700x(SiS_Pr,0x2801);
8198 /* Set video bandwidth
8199 High bandwith Luma composite video filter(S0=1)
8200 low bandwith Luma S-video filter (S2-1=00)
8201 disable peak filter in S-video channel (S3=0)
8202 high bandwidth Chroma Filter (S5-4=11)
8203 =00110001=0x31
8205 SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */
8207 /* Register 0x3D does not exist in non-macrovision register map
8208 (Maybe this is a macrovision register?)
8210 #ifndef SIS_CP
8211 SiS_SetCH70xx(SiS_Pr,0x003D);
8212 #endif
8214 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8215 all other bits a read-only. Macrovision?
8217 SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
8219 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8220 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8222 SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
8224 /* Clear DSEN
8226 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
8228 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8229 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8230 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8231 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8232 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on, no need to set FSCI */
8233 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8234 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8235 SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
8236 SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
8237 SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
8238 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
8239 SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
8240 SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
8241 SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
8242 SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF); /* Loop filter on for mode 23 */
8243 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8245 } else {
8246 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8247 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8248 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8249 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8250 #if 0
8251 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8252 SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */
8253 SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0); /* 198b3a63 */
8254 SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
8255 SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
8256 SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
8257 SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
8258 SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
8259 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */
8260 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8261 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8262 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8263 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8266 } else { /* ---- PAL ---- */
8267 /* We don't play around with FSCI in PAL mode */
8268 if(resindex == 0x04) {
8269 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8270 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8271 } else {
8272 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8273 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8277 #endif /* 300 */
8279 } else {
8281 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8283 #ifdef SIS315H
8285 /* We don't support modes >1024x768 */
8286 if (resindex > 6) return;
8288 temp = CHTVRegData[resindex].Reg[0];
8289 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8290 temp |= 0x10;
8292 tempbx=((temp & 0x00FF) << 8) | 0x00;
8293 SiS_SetCH701x(SiS_Pr,tempbx);
8295 temp = CHTVRegData[resindex].Reg[1];
8296 tempbx=((temp & 0x00FF) << 8) | 0x01;
8297 SiS_SetCH701x(SiS_Pr,tempbx);
8299 temp = CHTVRegData[resindex].Reg[2];
8300 tempbx=((temp & 0x00FF) << 8) | 0x02;
8301 SiS_SetCH701x(SiS_Pr,tempbx);
8303 temp = CHTVRegData[resindex].Reg[3];
8304 tempbx=((temp & 0x00FF) << 8) | 0x04;
8305 SiS_SetCH701x(SiS_Pr,tempbx);
8307 temp = CHTVRegData[resindex].Reg[4];
8308 tempbx=((temp & 0x00FF) << 8) | 0x03;
8309 SiS_SetCH701x(SiS_Pr,tempbx);
8311 temp = CHTVRegData[resindex].Reg[5];
8312 tempbx=((temp & 0x00FF) << 8) | 0x05;
8313 SiS_SetCH701x(SiS_Pr,tempbx);
8315 temp = CHTVRegData[resindex].Reg[6];
8316 tempbx=((temp & 0x00FF) << 8) | 0x06;
8317 SiS_SetCH701x(SiS_Pr,tempbx);
8319 temp = CHTVRegData[resindex].Reg[7];
8320 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8321 temp = 0x66;
8323 tempbx=((temp & 0x00FF) << 8) | 0x07;
8324 SiS_SetCH701x(SiS_Pr,tempbx);
8326 temp = CHTVRegData[resindex].Reg[8];
8327 tempbx=((temp & 0x00FF) << 8) | 0x08;
8328 SiS_SetCH701x(SiS_Pr,tempbx);
8330 temp = CHTVRegData[resindex].Reg[9];
8331 tempbx=((temp & 0x00FF) << 8) | 0x15;
8332 SiS_SetCH701x(SiS_Pr,tempbx);
8334 temp = CHTVRegData[resindex].Reg[10];
8335 tempbx=((temp & 0x00FF) << 8) | 0x1f;
8336 SiS_SetCH701x(SiS_Pr,tempbx);
8338 temp = CHTVRegData[resindex].Reg[11];
8339 tempbx=((temp & 0x00FF) << 8) | 0x0c;
8340 SiS_SetCH701x(SiS_Pr,tempbx);
8342 temp = CHTVRegData[resindex].Reg[12];
8343 tempbx=((temp & 0x00FF) << 8) | 0x0d;
8344 SiS_SetCH701x(SiS_Pr,tempbx);
8346 temp = CHTVRegData[resindex].Reg[13];
8347 tempbx=((temp & 0x00FF) << 8) | 0x0e;
8348 SiS_SetCH701x(SiS_Pr,tempbx);
8350 temp = CHTVRegData[resindex].Reg[14];
8351 tempbx=((temp & 0x00FF) << 8) | 0x0f;
8352 SiS_SetCH701x(SiS_Pr,tempbx);
8354 temp = CHTVRegData[resindex].Reg[15];
8355 tempbx=((temp & 0x00FF) << 8) | 0x10;
8356 SiS_SetCH701x(SiS_Pr,tempbx);
8358 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8359 /* D1 should be set for PAL, PAL-N and NTSC-J,
8360 but I won't do that for PAL unless somebody
8361 tells me to do so. Since the BIOS uses
8362 non-default CIV values and blacklevels,
8363 this might be compensated anyway.
8365 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8366 SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
8368 #endif /* 315 */
8372 #ifdef SIS_CP
8373 SIS_CP_INIT301_CP3
8374 #endif
8378 void
8379 SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8381 USHORT temp;
8383 /* Enable Chrontel 7019 LCD panel backlight */
8384 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8385 if(HwInfo->jChipType == SIS_740) {
8386 SiS_SetCH701x(SiS_Pr,0x6566);
8387 } else {
8388 temp = SiS_GetCH701x(SiS_Pr,0x66);
8389 temp |= 0x20;
8390 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8395 void
8396 SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
8398 USHORT temp;
8400 /* Disable Chrontel 7019 LCD panel backlight */
8401 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8402 temp = SiS_GetCH701x(SiS_Pr,0x66);
8403 temp &= 0xDF;
8404 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8408 #ifdef SIS315H /* ----------- 315 series only ---------- */
8410 static void
8411 SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8413 UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8414 UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8415 UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8416 UCHAR asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8417 UCHAR asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8418 UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8419 UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8420 UCHAR *tableptr = NULL;
8421 int i;
8423 /* Set up Power up/down timing */
8425 if(HwInfo->jChipType == SIS_740) {
8426 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8427 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8428 else tableptr = table1024_740;
8429 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8430 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8431 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8432 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8433 else tableptr = table1400_740;
8434 } else return;
8435 } else {
8436 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8437 tableptr = table1024_650;
8438 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8439 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8440 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8441 tableptr = table1400_650;
8442 } else return;
8445 for(i=0; i<5; i++) {
8446 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8450 static void
8451 SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8453 UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8454 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
8455 UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8456 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
8457 UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8458 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8459 UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8460 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8461 UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8462 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
8463 UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8464 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
8465 UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8466 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
8467 UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8468 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
8469 UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8470 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
8471 UCHAR *tableptr = NULL;
8472 USHORT tempbh;
8473 int i;
8475 if(HwInfo->jChipType == SIS_740) {
8476 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8477 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8478 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8479 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8480 else return;
8481 } else {
8482 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8483 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8484 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8485 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8486 else return;
8489 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8490 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8491 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8492 if(tempbh == 0xc8) {
8493 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8494 } else if(tempbh == 0xdb) {
8495 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8496 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8497 } else if(tempbh == 0xde) {
8498 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8502 if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
8503 else tempbh = 0x0c;
8505 for(i = 0; i < tempbh; i++) {
8506 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8508 SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
8509 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8510 tempbh |= 0xc0;
8511 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
8513 if(HwInfo->jChipType == SIS_740) {
8514 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8515 tempbh &= 0xfb;
8516 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
8517 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8518 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8519 tempbh |= 0x40;
8520 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
8521 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8522 tempbh &= 0x3f;
8523 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
8527 static void
8528 SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
8530 unsigned char temp, temp1;
8532 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8533 SiS_SetCH701x(SiS_Pr,0x3e49);
8534 temp = SiS_GetCH701x(SiS_Pr,0x47);
8535 temp &= 0x7f; /* Use external VSYNC */
8536 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8537 SiS_LongDelay(SiS_Pr,3);
8538 temp = SiS_GetCH701x(SiS_Pr,0x47);
8539 temp |= 0x80; /* Use internal VSYNC */
8540 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8541 SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
8544 static void
8545 SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8547 USHORT temp;
8549 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8550 if(HwInfo->jChipType == SIS_740) {
8551 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8552 temp |= 0x04; /* Invert XCLK phase */
8553 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8555 if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
8556 temp = SiS_GetCH701x(SiS_Pr,0x01);
8557 temp &= 0x3f;
8558 temp |= 0x80; /* Enable YPrPb (HDTV) */
8559 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8561 if(SiS_IsChScart(SiS_Pr, HwInfo)) {
8562 temp = SiS_GetCH701x(SiS_Pr,0x01);
8563 temp &= 0x3f;
8564 temp |= 0xc0; /* Enable SCART + CVBS */
8565 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8567 if(HwInfo->jChipType == SIS_740) {
8568 SiS_ChrontelResetVSync(SiS_Pr);
8569 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8570 } else {
8571 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8572 temp = SiS_GetCH701x(SiS_Pr,0x49);
8573 if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
8574 temp = SiS_GetCH701x(SiS_Pr,0x73);
8575 temp |= 0x60;
8576 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
8578 temp = SiS_GetCH701x(SiS_Pr,0x47);
8579 temp &= 0x7f;
8580 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8581 SiS_LongDelay(SiS_Pr,2);
8582 temp = SiS_GetCH701x(SiS_Pr,0x47);
8583 temp |= 0x80;
8584 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8589 static void
8590 SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8592 USHORT temp;
8594 /* Complete power down of LVDS */
8595 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8596 if(HwInfo->jChipType == SIS_740) {
8597 SiS_LongDelay(SiS_Pr,1);
8598 SiS_GenericDelay(SiS_Pr,0x16ff);
8599 SiS_SetCH701x(SiS_Pr,0xac76);
8600 SiS_SetCH701x(SiS_Pr,0x0066);
8601 } else {
8602 SiS_LongDelay(SiS_Pr,2);
8603 temp = SiS_GetCH701x(SiS_Pr,0x76);
8604 temp &= 0xfc;
8605 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8606 SiS_SetCH701x(SiS_Pr,0x0066);
8611 static void
8612 SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8614 USHORT temp;
8616 if(HwInfo->jChipType == SIS_740) {
8618 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8619 temp &= 0x01;
8620 if(!temp) {
8622 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8623 temp = SiS_GetCH701x(SiS_Pr,0x49);
8624 SiS_SetCH701x(SiS_Pr,0x3e49);
8626 /* Reset Chrontel 7019 datapath */
8627 SiS_SetCH701x(SiS_Pr,0x1048);
8628 SiS_LongDelay(SiS_Pr,1);
8629 SiS_SetCH701x(SiS_Pr,0x1848);
8631 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8632 SiS_ChrontelResetVSync(SiS_Pr);
8633 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
8636 } else {
8638 /* Clear/set/clear GPIO */
8639 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8640 temp &= 0xef;
8641 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8642 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8643 temp |= 0x10;
8644 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8645 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8646 temp &= 0xef;
8647 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8648 temp = SiS_GetCH701x(SiS_Pr,0x61);
8649 if(!temp) {
8650 SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
8654 } else { /* 650 */
8655 /* Reset Chrontel 7019 datapath */
8656 SiS_SetCH701x(SiS_Pr,0x1048);
8657 SiS_LongDelay(SiS_Pr,1);
8658 SiS_SetCH701x(SiS_Pr,0x1848);
8662 static void
8663 SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8665 USHORT temp;
8667 if(HwInfo->jChipType == SIS_740) {
8669 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8670 SiS_ChrontelResetVSync(SiS_Pr);
8673 } else {
8675 SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
8676 temp = SiS_GetCH701x(SiS_Pr,0x49);
8677 temp &= 1;
8678 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8679 temp = SiS_GetCH701x(SiS_Pr,0x47);
8680 temp &= 0x70;
8681 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
8682 SiS_LongDelay(SiS_Pr,3);
8683 temp = SiS_GetCH701x(SiS_Pr,0x47);
8684 temp |= 0x80;
8685 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
8691 static void
8692 SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
8694 USHORT temp,temp1;
8696 if(HwInfo->jChipType == SIS_740) {
8698 temp = SiS_GetCH701x(SiS_Pr,0x61);
8699 if(temp < 1) {
8700 temp++;
8701 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8703 SiS_SetCH701x(SiS_Pr,0x4566); /* Panel power on */
8704 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on */
8705 SiS_LongDelay(SiS_Pr,1);
8706 SiS_GenericDelay(SiS_Pr,0x16ff);
8708 } else { /* 650 */
8710 temp1 = 0;
8711 temp = SiS_GetCH701x(SiS_Pr,0x61);
8712 if(temp < 2) {
8713 temp++;
8714 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8715 temp1 = 1;
8717 SiS_SetCH701x(SiS_Pr,0xac76);
8718 temp = SiS_GetCH701x(SiS_Pr,0x66);
8719 temp |= 0x5f;
8720 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8721 if(ModeNo > 0x13) {
8722 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8723 SiS_GenericDelay(SiS_Pr,0x3ff);
8724 } else {
8725 SiS_GenericDelay(SiS_Pr,0x2ff);
8727 } else {
8728 if(!temp1)
8729 SiS_GenericDelay(SiS_Pr,0x2ff);
8731 temp = SiS_GetCH701x(SiS_Pr,0x76);
8732 temp |= 0x03;
8733 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8734 temp = SiS_GetCH701x(SiS_Pr,0x66);
8735 temp &= 0x7f;
8736 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8737 SiS_LongDelay(SiS_Pr,1);
8742 static void
8743 SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8745 USHORT temp,tempcl,tempch;
8747 SiS_LongDelay(SiS_Pr, 1);
8748 tempcl = 3;
8749 tempch = 0;
8751 do {
8752 temp = SiS_GetCH701x(SiS_Pr,0x66);
8753 temp &= 0x04; /* PLL stable? -> bail out */
8754 if(temp == 0x04) break;
8756 if(HwInfo->jChipType == SIS_740) {
8757 /* Power down LVDS output, PLL normal operation */
8758 SiS_SetCH701x(SiS_Pr,0xac76);
8761 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8763 if(tempcl == 0) {
8764 if(tempch == 3) break;
8765 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8766 tempcl = 3;
8767 tempch++;
8769 tempcl--;
8770 temp = SiS_GetCH701x(SiS_Pr,0x76);
8771 temp &= 0xfb; /* Reset PLL */
8772 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8773 SiS_LongDelay(SiS_Pr,2);
8774 temp = SiS_GetCH701x(SiS_Pr,0x76);
8775 temp |= 0x04; /* PLL normal operation */
8776 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8777 if(HwInfo->jChipType == SIS_740) {
8778 SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */
8779 } else {
8780 SiS_SetCH701x(SiS_Pr,0x6078);
8782 SiS_LongDelay(SiS_Pr,2);
8783 } while(0);
8785 SiS_SetCH701x(SiS_Pr,0x0077); /* MV? */
8788 static void
8789 SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8791 USHORT temp;
8793 temp = SiS_GetCH701x(SiS_Pr,0x03);
8794 temp |= 0x80; /* Set datapath 1 to TV */
8795 temp &= 0xbf; /* Set datapath 2 to LVDS */
8796 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8798 if(HwInfo->jChipType == SIS_740) {
8800 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8801 temp &= 0xfb; /* Normal XCLK phase */
8802 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8804 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8806 temp = SiS_GetCH701x(SiS_Pr,0x64);
8807 temp |= 0x40; /* ? Bit not defined */
8808 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
8810 temp = SiS_GetCH701x(SiS_Pr,0x03);
8811 temp &= 0x3f; /* D1 input to both LVDS and TV */
8812 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8814 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8815 SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
8816 SiS_LongDelay(SiS_Pr, 1);
8817 SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
8818 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8819 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8820 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8821 } else {
8822 temp = SiS_GetCH701x(SiS_Pr,0x66);
8823 if(temp != 0x45) {
8824 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8825 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8826 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8830 } else { /* 650 */
8832 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8833 SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
8834 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8835 SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
8836 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on, LVDS normal operation */
8841 #endif /* 315 series */
8843 /*********************************************/
8844 /* MAIN: SET CRT2 REGISTER GROUP */
8845 /*********************************************/
8847 BOOLEAN
8848 SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8850 #ifdef SIS300
8851 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8852 #endif
8853 USHORT ModeIdIndex, RefreshRateTableIndex;
8854 #if 0
8855 USHORT temp;
8856 #endif
8858 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8860 if(!SiS_Pr->UseCustomMode) {
8861 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8862 } else {
8863 ModeIdIndex = 0;
8866 /* Used for shifting CR33 */
8867 SiS_Pr->SiS_SelectCRT2Rate = 4;
8869 SiS_UnLockCRT2(SiS_Pr, HwInfo);
8871 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8873 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8875 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8876 SiS_DisableBridge(SiS_Pr,HwInfo);
8877 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
8878 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8880 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8883 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8884 SiS_LockCRT2(SiS_Pr, HwInfo);
8885 SiS_DisplayOn(SiS_Pr);
8886 return TRUE;
8889 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8891 /* Set up Panel Link for LVDS and LCDA */
8892 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8893 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8894 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8895 ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
8896 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8899 #ifdef LINUX_XF86
8900 #ifdef TWDEBUG
8901 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8902 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8903 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8904 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8905 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8906 #endif
8907 #endif
8909 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8910 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
8913 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8915 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8917 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8918 #ifdef SIS315H
8919 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8920 #endif
8921 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8922 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8923 #ifdef SIS315H
8924 SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8925 #endif
8926 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8928 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8930 /* For 301BDH (Panel link initialization): */
8931 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8932 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
8933 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8934 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8935 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
8936 RefreshRateTableIndex,HwInfo);
8940 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
8941 RefreshRateTableIndex,HwInfo);
8945 } else {
8947 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8949 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8950 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8953 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8955 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8956 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8957 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8958 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8959 #ifdef SIS315H
8960 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8961 #endif
8964 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8965 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8972 #ifdef SIS300
8973 if(HwInfo->jChipType < SIS_315H) {
8974 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8975 if(SiS_Pr->SiS_UseOEM) {
8976 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8977 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8978 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8979 RefreshRateTableIndex);
8981 } else {
8982 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8983 RefreshRateTableIndex);
8986 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8987 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8988 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8989 SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8991 SiS_DisplayOn(SiS_Pr);
8995 #endif
8997 #ifdef SIS315H
8998 if(HwInfo->jChipType >= SIS_315H) {
8999 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9000 if(HwInfo->jChipType < SIS_661) {
9001 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
9002 SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
9003 } else {
9004 SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
9006 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
9009 #endif
9011 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9012 SiS_EnableBridge(SiS_Pr, HwInfo);
9015 SiS_DisplayOn(SiS_Pr);
9017 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
9018 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9019 /* Disable LCD panel when using TV */
9020 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
9021 } else {
9022 /* Disable TV when using LCD */
9023 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
9027 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9028 SiS_LockCRT2(SiS_Pr,HwInfo);
9031 return TRUE;
9035 /*********************************************/
9036 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
9037 /*********************************************/
9039 void
9040 SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9042 /* Switch on LCD backlight on SiS30xLV */
9043 SiS_DDC2Delay(SiS_Pr,0xff00);
9044 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9045 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9046 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
9048 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9049 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9053 void
9054 SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9056 /* Switch off LCD backlight on SiS30xLV */
9057 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9058 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
9059 SiS_DDC2Delay(SiS_Pr,0xe000);
9062 /*********************************************/
9063 /* DDC RELATED FUNCTIONS */
9064 /*********************************************/
9066 static void
9067 SiS_SetupDDCN(SiS_Private *SiS_Pr)
9069 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9070 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
9071 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9072 SiS_Pr->SiS_DDC_NData &= 0x0f;
9073 SiS_Pr->SiS_DDC_NClk &= 0x0f;
9077 #ifdef SIS300
9078 static UCHAR *
9079 SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
9081 int i, j, num;
9082 USHORT tempah,temp;
9083 UCHAR *mydataptr;
9085 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9086 mydataptr = dataptr;
9087 num = *mydataptr++;
9088 if(!num) return mydataptr;
9089 if(i) {
9090 SiS_SetStop(SiS_Pr);
9091 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
9093 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9094 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9095 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9096 if(temp) continue; /* (ERROR: no ack) */
9097 tempah = *mydataptr++;
9098 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
9099 if(temp) continue; /* (ERROR: no ack) */
9100 for(j=0; j<num; j++) {
9101 tempah = *mydataptr++;
9102 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9103 if(temp) break;
9105 if(temp) continue;
9106 if(SiS_SetStop(SiS_Pr)) continue;
9107 return mydataptr;
9109 return NULL;
9112 static BOOLEAN
9113 SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
9115 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9116 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9117 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9118 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9119 SiS_SetupDDCN(SiS_Pr);
9121 SiS_SetSwitchDDC2(SiS_Pr);
9123 while(*dataptr) {
9124 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9125 if(!dataptr) return FALSE;
9127 #ifdef TWDEBUG
9128 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
9129 #endif
9130 return TRUE;
9132 #endif
9134 /* The Chrontel 700x is connected to the 630/730 via
9135 * the 630/730's DDC/I2C port.
9137 * On 630(S)T chipset, the index changed from 0x11 to
9138 * 0x0a, possibly for working around the DDC problems
9141 static BOOLEAN
9142 SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
9144 USHORT tempah,temp,i;
9146 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9147 if(i) {
9148 SiS_SetStop(SiS_Pr);
9149 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9151 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9152 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9153 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9154 if(temp) continue; /* (ERROR: no ack) */
9155 tempah = tempbx & 0x00FF; /* Write RAB */
9156 tempah |= myor; /* (700x: set bit 7, see datasheet) */
9157 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9158 if(temp) continue; /* (ERROR: no ack) */
9159 tempah = (tempbx & 0xFF00) >> 8;
9160 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
9161 if(temp) continue; /* (ERROR: no ack) */
9162 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9163 SiS_Pr->SiS_ChrontelInit = 1;
9164 return TRUE;
9166 return FALSE;
9169 #if 0
9170 #ifdef SIS300
9171 /* Write Trumpion register */
9172 static void
9173 SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9175 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9176 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9177 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9178 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9179 SiS_SetupDDCN(SiS_Pr);
9180 SiS_SetChReg(SiS_Pr, tempbx, 0);
9182 #endif
9183 #endif
9185 /* Write to Chrontel 700x */
9186 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9187 void
9188 SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9190 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9192 if(!(SiS_Pr->SiS_ChrontelInit)) {
9193 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9194 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9195 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9196 SiS_SetupDDCN(SiS_Pr);
9199 if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
9200 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9201 SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */
9202 SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
9203 SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
9204 SiS_SetupDDCN(SiS_Pr);
9206 SiS_SetChReg(SiS_Pr, tempbx, 0x80);
9210 /* Write to Chrontel 701x */
9211 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9212 void
9213 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9215 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9216 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9217 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9218 SiS_SetupDDCN(SiS_Pr);
9219 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9220 SiS_SetChReg(SiS_Pr, tempbx, 0);
9223 static void
9224 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9226 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9227 SiS_SetCH700x(SiS_Pr,tempbx);
9228 else
9229 SiS_SetCH701x(SiS_Pr,tempbx);
9232 static USHORT
9233 SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
9235 USHORT tempah,temp,i;
9237 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9238 if(i) {
9239 SiS_SetStop(SiS_Pr);
9240 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9242 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9243 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9244 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9245 if(temp) continue; /* (ERROR: no ack) */
9246 tempah = SiS_Pr->SiS_DDC_ReadAddr | myor; /* Write RAB (700x: | 0x80) */
9247 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9248 if(temp) continue; /* (ERROR: no ack) */
9249 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9250 tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
9251 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
9252 if(temp) continue; /* (ERROR: no ack) */
9253 tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
9254 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9255 SiS_Pr->SiS_ChrontelInit = 1;
9256 return(tempah);
9258 return 0xFFFF;
9261 #if 0
9262 #ifdef SIS300
9263 /* Read from Trumpion */
9264 static USHORT
9265 SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9267 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB */
9268 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9269 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9270 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9271 SiS_SetupDDCN(SiS_Pr);
9272 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9273 return(SiS_GetChReg(SiS_Pr,0));
9275 #endif
9276 #endif
9278 /* Read from Chrontel 700x */
9279 /* Parameter is [Register no (S7-S0)] */
9280 USHORT
9281 SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9283 USHORT result;
9285 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9287 if(!(SiS_Pr->SiS_ChrontelInit)) {
9288 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9289 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9290 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9291 SiS_SetupDDCN(SiS_Pr);
9294 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9296 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9297 (!SiS_Pr->SiS_ChrontelInit) ) {
9299 SiS_Pr->SiS_DDC_Index = 0x0a;
9300 SiS_Pr->SiS_DDC_Data = 0x80;
9301 SiS_Pr->SiS_DDC_Clk = 0x40;
9302 SiS_SetupDDCN(SiS_Pr);
9304 result = SiS_GetChReg(SiS_Pr,0x80);
9306 return(result);
9309 /* Read from Chrontel 701x */
9310 /* Parameter is [Register no (S7-S0)] */
9311 USHORT
9312 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9314 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9315 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9316 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9317 SiS_SetupDDCN(SiS_Pr);
9318 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9320 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9322 return(SiS_GetChReg(SiS_Pr,0));
9325 /* Read from Chrontel 70xx */
9326 /* Parameter is [Register no (S7-S0)] */
9327 static USHORT
9328 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9330 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9331 return(SiS_GetCH700x(SiS_Pr, tempbx));
9332 else
9333 return(SiS_GetCH701x(SiS_Pr, tempbx));
9336 /* Our own DDC functions */
9337 static USHORT
9338 SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9339 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
9341 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9342 unsigned char flag, cr32;
9343 USHORT temp = 0, myadaptnum = adaptnum;
9345 if(adaptnum != 0) {
9346 if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
9347 if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9350 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9352 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9354 SiS_Pr->SiS_DDC_SecAddr = 0;
9355 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9356 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9357 SiS_Pr->SiS_DDC_Index = 0x11;
9358 flag = 0xff;
9360 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9362 #if 0
9363 if(VBFlags & VB_SISBRIDGE) {
9364 if(myadaptnum == 0) {
9365 if(!(cr32 & 0x20)) {
9366 myadaptnum = 2;
9367 if(!(cr32 & 0x10)) {
9368 myadaptnum = 1;
9369 if(!(cr32 & 0x08)) {
9370 myadaptnum = 0;
9376 #endif
9378 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9380 if(myadaptnum != 0) {
9381 flag = 0;
9382 if(VBFlags & VB_SISBRIDGE) {
9383 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9384 SiS_Pr->SiS_DDC_Index = 0x0f;
9388 if(!(VBFlags & VB_301)) {
9389 if((cr32 & 0x80) && (checkcr32)) {
9390 if(myadaptnum >= 1) {
9391 if(!(cr32 & 0x08)) {
9392 myadaptnum = 1;
9393 if(!(cr32 & 0x10)) return 0xFFFF;
9399 temp = 4 - (myadaptnum * 2);
9400 if(flag) temp = 0;
9402 } else { /* 315/330 series */
9404 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9406 if(VBFlags & VB_SISBRIDGE) {
9407 if(myadaptnum == 2) {
9408 myadaptnum = 1;
9412 if(myadaptnum == 1) {
9413 flag = 0;
9414 if(VBFlags & VB_SISBRIDGE) {
9415 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9416 SiS_Pr->SiS_DDC_Index = 0x0f;
9420 if((cr32 & 0x80) && (checkcr32)) {
9421 if(myadaptnum >= 1) {
9422 if(!(cr32 & 0x08)) {
9423 myadaptnum = 1;
9424 if(!(cr32 & 0x10)) return 0xFFFF;
9429 temp = myadaptnum;
9430 if(myadaptnum == 1) {
9431 temp = 0;
9432 if(VBFlags & VB_LVDS) flag = 0xff;
9435 if(flag) temp = 0;
9438 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9439 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9441 SiS_SetupDDCN(SiS_Pr);
9443 #ifdef TWDEBUG
9444 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9445 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9446 #endif
9448 return 0;
9451 static USHORT
9452 SiS_WriteDABDDC(SiS_Private *SiS_Pr)
9454 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9455 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9456 return 0xFFFF;
9458 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9459 return 0xFFFF;
9461 return(0);
9464 static USHORT
9465 SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
9467 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9468 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9469 return 0xFFFF;
9471 return(0);
9474 static USHORT
9475 SiS_PrepareDDC(SiS_Private *SiS_Pr)
9477 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9478 if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
9479 return(0);
9482 static void
9483 SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
9485 SiS_SetSCLKLow(SiS_Pr);
9486 if(yesno) {
9487 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9488 SiS_Pr->SiS_DDC_Index,
9489 SiS_Pr->SiS_DDC_NData,
9490 SiS_Pr->SiS_DDC_Data);
9491 } else {
9492 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9493 SiS_Pr->SiS_DDC_Index,
9494 SiS_Pr->SiS_DDC_NData,
9497 SiS_SetSCLKHigh(SiS_Pr);
9500 static USHORT
9501 SiS_DoProbeDDC(SiS_Private *SiS_Pr)
9503 unsigned char mask, value;
9504 USHORT temp, ret=0;
9505 BOOLEAN failed = FALSE;
9507 SiS_SetSwitchDDC2(SiS_Pr);
9508 if(SiS_PrepareDDC(SiS_Pr)) {
9509 SiS_SetStop(SiS_Pr);
9510 #ifdef TWDEBUG
9511 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9512 #endif
9513 return(0xFFFF);
9515 mask = 0xf0;
9516 value = 0x20;
9517 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9518 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9519 SiS_SendACK(SiS_Pr, 0);
9520 if(temp == 0) {
9521 mask = 0xff;
9522 value = 0xff;
9523 } else {
9524 failed = TRUE;
9525 ret = 0xFFFF;
9526 #ifdef TWDEBUG
9527 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9528 #endif
9531 if(failed == FALSE) {
9532 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9533 SiS_SendACK(SiS_Pr, 1);
9534 temp &= mask;
9535 if(temp == value) ret = 0;
9536 else {
9537 ret = 0xFFFF;
9538 #ifdef TWDEBUG
9539 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9540 #endif
9541 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9542 if(temp == 0x30) ret = 0;
9546 SiS_SetStop(SiS_Pr);
9547 return(ret);
9550 static USHORT
9551 SiS_ProbeDDC(SiS_Private *SiS_Pr)
9553 USHORT flag;
9555 flag = 0x180;
9556 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9557 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9558 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9559 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9560 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9561 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9562 if(!(flag & 0x1a)) flag = 0;
9563 return(flag);
9566 static USHORT
9567 SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9569 USHORT flag, length, i;
9570 unsigned char chksum,gotcha;
9572 if(DDCdatatype > 4) return 0xFFFF;
9574 flag = 0;
9575 SiS_SetSwitchDDC2(SiS_Pr);
9576 if(!(SiS_PrepareDDC(SiS_Pr))) {
9577 length = 127;
9578 if(DDCdatatype != 1) length = 255;
9579 chksum = 0;
9580 gotcha = 0;
9581 for(i=0; i<length; i++) {
9582 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9583 chksum += buffer[i];
9584 gotcha |= buffer[i];
9585 SiS_SendACK(SiS_Pr, 0);
9587 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9588 chksum += buffer[i];
9589 SiS_SendACK(SiS_Pr, 1);
9590 if(gotcha) flag = (USHORT)chksum;
9591 else flag = 0xFFFF;
9592 } else {
9593 flag = 0xFFFF;
9595 SiS_SetStop(SiS_Pr);
9596 return(flag);
9599 /* Our private DDC functions
9601 It complies somewhat with the corresponding VESA function
9602 in arguments and return values.
9604 Since this is probably called before the mode is changed,
9605 we use our pre-detected pSiS-values instead of SiS_Pr as
9606 regards chipset and video bridge type.
9608 Arguments:
9609 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9610 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9611 LCDA is CRT1, but DDC is read from CRT2 port.
9612 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9613 buffer: ptr to 256 data bytes which will be filled with read data.
9615 Returns 0xFFFF if error, otherwise
9616 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9617 if DDCdatatype = 0: Returns supported DDC modes
9620 USHORT
9621 SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9622 USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
9624 unsigned char sr1f,cr17=1;
9625 USHORT result;
9627 if(adaptnum > 2) return 0xFFFF;
9628 if(DDCdatatype > 4) return 0xFFFF;
9629 if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
9630 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
9632 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9633 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9634 if(VGAEngine == SIS_300_VGA) {
9635 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9636 if(!cr17) {
9637 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9638 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9639 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9642 if((sr1f) || (!cr17)) {
9643 SiS_WaitRetrace1(SiS_Pr);
9644 SiS_WaitRetrace1(SiS_Pr);
9645 SiS_WaitRetrace1(SiS_Pr);
9646 SiS_WaitRetrace1(SiS_Pr);
9649 if(DDCdatatype == 0) {
9650 result = SiS_ProbeDDC(SiS_Pr);
9651 } else {
9652 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9653 if((!result) && (DDCdatatype == 1)) {
9654 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9655 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9656 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9657 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9658 (buffer[0x12] == 1)) {
9659 if(adaptnum == 1) {
9660 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9661 } else {
9662 if(buffer[0x14] & 0x80) result = 0xFFFE;
9667 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9668 if(VGAEngine == SIS_300_VGA) {
9669 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9671 return result;
9674 #ifdef LINUX_XF86
9676 static BOOLEAN
9677 checkedid1(unsigned char *buffer)
9679 /* Check header */
9680 if((buffer[0] != 0x00) ||
9681 (buffer[1] != 0xff) ||
9682 (buffer[2] != 0xff) ||
9683 (buffer[3] != 0xff) ||
9684 (buffer[4] != 0xff) ||
9685 (buffer[5] != 0xff) ||
9686 (buffer[6] != 0xff) ||
9687 (buffer[7] != 0x00))
9688 return FALSE;
9690 /* Check EDID version and revision */
9691 if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
9693 /* Check week of manufacture for sanity */
9694 if(buffer[0x10] > 53) return FALSE;
9696 /* Check year of manufacture for sanity */
9697 if(buffer[0x11] > 40) return FALSE;
9699 return TRUE;
9702 static BOOLEAN
9703 checkedid2(unsigned char *buffer)
9705 USHORT year = buffer[6] | (buffer[7] << 8);
9707 /* Check EDID version */
9708 if((buffer[0] & 0xf0) != 0x20) return FALSE;
9710 /* Check week of manufacture for sanity */
9711 if(buffer[5] > 53) return FALSE;
9713 /* Check year of manufacture for sanity */
9714 if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
9716 return TRUE;
9719 /* Sense the LCD parameters (CR36, CR37) via DDC */
9720 /* SiS30x(B) only */
9721 USHORT
9722 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
9724 USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
9725 USHORT index, myindex, lumsize, numcodes, panelvendor, panelproduct;
9726 int maxx=0, maxy=0, prefx=0, prefy=0;
9727 unsigned char cr37=0, seekcode;
9728 BOOLEAN checkexpand = FALSE;
9729 BOOLEAN havesync = FALSE;
9730 BOOLEAN indb = FALSE;
9731 int retry, i;
9732 unsigned char buffer[256];
9734 for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
9735 SiS_Pr->CP_HaveCustomData = FALSE;
9736 SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
9737 SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
9738 SiS_Pr->CP_PreferredIndex = -1;
9739 SiS_Pr->CP_PrefClock = 0;
9740 SiS_Pr->PanelSelfDetected = FALSE;
9742 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
9743 if(pSiS->VBFlags & VB_30xBDH) return 0;
9745 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
9747 SiS_Pr->SiS_DDC_SecAddr = 0x00;
9749 /* Probe supported DA's */
9750 flag = SiS_ProbeDDC(SiS_Pr);
9751 #ifdef TWDEBUG
9752 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
9753 "CRT2 DDC capabilities 0x%x\n", flag);
9754 #endif
9755 if(flag & 0x10) {
9756 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
9757 DDCdatatype = 4;
9758 } else if(flag & 0x08) {
9759 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
9760 DDCdatatype = 3;
9761 } else if(flag & 0x02) {
9762 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
9763 DDCdatatype = 1;
9764 } else return 0; /* no DDC support (or no device attached) */
9766 /* Read the entire EDID */
9767 retry = 2;
9768 do {
9769 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
9770 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9771 "CRT2: DDC read failed (attempt %d), %s\n",
9772 (3-retry), (retry == 1) ? "giving up" : "retrying");
9773 retry--;
9774 if(retry == 0) return 0xFFFF;
9775 } else break;
9776 } while(1);
9778 #ifdef TWDEBUG
9779 for(i=0; i<256; i+=16) {
9780 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9781 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
9782 buffer[i], buffer[i+1], buffer[i+2], buffer[i+3],
9783 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
9784 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
9785 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
9787 #endif
9789 /* Analyze EDID and retrieve LCD panel information */
9790 paneltype = 0;
9791 switch(DDCdatatype) {
9792 case 1: /* Analyze EDID V1 */
9793 /* Catch a few clear cases: */
9794 if(!(checkedid1(buffer))) {
9795 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9796 "LCD sense: EDID corrupt\n");
9797 return 0;
9800 if(!(buffer[0x14] & 0x80)) {
9801 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9802 "LCD sense: Attached display expects analog input (0x%02x)\n",
9803 buffer[0x14]);
9804 return 0;
9807 if((buffer[0x18] & 0x18) != 0x08) {
9808 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9809 "LCD sense: Warning: Attached display is not of RGB but of %s type (0x%02x)\n",
9810 ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
9811 ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
9812 "undefined"),
9813 buffer[0x18]);
9816 /* Now analyze the first Detailed Timing Block and see
9817 * if the preferred timing mode is stored there. If so,
9818 * check if this is a standard panel for which we already
9819 * know the timing.
9822 paneltype = Panel_Custom;
9823 checkexpand = FALSE;
9825 panelvendor = buffer[9] | (buffer[8] << 8);
9826 panelproduct = buffer[10] | (buffer[11] << 8);
9828 /* Overrule bogus preferred modes from database */
9829 if((indb = SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
9830 if(prefx) SiS_Pr->CP_PreferredX = xres = prefx;
9831 if(prefy) SiS_Pr->CP_PreferredY = yres = prefy;
9834 if(buffer[0x18] & 0x02) {
9836 USHORT pclk = (buffer[0x36] | (buffer[0x37] << 8));
9837 USHORT phb = (buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8));
9838 USHORT pvb = (buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8));
9840 if(!xres) SiS_Pr->CP_PreferredX = xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
9841 if(!yres) SiS_Pr->CP_PreferredY = yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
9843 switch(xres) {
9844 #if 0 /* Treat as custom */
9845 case 800:
9846 if(yres == 600) {
9847 paneltype = Panel_800x600;
9848 checkexpand = TRUE;
9850 break;
9851 #endif
9852 case 1024:
9853 if(yres == 768) {
9854 paneltype = Panel_1024x768;
9855 checkexpand = TRUE;
9857 break;
9858 case 1280:
9859 if(yres == 1024) {
9860 paneltype = Panel_1280x1024;
9861 checkexpand = TRUE;
9862 } else if(yres == 960) {
9863 if(pSiS->VGAEngine == SIS_300_VGA) {
9864 paneltype = Panel300_1280x960;
9865 } else {
9866 paneltype = Panel310_1280x960;
9868 } else if(yres == 768) {
9869 if( (pclk == 8100) &&
9870 (phb == (1688 - 1280)) &&
9871 (pvb == (802 - 768)) ) {
9872 paneltype = Panel_1280x768;
9873 checkexpand = FALSE;
9874 cr37 |= 0x10;
9876 } else if(yres == 800) {
9877 if( (pclk == 6900) &&
9878 (phb == (1408 - 1280)) &&
9879 (pvb == (816 - 800)) ) {
9880 paneltype = Panel_1280x800;
9883 break;
9884 case 1400:
9885 if(pSiS->VGAEngine == SIS_315_VGA) {
9886 if(yres == 1050) {
9887 paneltype = Panel310_1400x1050;
9888 checkexpand = TRUE;
9891 break;
9892 case 1600:
9893 if(pSiS->VGAEngine == SIS_315_VGA) {
9894 if(pSiS->VBFlags & VB_301C) {
9895 if(yres == 1200) {
9896 paneltype = Panel310_1600x1200;
9897 checkexpand = TRUE;
9901 break;
9904 /* Save sync: This is used if "Pass 1:1" is off; in this case
9905 * we always use the panel's native mode = this "preferred mode"
9906 * we just have been analysing. Hence, we also need its sync.
9908 if((buffer[0x47] & 0x18) == 0x18) {
9909 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
9910 havesync = TRUE;
9911 } else {
9912 /* What now? There is no digital separate output timing... */
9913 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9914 "LCD sense: Unable to retrieve Sync polarity information\n");
9915 cr37 |= 0xc0; /* Default */
9920 /* Check against our database; eg. Sanyo Z2 projector reports
9921 * 1024x768 as preferred mode, although it supports 1280x720
9922 * natively in non-HDCP mode. Treat such wrongly reporting
9923 * panels as custom and fixup actual maximum resolutions.
9925 if(paneltype != Panel_Custom) {
9926 if(indb) {
9927 paneltype = Panel_Custom;
9928 SiS_Pr->CP_MaxX = maxx;
9929 SiS_Pr->CP_MaxY = maxy;
9930 /* Leave preferred unchanged (MUST contain a valid mode!) */
9934 /* If we still don't know what panel this is, we take it
9935 * as a custom panel and derive the timing data from the
9936 * detailed timing blocks
9938 if(paneltype == Panel_Custom) {
9940 int i, temp, base = 0x36;
9941 unsigned long estpack;
9942 const unsigned short estx[] = {
9943 720, 720, 640, 640, 640, 640, 800, 800,
9944 800, 800, 832,1024,1024,1024,1024,1280,
9945 1152
9947 const unsigned short esty[] = {
9948 400, 400, 480, 480, 480, 480, 600, 600,
9949 600, 600, 624, 768, 768, 768, 768,1024,
9952 const int estclk[] = {
9953 0, 0, 25100, 0, 31500, 31500, 36100, 40000,
9954 50100, 49500, 0, 0, 65100, 75200, 78700,135200,
9958 paneltype = 0;
9959 SiS_Pr->CP_Supports64048075 = TRUE;
9961 /* Find the maximum resolution */
9963 /* 1. From Established timings */
9964 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
9965 for(i=16; i>=0; i--) {
9966 if(estpack & (1 << i)) {
9967 if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
9968 if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
9969 if(estclk[16 - i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = estclk[16 - i];
9973 /* By default we drive the LCD at 75Hz in 640x480 mode; if
9974 * the panel does not provide this mode, use 60hz
9976 if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
9978 /* 2. From Standard Timings */
9979 for(i=0x26; i < 0x36; i+=2) {
9980 if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
9981 temp = (buffer[i] + 31) * 8;
9982 if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
9983 switch((buffer[i+1] & 0xc0) >> 6) {
9984 case 0x03: temp = temp * 9 / 16; break;
9985 case 0x02: temp = temp * 4 / 5; break;
9986 case 0x01: temp = temp * 3 / 4; break;
9988 if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
9992 /* Now extract the Detailed Timings and convert them into modes */
9994 for(i = 0; i < 4; i++, base += 18) {
9996 /* Is this a detailed timing block or a monitor descriptor? */
9997 if(buffer[base] || buffer[base+1] || buffer[base+2]) {
9999 xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
10000 yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
10002 SiS_Pr->CP_HDisplay[i] = xres;
10003 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
10004 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
10005 SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
10006 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10007 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10009 SiS_Pr->CP_VDisplay[i] = yres;
10010 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
10011 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
10012 SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
10013 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10014 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10016 SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
10018 SiS_Pr->CP_DataValid[i] = TRUE;
10020 /* Sort out invalid timings, interlace and too high clocks */
10021 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10022 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10023 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10024 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10025 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10026 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10027 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10028 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10029 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10030 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10031 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10032 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10033 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10034 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10035 ((!(pSiS->VBFlags & VB_301C)) &&
10036 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024) ||
10037 (SiS_Pr->CP_HDisplay[i] > 1600)))) ||
10038 (buffer[base+17] & 0x80)) {
10040 SiS_Pr->CP_DataValid[i] = FALSE;
10042 } else {
10044 SiS_Pr->CP_HaveCustomData = TRUE;
10046 if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
10047 if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
10048 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10050 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10051 SiS_Pr->CP_PreferredIndex = i;
10052 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10053 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10056 /* Extract the sync polarisation information. This only works
10057 * if the Flags indicate a digital separate output.
10059 if((buffer[base+17] & 0x18) == 0x18) {
10060 SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
10061 SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
10062 SiS_Pr->CP_SyncValid[i] = TRUE;
10063 if((i == SiS_Pr->CP_PreferredIndex) && (!havesync)) {
10064 cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
10065 havesync = TRUE;
10067 } else {
10068 SiS_Pr->CP_SyncValid[i] = FALSE;
10073 } else if((!buffer[base]) && (!buffer[base+1]) && (!buffer[base+2]) && (!buffer[base+4])) {
10075 /* Maximum pixclock from Monitor Range Limits */
10076 if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) {
10077 int maxclk = buffer[base+9] * 10;
10078 /* More than 170 is not supported anyway */
10079 if(maxclk <= 170) SiS_Pr->CP_MaxClock = maxclk * 1000;
10086 if(SiS_Pr->CP_MaxX && SiS_Pr->CP_MaxY) {
10087 paneltype = Panel_Custom;
10088 checkexpand = FALSE;
10089 cr37 |= 0x10;
10090 SiS_Pr->CP_Vendor = panelvendor;
10091 SiS_Pr->CP_Product = panelproduct;
10096 if(paneltype && checkexpand) {
10097 /* If any of the Established low-res modes is supported, the
10098 * panel can scale automatically. For 800x600 panels, we only
10099 * check the even lower ones.
10101 if(paneltype == Panel_800x600) {
10102 if(buffer[0x23] & 0xfc) cr37 |= 0x10;
10103 } else {
10104 if(buffer[0x23]) cr37 |= 0x10;
10108 break;
10110 case 3: /* Analyze EDID V2 */
10111 case 4:
10112 index = 0;
10114 if(!(checkedid2(buffer))) {
10115 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10116 "LCD sense: EDID corrupt\n");
10117 return 0;
10120 if((buffer[0x41] & 0x0f) == 0x03) {
10121 index = 0x42 + 3;
10122 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10123 "LCD sense: Display supports TMDS input on primary interface\n");
10124 } else if((buffer[0x41] & 0xf0) == 0x30) {
10125 index = 0x46 + 3;
10126 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10127 "LCD sense: Display supports TMDS input on secondary interface\n");
10128 } else {
10129 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10130 "LCD sense: Display does not support TMDS video interface (0x%02x)\n",
10131 buffer[0x41]);
10132 return 0;
10135 SiS_Pr->CP_Vendor = panelvendor = buffer[2] | (buffer[1] << 8);
10136 SiS_Pr->CP_Product = panelproduct = buffer[3] | (buffer[4] << 8);
10138 paneltype = Panel_Custom;
10139 SiS_Pr->CP_MaxX = SiS_Pr->CP_PreferredX = xres = buffer[0x76] | (buffer[0x77] << 8);
10140 SiS_Pr->CP_MaxY = SiS_Pr->CP_PreferredY = yres = buffer[0x78] | (buffer[0x79] << 8);
10142 switch(xres) {
10143 #if 0
10144 case 800:
10145 if(yres == 600) {
10146 paneltype = Panel_800x600;
10147 checkexpand = TRUE;
10149 break;
10150 #endif
10151 case 1024:
10152 if(yres == 768) {
10153 paneltype = Panel_1024x768;
10154 checkexpand = TRUE;
10156 break;
10157 case 1280:
10158 if(yres == 960) {
10159 if(pSiS->VGAEngine == SIS_315_VGA) {
10160 paneltype = Panel310_1280x960;
10161 } else {
10162 paneltype = Panel300_1280x960;
10164 } else if(yres == 1024) {
10165 paneltype = Panel_1280x1024;
10166 checkexpand = TRUE;
10168 /* 1280x768 treated as custom here */
10169 break;
10170 case 1400:
10171 if(pSiS->VGAEngine == SIS_315_VGA) {
10172 if(yres == 1050) {
10173 paneltype = Panel310_1400x1050;
10174 checkexpand = TRUE;
10177 break;
10178 case 1600:
10179 if(pSiS->VGAEngine == SIS_315_VGA) {
10180 if(pSiS->VBFlags & VB_301C) {
10181 if(yres == 1200) {
10182 paneltype = Panel310_1600x1200;
10183 checkexpand = TRUE;
10187 break;
10190 /* Determine if RGB18 or RGB24 */
10191 if(index) {
10192 if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
10193 cr37 |= 0x01;
10197 if(checkexpand) {
10198 /* TODO - for now, we let the panel scale */
10199 cr37 |= 0x10;
10202 /* Now seek 4-Byte Timing codes and extract sync pol info */
10203 index = 0x80;
10204 if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
10205 lumsize = buffer[0x80] & 0x1f;
10206 if(buffer[0x80] & 0x80) lumsize *= 3;
10207 lumsize++; /* luminance header byte */
10208 index += lumsize;
10210 #if 0 /* "pixel rate" = pixel clock? */
10211 if(buffer[0x7e] & 0x1c) {
10212 for(i=0; i<((buffer[0x7e] & 0x1c) >> 2); i++) {
10213 if(buffer[index + (i*8) + 6] && (buffer[index + (i*8) + 7] & 0x0f)) {
10214 int clk = (buffer[index + (i*8) + 6] | ((buffer[index + (i*8) + 7] & 0x0f) << 4)) * 1000;
10215 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10219 #endif
10220 index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */
10221 if(buffer[0x7e] & 0x03) {
10222 for(i=0; i<(buffer[0x7e] & 0x03); i++) {
10223 if((buffer[index + (i*27) + 9]) || (buffer[index + (i*27) + 10])) {
10224 int clk = ((buffer[index + (i*27) + 9]) | ((buffer[index + (i*27) + 9]) << 8)) * 10;
10225 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10229 index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */
10230 numcodes = (buffer[0x7f] & 0xf8) >> 3;
10231 if(numcodes) {
10232 myindex = index;
10233 seekcode = (xres - 256) / 16;
10234 for(i=0; i<numcodes; i++) {
10235 if(buffer[myindex] == seekcode) break;
10236 myindex += 4;
10238 if(buffer[myindex] == seekcode) {
10239 cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
10240 havesync = TRUE;
10241 } else {
10242 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10243 "LCD sense: Unable to retrieve Sync polarity information\n");
10245 } else {
10246 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10247 "LCD sense: Unable to retrieve Sync polarity information\n");
10250 /* Check against our database; Eg. Sanyo projector reports
10251 * 1024x768 in non-HDPC mode, although it supports 1280x720.
10252 * Treat such wrongly reporting panels as custom.
10254 if(paneltype != Panel_Custom) {
10255 int maxx, maxy, prefx, prefy;
10256 if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
10257 paneltype = Panel_Custom;
10258 SiS_Pr->CP_MaxX = maxx;
10259 SiS_Pr->CP_MaxY = maxy;
10260 cr37 |= 0x10;
10261 /* Leave preferred unchanged (MUST be a valid mode!) */
10265 /* Now seek the detailed timing descriptions for custom panels */
10266 if(paneltype == Panel_Custom) {
10268 SiS_Pr->CP_Supports64048075 = TRUE;
10270 index += (numcodes * 4);
10271 numcodes = buffer[0x7f] & 0x07;
10272 for(i=0; i<numcodes; i++, index += 18) {
10273 xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
10274 yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
10276 SiS_Pr->CP_HDisplay[i] = xres;
10277 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
10278 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
10279 SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
10280 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10281 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10283 SiS_Pr->CP_VDisplay[i] = yres;
10284 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10285 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10286 SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10287 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10288 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10290 SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10292 SiS_Pr->CP_DataValid[i] = TRUE;
10294 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10295 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10296 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10297 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10298 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10299 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10300 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10301 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10302 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10303 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10304 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10305 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10306 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10307 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10308 ((!(pSiS->VBFlags & VB_301C)) &&
10309 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024)))) ||
10310 (buffer[index + 17] & 0x80)) {
10312 SiS_Pr->CP_DataValid[i] = FALSE;
10314 } else {
10316 SiS_Pr->CP_HaveCustomData = TRUE;
10318 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10320 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10321 SiS_Pr->CP_PreferredIndex = i;
10322 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10323 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10324 if(!havesync) {
10325 cr37 |= ((((buffer[index + 17] & 0x06) ^ 0x06) << 5) | 0x20);
10326 havesync = TRUE;
10330 SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10331 SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10332 SiS_Pr->CP_SyncValid[i] = TRUE;
10337 cr37 |= 0x10;
10341 break;
10345 /* 1280x960 panels are always RGB24, unable to scale and use
10346 * high active sync polarity
10348 if(pSiS->VGAEngine == SIS_315_VGA) {
10349 if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10350 } else {
10351 if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10354 for(i = 0; i < 7; i++) {
10355 if(SiS_Pr->CP_DataValid[i]) {
10356 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10357 "Non-standard LCD/DVI-D timing data no. %d:\n", i);
10358 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10359 " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10360 SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10361 SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10362 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10363 " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10364 SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10365 SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10366 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10367 " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10368 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10369 " To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10370 SiS_Pr->CP_HDisplay[i],
10371 SiS_Pr->CP_VDisplay[i]);
10375 if(paneltype) {
10376 if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10377 if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10378 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10379 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
10380 cr37 &= 0xf1;
10381 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
10382 SiS_Pr->PanelSelfDetected = TRUE;
10383 #ifdef TWDEBUG
10384 xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
10385 "LCD sense: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10386 #endif
10387 } else {
10388 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
10389 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
10391 return 0;
10394 USHORT
10395 SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10397 USHORT DDCdatatype,flag;
10398 BOOLEAN foundcrt = FALSE;
10399 int retry;
10400 unsigned char buffer[256];
10402 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10404 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10406 SiS_Pr->SiS_DDC_SecAddr = 0x00;
10408 /* Probe supported DA's */
10409 flag = SiS_ProbeDDC(SiS_Pr);
10410 if(flag & 0x10) {
10411 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
10412 DDCdatatype = 4;
10413 } else if(flag & 0x08) {
10414 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
10415 DDCdatatype = 3;
10416 } else if(flag & 0x02) {
10417 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
10418 DDCdatatype = 1;
10419 } else {
10420 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10421 "VGA2 sense: Do DDC answer\n");
10422 return 0; /* no DDC support (or no device attached) */
10425 /* Read the entire EDID */
10426 retry = 2;
10427 do {
10428 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10429 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10430 "VGA2 sense: DDC read failed (attempt %d), %s\n",
10431 (3-retry), (retry == 1) ? "giving up" : "retrying");
10432 retry--;
10433 if(retry == 0) return 0xFFFF;
10434 } else break;
10435 } while(1);
10437 /* Analyze EDID. We don't have many chances to
10438 * distinguish a flat panel from a CRT...
10440 switch(DDCdatatype) {
10441 case 1:
10442 if(!(checkedid1(buffer))) {
10443 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10444 "VGA2 sense: EDID corrupt\n");
10445 return 0;
10447 if(buffer[0x14] & 0x80) { /* Display uses digital input */
10448 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10449 "VGA2 sense: Attached display expects digital input\n");
10450 return 0;
10452 SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10453 SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10454 foundcrt = TRUE;
10455 break;
10456 case 3:
10457 case 4:
10458 if(!(checkedid2(buffer))) {
10459 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10460 "VGA2 sense: EDID corrupt\n");
10461 return 0;
10463 if( ((buffer[0x41] & 0x0f) != 0x01) && /* Display does not support analog input */
10464 ((buffer[0x41] & 0x0f) != 0x02) &&
10465 ((buffer[0x41] & 0xf0) != 0x10) &&
10466 ((buffer[0x41] & 0xf0) != 0x20) ) {
10467 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10468 "VGA2 sense: Attached display does not support analog input (0x%02x)\n",
10469 buffer[0x41]);
10470 return 0;
10472 SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10473 SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10474 foundcrt = TRUE;
10475 break;
10478 if(foundcrt) {
10479 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10481 return(0);
10484 #endif
10486 void
10487 SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10489 USHORT tempbl;
10491 tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10492 tempbl = (((tempbl & tempbh) << 8) | tempax);
10493 SiS_SetCH70xx(SiS_Pr,tempbl);
10496 /* Generic I2C functions for Chrontel & DDC --------- */
10498 static void
10499 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10501 SiS_SetSCLKHigh(SiS_Pr);
10502 SiS_WaitRetrace1(SiS_Pr);
10504 SiS_SetSCLKLow(SiS_Pr);
10505 SiS_WaitRetrace1(SiS_Pr);
10508 USHORT
10509 SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
10511 SiS_WaitRetrace1(SiS_Pr);
10512 return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10515 /* Set I2C start condition */
10516 /* This is done by a SD high-to-low transition while SC is high */
10517 static USHORT
10518 SiS_SetStart(SiS_Private *SiS_Pr)
10520 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10521 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10522 SiS_Pr->SiS_DDC_Index,
10523 SiS_Pr->SiS_DDC_NData,
10524 SiS_Pr->SiS_DDC_Data); /* SD->high */
10525 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10526 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10527 SiS_Pr->SiS_DDC_Index,
10528 SiS_Pr->SiS_DDC_NData,
10529 0x00); /* SD->low = start condition */
10530 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10531 return 0;
10534 /* Set I2C stop condition */
10535 /* This is done by a SD low-to-high transition while SC is high */
10536 static USHORT
10537 SiS_SetStop(SiS_Private *SiS_Pr)
10539 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10540 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10541 SiS_Pr->SiS_DDC_Index,
10542 SiS_Pr->SiS_DDC_NData,
10543 0x00); /* SD->low */
10544 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10545 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10546 SiS_Pr->SiS_DDC_Index,
10547 SiS_Pr->SiS_DDC_NData,
10548 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
10549 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
10550 return 0;
10553 /* Write 8 bits of data */
10554 static USHORT
10555 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10557 USHORT i,flag,temp;
10559 flag = 0x80;
10560 for(i=0; i<8; i++) {
10561 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
10562 if(tempax & flag) {
10563 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10564 SiS_Pr->SiS_DDC_Index,
10565 SiS_Pr->SiS_DDC_NData,
10566 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
10567 } else {
10568 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10569 SiS_Pr->SiS_DDC_Index,
10570 SiS_Pr->SiS_DDC_NData,
10571 0x00); /* Write bit (0) to SD */
10573 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
10574 flag >>= 1;
10576 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
10577 return(temp);
10580 static USHORT
10581 SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10583 USHORT i,temp,getdata;
10585 getdata=0;
10586 for(i=0; i<8; i++) {
10587 getdata <<= 1;
10588 SiS_SetSCLKLow(SiS_Pr);
10589 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10590 SiS_Pr->SiS_DDC_Index,
10591 SiS_Pr->SiS_DDC_NData,
10592 SiS_Pr->SiS_DDC_Data);
10593 SiS_SetSCLKHigh(SiS_Pr);
10594 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10595 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
10597 return(getdata);
10600 static USHORT
10601 SiS_SetSCLKLow(SiS_Private *SiS_Pr)
10603 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10604 SiS_Pr->SiS_DDC_Index,
10605 SiS_Pr->SiS_DDC_NClk,
10606 0x00); /* SetSCLKLow() */
10607 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10608 return 0;
10611 static USHORT
10612 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
10614 USHORT temp, watchdog=1000;
10616 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10617 SiS_Pr->SiS_DDC_Index,
10618 SiS_Pr->SiS_DDC_NClk,
10619 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
10620 do {
10621 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10622 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
10623 if (!watchdog) {
10624 #ifdef TWDEBUG
10625 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
10626 #endif
10627 return 0xFFFF;
10629 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10630 return 0;
10633 /* Check I2C acknowledge */
10634 /* Returns 0 if ack ok, non-0 if ack not ok */
10635 static USHORT
10636 SiS_CheckACK(SiS_Private *SiS_Pr)
10638 USHORT tempah;
10640 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
10641 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10642 SiS_Pr->SiS_DDC_Index,
10643 SiS_Pr->SiS_DDC_NData,
10644 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
10645 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
10646 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
10647 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
10648 if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */
10649 else return(0);
10652 /* End of I2C functions ----------------------- */
10655 /* =============== SiS 315/330 O.E.M. ================= */
10657 #ifdef SIS315H
10659 static USHORT
10660 GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10662 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10663 USHORT romptr;
10665 if(HwInfo->jChipType < SIS_330) {
10666 romptr = SISGETROMW(0x128);
10667 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10668 romptr = SISGETROMW(0x12a);
10669 } else {
10670 romptr = SISGETROMW(0x1a8);
10671 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10672 romptr = SISGETROMW(0x1aa);
10674 return(romptr);
10677 static USHORT
10678 GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10680 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10681 USHORT romptr;
10683 if(HwInfo->jChipType < SIS_330) {
10684 romptr = SISGETROMW(0x120);
10685 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10686 romptr = SISGETROMW(0x122);
10687 } else {
10688 romptr = SISGETROMW(0x1a0);
10689 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10690 romptr = SISGETROMW(0x1a2);
10692 return(romptr);
10695 static USHORT
10696 GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10698 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10699 USHORT romptr;
10701 if(HwInfo->jChipType < SIS_330) {
10702 romptr = SISGETROMW(0x114);
10703 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10704 romptr = SISGETROMW(0x11a);
10705 } else {
10706 romptr = SISGETROMW(0x194);
10707 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10708 romptr = SISGETROMW(0x19a);
10710 return(romptr);
10713 static USHORT
10714 GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10716 USHORT index;
10718 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10719 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
10720 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
10721 index >>= 4;
10722 index *= 3;
10723 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10724 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10725 return index;
10730 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
10731 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
10732 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
10733 index--;
10734 index *= 3;
10735 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10736 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10737 return index;
10740 static USHORT
10741 GetLCDPtrIndex(SiS_Private *SiS_Pr)
10743 USHORT index;
10745 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
10746 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10747 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10748 return index;
10751 static USHORT
10752 GetTVPtrIndex(SiS_Private *SiS_Pr)
10754 USHORT index;
10756 index = 0;
10757 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10758 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
10760 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
10762 index <<= 1;
10764 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
10765 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10766 index++;
10769 return index;
10772 static ULONG
10773 GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10775 USHORT index = 0, temp = 0;
10777 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10778 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
10779 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
10780 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
10781 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
10782 index = 4;
10783 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
10784 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
10787 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10788 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
10789 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10790 index += addme;
10791 temp++;
10793 temp += 0x0100;
10795 return(ULONG)(index | (temp << 16));
10798 static ULONG
10799 GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
10801 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
10804 #if 0
10805 static ULONG
10806 GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
10808 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
10810 #endif
10812 static int
10813 GetOEMTVPtr661(SiS_Private *SiS_Pr)
10815 int index = 0;
10817 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
10818 if(SiS_Pr->SiS_ROMNew) {
10819 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
10820 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
10821 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
10822 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
10823 } else {
10824 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
10825 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
10826 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
10827 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
10830 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
10832 return index;
10835 static void
10836 SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10838 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10839 USHORT delay=0,index,myindex,temp,romptr=0;
10840 BOOLEAN dochiptest = TRUE;
10842 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10843 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
10844 } else {
10845 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
10848 /* Find delay (from ROM, internal tables, PCI subsystem) */
10850 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
10852 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10853 romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
10855 if(romptr) delay = ROMAddr[romptr];
10856 else {
10857 delay = 0x04;
10858 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10859 if(IS_SIS650) {
10860 delay = 0x0a;
10861 } else if(IS_SIS740) {
10862 delay = 0x00;
10863 } else if(HwInfo->jChipType < SIS_330) {
10864 delay = 0x0c;
10865 } else {
10866 delay = 0x0c;
10868 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10869 delay = 0x00;
10873 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
10875 BOOLEAN gotitfrompci = FALSE;
10877 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
10879 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10880 if(SiS_Pr->PDC != -1) {
10881 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
10882 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
10883 return;
10885 } else {
10886 if(SiS_Pr->PDCA != -1) {
10887 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10888 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10889 return;
10893 /* Custom Panel? */
10895 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10896 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10897 delay = 0x00;
10898 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10899 delay = 0x20;
10901 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10902 } else {
10903 delay = 0x0c;
10904 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
10905 else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10906 if(IS_SIS740) delay = 0x01;
10907 else delay = 0x03;
10909 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10911 return;
10914 /* This is a piece of typical SiS crap: They code the OEM LCD
10915 * delay into the code, at no defined place in the BIOS.
10916 * We now have to start doing a PCI subsystem check here.
10919 switch(SiS_Pr->SiS_CustomT) {
10920 case CUT_COMPAQ1280:
10921 case CUT_COMPAQ12802:
10922 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10923 gotitfrompci = TRUE;
10924 dochiptest = FALSE;
10925 delay = 0x03;
10927 break;
10928 case CUT_CLEVO1400:
10929 case CUT_CLEVO14002:
10930 gotitfrompci = TRUE;
10931 dochiptest = FALSE;
10932 delay = 0x02;
10933 break;
10934 case CUT_CLEVO1024:
10935 case CUT_CLEVO10242:
10936 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10937 gotitfrompci = TRUE;
10938 dochiptest = FALSE;
10939 delay = 0x33;
10940 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10941 delay &= 0x0f;
10943 break;
10946 /* Could we find it through the PCI ID? If no, use ROM or table */
10948 if(!gotitfrompci) {
10950 index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
10951 myindex = GetLCDPtrIndex(SiS_Pr);
10953 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10955 if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
10957 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10958 /* Always use the second pointer on 650; some BIOSes */
10959 /* still carry old 301 data at the first location */
10960 /* romptr = SISGETROMW(0x120); */
10961 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10962 romptr = SISGETROMW(0x122);
10963 if(!romptr) return;
10964 delay = ROMAddr[(romptr + index)];
10965 } else {
10966 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10969 } else {
10971 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10972 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10973 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10977 } else if(SiS_Pr->SiS_UseROM &&
10978 (!(SiS_Pr->SiS_ROMNew)) &&
10979 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10980 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10981 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
10983 /* Data for 1280x1024 wrong in 301B BIOS */
10984 romptr = GetLCDromptr(SiS_Pr, HwInfo);
10985 if(!romptr) return;
10986 delay = ROMAddr[(romptr + index)];
10988 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10990 if(IS_SIS740) delay = 0x03;
10991 else delay = 0x00;
10993 } else {
10995 delay = SiS310_LCDDelayCompensation_301[myindex];
10996 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10997 if(IS_SIS740) delay = 0x01;
10998 else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10999 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
11000 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
11001 if(IS_SIS740) delay = 0x01; /* ? */
11002 else delay = 0x03;
11003 } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
11004 if(IS_SIS740) delay = 0x01;
11005 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
11010 } /* got it from PCI */
11012 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11013 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
11014 dochiptest = FALSE;
11017 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
11019 index = GetTVPtrIndex(SiS_Pr);
11021 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
11023 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
11025 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
11026 /* Always use the second pointer on 650; some BIOSes */
11027 /* still carry old 301 data at the first location */
11028 /* romptr = SISGETROMW(0x114); */
11029 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
11030 romptr = SISGETROMW(0x11a);
11031 if(!romptr) return;
11032 delay = ROMAddr[romptr + index];
11034 } else {
11036 delay = SiS310_TVDelayCompensation_301B[index];
11040 } else {
11042 switch(SiS_Pr->SiS_CustomT) {
11043 case CUT_COMPAQ1280:
11044 case CUT_COMPAQ12802:
11045 case CUT_CLEVO1400:
11046 case CUT_CLEVO14002:
11047 delay = 0x02;
11048 dochiptest = FALSE;
11049 break;
11050 case CUT_CLEVO1024:
11051 case CUT_CLEVO10242:
11052 delay = 0x03;
11053 dochiptest = FALSE;
11054 break;
11055 default:
11056 delay = SiS310_TVDelayCompensation_651301LV[index];
11057 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
11058 delay = SiS310_TVDelayCompensation_651302LV[index];
11063 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
11065 romptr = GetTVromptr(SiS_Pr, HwInfo);
11066 if(!romptr) return;
11067 delay = ROMAddr[romptr + index];
11069 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11071 delay = SiS310_TVDelayCompensation_LVDS[index];
11073 } else {
11075 delay = SiS310_TVDelayCompensation_301[index];
11076 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11077 if(IS_SIS740) {
11078 delay = SiS310_TVDelayCompensation_740301B[index];
11079 /* LV: use 301 data? BIOS bug? */
11080 } else {
11081 delay = SiS310_TVDelayCompensation_301B[index];
11082 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
11088 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
11089 delay &= 0x0f;
11090 dochiptest = FALSE;
11093 } else return;
11095 /* Write delay */
11097 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11099 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
11101 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
11102 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
11103 delay &= 0x0f;
11104 delay |= 0xb0;
11105 } else if(temp == 6) {
11106 delay &= 0x0f;
11107 delay |= 0xc0;
11108 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
11109 delay = 0x35;
11111 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
11113 } else {
11115 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11119 } else { /* LVDS */
11121 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11122 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11123 } else {
11124 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
11125 delay <<= 4;
11126 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
11127 } else {
11128 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11136 static void
11137 SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11138 USHORT ModeNo,USHORT ModeIdIndex)
11140 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11141 USHORT index,temp,temp1,romptr=0;
11143 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
11145 if(ModeNo<=0x13)
11146 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
11147 else
11148 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
11150 temp = GetTVPtrIndex(SiS_Pr);
11151 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11152 temp1 = temp;
11154 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11155 if(HwInfo->jChipType >= SIS_661) {
11156 temp1 = GetOEMTVPtr661(SiS_Pr);
11157 temp1 >>= 1;
11158 romptr = SISGETROMW(0x260);
11159 if(HwInfo->jChipType >= SIS_760) {
11160 romptr = SISGETROMW(0x360);
11162 } else if(HwInfo->jChipType >= SIS_330) {
11163 romptr = SISGETROMW(0x192);
11164 } else {
11165 romptr = SISGETROMW(0x112);
11169 if(romptr) {
11170 temp1 <<= 1;
11171 temp = ROMAddr[romptr + temp1 + index];
11172 } else {
11173 temp = SiS310_TVAntiFlick1[temp][index];
11175 temp <<= 4;
11177 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
11180 static void
11181 SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11182 USHORT ModeNo,USHORT ModeIdIndex)
11184 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11185 USHORT index,temp,temp1,romptr=0;
11187 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11189 if(ModeNo <= 0x13)
11190 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
11191 else
11192 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
11194 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11195 if(HwInfo->jChipType >= SIS_661) {
11196 romptr = SISGETROMW(0x26c);
11197 if(HwInfo->jChipType >= SIS_760) {
11198 romptr = SISGETROMW(0x36c);
11200 temp1 = GetOEMTVPtr661(SiS_Pr);
11201 temp1 >>= 1;
11202 } else if(HwInfo->jChipType >= SIS_330) {
11203 romptr = SISGETROMW(0x1a4);
11204 } else {
11205 romptr = SISGETROMW(0x124);
11209 if(romptr) {
11210 temp1 <<= 1;
11211 temp = ROMAddr[romptr + temp1 + index];
11212 } else {
11213 temp = SiS310_TVEdge1[temp][index];
11215 temp <<= 5;
11216 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
11219 static void
11220 SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11221 USHORT ModeNo,USHORT ModeIdIndex)
11223 USHORT index, temp, i, j;
11225 if(ModeNo <= 0x13) {
11226 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
11227 } else {
11228 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
11231 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11233 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
11234 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
11235 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
11236 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
11238 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11239 for(i=0x35, j=0; i<=0x38; i++, j++) {
11240 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11242 for(i=0x48; i<=0x4A; i++, j++) {
11243 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11245 } else {
11246 for(i=0x35, j=0; i<=0x38; i++, j++) {
11247 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
11252 static void
11253 SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11254 USHORT ModeNo,USHORT ModeIdIndex)
11256 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11257 USHORT index,temp,i,j,resinfo,romptr=0;
11258 ULONG lindex;
11260 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
11262 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
11263 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
11265 if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
11266 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
11267 lindex <<= 2;
11268 for(j=0, i=0x31; i<=0x34; i++, j++) {
11269 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
11271 return;
11274 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
11275 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
11277 if(ModeNo<=0x13) {
11278 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11279 } else {
11280 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11283 temp = GetTVPtrIndex(SiS_Pr);
11284 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
11285 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
11287 if(SiS_Pr->SiS_UseROM) {
11288 romptr = SISGETROMW(0x116);
11289 if(HwInfo->jChipType >= SIS_330) {
11290 romptr = SISGETROMW(0x196);
11292 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11293 romptr = SISGETROMW(0x11c);
11294 if(HwInfo->jChipType >= SIS_330) {
11295 romptr = SISGETROMW(0x19c);
11297 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11298 romptr = SISGETROMW(0x116);
11299 if(HwInfo->jChipType >= SIS_330) {
11300 romptr = SISGETROMW(0x196);
11305 if(romptr) {
11306 romptr += (temp << 2);
11307 for(j=0, i=0x31; i<=0x34; i++, j++) {
11308 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11310 } else {
11311 index = temp % 2;
11312 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
11313 for(j=0, i=0x31; i<=0x34; i++, j++) {
11314 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
11315 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11316 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11317 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
11318 else
11319 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11323 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11324 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11325 if((resinfo == SIS_RI_640x480) ||
11326 (resinfo == SIS_RI_800x600)) {
11327 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
11328 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
11329 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
11330 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
11331 } else if(resinfo == SIS_RI_1024x768) {
11332 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
11333 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
11334 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
11335 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
11341 static void
11342 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11343 USHORT ModeIdIndex, USHORT RTI)
11345 USHORT delay = 0, romptr = 0, index, lcdpdcindex;
11346 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11348 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11349 return;
11351 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
11352 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
11354 if(SiS_Pr->SiS_ROMNew) {
11355 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
11356 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
11357 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
11358 index = 25;
11359 if(SiS_Pr->UseCustomMode) {
11360 index = SiS_Pr->CSRClock;
11361 } else if(ModeNo > 0x13) {
11362 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
11363 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
11365 if(index < 25) index = 25;
11366 index = ((index / 25) - 1) << 1;
11367 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
11368 index++;
11370 romptr = SISGETROMW(0x104);
11371 delay = ROMAddr[romptr + index];
11372 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
11373 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11374 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11375 } else {
11376 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11377 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11379 return;
11383 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
11385 if(SiS_Pr->UseCustomMode) delay = 0x04;
11386 else if(ModeNo <= 0x13) delay = 0x04;
11387 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
11388 delay |= (delay << 8);
11390 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11392 /* 3. TV */
11394 index = GetOEMTVPtr661(SiS_Pr);
11395 if(SiS_Pr->SiS_ROMNew) {
11396 romptr = SISGETROMW(0x106);
11397 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
11398 delay = ROMAddr[romptr + index];
11399 } else {
11400 delay = 0x04;
11401 if(index > 3) delay = 0;
11404 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11406 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
11408 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
11409 ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
11411 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
11413 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
11414 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
11415 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
11417 } else {
11419 /* TMDS: Set our own, since BIOS has no idea */
11420 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
11421 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11422 switch(SiS_Pr->SiS_LCDResInfo) {
11423 case Panel_1024x768: delay = 0x0008; break;
11424 case Panel_1280x720: delay = 0x0004; break;
11425 case Panel_1280x768:
11426 case Panel_1280x768_2:delay = 0x0004; break;
11427 case Panel_1280x800:
11428 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
11429 case Panel_1280x1024: delay = 0x1e04; break;
11430 case Panel_1400x1050: delay = 0x0004; break;
11431 case Panel_1600x1200: delay = 0x0400; break;
11432 case Panel_1680x1050: delay = 0x0e04; break;
11433 default:
11434 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
11435 delay = 0x0008;
11436 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
11437 delay = 0x1e04;
11438 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
11439 delay = 0x0004;
11440 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
11441 delay = 0x0400;
11442 } else
11443 delay = 0x0e04;
11444 break;
11448 /* Override by detected or user-set values */
11449 /* (but only if, for some reason, we can't read value from BIOS) */
11450 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
11451 delay = SiS_Pr->PDC & 0x1f;
11453 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
11454 delay = (SiS_Pr->PDCA & 0x1f) << 8;
11461 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11462 delay >>= 8;
11463 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11464 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11465 } else {
11466 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11467 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11471 static void
11472 SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
11474 USHORT infoflag;
11475 UCHAR temp;
11477 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11479 if(ModeNo <= 0x13) {
11480 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
11481 } else if(SiS_Pr->UseCustomMode) {
11482 infoflag = SiS_Pr->CInfoFlag;
11483 } else {
11484 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
11487 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11488 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
11491 infoflag &= 0xc0;
11493 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11494 temp = (infoflag >> 6) | 0x0c;
11495 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
11496 temp ^= 0x04;
11497 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
11499 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
11500 } else {
11501 temp = 0x30;
11502 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
11503 temp |= infoflag;
11504 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
11505 temp = 0;
11506 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
11507 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
11509 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
11515 static void
11516 SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11518 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11519 USHORT romptr, temp1, temp2;
11521 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11522 if(SiS_Pr->LVDSHL != -1) {
11523 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11527 if(SiS_Pr->SiS_ROMNew) {
11529 if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
11530 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11531 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
11532 temp2 = 0xfc;
11533 if(SiS_Pr->LVDSHL != -1) {
11534 temp1 &= 0xfc;
11535 temp2 = 0xf3;
11537 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
11539 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11540 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
11541 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
11548 static void
11549 SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11550 USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)
11552 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
11553 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11554 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11555 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11556 SetPanelParms661(SiS_Pr,HwInfo);
11558 } else {
11559 SetDelayComp(SiS_Pr,HwInfo,ModeNo);
11562 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11563 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11564 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11565 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11566 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11567 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11572 static void
11573 SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11574 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
11576 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11578 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11580 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11581 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11582 SetPanelParms661(SiS_Pr,HwInfo);
11585 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11586 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11587 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11588 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11589 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11590 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11596 /* FinalizeLCD
11597 * This finalizes some CRT2 registers for the very panel used.
11598 * If we have a backup if these registers, we use it; otherwise
11599 * we set the register according to most BIOSes. However, this
11600 * function looks quite different in every BIOS, so you better
11601 * pray that we have a backup...
11603 static void
11604 SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11605 PSIS_HW_INFO HwInfo)
11607 USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
11608 USHORT resinfo,modeflag;
11610 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
11611 if(SiS_Pr->SiS_ROMNew) return;
11613 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11614 if(SiS_Pr->LVDSHL != -1) {
11615 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11619 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11620 if(SiS_Pr->UseCustomMode) return;
11622 switch(SiS_Pr->SiS_CustomT) {
11623 case CUT_COMPAQ1280:
11624 case CUT_COMPAQ12802:
11625 case CUT_CLEVO1400:
11626 case CUT_CLEVO14002:
11627 return;
11630 if(ModeNo <= 0x13) {
11631 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11632 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11633 } else {
11634 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11635 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11638 if(IS_SIS650) {
11639 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
11640 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11641 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
11642 } else {
11643 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
11648 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11649 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11650 /* Maybe all panels? */
11651 if(SiS_Pr->LVDSHL == -1) {
11652 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11654 return;
11658 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
11659 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11660 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11661 if(SiS_Pr->LVDSHL == -1) {
11662 /* Maybe all panels? */
11663 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11665 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11666 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11667 if(tempch == 3) {
11668 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11669 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11670 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11671 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11674 return;
11679 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11680 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11681 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
11682 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
11683 #ifdef SET_EMI
11684 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
11685 #endif
11686 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
11688 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
11689 if(SiS_Pr->LVDSHL == -1) {
11690 /* Maybe ACER only? */
11691 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11694 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11695 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11696 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
11697 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
11698 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11699 if(tempch == 0x03) {
11700 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11701 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11702 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11703 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11705 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
11706 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
11707 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
11708 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
11709 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
11710 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
11711 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
11712 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
11713 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
11714 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
11715 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
11716 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
11717 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
11718 if(ModeNo <= 0x13) {
11719 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
11720 if((resinfo == 0) || (resinfo == 2)) return;
11721 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
11722 if((resinfo == 1) || (resinfo == 3)) return;
11724 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11725 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
11726 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
11727 #if 0
11728 tempbx = 806; /* 0x326 */ /* other older BIOSes */
11729 tempbx--;
11730 temp = tempbx & 0xff;
11731 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
11732 temp = (tempbx >> 8) & 0x03;
11733 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
11734 #endif
11736 } else if(ModeNo <= 0x13) {
11737 if(ModeNo <= 1) {
11738 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
11739 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
11740 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11741 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11743 if(!(modeflag & HalfDCLK)) {
11744 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
11745 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
11746 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
11747 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
11748 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
11749 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11750 if(ModeNo == 0x12) {
11751 switch(tempch) {
11752 case 0:
11753 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11754 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11755 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
11756 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11757 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
11758 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11759 break;
11760 case 2:
11761 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11762 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11763 break;
11764 case 3:
11765 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11766 break;
11772 } else {
11773 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
11774 tempcl &= 0x0f;
11775 tempbh &= 0x70;
11776 tempbh >>= 4;
11777 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
11778 tempbx = (tempbh << 8) | tempbl;
11779 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11780 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
11781 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
11782 tempbx = 770;
11783 } else {
11784 if(tempbx > 770) tempbx = 770;
11785 if(SiS_Pr->SiS_VGAVDE < 600) {
11786 tempax = 768 - SiS_Pr->SiS_VGAVDE;
11787 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
11788 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
11789 tempbx -= tempax;
11792 } else return;
11794 temp = tempbx & 0xff;
11795 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
11796 temp = ((tempbx & 0xff00) >> 4) | tempcl;
11797 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
11802 #endif
11804 /* ================= SiS 300 O.E.M. ================== */
11806 #ifdef SIS300
11808 static void
11809 SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11810 USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
11812 USHORT crt2crtc=0, modeflag, myindex=0;
11813 UCHAR temp;
11814 int i;
11816 if(ModeNo <= 0x13) {
11817 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11818 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
11819 } else {
11820 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11821 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
11824 crt2crtc &= 0x3f;
11826 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
11827 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
11830 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
11831 if(modeflag & HalfDCLK) myindex = 1;
11833 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
11834 for(i=0; i<7; i++) {
11835 if(barco_p1[myindex][crt2crtc][i][0]) {
11836 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
11837 barco_p1[myindex][crt2crtc][i][0],
11838 barco_p1[myindex][crt2crtc][i][2],
11839 barco_p1[myindex][crt2crtc][i][1]);
11843 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
11844 if(temp & 0x80) {
11845 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
11846 temp++;
11847 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
11852 static USHORT
11853 GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
11855 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11856 USHORT tempbx=0,romptr=0;
11857 UCHAR customtable300[] = {
11858 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11859 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11861 UCHAR customtable630[] = {
11862 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11863 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11866 if(HwInfo->jChipType == SIS_300) {
11868 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11869 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11870 tempbx -= 2;
11871 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11872 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11873 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11875 if(SiS_Pr->SiS_UseROM) {
11876 if(ROMAddr[0x235] & 0x80) {
11877 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11878 if(Flag) {
11879 romptr = SISGETROMW(0x255);
11880 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11881 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11882 if(tempbx == 0xFF) return 0xFFFF;
11884 tempbx <<= 1;
11885 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11889 } else {
11891 if(Flag) {
11892 if(SiS_Pr->SiS_UseROM) {
11893 romptr = SISGETROMW(0x255);
11894 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11895 else tempbx = 0xff;
11896 } else {
11897 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11899 if(tempbx == 0xFF) return 0xFFFF;
11900 tempbx <<= 2;
11901 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11902 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11903 return tempbx;
11905 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11906 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11907 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11911 return tempbx;
11914 static void
11915 SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11916 USHORT ModeNo,USHORT ModeIdIndex)
11918 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11919 USHORT index,temp,romptr=0;
11921 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11923 if(SiS_Pr->SiS_UseROM) {
11924 if(!(ROMAddr[0x237] & 0x01)) return;
11925 if(!(ROMAddr[0x237] & 0x02)) return;
11926 romptr = SISGETROMW(0x24b);
11929 /* The Panel Compensation Delay should be set according to tables
11930 * here. Unfortunately, various BIOS versions don't case about
11931 * a uniform way using eg. ROM byte 0x220, but use different
11932 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11933 * Thus we don't set this if the user select a custom pdc or if
11934 * we otherwise detected a valid pdc.
11936 if(SiS_Pr->PDC != -1) return;
11938 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
11940 if(SiS_Pr->UseCustomMode)
11941 index = 0;
11942 else
11943 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11945 if(HwInfo->jChipType != SIS_300) {
11946 if(romptr) {
11947 romptr += (temp * 2);
11948 romptr = SISGETROMW(romptr);
11949 romptr += index;
11950 temp = ROMAddr[romptr];
11951 } else {
11952 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11953 temp = SiS300_OEMLCDDelay2[temp][index];
11954 } else {
11955 temp = SiS300_OEMLCDDelay3[temp][index];
11958 } else {
11959 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11960 if(romptr) {
11961 romptr += (temp * 2);
11962 romptr = SISGETROMW(romptr);
11963 romptr += index;
11964 temp = ROMAddr[romptr];
11965 } else {
11966 temp = SiS300_OEMLCDDelay5[temp][index];
11968 } else {
11969 if(SiS_Pr->SiS_UseROM) {
11970 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11971 if(romptr) {
11972 romptr += (temp * 2);
11973 romptr = SISGETROMW(romptr);
11974 romptr += index;
11975 temp = ROMAddr[romptr];
11976 } else {
11977 temp = SiS300_OEMLCDDelay4[temp][index];
11979 } else {
11980 temp = SiS300_OEMLCDDelay4[temp][index];
11984 temp &= 0x3c;
11985 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11988 static void
11989 SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11990 USHORT ModeNo,USHORT ModeIdIndex)
11992 #if 0 /* Unfinished; Data table missing */
11993 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11994 USHORT index,temp;
11996 if((SiS_Pr->SiS_UseROM) {
11997 if(!(ROMAddr[0x237] & 0x01)) return;
11998 if(!(ROMAddr[0x237] & 0x04)) return;
11999 /* No rom pointer in BIOS header! */
12002 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
12003 if(temp = 0xFFFF) return;
12005 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
12006 for(i=0x14, j=0; i<=0x17; i++, j++) {
12007 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
12009 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
12011 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
12012 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
12013 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
12014 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
12015 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
12016 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
12018 #endif
12021 static USHORT
12022 GetOEMTVPtr(SiS_Private *SiS_Pr)
12024 USHORT index;
12026 index = 0;
12027 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
12028 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12029 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
12030 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
12031 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
12032 } else {
12033 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
12034 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
12036 return index;
12039 static void
12040 SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12041 USHORT ModeNo,USHORT ModeIdIndex)
12043 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12044 USHORT index,temp,romptr=0;
12046 if(SiS_Pr->SiS_UseROM) {
12047 if(!(ROMAddr[0x238] & 0x01)) return;
12048 if(!(ROMAddr[0x238] & 0x02)) return;
12049 romptr = SISGETROMW(0x241);
12052 temp = GetOEMTVPtr(SiS_Pr);
12054 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
12056 if(romptr) {
12057 romptr += (temp * 2);
12058 romptr = SISGETROMW(romptr);
12059 romptr += index;
12060 temp = ROMAddr[romptr];
12061 } else {
12062 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12063 temp = SiS300_OEMTVDelay301[temp][index];
12064 } else {
12065 temp = SiS300_OEMTVDelayLVDS[temp][index];
12068 temp &= 0x3c;
12069 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
12072 static void
12073 SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12074 USHORT ModeNo, USHORT ModeIdIndex)
12076 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12077 USHORT index,temp,romptr=0;
12079 if(SiS_Pr->SiS_UseROM) {
12080 if(!(ROMAddr[0x238] & 0x01)) return;
12081 if(!(ROMAddr[0x238] & 0x04)) return;
12082 romptr = SISGETROMW(0x243);
12085 temp = GetOEMTVPtr(SiS_Pr);
12087 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
12089 if(romptr) {
12090 romptr += (temp * 2);
12091 romptr = SISGETROMW(romptr);
12092 romptr += index;
12093 temp = ROMAddr[romptr];
12094 } else {
12095 temp = SiS300_OEMTVFlicker[temp][index];
12097 temp &= 0x70;
12098 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
12101 static void
12102 SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12103 USHORT ModeNo,USHORT ModeIdIndex)
12105 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12106 USHORT index,i,j,temp,romptr=0;
12108 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
12110 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
12112 if(SiS_Pr->SiS_UseROM) {
12113 if(!(ROMAddr[0x238] & 0x01)) return;
12114 if(!(ROMAddr[0x238] & 0x08)) return;
12115 romptr = SISGETROMW(0x245);
12118 temp = GetOEMTVPtr(SiS_Pr);
12120 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
12122 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12123 for(i=0x31, j=0; i<=0x34; i++, j++) {
12124 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
12126 } else {
12127 if(romptr) {
12128 romptr += (temp * 2);
12129 romptr = SISGETROMW(romptr);
12130 romptr += (index * 4);
12131 for(i=0x31, j=0; i<=0x34; i++, j++) {
12132 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12134 } else {
12135 for(i=0x31, j=0; i<=0x34; i++, j++) {
12136 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
12142 static void
12143 SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12144 USHORT ModeNo,USHORT ModeIdIndex)
12146 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12147 USHORT index,temp,i,j,romptr=0;
12149 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
12151 if(SiS_Pr->SiS_UseROM) {
12152 if(!(ROMAddr[0x238] & 0x01)) return;
12153 if(!(ROMAddr[0x238] & 0x10)) return;
12154 romptr = SISGETROMW(0x247);
12157 temp = GetOEMTVPtr(SiS_Pr);
12159 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
12160 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
12161 /* NTSCJ uses NTSC filters */
12163 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
12165 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12166 for(i=0x35, j=0; i<=0x38; i++, j++) {
12167 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12169 for(i=0x48; i<=0x4A; i++, j++) {
12170 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12172 } else {
12173 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
12174 romptr += (temp * 2);
12175 romptr = SISGETROMW(romptr);
12176 romptr += (index * 4);
12177 for(i=0x35, j=0; i<=0x38; i++, j++) {
12178 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12180 } else {
12181 for(i=0x35, j=0; i<=0x38; i++, j++) {
12182 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
12188 static USHORT
12189 SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
12191 USHORT ModeIdIndex;
12192 UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
12194 if(*ModeNo <= 5) *ModeNo |= 1;
12196 for(ModeIdIndex=0; ; ModeIdIndex++) {
12197 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
12198 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
12201 if(*ModeNo != 0x07) {
12202 if(*ModeNo > 0x03) return ModeIdIndex;
12203 if(VGAINFO & 0x80) return ModeIdIndex;
12204 ModeIdIndex++;
12207 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
12208 /* else 350 lines */
12209 return ModeIdIndex;
12212 static void
12213 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12214 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
12216 USHORT OEMModeIdIndex=0;
12218 if(!SiS_Pr->UseCustomMode) {
12219 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
12220 if(!(OEMModeIdIndex)) return;
12223 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
12224 SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12225 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
12226 SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12229 if(SiS_Pr->UseCustomMode) return;
12230 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
12231 SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
12232 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12233 SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12234 SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12235 SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12239 #endif