initial commit with v2.6.9
[linux-2.6.9-moxart.git] / drivers / video / sis / init301.c
blobe4b1aa297ea870560ceadb737df42581c1e91a21
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);
90 /*********************************************/
91 /* HELPER: Lock/Unlock CRT2 */
92 /*********************************************/
94 void
95 SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
97 if(HwInfo->jChipType >= SIS_315H)
98 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
99 else
100 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
103 void
104 SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
106 if(HwInfo->jChipType >= SIS_315H)
107 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
108 else
109 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
112 /*********************************************/
113 /* HELPER: Write SR11 */
114 /*********************************************/
116 static void
117 SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
119 if(HwInfo->jChipType >= SIS_661) {
120 DataAND &= 0x0f;
121 DataOR &= 0x0f;
123 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
126 /*********************************************/
127 /* HELPER: Get Pointer to LCD structure */
128 /*********************************************/
130 #ifdef SIS315H
131 static UCHAR *
132 GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
134 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
135 UCHAR *myptr = NULL;
136 USHORT romindex = 0;
138 /* Use the BIOS tables only for LVDS panels; DVI is unreliable
139 * due to the variaty of panels the BIOS doesn't know about.
142 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
143 myptr = (UCHAR *)SiS_LCDStruct661;
144 romindex = SISGETROMW(0x100);
145 if(romindex) {
146 romindex += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x7d) & 0x1f) * 26);
147 myptr = &ROMAddr[romindex];
150 return myptr;
153 static USHORT
154 GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
156 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
157 USHORT romptr = 0;
159 /* Use the BIOS tables only for LVDS panels; DVI is unreliable
160 * due to the variaty of panels the BIOS doesn't know about.
163 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
164 romptr = SISGETROMW(0x102);
165 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
168 return(romptr);
170 #endif
172 /*********************************************/
173 /* Adjust Rate for CRT2 */
174 /*********************************************/
176 static BOOLEAN
177 SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
178 USHORT RefreshRateTableIndex, USHORT *i,
179 PSIS_HW_INFO HwInfo)
181 USHORT checkmask=0,modeid,infoflag;
183 modeid = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
185 if(SiS_Pr->SiS_VBType & VB_SISVB) {
187 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
189 checkmask |= SupportRAMDAC2;
190 if(HwInfo->jChipType >= SIS_315H) {
191 checkmask |= SupportRAMDAC2_135;
192 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
193 checkmask |= SupportRAMDAC2_162;
194 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
195 checkmask |= SupportRAMDAC2_202;
200 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
202 checkmask |= SupportLCD;
203 if(HwInfo->jChipType >= SIS_315H) {
204 if(SiS_Pr->SiS_VBType & VB_SISVB) {
205 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
206 if(modeid == 0x2e) checkmask |= Support64048060Hz;
211 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
213 checkmask |= SupportHiVision;
215 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
217 checkmask |= SupportTV;
218 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
219 checkmask |= SupportTV1024;
220 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
221 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
222 checkmask |= SupportYPbPr750p;
229 } else { /* LVDS */
231 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
232 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
233 checkmask |= SupportCHTV;
237 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
238 checkmask |= SupportLCD;
243 /* Look backwards in table for matching CRT2 mode */
244 for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == modeid; (*i)--) {
245 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
246 if(infoflag & checkmask) return TRUE;
247 if((*i) == 0) break;
250 /* Look through the whole mode-section of the table from the beginning
251 * for a matching CRT2 mode if no mode was found yet.
253 for((*i) = 0; ; (*i)++) {
254 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != modeid) {
255 return FALSE;
257 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
258 if(infoflag & checkmask) return TRUE;
260 return TRUE;
263 /*********************************************/
264 /* Get rate index */
265 /*********************************************/
267 USHORT
268 SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
269 PSIS_HW_INFO HwInfo)
271 SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
272 0x01, 0x01, 0x01, 0x01,
273 0x01, 0x01, 0x01, 0x01,
274 0x01, 0x01, 0x01, 0x01,
275 0x00, 0x00, 0x00, 0x00 };
276 USHORT RefreshRateTableIndex,i,backup_i;
277 USHORT modeflag,index,temp,backupindex;
279 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
280 if(ModeNo == 0xfe) return 0;
282 if(ModeNo <= 0x13) {
283 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
284 } else {
285 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
288 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
289 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
290 if(modeflag & HalfDCLK) return 0;
294 if(ModeNo < 0x14) return 0xFFFF;
296 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
297 backupindex = index;
299 if(index > 0) index--;
301 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
302 if(SiS_Pr->SiS_VBType & VB_SISVB) {
303 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
304 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
305 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
307 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
308 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
309 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
310 if(index > temp) index = temp;
313 } else {
314 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
315 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
316 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
321 RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
322 ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
324 if(HwInfo->jChipType >= SIS_315H) {
325 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
326 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
327 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
328 if(backupindex <= 1) RefreshRateTableIndex++;
333 i = 0;
334 do {
335 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
336 temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
337 temp &= ModeInfoFlag;
338 if(temp < SiS_Pr->SiS_ModeType) break;
339 i++;
340 index--;
341 } while(index != 0xFFFF);
343 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
344 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
345 temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
346 if(temp & InterlaceMode) i++;
350 i--;
352 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
353 backup_i = i;
354 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &i, HwInfo))) {
355 i = backup_i;
359 return(RefreshRateTableIndex + i);
362 /*********************************************/
363 /* STORE CRT2 INFO in CR34 */
364 /*********************************************/
366 static void
367 SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
369 USHORT temp1,temp2;
371 /* Store CRT1 ModeNo in CR34 */
372 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
373 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
374 temp2 = ~(SetInSlaveMode >> 8);
375 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
378 /*********************************************/
379 /* HELPER: GET SOME DATA FROM BIOS ROM */
380 /*********************************************/
382 #ifdef SIS300
383 static BOOLEAN
384 SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
386 UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
387 USHORT temp,temp1;
389 if(SiS_Pr->SiS_UseROM) {
390 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
391 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
392 temp1 = SISGETROMW(0x23b);
393 if(temp1 & temp) return TRUE;
396 return FALSE;
399 static BOOLEAN
400 SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
402 UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
403 USHORT temp,temp1;
405 if(SiS_Pr->SiS_UseROM) {
406 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
407 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
408 temp1 = SISGETROMW(0x23d);
409 if(temp1 & temp) return TRUE;
412 return FALSE;
414 #endif
416 /*********************************************/
417 /* HELPER: DELAY FUNCTIONS */
418 /*********************************************/
420 void
421 SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
423 USHORT i, j;
425 for(i=0; i<delaytime; i++) {
426 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
430 #if defined(SIS300) || defined(SIS315H)
431 static void
432 SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
434 USHORT temp,flag;
436 flag = SiS_GetRegByte(0x61) & 0x10;
438 while(delay) {
439 temp = SiS_GetRegByte(0x61) & 0x10;
440 if(temp == flag) continue;
441 flag = temp;
442 delay--;
445 #endif
447 #ifdef SIS315H
448 static void
449 SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
451 while(delay--) {
452 SiS_GenericDelay(SiS_Pr,0x19df);
455 #endif
457 #if defined(SIS300) || defined(SIS315H)
458 static void
459 SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
461 while(delay--) {
462 SiS_GenericDelay(SiS_Pr,0x42);
465 #endif
467 static void
468 SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
470 #if defined(SIS300) || defined(SIS315H)
471 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
472 USHORT PanelID, DelayIndex, Delay=0;
473 #endif
475 if(HwInfo->jChipType < SIS_315H) {
477 #ifdef SIS300
479 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
480 if(SiS_Pr->SiS_VBType & VB_SISVB) {
481 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
483 DelayIndex = PanelID >> 4;
484 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
485 Delay = 3;
486 } else {
487 if(DelayTime >= 2) DelayTime -= 2;
488 if(!(DelayTime & 0x01)) {
489 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
490 } else {
491 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
493 if(SiS_Pr->SiS_UseROM) {
494 if(ROMAddr[0x220] & 0x40) {
495 if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
496 else Delay = (USHORT)ROMAddr[0x226];
500 SiS_ShortDelay(SiS_Pr, Delay);
502 #endif /* SIS300 */
504 } else {
506 #ifdef SIS315H
508 if((HwInfo->jChipType >= SIS_661) ||
509 (HwInfo->jChipType <= SIS_315PRO) ||
510 (HwInfo->jChipType == SIS_330)) {
512 if(!(DelayTime & 0x01)) {
513 SiS_DDC2Delay(SiS_Pr, 0x1000);
514 } else {
515 SiS_DDC2Delay(SiS_Pr, 0x4000);
518 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
519 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
520 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
522 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
523 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
524 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
525 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
527 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
528 DelayIndex = PanelID & 0x0f;
529 } else {
530 DelayIndex = PanelID >> 4;
532 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
533 Delay = 3;
534 } else {
535 if(DelayTime >= 2) DelayTime -= 2;
536 if(!(DelayTime & 0x01)) {
537 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
538 } else {
539 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
541 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
542 if(ROMAddr[0x13c] & 0x40) {
543 if(!(DelayTime & 0x01)) {
544 Delay = (USHORT)ROMAddr[0x17e];
545 } else {
546 Delay = (USHORT)ROMAddr[0x17f];
551 SiS_ShortDelay(SiS_Pr, Delay);
554 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
556 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
557 if(!(DelayTime & 0x01)) {
558 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
559 } else {
560 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
562 Delay <<= 8;
563 SiS_DDC2Delay(SiS_Pr, Delay);
567 #endif /* SIS315H */
572 #ifdef SIS315H
573 static void
574 SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
575 USHORT DelayTime, USHORT DelayLoop)
577 int i;
578 for(i=0; i<DelayLoop; i++) {
579 SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
582 #endif
584 /*********************************************/
585 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
586 /*********************************************/
588 void
589 SiS_WaitRetrace1(SiS_Private *SiS_Pr)
591 USHORT watchdog;
593 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
594 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
596 watchdog = 65535;
597 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
598 watchdog = 65535;
599 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
602 #if defined(SIS300) || defined(SIS315H)
603 static void
604 SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
606 USHORT watchdog;
608 watchdog = 65535;
609 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
610 watchdog = 65535;
611 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
613 #endif
615 static void
616 SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
618 if(HwInfo->jChipType < SIS_315H) {
619 #ifdef SIS300
620 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
621 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
623 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
624 SiS_WaitRetrace1(SiS_Pr);
625 } else {
626 SiS_WaitRetrace2(SiS_Pr, 0x25);
628 #endif
629 } else {
630 #ifdef SIS315H
631 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
632 SiS_WaitRetrace1(SiS_Pr);
633 } else {
634 SiS_WaitRetrace2(SiS_Pr, 0x30);
636 #endif
640 static void
641 SiS_VBWait(SiS_Private *SiS_Pr)
643 USHORT tempal,temp,i,j;
645 temp = 0;
646 for(i=0; i<3; i++) {
647 for(j=0; j<100; j++) {
648 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
649 if(temp & 0x01) {
650 if((tempal & 0x08)) continue;
651 else break;
652 } else {
653 if(!(tempal & 0x08)) continue;
654 else break;
657 temp ^= 0x01;
661 static void
662 SiS_VBLongWait(SiS_Private *SiS_Pr)
664 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
665 SiS_VBWait(SiS_Pr);
666 } else {
667 SiS_WaitRetrace1(SiS_Pr);
671 /*********************************************/
672 /* HELPER: MISC */
673 /*********************************************/
675 #ifdef SIS300
676 static BOOLEAN
677 SiS_Is301B(SiS_Private *SiS_Pr)
679 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
680 return FALSE;
682 #endif
684 static BOOLEAN
685 SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
687 USHORT flag;
689 if(HwInfo->jChipType == SIS_730) {
690 flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
691 if(flag & 0x20) return TRUE;
693 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
694 if(flag & 0x20) return TRUE;
695 return FALSE;
698 BOOLEAN
699 SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
701 #ifdef SIS315H
702 USHORT flag;
704 if(HwInfo->jChipType >= SIS_315H) {
705 if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
706 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
707 if(flag & EnableDualEdge) return TRUE;
710 #endif
711 return FALSE;
714 BOOLEAN
715 SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
717 #ifdef SIS315H
718 USHORT flag;
720 if(HwInfo->jChipType >= SIS_315H) {
721 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
722 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
724 #endif
725 return FALSE;
728 #ifdef SIS315H
729 static BOOLEAN
730 SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
732 if(SiS_IsVAMode(SiS_Pr,HwInfo)) return TRUE;
733 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
734 return FALSE;
736 #endif
738 static BOOLEAN
739 SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
741 #ifdef SIS315H
742 if(HwInfo->jChipType >= SIS_315H) {
743 if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
744 (SiS_IsVAMode(SiS_Pr, HwInfo))) {
745 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
748 #endif
749 return FALSE;
752 #ifdef SIS315H
753 static BOOLEAN
754 SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
756 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
757 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
758 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
760 return FALSE;
762 #endif
764 #ifdef SIS315H
765 static BOOLEAN
766 SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
768 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
769 return FALSE;
771 #endif
773 #ifdef SIS315H
774 static BOOLEAN
775 SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
777 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
778 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
780 return FALSE;
782 #endif
784 #ifdef SIS315H
785 static BOOLEAN
786 SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
788 USHORT flag;
790 if(HwInfo->jChipType == SIS_650) {
791 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
792 flag &= 0xF0;
793 /* Check for revision != A0 only */
794 if((flag == 0xe0) || (flag == 0xc0) ||
795 (flag == 0xb0) || (flag == 0x90)) return FALSE;
796 } else if(HwInfo->jChipType >= SIS_661) return FALSE;
797 return TRUE;
799 #endif
801 #ifdef SIS315H
802 static BOOLEAN
803 SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
805 USHORT flag;
807 if(HwInfo->jChipType >= SIS_315H) {
808 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
809 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
811 return FALSE;
813 #endif
815 #ifdef SIS315H
816 static BOOLEAN
817 SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
819 USHORT flag;
821 if(HwInfo->jChipType >= SIS_315H) {
822 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
823 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 */
825 return FALSE;
827 #endif
829 #ifdef SIS315H
830 static BOOLEAN
831 SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
833 USHORT flag;
835 if(HwInfo->jChipType >= SIS_315H) {
836 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
837 if(flag & SetCRT2ToTV) return TRUE;
838 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
839 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
840 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
841 } else {
842 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
843 if(flag & SetCRT2ToTV) return TRUE;
845 return FALSE;
847 #endif
849 #ifdef SIS315H
850 static BOOLEAN
851 SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
853 USHORT flag;
855 if(HwInfo->jChipType >= SIS_315H) {
856 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
857 if(flag & SetCRT2ToLCD) return TRUE;
858 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
859 if(flag & SetToLCDA) return TRUE;
860 } else {
861 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
862 if(flag & SetCRT2ToLCD) return TRUE;
864 return FALSE;
866 #endif
868 static BOOLEAN
869 SiS_BridgeIsOn(SiS_Private *SiS_Pr)
871 USHORT flag;
873 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
874 return TRUE;
875 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
876 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
877 if((flag == 1) || (flag == 2)) return TRUE;
879 return FALSE;
882 static BOOLEAN
883 SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
885 USHORT flag;
887 if(SiS_BridgeIsOn(SiS_Pr)) {
888 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
889 if(HwInfo->jChipType < SIS_315H) {
890 flag &= 0xa0;
891 if((flag == 0x80) || (flag == 0x20)) return TRUE;
892 } else {
893 flag &= 0x50;
894 if((flag == 0x40) || (flag == 0x10)) return TRUE;
897 return FALSE;
900 static BOOLEAN
901 SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
903 USHORT flag1;
905 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
906 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
907 return FALSE;
910 /*********************************************/
911 /* GET VIDEO BRIDGE CONFIG INFO */
912 /*********************************************/
914 /* Setup general purpose IO for Chrontel communication */
915 void
916 SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
918 unsigned long acpibase;
919 unsigned short temp;
921 if(!(SiS_Pr->SiS_ChSW)) return;
923 #ifndef LINUX_XF86
924 SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */
925 acpibase = SiS_GetRegLong(0xcfc);
926 #else
927 acpibase = pciReadLong(0x00000800, 0x74);
928 #endif
929 acpibase &= 0xFFFF;
930 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
931 temp &= 0xFEFF;
932 SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
933 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
934 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
935 temp &= 0xFEFF;
936 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
937 SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
938 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
941 void
942 SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
943 PSIS_HW_INFO HwInfo, int checkcrt2mode)
945 USHORT tempax,tempbx,temp;
946 USHORT modeflag, resinfo=0;
948 if(ModeNo <= 0x13) {
949 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
950 } else if(SiS_Pr->UseCustomMode) {
951 modeflag = SiS_Pr->CModeFlag;
952 } else {
953 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
954 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
957 SiS_Pr->SiS_SetFlag = 0;
959 SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
961 tempbx = 0;
962 if(SiS_BridgeIsOn(SiS_Pr)) {
963 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
964 #if 0
965 if(HwInfo->jChipType < SIS_661) {
966 /* NO - YPbPr not set yet ! */
967 if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
968 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
969 temp |= SetCRT2ToHiVision; /* 0x80 */
971 if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
972 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
973 temp |= SetCRT2ToSVIDEO; /* 0x08 */
976 #endif
977 tempbx |= temp;
978 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
979 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
980 tempbx |= tempax;
982 #ifdef SIS315H
983 if(HwInfo->jChipType >= SIS_315H) {
984 if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
985 if(ModeNo == 0x03) {
986 /* Mode 0x03 is never in driver mode */
987 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
989 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
990 /* Reset LCDA setting if not driver mode */
991 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
993 if(IS_SIS650) {
994 if(SiS_Pr->SiS_UseLCDA) {
995 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
996 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
997 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1002 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1003 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1004 tempbx |= SetCRT2ToLCDA;
1008 if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1009 tempbx &= ~(SetCRT2ToRAMDAC);
1012 if(HwInfo->jChipType >= SIS_661) {
1013 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1014 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1015 if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1016 if(temp & 0x04) {
1017 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1018 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1019 else tempbx |= SetCRT2ToYPbPr525750;
1021 } else if(SiS_Pr->SiS_VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B)) {
1022 if(temp & 0x04) {
1023 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1024 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1029 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1030 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1031 if(temp & SetToLCDA) {
1032 tempbx |= SetCRT2ToLCDA;
1034 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1035 if(temp & EnableCHYPbPr) {
1036 tempbx |= SetCRT2ToCHYPbPr;
1042 #endif /* SIS315H */
1044 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1045 temp = SetCRT2ToSVIDEO |
1046 SetCRT2ToAVIDEO |
1047 SetCRT2ToSCART |
1048 SetCRT2ToLCDA |
1049 SetCRT2ToLCD |
1050 SetCRT2ToRAMDAC |
1051 SetCRT2ToHiVision |
1052 SetCRT2ToYPbPr525750;
1053 } else {
1054 if(HwInfo->jChipType >= SIS_315H) {
1055 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1056 temp = SetCRT2ToAVIDEO |
1057 SetCRT2ToSVIDEO |
1058 SetCRT2ToSCART |
1059 SetCRT2ToLCDA |
1060 SetCRT2ToLCD |
1061 SetCRT2ToCHYPbPr;
1062 } else {
1063 temp = SetCRT2ToLCDA |
1064 SetCRT2ToLCD;
1066 } else {
1067 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1068 temp = SetCRT2ToTV | SetCRT2ToLCD;
1069 } else {
1070 temp = SetCRT2ToLCD;
1075 if(!(tempbx & temp)) {
1076 tempax = DisableCRT2Display;
1077 tempbx = 0;
1080 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1081 USHORT clearmask = ( DriverMode |
1082 DisableCRT2Display |
1083 LoadDACFlag |
1084 SetNotSimuMode |
1085 SetInSlaveMode |
1086 SetPALTV |
1087 SwitchCRT2 |
1088 SetSimuScanMode );
1089 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1090 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1091 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1092 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1093 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1094 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1095 } else {
1096 if(HwInfo->jChipType >= SIS_315H) {
1097 if(tempbx & SetCRT2ToLCDA) {
1098 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1101 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1102 if(tempbx & SetCRT2ToTV) {
1103 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1106 if(tempbx & SetCRT2ToLCD) {
1107 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1109 if(HwInfo->jChipType >= SIS_315H) {
1110 if(tempbx & SetCRT2ToLCDA) {
1111 tempbx |= SetCRT2ToLCD;
1116 if(tempax & DisableCRT2Display) {
1117 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1118 tempbx = SetSimuScanMode | DisableCRT2Display;
1122 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1124 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1125 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1126 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1127 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1128 modeflag &= (~CRT2Mode);
1132 if(!(tempbx & SetSimuScanMode)) {
1133 if(tempbx & SwitchCRT2) {
1134 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1135 if( (HwInfo->jChipType >= SIS_315H) &&
1136 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1137 if(resinfo != SIS_RI_1600x1200) {
1138 tempbx |= SetSimuScanMode;
1140 } else {
1141 tempbx |= SetSimuScanMode;
1144 } else {
1145 if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
1146 if(!(tempbx & DriverMode)) {
1147 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1148 tempbx |= SetSimuScanMode;
1155 if(!(tempbx & DisableCRT2Display)) {
1156 if(tempbx & DriverMode) {
1157 if(tempbx & SetSimuScanMode) {
1158 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1159 if( (HwInfo->jChipType >= SIS_315H) &&
1160 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1161 if(resinfo != SIS_RI_1600x1200) {
1162 tempbx |= SetInSlaveMode;
1164 } else {
1165 tempbx |= SetInSlaveMode;
1169 } else {
1170 tempbx |= SetInSlaveMode;
1176 SiS_Pr->SiS_VBInfo = tempbx;
1178 if(HwInfo->jChipType == SIS_630) {
1179 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1182 #ifdef TWDEBUG
1183 #ifdef LINUX_KERNEL
1184 printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1185 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1186 #endif
1187 #ifdef LINUX_XF86
1188 xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1189 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1190 #endif
1191 #endif
1194 /*********************************************/
1195 /* DETERMINE YPbPr MODE */
1196 /*********************************************/
1198 void
1199 SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1202 UCHAR temp;
1204 /* Note: This variable is only used on 30xLV systems.
1205 * CR38 has a different meaning on LVDS/CH7019 systems.
1206 * On 661 and later, these bits moved to CR35.
1208 * On 301, 301B, only HiVision 1080i is supported.
1209 * On 30xLV, 301C, only YPbPr 1080i is supported.
1212 SiS_Pr->SiS_YPbPr = 0;
1213 if(HwInfo->jChipType >= SIS_661) return;
1215 if(SiS_Pr->SiS_VBType) {
1216 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1217 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1221 if(HwInfo->jChipType >= SIS_315H) {
1222 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
1223 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1224 if(temp & 0x08) {
1225 switch((temp >> 4)) {
1226 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1227 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1228 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1229 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1237 /*********************************************/
1238 /* DETERMINE TVMode flag */
1239 /*********************************************/
1241 void
1242 SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
1244 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1245 USHORT temp, temp1, resinfo = 0, romindex = 0;
1246 UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1248 SiS_Pr->SiS_TVMode = 0;
1250 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1251 if(SiS_Pr->UseCustomMode) return;
1253 if(ModeNo > 0x13) {
1254 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1257 if(HwInfo->jChipType < SIS_661) {
1259 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1261 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1262 temp = 0;
1263 if((HwInfo->jChipType == SIS_630) ||
1264 (HwInfo->jChipType == SIS_730)) {
1265 temp = 0x35;
1266 romindex = 0xfe;
1267 } else if(HwInfo->jChipType >= SIS_315H) {
1268 temp = 0x38;
1269 romindex = 0xf3;
1270 if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
1272 if(temp) {
1273 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1274 OutputSelect = ROMAddr[romindex];
1275 if(!(OutputSelect & EnablePALMN)) {
1276 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1279 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1280 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1281 if(temp1 & EnablePALM) { /* 0x40 */
1282 SiS_Pr->SiS_TVMode |= TVSetPALM;
1283 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1284 } else if(temp1 & EnablePALN) { /* 0x80 */
1285 SiS_Pr->SiS_TVMode |= TVSetPALN;
1287 } else {
1288 if(temp1 & EnableNTSCJ) { /* 0x40 */
1289 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1293 /* Translate HiVision/YPbPr to our new flags */
1294 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1295 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1296 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1297 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1298 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1299 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1300 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1301 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1302 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1303 SiS_Pr->SiS_TVMode |= TVSetPAL;
1306 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1307 if(SiS_Pr->SiS_CHOverScan) {
1308 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1309 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1310 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1311 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1313 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1314 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1315 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1316 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1319 if(SiS_Pr->SiS_CHSOverScan) {
1320 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1323 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1324 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1325 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1326 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1327 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1328 } else {
1329 if(temp & EnableNTSCJ) {
1330 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1336 } else { /* 661 and later */
1338 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1339 if(temp1 & 0x01) {
1340 SiS_Pr->SiS_TVMode |= TVSetPAL;
1341 if(temp1 & 0x08) {
1342 SiS_Pr->SiS_TVMode |= TVSetPALN;
1343 } else if(temp1 & 0x04) {
1344 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1345 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1347 SiS_Pr->SiS_TVMode |= TVSetPALM;
1349 } else {
1350 if(temp1 & 0x02) {
1351 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1354 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1355 if(SiS_Pr->SiS_CHOverScan) {
1356 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1357 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1361 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1362 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1363 temp1 &= 0xe0;
1364 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1365 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1366 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1367 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1368 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1370 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1371 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1372 SiS_Pr->SiS_TVMode |= TVAspect169;
1373 } else {
1374 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1375 if(temp1 & 0x02) {
1376 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1377 SiS_Pr->SiS_TVMode |= TVAspect169;
1378 } else {
1379 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1381 } else {
1382 SiS_Pr->SiS_TVMode |= TVAspect43;
1389 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1391 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1393 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1394 SiS_Pr->SiS_TVMode |= TVSetPAL;
1395 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1396 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1397 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1398 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1402 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1403 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1404 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1408 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1409 /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
1410 if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
1411 if(resinfo == SIS_RI_1024x768) {
1412 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1417 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1418 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1419 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1420 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1421 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1422 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1423 } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
1424 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1425 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1431 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1433 #ifdef TWDEBUG
1434 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1435 #endif
1438 /*********************************************/
1439 /* GET LCD INFO */
1440 /*********************************************/
1442 static USHORT
1443 SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
1445 USHORT temp = SiS_Pr->SiS_LCDResInfo;
1446 /* Translate my LCDResInfo to BIOS value */
1447 if(temp == Panel_1280x768_2) temp = Panel_1280x768;
1448 if(temp == Panel_1280x768_3) temp = Panel_1280x768;
1449 return temp;
1452 static void
1453 SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1455 #ifdef SIS315H
1456 UCHAR *ROMAddr;
1457 USHORT temp;
1459 #ifdef TWDEBUG
1460 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1461 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1462 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1463 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1464 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1465 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1466 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1467 #endif
1469 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1470 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1471 SiS_Pr->SiS_NeedRomModeData = TRUE;
1472 SiS_Pr->PanelHT = temp;
1474 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1475 SiS_Pr->SiS_NeedRomModeData = TRUE;
1476 SiS_Pr->PanelVT = temp;
1478 SiS_Pr->PanelHRS = SISGETROMW(10);
1479 SiS_Pr->PanelHRE = SISGETROMW(12);
1480 SiS_Pr->PanelVRS = SISGETROMW(14);
1481 SiS_Pr->PanelVRE = SISGETROMW(16);
1482 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1483 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1484 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
1485 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1486 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1487 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1488 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1490 #ifdef TWDEBUG
1491 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1492 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1493 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1494 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1495 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1496 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1497 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1498 #endif
1501 #endif
1504 void
1505 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1506 PSIS_HW_INFO HwInfo)
1508 #ifdef SIS300
1509 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1510 #endif
1511 #ifdef SIS315H
1512 UCHAR *myptr = NULL;
1513 #endif
1514 USHORT temp,modeflag,resinfo=0;
1515 const unsigned char SiS300SeriesLCDRes[] =
1516 { 0, 1, 2, 3, 7, 4, 5, 8,
1517 0, 0, 10, 0, 0, 0, 0, 15 };
1519 SiS_Pr->SiS_LCDResInfo = 0;
1520 SiS_Pr->SiS_LCDTypeInfo = 0;
1521 SiS_Pr->SiS_LCDInfo = 0;
1522 SiS_Pr->PanelHRS = 999; /* HSync start */
1523 SiS_Pr->PanelHRE = 999; /* HSync end */
1524 SiS_Pr->PanelVRS = 999; /* VSync start */
1525 SiS_Pr->PanelVRE = 999; /* VSync end */
1526 SiS_Pr->SiS_NeedRomModeData = FALSE;
1528 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1530 if(ModeNo <= 0x13) {
1531 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1532 } else if(SiS_Pr->UseCustomMode) {
1533 modeflag = SiS_Pr->CModeFlag;
1534 } else {
1535 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1536 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1539 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1540 if(!temp) return;
1542 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1543 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1544 } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
1545 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1546 } else {
1547 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1549 temp &= 0x0f;
1550 if(HwInfo->jChipType < SIS_315H) {
1551 /* Translate 300 series LCDRes to 315 series for unified usage */
1552 temp = SiS300SeriesLCDRes[temp];
1555 if(HwInfo->jChipType == SIS_550) {
1556 if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
1557 if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
1560 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* SiS LVDS */
1561 if(temp == Panel310_1280x768) {
1562 temp = Panel_1280x768_2;
1563 #ifdef SIS315H
1564 if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1565 if((myptr[8] | (myptr[9] << 8)) == 798) temp = Panel_1280x768_3;
1567 #endif
1571 SiS_Pr->SiS_LCDResInfo = temp;
1573 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1574 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1575 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1576 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1577 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1581 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1582 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1583 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1584 } else {
1585 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1586 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1589 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1590 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1592 switch(SiS_Pr->SiS_LCDResInfo) {
1593 case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480;
1594 SiS_Pr->PanelHT = 400; SiS_Pr->PanelVT = 525;
1595 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1596 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1597 break;
1598 case Panel_640x480_2:
1599 case Panel_640x480_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1600 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1601 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1602 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1603 break;
1604 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1605 SiS_Pr->PanelVRE = 3;
1606 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1607 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1608 break;
1609 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1610 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1611 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1612 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1613 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1614 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1615 break;
1616 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1617 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1618 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1619 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1620 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1621 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1622 break;
1623 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1624 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1625 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1626 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1627 if(HwInfo->jChipType < SIS_315H) {
1628 SiS_Pr->PanelHRS = 23;
1629 SiS_Pr->PanelVRE = 5;
1631 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1632 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1633 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1634 break;
1635 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1636 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1637 SiS_Pr->PanelHRS = 24;
1638 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1639 if(HwInfo->jChipType < SIS_315H) {
1640 SiS_Pr->PanelHRS = 23;
1641 SiS_Pr->PanelVRE = 5;
1643 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1644 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1645 break;
1646 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1647 break;
1648 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1649 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1650 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1651 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1652 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1653 /* Data above for TMDS (projector); get from BIOS for LVDS */
1654 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1655 break;
1656 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1657 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1658 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1659 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1660 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1661 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1662 break;
1663 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1664 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1665 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 64;
1666 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1667 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1668 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1669 break;
1670 case Panel_1280x768_3: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1671 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 798;
1672 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 128;
1673 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 7;
1674 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_3;
1675 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1676 break;
1677 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1678 SiS_Pr->PanelHT = 1656; SiS_Pr->PanelVT = 841; /* 1408, 816 */
1679 SiS_Pr->PanelHRS = 32; SiS_Pr->PanelHRE = 312; /* 16, 64 */
1680 SiS_Pr->PanelVRS = 16; SiS_Pr->PanelVRE = 8; /* 4, 3 */
1681 SiS_Pr->PanelVCLKIdx315 = VCLK83_315;
1682 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1683 break;
1684 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1685 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1686 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1687 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1688 if(resinfo == SIS_RI_1280x1024) {
1689 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1690 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1692 break;
1693 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1694 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1695 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1696 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1697 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1698 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1699 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1700 break;
1701 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1702 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1703 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; /* HRE OK for LVDS, not for LCDA */
1704 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1705 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1706 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1707 break;
1708 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1709 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1710 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1711 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1712 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1713 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1714 break;
1715 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1716 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1717 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1718 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1719 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1720 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1721 break;
1722 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1723 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1724 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1725 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1726 if(SiS_Pr->CP_PreferredIndex != -1) {
1727 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1728 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1729 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1730 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1731 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1732 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1733 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1734 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1735 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1736 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1737 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1738 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1740 break;
1741 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1742 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1743 break;
1744 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1745 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1746 break;
1747 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1748 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1749 break;
1752 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1753 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1755 if(!(SiS_Pr->UsePanelScaler)) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1756 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1758 #ifdef SIS315H
1759 if(HwInfo->jChipType >= SIS_661) {
1760 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1761 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1763 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1764 if(SiS_Pr->SiS_ROMNew) {
1765 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1766 } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1767 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1770 } else if(HwInfo->jChipType >= SIS_315H) {
1771 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1772 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1774 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1775 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1776 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1777 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1778 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1779 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1783 #endif
1785 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1786 /* Always center screen on LVDS (if scaling is disabled) */
1787 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1788 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1789 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
1790 /* Always center screen on SiS LVDS (if scaling is disabled) */
1791 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1792 } else {
1793 /* By default, pass 1:1 on SiS TMDS (if scaling is disabled) */
1794 SiS_Pr->SiS_LCDInfo |= LCDPass11;
1795 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1799 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1800 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1801 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
1805 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1806 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
1807 if(modeflag & NoSupportLCDScale) {
1808 /* No scaling for this mode on any panel */
1809 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1811 switch(SiS_Pr->SiS_LCDResInfo) {
1812 case Panel_Custom:
1813 /* For non-standard LCD resolution, we let the panel scale */
1814 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1815 break;
1816 case Panel_1280x720:
1817 if(SiS_Pr->PanelHT == 1650) {
1818 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1820 case Panel_1280x768: /* TMDS only */
1821 /* No idea about the timing and zoom factors */
1822 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1823 break;
1824 case Panel_1280x960:
1825 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1826 break;
1827 case Panel_1280x1024:
1828 if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1829 if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
1830 ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
1831 ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16) {
1832 /* We do not scale to 1280x720/800/960 (B/C bridges only) */
1833 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1835 if(((HwInfo->jChipType >= SIS_315H) &&
1836 (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
1837 ((HwInfo->jChipType < SIS_315H) &&
1838 (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
1839 /* We do not scale to 1280x768 (B/C bridges only) */
1840 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1843 break;
1844 case Panel_1400x1050:
1845 if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1846 if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
1847 ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
1848 ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16 ||
1849 ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25) {
1850 /* Do not scale to 1280x720/768/800/960 (B/C bridges only) */
1851 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1854 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
1855 if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
1856 if(SiS_Pr->UsePanelScaler == -1) {
1857 /* Do not scale to 1280x720 by default (LVDS bridges) */
1858 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1862 if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
1863 /* Do not scale to 1280x1024 (all bridges) */
1864 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1866 break;
1867 case Panel_1600x1200:
1868 if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1869 /* No idea about the timing and zoom factors (C bridge only) */
1870 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1872 break;
1877 #ifdef SIS300
1878 if(HwInfo->jChipType < SIS_315H) {
1879 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1880 if(SiS_Pr->SiS_UseROM) {
1881 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
1882 if(!(ROMAddr[0x235] & 0x02)) {
1883 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1887 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
1888 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
1889 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1893 #endif
1895 /* Special cases */
1896 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
1897 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
1900 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
1901 SiS_Pr->SiS_LCDInfo |= LCDPass11;
1904 if(SiS_Pr->UseCustomMode) {
1905 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
1908 /* (In)validate LCDPass11 flag */
1909 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1910 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1913 /* Special cases */
1914 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1915 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1916 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1917 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1918 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1919 SiS_Pr->PanelHRS = 999;
1920 SiS_Pr->PanelHRE = 999;
1923 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1924 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1925 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1926 SiS_Pr->PanelVRS = 999;
1927 SiS_Pr->PanelVRE = 999;
1930 #ifdef SIS315H
1931 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
1932 if(!(SiS_Pr->SiS_ROMNew)) {
1933 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1934 /* Enable 302LV/302ELV dual link mode.
1935 * For 661, this is done above.
1937 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1938 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1939 /* (Sets this in SenseLCD; new paneltypes) */
1940 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1942 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1943 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1944 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1945 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1946 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1951 #endif
1953 if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
1955 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1956 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
1957 if(ModeNo == 0x12) {
1958 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
1959 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1961 } else if(ModeNo > 0x13) {
1962 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
1963 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1964 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
1965 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1973 if(modeflag & HalfDCLK) {
1974 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
1975 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1976 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1977 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1978 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
1979 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1980 } else if(ModeNo > 0x13) {
1981 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
1982 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1983 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
1984 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1991 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1992 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
1993 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1995 } else {
1996 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1999 #ifdef LINUX_KERNEL
2000 #ifdef TWDEBUG
2001 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2002 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2003 #endif
2004 #endif
2005 #ifdef LINUX_XF86
2006 xf86DrvMsgVerb(0, X_PROBED, 4,
2007 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2008 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2009 #endif
2012 /*********************************************/
2013 /* GET VCLK */
2014 /*********************************************/
2016 USHORT
2017 SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2018 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
2020 USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
2021 USHORT modeflag,resinfo,tempbx;
2022 const UCHAR *CHTVVCLKPtr = NULL;
2024 if(ModeNo <= 0x13) {
2025 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2026 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2027 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2028 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2029 } else {
2030 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2031 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2032 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2033 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2034 if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
2037 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2039 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2041 CRT2Index >>= 6;
2042 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2044 if(HwInfo->jChipType < SIS_315H) {
2045 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2046 } else {
2047 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2048 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2049 VCLKIndex = VCLKIndexGEN;
2050 switch(resinfo) {
2051 /* Only those whose IndexGEN doesn't match VBVCLK array: */
2052 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720;
2053 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
2054 if(SiS_Pr->PanelHT == 1344) {
2055 VCLKIndex = VCLK_1280x720_2;
2058 break;
2059 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2060 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2061 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2062 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2063 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2064 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2065 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2066 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2067 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2070 if(ModeNo <= 0x13) {
2071 if(HwInfo->jChipType <= SIS_315PRO) {
2072 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2073 } else {
2074 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2077 if(HwInfo->jChipType <= SIS_315PRO) {
2078 if(VCLKIndex == 0) VCLKIndex = 0x41;
2079 if(VCLKIndex == 1) VCLKIndex = 0x43;
2080 if(VCLKIndex == 4) VCLKIndex = 0x44;
2085 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2087 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2088 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2089 else VCLKIndex = HiTVVCLK;
2090 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
2091 if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
2092 else VCLKIndex = HiTVTextVCLK;
2094 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2095 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2096 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2097 else VCLKIndex = TVVCLK;
2099 if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2100 else VCLKIndex += TVCLKBASE_315;
2102 } else { /* VGA2 */
2104 VCLKIndex = VCLKIndexGEN;
2105 if(HwInfo->jChipType < SIS_315H) {
2106 if(ModeNo > 0x13) {
2107 if( (HwInfo->jChipType == SIS_630) &&
2108 (HwInfo->jChipRevision >= 0x30)) {
2109 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2111 /* Better VGA2 clock for 1280x1024@75 */
2112 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2117 } else { /* If not programming CRT2 */
2119 VCLKIndex = VCLKIndexGEN;
2120 if(HwInfo->jChipType < SIS_315H) {
2121 if(ModeNo > 0x13) {
2122 if( (HwInfo->jChipType != SIS_630) &&
2123 (HwInfo->jChipType != SIS_300) ) {
2124 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2130 } else { /* LVDS */
2132 VCLKIndex = CRT2Index;
2134 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2136 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2138 VCLKIndex &= 0x1f;
2139 tempbx = 0;
2140 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2141 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2142 tempbx += 2;
2143 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2144 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2146 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2147 tempbx = 4;
2148 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2149 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2150 tempbx = 6;
2151 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2154 switch(tempbx) {
2155 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2156 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2157 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2158 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2159 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2160 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2161 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2162 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2163 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2164 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2166 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2168 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2170 if(HwInfo->jChipType < SIS_315H) {
2171 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2172 } else {
2173 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2176 /* Special Timing: Barco iQ Pro R series */
2177 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2179 /* Special Timing: 848x480 parallel lvds */
2180 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2181 if(HwInfo->jChipType < SIS_315H) {
2182 VCLKIndex = VCLK34_300;
2183 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2184 } else {
2185 VCLKIndex = VCLK34_315;
2186 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2190 } else {
2192 VCLKIndex = VCLKIndexGEN;
2193 if(HwInfo->jChipType < SIS_315H) {
2194 if(ModeNo > 0x13) {
2195 if( (HwInfo->jChipType == SIS_630) &&
2196 (HwInfo->jChipRevision >= 0x30) ) {
2197 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2203 } else { /* if not programming CRT2 */
2205 VCLKIndex = VCLKIndexGEN;
2206 if(HwInfo->jChipType < SIS_315H) {
2207 if(ModeNo > 0x13) {
2208 if( (HwInfo->jChipType != SIS_630) &&
2209 (HwInfo->jChipType != SIS_300) ) {
2210 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2212 #if 0
2213 if(HwInfo->jChipType == SIS_730) {
2214 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2215 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2217 #endif
2225 #ifdef TWDEBUG
2226 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2227 #endif
2229 return(VCLKIndex);
2232 /*********************************************/
2233 /* SET CRT2 MODE TYPE REGISTERS */
2234 /*********************************************/
2236 static void
2237 SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2238 PSIS_HW_INFO HwInfo)
2240 USHORT i,j,modeflag;
2241 USHORT tempcl,tempah=0;
2242 #if defined(SIS300) || defined(SIS315H)
2243 USHORT tempbl;
2244 #endif
2245 #ifdef SIS315H
2246 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
2247 USHORT tempah2, tempbl2;
2248 #endif
2250 if(ModeNo <= 0x13) {
2251 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2252 } else if(SiS_Pr->UseCustomMode) {
2253 modeflag = SiS_Pr->CModeFlag;
2254 } else {
2255 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2258 /* BIOS does not do this (neither 301 nor LVDS) */
2259 /* (But it's harmless; see SetCRT2Offset) */
2260 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x00); /* fix write part1 index 0 BTDRAM bit Bug */
2262 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2264 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2265 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2267 } else {
2269 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2270 if(HwInfo->jChipType >= SIS_315H) {
2271 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2274 tempcl = SiS_Pr->SiS_ModeType;
2276 if(HwInfo->jChipType < SIS_315H) {
2278 #ifdef SIS300 /* ---- 300 series ---- */
2280 /* For 301BDH: (with LCD via LVDS) */
2281 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2282 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2283 tempbl &= 0xef;
2284 tempbl |= 0x02;
2285 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2286 tempbl |= 0x10;
2287 tempbl &= 0xfd;
2289 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2292 if(ModeNo > 0x13) {
2293 tempcl -= ModeVGA;
2294 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2295 tempah = ((0x10 >> tempcl) | 0x80);
2297 } else tempah = 0x80;
2299 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2301 #endif /* SIS300 */
2303 } else {
2305 #ifdef SIS315H /* ------- 315/330 series ------ */
2307 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2308 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2309 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2313 if(ModeNo > 0x13) {
2314 tempcl -= ModeVGA;
2315 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2316 tempah = (0x08 >> tempcl);
2317 if (tempah == 0) tempah = 1;
2318 tempah |= 0x40;
2320 } else tempah = 0x40;
2322 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2324 #endif /* SIS315H */
2328 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2330 if(HwInfo->jChipType < SIS_315H) {
2331 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2332 } else {
2333 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2334 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2335 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2336 if(IS_SIS740) {
2337 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2338 } else {
2339 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2344 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2346 tempah = 0x01;
2347 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2348 tempah |= 0x02;
2350 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2351 tempah ^= 0x05;
2352 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2353 tempah ^= 0x01;
2357 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2359 if(HwInfo->jChipType < SIS_315H) {
2361 tempah = (tempah << 5) & 0xFF;
2362 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2363 tempah = (tempah >> 5) & 0xFF;
2365 } else {
2367 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2371 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2372 tempah |= 0x10;
2375 if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
2376 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2377 (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)) {
2378 tempah |= 0x80;
2380 } else {
2381 tempah |= 0x80;
2384 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2385 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2386 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2387 tempah |= 0x20;
2392 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2394 tempah = 0;
2396 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
2398 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2399 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2400 tempah |= 0x40;
2404 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2405 (SiS_Pr->SiS_LCDResInfo == Panel_1280x960) ||
2406 ((SiS_Pr->SiS_LCDResInfo == Panel_Custom) &&
2407 (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
2408 tempah |= 0x80;
2411 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2413 } else { /* LVDS */
2415 if(HwInfo->jChipType >= SIS_315H) {
2417 /* LVDS can only be slave in 8bpp modes */
2418 tempah = 0x80;
2419 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2420 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2421 tempah |= 0x02;
2425 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2426 tempah |= 0x02;
2429 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2430 tempah ^= 0x01;
2433 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2434 tempah = 1;
2437 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2439 } else {
2441 tempah = 0;
2442 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2443 tempah |= 0x02;
2445 tempah <<= 5;
2447 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2449 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2455 } /* LCDA */
2457 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2459 if(HwInfo->jChipType >= SIS_315H) {
2461 #ifdef SIS315H
2463 unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
2465 /* The following is nearly unpreditable and varies from machine
2466 * to machine. Especially the 301DH seems to be a real trouble
2467 * maker. Some BIOSes simply set the registers (like in the
2468 * NoLCD-if-statements here), some set them according to the
2469 * LCDA stuff. It is very likely that some machines are not
2470 * treated correctly in the following, very case-orientated
2471 * code. What do I do then...?
2474 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2476 if(!(IS_SIS740)) {
2477 tempah = 0x04; /* For all bridges */
2478 tempbl = 0xfb;
2479 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2480 tempah = 0x00;
2481 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2482 tempbl = 0xff;
2485 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2488 /* The following two are responsible for eventually wrong colors
2489 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2490 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2491 * in a 650 box (Jake). What is the criteria?
2494 if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2495 tempah = 0x30;
2496 tempbl = 0xc0;
2497 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2498 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2499 tempah = 0x00;
2500 tempbl = 0x00;
2502 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2503 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2504 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2505 /* Fixes "TV-blue-bug" on 315+301 */
2506 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2507 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2508 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2509 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2510 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2511 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2512 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */
2513 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2514 } else {
2515 tempah = 0x30; tempah2 = 0xc0; /* For 30xB (and 301BDH rev b1) */
2516 tempbl = 0xcf; tempbl2 = 0x3f;
2517 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2518 tempah = tempah2 = 0x00;
2519 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2520 tempbl = tempbl2 = 0xff;
2523 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2524 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2527 if(IS_SIS740) {
2528 tempah = 0x80;
2529 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2530 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2531 } else {
2532 tempah = 0x00;
2533 tempbl = 0x7f;
2534 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2535 tempbl = 0xff;
2536 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
2538 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2541 #if 0
2542 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
2543 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0xc0);
2545 #endif
2547 #endif /* SIS315H */
2549 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2551 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2553 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2554 ( (SiS_Pr->SiS_VBType & VB_NoLCD) &&
2555 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
2556 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2557 } else {
2558 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2563 } else { /* LVDS */
2565 #ifdef SIS315H
2566 if(HwInfo->jChipType >= SIS_315H) {
2568 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2570 tempah = 0x04;
2571 tempbl = 0xfb;
2572 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2573 tempah = 0x00;
2574 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
2576 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2578 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2579 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2582 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2584 } else if(HwInfo->jChipType == SIS_550) {
2586 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2587 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2592 #endif
2598 /*********************************************/
2599 /* GET RESOLUTION DATA */
2600 /*********************************************/
2602 USHORT
2603 SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
2605 if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2606 else return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2609 static void
2610 SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2611 PSIS_HW_INFO HwInfo)
2613 USHORT xres,yres,modeflag=0,resindex;
2615 if(SiS_Pr->UseCustomMode) {
2616 xres = SiS_Pr->CHDisplay;
2617 if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
2618 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2619 yres = SiS_Pr->CVDisplay;
2620 if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
2621 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2622 return;
2625 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2627 if(ModeNo <= 0x13) {
2628 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2629 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2630 } else {
2631 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2632 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2633 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2636 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2638 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2639 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2640 if(yres == 350) yres = 400;
2642 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2643 if(ModeNo == 0x12) yres = 400;
2647 if(modeflag & HalfDCLK) xres *= 2;
2648 if(modeflag & DoubleScanMode) yres *= 2;
2652 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2654 #if 0
2655 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
2656 if(xres == 720) xres = 640;
2658 #endif
2660 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2661 switch(SiS_Pr->SiS_LCDResInfo) {
2662 case Panel_1024x768:
2663 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2664 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2665 if(yres == 350) yres = 357;
2666 if(yres == 400) yres = 420;
2667 if(yres == 480) yres = 525;
2670 break;
2671 case Panel_1280x1024:
2672 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2673 /* BIOS bug - does this regardless of scaling */
2674 if(yres == 400) yres = 405;
2676 if(yres == 350) yres = 360;
2677 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2678 if(yres == 360) yres = 375;
2680 break;
2681 case Panel_1600x1200:
2682 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2683 if(yres == 1024) yres = 1056;
2685 break;
2689 } else {
2691 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2692 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2693 if(xres == 720) xres = 640;
2695 } else if(xres == 720) xres = 640;
2697 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2698 yres = 400;
2699 if(HwInfo->jChipType >= SIS_315H) {
2700 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2701 } else {
2702 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2704 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2708 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2709 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2712 /*********************************************/
2713 /* GET CRT2 TIMING DATA */
2714 /*********************************************/
2716 static BOOLEAN
2717 SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2718 USHORT RefreshRateTableIndex, USHORT *ResIndex,
2719 USHORT *DisplayType)
2721 USHORT modeflag=0;
2723 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2724 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2725 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2727 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2728 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2729 } else
2730 return FALSE;
2732 if(ModeNo <= 0x13) {
2733 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2734 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2735 } else {
2736 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2737 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2740 (*ResIndex) &= 0x3F;
2742 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2743 (*DisplayType) = 18;
2744 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2745 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2746 (*DisplayType) += 2;
2747 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2748 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
2750 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2751 (*DisplayType) = 18; /* PALM uses NTSC data */
2752 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2753 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2754 (*DisplayType) = 20; /* PALN uses PAL data */
2755 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2758 } else {
2759 switch(SiS_Pr->SiS_LCDResInfo) {
2760 case Panel_640x480: (*DisplayType) = 50; break;
2761 case Panel_640x480_2: (*DisplayType) = 52; break;
2762 case Panel_640x480_3: (*DisplayType) = 54; break;
2763 case Panel_800x600: (*DisplayType) = 0; break;
2764 case Panel_1024x600: (*DisplayType) = 23; break;
2765 case Panel_1024x768: (*DisplayType) = 4; break;
2766 case Panel_1152x768: (*DisplayType) = 27; break;
2767 case Panel_1280x768: (*DisplayType) = 40; break;
2768 case Panel_1280x1024: (*DisplayType) = 8; break;
2769 case Panel_1400x1050: (*DisplayType) = 14; break;
2770 case Panel_1600x1200: (*DisplayType) = 36; break;
2771 default: return FALSE;
2774 if(modeflag & HalfDCLK) (*DisplayType)++;
2776 switch(SiS_Pr->SiS_LCDResInfo) {
2777 case Panel_640x480:
2778 case Panel_640x480_2:
2779 case Panel_640x480_3:
2780 break;
2781 default:
2782 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
2785 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2786 (*DisplayType) = 12;
2787 if(modeflag & HalfDCLK) (*DisplayType)++;
2791 #if 0
2792 if(SiS_Pr->SiS_IF_DEF_FSTN) {
2793 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2794 (*DisplayType) = 22;
2797 #endif
2799 return TRUE;
2802 static void
2803 SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2804 USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
2805 PSIS_HW_INFO HwInfo)
2807 USHORT tempbx=0,tempal=0,resinfo=0;
2809 if(ModeNo <= 0x13) {
2810 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2811 } else {
2812 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2813 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2816 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2818 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2820 tempbx = SiS_Pr->SiS_LCDResInfo;
2821 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2823 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2824 if (resinfo == SIS_RI_1280x800) tempal = 9;
2825 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2828 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { /* Pass 1:1 only (center-screen handled outside) */
2829 tempbx = 100;
2830 if(ModeNo >= 0x13) {
2831 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2832 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
2833 (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 768)) {
2834 /* Special for Fujitsu 7911 (VL-17WDX8), others custom */
2835 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) tempal = 0x08;
2836 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) tempal = 0x0f;
2837 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) tempal = 0x10;
2842 #ifdef SIS315H
2843 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2844 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2845 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2846 tempbx = 200;
2847 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2851 #endif
2853 } else { /* TV */
2855 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2856 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2857 tempbx = 2;
2858 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2859 tempbx = 13;
2860 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2862 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2863 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2864 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2865 else tempbx = 5;
2866 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2867 } else {
2868 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2869 else tempbx = 4;
2870 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2875 tempal &= 0x3F;
2877 if(ModeNo > 0x13) {
2878 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2879 if(tempal == 6) tempal = 7;
2880 if((resinfo == SIS_RI_720x480) ||
2881 (resinfo == SIS_RI_720x576) ||
2882 (resinfo == SIS_RI_768x576)) {
2883 tempal = 6;
2884 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
2885 if(resinfo == SIS_RI_720x480) tempal = 9;
2888 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2889 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
2890 if(resinfo == SIS_RI_1024x768) tempal = 8;
2892 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
2893 if((resinfo == SIS_RI_720x576) ||
2894 (resinfo == SIS_RI_768x576)) {
2895 tempal = 8;
2897 if(resinfo == SIS_RI_1280x720) tempal = 9;
2903 *CRT2Index = tempbx;
2904 *ResIndex = tempal;
2906 } else { /* LVDS, 301B-DH (if running on LCD) */
2908 tempbx = 0;
2909 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2910 tempbx = 10;
2911 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2912 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2913 tempbx += 2;
2914 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2915 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2917 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2918 tempbx = 90;
2919 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2920 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2921 tempbx = 92;
2922 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2925 } else {
2926 switch(SiS_Pr->SiS_LCDResInfo) {
2927 case Panel_640x480: tempbx = 6; break;
2928 case Panel_640x480_2: tempbx = 30; break;
2929 case Panel_640x480_3: tempbx = 30; break;
2930 case Panel_800x600: tempbx = 0; break;
2931 case Panel_1024x600: tempbx = 15; break;
2932 case Panel_1024x768: tempbx = 2; break;
2933 case Panel_1152x768: tempbx = 17; break;
2934 case Panel_1280x768: tempbx = 18; break;
2935 case Panel_1280x1024: tempbx = 4; break;
2936 case Panel_1400x1050: tempbx = 8; break;
2937 case Panel_1600x1200: tempbx = 21; break;
2938 case Panel_Barco1366: tempbx = 80; break;
2941 switch(SiS_Pr->SiS_LCDResInfo) {
2942 case Panel_640x480:
2943 case Panel_640x480_2:
2944 case Panel_640x480_3:
2945 break;
2946 default:
2947 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2950 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
2952 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
2953 tempbx = 82;
2954 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2955 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2956 tempbx = 84;
2957 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2962 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2963 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempal = 7;
2964 if(HwInfo->jChipType < SIS_315H) {
2965 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
2969 (*CRT2Index) = tempbx;
2970 (*ResIndex) = tempal & 0x1F;
2974 static void
2975 SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2976 USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
2978 USHORT tempax=0,tempbx=0;
2979 USHORT temp1=0,modeflag=0,tempcx=0;
2980 USHORT index;
2982 SiS_Pr->SiS_RVBHCMAX = 1;
2983 SiS_Pr->SiS_RVBHCFACT = 1;
2985 if(ModeNo <= 0x13) {
2987 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2988 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
2990 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
2991 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
2992 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
2994 } else {
2996 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2997 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2999 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3000 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3001 tempax &= 0x03FF;
3002 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3003 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3004 tempcx &= 0x0100;
3005 tempcx <<= 2;
3006 tempbx |= tempcx;
3007 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3011 if(temp1 & 0x01) tempbx |= 0x0100;
3012 if(temp1 & 0x20) tempbx |= 0x0200;
3014 tempax += 5;
3016 /* Charx8Dot is no more used (and assumed), so we set it */
3017 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3018 modeflag |= Charx8Dot;
3021 if(modeflag & Charx8Dot) tempax *= 8;
3022 else tempax *= 9;
3024 if(modeflag & HalfDCLK) tempax <<= 1;
3026 tempbx++;
3028 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3029 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3032 static void
3033 SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3034 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3036 USHORT CRT2Index, ResIndex;
3037 const SiS_LVDSDataStruct *LVDSData = NULL;
3039 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3041 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3042 SiS_Pr->SiS_RVBHCMAX = 1;
3043 SiS_Pr->SiS_RVBHCFACT = 1;
3044 SiS_Pr->SiS_NewFlickerMode = 0;
3045 SiS_Pr->SiS_RVBHRS = 50;
3046 SiS_Pr->SiS_RY1COE = 0;
3047 SiS_Pr->SiS_RY2COE = 0;
3048 SiS_Pr->SiS_RY3COE = 0;
3049 SiS_Pr->SiS_RY4COE = 0;
3052 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3054 #ifdef SIS315H
3055 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3056 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3057 if(SiS_Pr->UseCustomMode) {
3058 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3059 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3060 } else {
3061 if(ModeNo < 0x13) {
3062 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3063 } else {
3064 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3065 /* Special for our 3 types, others custom (works with default) */
3066 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
3067 (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 768)) {
3068 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) ResIndex = 0x08;
3069 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) ResIndex = 0x0f;
3070 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) ResIndex = 0x10;
3072 /* Special for 1280x720 TMDS <> LVDS */
3073 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
3074 (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 720)) {
3075 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
3076 if(SiS_Pr->PanelHT == 1344) ResIndex = 0x12;
3080 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3081 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3082 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3083 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3085 } else {
3086 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3087 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3089 } else {
3090 /* This handles custom modes and custom panels */
3091 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3092 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3093 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3094 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3095 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3096 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3099 SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
3101 #endif
3103 } else {
3105 /* 301BDH needs LVDS Data */
3106 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3107 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3110 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3111 &CRT2Index, &ResIndex, HwInfo);
3113 /* 301BDH needs LVDS Data */
3114 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3115 SiS_Pr->SiS_IF_DEF_LVDS = 0;
3118 switch (CRT2Index) {
3119 case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3120 case 1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
3121 case 2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3122 case 3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
3123 case 4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
3124 case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
3125 case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3126 case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
3127 case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
3128 case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
3129 case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3130 case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3131 case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3132 case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3133 case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
3134 case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3135 case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
3136 case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
3137 case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
3138 case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
3139 case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
3140 case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
3141 case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
3142 case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
3143 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3144 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3145 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3146 case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
3147 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3148 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3149 case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3150 case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3151 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3152 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3153 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
3154 default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3157 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3158 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3159 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3160 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3162 if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
3163 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3164 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3165 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3166 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3167 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3168 if(ResIndex < 0x08) {
3169 SiS_Pr->SiS_HDE = 1280;
3170 SiS_Pr->SiS_VDE = 1024;
3179 static void
3180 SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3181 USHORT RefreshRateTableIndex,
3182 PSIS_HW_INFO HwInfo)
3184 UCHAR *ROMAddr = NULL;
3185 USHORT tempax,tempbx,modeflag,romptr=0;
3186 USHORT resinfo,CRT2Index,ResIndex;
3187 const SiS_LCDDataStruct *LCDPtr = NULL;
3188 const SiS_TVDataStruct *TVPtr = NULL;
3189 #ifdef SIS315H
3190 SHORT resinfo661;
3191 #endif
3193 if(ModeNo <= 0x13) {
3194 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3195 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3196 } else if(SiS_Pr->UseCustomMode) {
3197 modeflag = SiS_Pr->CModeFlag;
3198 resinfo = 0;
3199 } else {
3200 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3201 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3202 #ifdef SIS315H
3203 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3204 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3205 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3206 (resinfo661 >= 0) &&
3207 (SiS_Pr->SiS_NeedRomModeData) ) {
3208 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
3209 if((romptr = (SISGETROMW(21)))) {
3210 romptr += (resinfo661 * 10);
3211 ROMAddr = HwInfo->pjVirtualRomBase;
3215 #endif
3218 SiS_Pr->SiS_NewFlickerMode = 0;
3219 SiS_Pr->SiS_RVBHRS = 50;
3220 SiS_Pr->SiS_RY1COE = 0;
3221 SiS_Pr->SiS_RY2COE = 0;
3222 SiS_Pr->SiS_RY3COE = 0;
3223 SiS_Pr->SiS_RY4COE = 0;
3225 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
3227 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
3229 if(SiS_Pr->UseCustomMode) {
3231 SiS_Pr->SiS_RVBHCMAX = 1;
3232 SiS_Pr->SiS_RVBHCFACT = 1;
3233 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3234 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3235 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3236 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3237 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3238 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3240 } else {
3242 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3246 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3248 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3249 &CRT2Index,&ResIndex,HwInfo);
3251 switch(CRT2Index) {
3252 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3253 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3254 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3255 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3256 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3257 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3258 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3259 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3260 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3261 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3262 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3263 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3264 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3265 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3268 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3269 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3270 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3271 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3272 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3273 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3274 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3275 SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3276 if(modeflag & HalfDCLK) {
3277 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3280 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3282 if((resinfo == SIS_RI_1024x768) ||
3283 (resinfo == SIS_RI_1280x1024) ||
3284 (resinfo == SIS_RI_1280x720)) {
3285 SiS_Pr->SiS_NewFlickerMode = 0x40;
3288 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3290 SiS_Pr->SiS_HT = ExtHiTVHT;
3291 SiS_Pr->SiS_VT = ExtHiTVVT;
3292 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3293 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3294 SiS_Pr->SiS_HT = StHiTVHT;
3295 SiS_Pr->SiS_VT = StHiTVVT;
3296 #if 0
3297 if(!(modeflag & Charx8Dot)) {
3298 SiS_Pr->SiS_HT = StHiTextTVHT;
3299 SiS_Pr->SiS_VT = StHiTextTVVT;
3301 #endif
3305 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3307 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3308 SiS_Pr->SiS_HT = 1650;
3309 SiS_Pr->SiS_VT = 750;
3310 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3311 SiS_Pr->SiS_HT = NTSCHT;
3312 SiS_Pr->SiS_VT = NTSCVT;
3313 } else {
3314 SiS_Pr->SiS_HT = NTSCHT;
3315 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3316 SiS_Pr->SiS_VT = NTSCVT;
3319 } else {
3321 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3322 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3323 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3324 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3326 if(modeflag & HalfDCLK) {
3327 SiS_Pr->SiS_RY1COE = 0x00;
3328 SiS_Pr->SiS_RY2COE = 0xf4;
3329 SiS_Pr->SiS_RY3COE = 0x10;
3330 SiS_Pr->SiS_RY4COE = 0x38;
3333 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3334 SiS_Pr->SiS_HT = NTSCHT;
3335 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3336 SiS_Pr->SiS_VT = NTSCVT;
3337 } else {
3338 SiS_Pr->SiS_HT = PALHT;
3339 SiS_Pr->SiS_VT = PALVT;
3344 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3346 SiS_Pr->SiS_RVBHCMAX = 1;
3347 SiS_Pr->SiS_RVBHCFACT = 1;
3349 if(SiS_Pr->UseCustomMode) {
3351 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3352 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3353 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3354 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3355 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3356 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3358 } else {
3360 BOOLEAN gotit = FALSE;
3362 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3364 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3365 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3366 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3367 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3368 gotit = TRUE;
3370 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3372 #ifdef SIS315H
3373 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3374 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3375 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3376 SiS_Pr->SiS_VGAVT = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
3377 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3378 SiS_Pr->SiS_VT = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
3379 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3380 #endif
3384 if(!gotit) {
3386 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3387 &CRT2Index,&ResIndex,HwInfo);
3389 switch(CRT2Index) {
3390 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3391 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3392 case Panel_1280x720 :
3393 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3394 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3395 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3396 case Panel_1280x768_3 :
3397 case Panel_1280x768_3+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x768_3Data; break;
3398 case Panel_1280x800 :
3399 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3400 case Panel_1280x960 :
3401 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3402 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3403 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3404 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3405 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3406 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3407 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3408 case Panel_1680x1050 :
3409 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3410 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3411 #ifdef SIS315H
3412 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3413 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3414 #endif
3415 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3418 #ifdef TWDEBUG
3419 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3420 #endif
3422 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3423 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3424 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3425 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3426 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3427 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3431 tempax = SiS_Pr->PanelXRes;
3432 tempbx = SiS_Pr->PanelYRes;
3434 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3435 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3436 if(HwInfo->jChipType < SIS_315H) {
3437 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3438 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3440 } else {
3441 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3442 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3443 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3444 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3445 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3446 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3448 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
3449 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3450 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3451 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3452 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3453 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3454 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3455 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3456 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
3457 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3458 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3459 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3463 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3464 tempax = SiS_Pr->SiS_VGAHDE;
3465 tempbx = SiS_Pr->SiS_VGAVDE;
3468 SiS_Pr->SiS_HDE = tempax;
3469 SiS_Pr->SiS_VDE = tempbx;
3474 static void
3475 SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3476 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3479 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3481 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3482 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3483 } else {
3484 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3485 /* Need LVDS Data for LCD on 301B-DH */
3486 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3487 } else {
3488 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3492 } else {
3494 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3499 /*********************************************/
3500 /* GET LVDS DES (SKEW) DATA */
3501 /*********************************************/
3503 static void
3504 SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3505 USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3506 USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3508 USHORT modeflag;
3510 if(ModeNo <= 0x13) {
3511 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3512 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3513 } else {
3514 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3515 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3518 (*ResIndex) &= 0x1F;
3519 (*PanelIndex) = 0;
3521 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3522 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3523 (*PanelIndex) = 50;
3524 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
3525 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
3526 /* Nothing special needed for SOverscan */
3527 /* PALM uses NTSC data, PALN uses PAL data */
3531 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3532 *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
3533 if(HwInfo->jChipType >= SIS_661) {
3534 /* As long as we don's use the BIOS tables, we
3535 * need to convert the TypeInfo as for 315 series
3537 (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
3539 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3540 (*PanelIndex) += 16;
3541 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3542 (*PanelIndex) = 32;
3543 if(modeflag & HalfDCLK) (*PanelIndex)++;
3548 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3549 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
3550 (*ResIndex) = 7;
3551 if(HwInfo->jChipType < SIS_315H) {
3552 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
3558 static void
3559 SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3560 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3562 USHORT modeflag;
3563 USHORT PanelIndex,ResIndex;
3564 const SiS_LVDSDesStruct *PanelDesPtr = NULL;
3566 SiS_Pr->SiS_LCDHDES = 0;
3567 SiS_Pr->SiS_LCDVDES = 0;
3569 if( (SiS_Pr->UseCustomMode) ||
3570 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3571 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3572 ((SiS_Pr->SiS_VBType & VB_SISVB) &&
3573 (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3574 (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3575 return;
3578 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3580 #ifdef SIS315H
3581 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3582 /* non-pass 1:1 only, see above */
3583 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3584 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3586 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3587 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3590 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3591 switch(SiS_Pr->SiS_CustomT) {
3592 case CUT_UNIWILL1024:
3593 case CUT_UNIWILL10242:
3594 case CUT_CLEVO1400:
3595 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3596 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3598 break;
3600 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3601 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3602 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3606 #endif
3608 } else {
3610 SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3611 &PanelIndex, &ResIndex, HwInfo);
3613 switch(PanelIndex) {
3614 case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */
3615 case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break;
3616 case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break;
3617 case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break;
3618 case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break;
3619 case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break;
3620 case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break;
3621 case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break;
3622 case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break;
3623 case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break;
3624 case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break;
3625 case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break;
3626 case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break;
3627 case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break;
3628 case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break;
3629 case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break;
3630 case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */
3631 case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break;
3632 case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break;
3633 case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break;
3634 case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break;
3635 case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break;
3636 case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break;
3637 case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break;
3638 case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break;
3639 case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break;
3640 case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break;
3641 case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break;
3642 case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break;
3643 case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break;
3644 case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break;
3645 case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break;
3646 case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */
3647 case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break;
3648 case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */
3649 case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
3650 case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
3651 case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
3652 default: return;
3655 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3656 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3658 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3659 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3660 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3661 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3662 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3663 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3664 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3665 if(HwInfo->jChipType < SIS_315H) {
3666 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3667 } else {
3668 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3669 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3670 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3671 if(!(modeflag & HalfDCLK)) {
3672 SiS_Pr->SiS_LCDHDES = 320;
3673 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3674 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3684 /*********************************************/
3685 /* DISABLE VIDEO BRIDGE */
3686 /*********************************************/
3688 /* NEVER use any variables (VBInfo), this will be called
3689 * from outside the context of modeswitch!
3690 * MUST call getVBType before calling this
3692 void
3693 SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3695 #ifdef SIS315H
3696 USHORT tempah,pushax=0,modenum;
3697 #endif
3698 USHORT temp=0;
3700 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3702 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
3704 if(HwInfo->jChipType < SIS_315H) {
3706 #ifdef SIS300 /* 300 series */
3708 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3709 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3710 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3711 } else {
3712 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3714 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3716 if(SiS_Is301B(SiS_Pr)) {
3717 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3718 SiS_ShortDelay(SiS_Pr,1);
3720 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3721 SiS_DisplayOff(SiS_Pr);
3722 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3723 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3724 SiS_UnLockCRT2(SiS_Pr,HwInfo);
3725 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
3726 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3727 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3729 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3730 (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3731 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3732 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3733 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3734 } else {
3735 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3739 #endif /* SIS300 */
3741 } else {
3743 #ifdef SIS315H /* 315 series */
3745 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3746 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3748 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3750 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3752 #ifdef SET_EMI
3753 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3754 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3755 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3758 #endif
3759 if( (modenum <= 0x13) ||
3760 (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3761 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
3762 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3763 if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3766 if(!custom1) {
3767 SiS_DDC2Delay(SiS_Pr,0xff00);
3768 SiS_DDC2Delay(SiS_Pr,0xe000);
3769 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3770 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3771 if(IS_SIS740) {
3772 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3774 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3779 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
3780 tempah = 0xef;
3781 if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
3782 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3785 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3786 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3789 tempah = 0x3f;
3790 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3791 tempah = 0x7f;
3792 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
3794 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3796 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3797 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3799 SiS_DisplayOff(SiS_Pr);
3800 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3801 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3803 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3804 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3808 if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
3809 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3811 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3812 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3813 SiS_DisplayOff(SiS_Pr);
3815 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3817 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3818 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3821 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3822 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3823 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3824 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3825 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3829 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
3830 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3833 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3835 if(!custom1) {
3837 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3838 if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3839 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3840 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3845 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3847 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3848 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
3849 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
3853 } else {
3855 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3856 (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
3857 if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
3858 (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
3859 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3860 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3861 SiS_PanelDelay(SiS_Pr, HwInfo, 4);
3868 #endif /* SIS315H */
3872 } else { /* ============ For 301 ================ */
3874 if(HwInfo->jChipType < SIS_315H) {
3875 #ifdef SIS300
3876 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3877 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3878 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3880 #endif
3883 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
3884 SiS_DisplayOff(SiS_Pr);
3886 if(HwInfo->jChipType >= SIS_315H) {
3887 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3890 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
3892 if(HwInfo->jChipType >= SIS_315H) {
3893 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3894 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3895 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
3896 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3897 } else {
3898 #ifdef SIS300
3899 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
3900 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3901 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
3902 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3903 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3905 #endif
3910 } else { /* ============ For LVDS =============*/
3912 if(HwInfo->jChipType < SIS_315H) {
3914 #ifdef SIS300 /* 300 series */
3916 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
3917 SiS_SetCH700x(SiS_Pr,0x090E);
3920 if(HwInfo->jChipType == SIS_730) {
3921 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
3922 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
3924 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3925 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3926 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3928 } else {
3929 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
3930 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
3931 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3932 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
3933 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
3934 SiS_DisplayOff(SiS_Pr);
3936 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3937 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3943 SiS_DisplayOff(SiS_Pr);
3945 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3947 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3948 SiS_UnLockCRT2(SiS_Pr,HwInfo);
3949 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3950 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3952 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3953 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
3954 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3955 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3958 #endif /* SIS300 */
3960 } else {
3962 #ifdef SIS315H /* 315 series */
3964 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
3965 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
3968 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3970 if(HwInfo->jChipType == SIS_740) {
3971 temp = SiS_GetCH701x(SiS_Pr,0x61);
3972 if(temp < 1) {
3973 SiS_SetCH701x(SiS_Pr,0xac76);
3974 SiS_SetCH701x(SiS_Pr,0x0066);
3977 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3978 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
3979 SiS_SetCH701x(SiS_Pr,0x3e49);
3983 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3984 (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
3985 SiS_Chrontel701xBLOff(SiS_Pr);
3986 SiS_Chrontel701xOff(SiS_Pr,HwInfo);
3989 if(HwInfo->jChipType != SIS_740) {
3990 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3991 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
3992 SiS_SetCH701x(SiS_Pr,0x0149);
3998 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
3999 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4000 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4003 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4004 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4005 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
4006 SiS_DisplayOff(SiS_Pr);
4009 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4010 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4011 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4012 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4015 if(HwInfo->jChipType == SIS_740) {
4016 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4019 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4021 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4022 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4023 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4024 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4027 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4028 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4029 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4030 if(HwInfo->jChipType == SIS_550) {
4031 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4032 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4035 } else {
4036 if(HwInfo->jChipType == SIS_740) {
4037 if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
4038 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4040 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4041 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4045 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4046 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4047 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4048 } else {
4049 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4053 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4055 if(HwInfo->jChipType == SIS_550) {
4056 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4057 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4058 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4059 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4060 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4061 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4064 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4065 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4066 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4067 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4068 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4073 #endif /* SIS315H */
4075 } /* 315 series */
4077 } /* LVDS */
4081 /*********************************************/
4082 /* ENABLE VIDEO BRIDGE */
4083 /*********************************************/
4085 /* NEVER use any variables (VBInfo), this will be called
4086 * from outside the context of a mode switch!
4087 * MUST call getVBType before calling this
4089 void
4090 SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4092 USHORT temp=0,tempah;
4093 #ifdef SIS315H
4094 USHORT temp1,pushax=0;
4095 BOOLEAN delaylong = FALSE;
4096 #endif
4098 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4100 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */
4102 if(HwInfo->jChipType < SIS_315H) {
4104 #ifdef SIS300 /* 300 series */
4106 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4107 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4108 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4109 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4110 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4112 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
4113 if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
4114 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4119 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4120 (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4122 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4123 SiS_DisplayOn(SiS_Pr);
4124 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4125 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4126 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4127 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4128 } else {
4129 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4131 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4132 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4133 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4134 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4136 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4137 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4141 } else {
4143 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4144 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4145 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4146 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4148 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4149 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4150 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4151 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4152 SiS_DisplayOn(SiS_Pr);
4153 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4154 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4155 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4156 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4157 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4159 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4167 #endif /* SIS300 */
4169 } else {
4171 #ifdef SIS315H /* 315 series */
4173 #ifdef SET_EMI
4174 UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
4175 /* USHORT emidelay=0; */
4176 #endif
4178 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4179 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4180 #ifdef SET_EMI
4181 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4182 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4184 #endif
4187 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
4188 tempah = 0x10;
4189 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4190 if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4191 else tempah = 0x08;
4193 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4196 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4198 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4199 SiS_DisplayOff(SiS_Pr);
4200 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4201 if(IS_SIS740) {
4202 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4205 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4206 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4207 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4208 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4209 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4210 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4211 SiS_GenericDelay(SiS_Pr, 0x4500);
4216 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4217 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4218 delaylong = TRUE;
4223 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4225 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4226 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4227 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4228 if(!(tempah & SetCRT2ToRAMDAC)) {
4229 if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
4232 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4234 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4236 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4237 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4239 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4240 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4243 } else {
4245 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4249 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4250 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4252 tempah = 0xc0;
4253 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
4254 tempah = 0x80;
4255 if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
4257 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4259 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4261 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4263 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4264 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4266 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4267 #ifdef SET_EMI
4268 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4269 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4271 #endif
4272 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4274 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4275 #ifdef SET_EMI
4276 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4278 if(SiS_Pr->SiS_ROMNew) {
4279 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4280 USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
4281 if(romptr) {
4282 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4283 SiS_Pr->EMI_30 = 0;
4284 SiS_Pr->EMI_31 = ROMAddr[romptr + 14];
4285 SiS_Pr->EMI_32 = ROMAddr[romptr + 15];
4286 SiS_Pr->EMI_33 = ROMAddr[romptr + 16];
4287 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4288 /* emidelay = SISGETROMW((romptr + 0x22)); */
4289 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4293 /* (P4_30|0x40) */
4294 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4295 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4296 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4297 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4298 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4299 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4300 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4301 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4302 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4304 if(SiS_Pr->HaveEMI) {
4305 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4306 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4307 } else {
4308 r30 = 0;
4311 /* EMI_30 is read at driver start; however, the BIOS sets this
4312 * (if it is used) only if the LCD is in use. In case we caught
4313 * the machine while on TV output, this bit is not set and we
4314 * don't know if it should be set - hence our detection is wrong.
4315 * Work-around this here:
4318 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4319 switch((cr36 & 0x0f)) {
4320 case 2:
4321 r30 |= 0x40;
4322 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4323 if(!SiS_Pr->HaveEMI) {
4324 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4325 if((cr36 & 0xf0) == 0x30) {
4326 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4329 break;
4330 case 3: /* 1280x1024 */
4331 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4332 if(!SiS_Pr->HaveEMI) {
4333 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4334 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4335 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4338 break;
4339 case 9: /* 1400x1050 */
4340 r30 |= 0x40;
4341 if(!SiS_Pr->HaveEMI) {
4342 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4343 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4344 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4347 break;
4348 case 11: /* 1600x1200 - unknown */
4349 r30 |= 0x40;
4350 if(!SiS_Pr->HaveEMI) {
4351 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4356 /* BIOS values don't work so well sometimes */
4357 if(!SiS_Pr->OverruleEMI) {
4358 #ifdef COMPAL_HACK
4359 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4360 if((cr36 & 0x0f) == 0x09) {
4361 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4364 #endif
4365 #ifdef COMPAQ_HACK
4366 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4367 if((cr36 & 0x0f) == 0x03) {
4368 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4371 #endif
4372 #ifdef ASUS_HACK
4373 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4374 if((cr36 & 0x0f) == 0x02) {
4375 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4376 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4377 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4378 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4381 #endif
4384 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4385 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4387 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4388 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4389 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4390 #endif /* SET_EMI */
4392 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4394 #ifdef SET_EMI
4395 if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
4396 (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4397 if(r30 & 0x40) {
4398 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4399 if(delaylong) {
4400 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4401 delaylong = FALSE;
4403 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4404 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4405 SiS_GenericDelay(SiS_Pr, 0x500);
4407 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
4410 #endif
4414 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4415 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4416 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4417 if(delaylong) {
4418 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4420 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4421 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4422 SiS_GenericDelay(SiS_Pr, 0x500);
4424 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4428 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4429 SiS_DisplayOn(SiS_Pr);
4430 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4434 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4435 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4438 #endif /* SIS315H */
4442 } else { /* ============ For 301 ================ */
4444 if(HwInfo->jChipType < SIS_315H) {
4445 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4446 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4447 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4451 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4452 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4453 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4454 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4456 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4458 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4460 if(HwInfo->jChipType >= SIS_315H) {
4461 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4462 if(!(temp & 0x80)) {
4463 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4467 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4469 SiS_VBLongWait(SiS_Pr);
4470 SiS_DisplayOn(SiS_Pr);
4471 if(HwInfo->jChipType >= SIS_315H) {
4472 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4474 SiS_VBLongWait(SiS_Pr);
4476 if(HwInfo->jChipType < SIS_315H) {
4477 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4478 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4479 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4485 } else { /* =================== For LVDS ================== */
4487 if(HwInfo->jChipType < SIS_315H) {
4489 #ifdef SIS300 /* 300 series */
4491 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4492 if(HwInfo->jChipType == SIS_730) {
4493 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4494 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4495 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4497 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4498 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4499 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4503 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4504 SiS_DisplayOn(SiS_Pr);
4505 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4506 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4507 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4508 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4509 } else {
4510 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4513 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4514 if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4515 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4516 SiS_SetCH700x(SiS_Pr,0x0B0E);
4520 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4521 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4522 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4523 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4524 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4525 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4527 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4528 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4533 #endif /* SIS300 */
4535 } else {
4537 #ifdef SIS315H /* 315 series */
4539 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4540 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4543 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4544 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4545 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4546 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4550 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4551 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4553 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4555 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4556 temp = SiS_GetCH701x(SiS_Pr,0x66);
4557 temp &= 0x20;
4558 SiS_Chrontel701xBLOff(SiS_Pr);
4561 if(HwInfo->jChipType != SIS_550) {
4562 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4565 if(HwInfo->jChipType == SIS_740) {
4566 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4567 if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
4568 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4573 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4574 if(!(temp1 & 0x80)) {
4575 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4578 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4579 if(temp) {
4580 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4584 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4585 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4586 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4587 if(HwInfo->jChipType == SIS_550) {
4588 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4589 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4592 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4593 if(HwInfo->jChipType != SIS_740) {
4594 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4598 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4599 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4602 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4603 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
4604 SiS_Chrontel701xOn(SiS_Pr,HwInfo);
4606 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4607 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4608 SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
4612 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4613 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4614 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4615 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4616 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4617 SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
4620 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4621 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4622 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4623 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4624 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4629 #endif /* SIS315H */
4631 } /* 310 series */
4633 } /* LVDS */
4637 /*********************************************/
4638 /* SET PART 1 REGISTER GROUP */
4639 /*********************************************/
4641 /* Set CRT2 OFFSET / PITCH */
4642 static void
4643 SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
4644 USHORT RRTI, PSIS_HW_INFO HwInfo)
4646 USHORT offset;
4647 UCHAR temp;
4649 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4651 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
4653 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
4654 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
4655 offset >>= 1;
4658 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4659 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4660 temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
4661 if(offset % 8) temp++;
4662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4665 /* Set CRT2 sync and PanelLink mode */
4666 static void
4667 SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
4668 PSIS_HW_INFO HwInfo)
4670 USHORT tempah=0,tempbl,infoflag;
4672 tempbl = 0xC0;
4674 if(SiS_Pr->UseCustomMode) {
4675 infoflag = SiS_Pr->CInfoFlag;
4676 } else {
4677 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4680 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4682 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4683 tempah = 0;
4684 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4685 tempah = SiS_Pr->SiS_LCDInfo;
4686 } else tempah = infoflag >> 8;
4687 tempah &= 0xC0;
4688 tempah |= 0x20;
4689 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4690 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4691 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4692 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4693 tempah |= 0xf0;
4695 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4696 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4697 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4698 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
4699 tempah |= 0x30;
4702 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4703 if(HwInfo->jChipType >= SIS_315H) {
4704 tempah >>= 3;
4705 tempah &= 0x18;
4706 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4707 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4708 } else {
4709 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4711 } else {
4712 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4715 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4717 if(HwInfo->jChipType < SIS_315H) {
4719 #ifdef SIS300 /* ---- 300 series --- */
4721 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */
4723 tempah = infoflag >> 8;
4724 tempbl = 0;
4725 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4726 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4727 tempah = SiS_Pr->SiS_LCDInfo;
4728 tempbl = (tempah >> 6) & 0x03;
4731 tempah &= 0xC0;
4732 tempah |= 0x20;
4733 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4734 tempah |= 0xc0;
4735 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4736 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4737 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4740 } else { /* 630 - 301 */
4742 tempah = infoflag >> 8;
4743 tempah &= 0xC0;
4744 tempah |= 0x20;
4745 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4746 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4750 #endif /* SIS300 */
4752 } else {
4754 #ifdef SIS315H /* ------- 315 series ------ */
4756 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - LVDS */
4758 tempbl = 0;
4759 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4760 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4761 tempah = infoflag >> 8;
4762 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4763 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4765 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4766 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4767 tempah = infoflag >> 8;
4768 tempbl = 0x03;
4769 } else {
4770 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4771 tempbl = (tempah >> 6) & 0x03;
4772 tempbl |= 0x08;
4773 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4775 tempah &= 0xC0;
4776 tempah |= 0x20;
4777 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4778 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4779 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4780 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4781 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4782 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4786 } else { /* 315 - TMDS */
4788 tempah = tempbl = infoflag >> 8;
4789 if(!SiS_Pr->UseCustomMode) {
4790 tempbl = 0;
4791 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4792 if(ModeNo <= 0x13) {
4793 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4796 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4797 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4798 tempah = SiS_Pr->SiS_LCDInfo;
4799 tempbl = (tempah >> 6) & 0x03;
4803 tempah &= 0xC0;
4804 tempah |= 0x20;
4805 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4806 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4807 /* Imitate BIOS bug */
4808 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4810 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4811 tempah >>= 3;
4812 tempah &= 0x18;
4813 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4814 } else {
4815 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4816 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4817 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4818 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4824 #endif /* SIS315H */
4829 /* Set CRT2 FIFO on 300/630/730 */
4830 #ifdef SIS300
4831 static void
4832 SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
4833 PSIS_HW_INFO HwInfo)
4835 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4836 USHORT temp,index;
4837 USHORT modeidindex,refreshratetableindex;
4838 USHORT VCLK=0,MCLK,colorth=0,data2=0;
4839 USHORT tempal, tempah, tempbx, tempcl, tempax;
4840 USHORT CRT1ModeNo,CRT2ModeNo;
4841 USHORT SelectRate_backup;
4842 ULONG data,eax;
4843 const UCHAR LatencyFactor[] = {
4844 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
4845 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
4846 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
4847 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
4848 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
4849 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
4850 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
4851 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
4853 const UCHAR LatencyFactor730[] = {
4854 69, 63, 61,
4855 86, 79, 77,
4856 103, 96, 94,
4857 120,113,111,
4858 137,130,128, /* <-- last entry, data below */
4859 137,130,128, /* to avoid using illegal values */
4860 137,130,128,
4861 137,130,128,
4862 137,130,128,
4863 137,130,128,
4864 137,130,128,
4865 137,130,128,
4866 137,130,128,
4867 137,130,128,
4868 137,130,128,
4869 137,130,128,
4871 const UCHAR ThLowB[] = {
4872 81, 4, 72, 6, 88, 8,120,12,
4873 55, 4, 54, 6, 66, 8, 90,12,
4874 42, 4, 45, 6, 55, 8, 75,12
4876 const UCHAR ThTiming[] = {
4877 1, 2, 2, 3, 0, 1, 1, 2
4880 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
4882 if(!SiS_Pr->CRT1UsesCustomMode) {
4884 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
4885 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
4886 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
4887 SiS_Pr->SiS_SelectCRT2Rate = 0;
4888 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
4890 if(CRT1ModeNo >= 0x13) {
4891 index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
4892 index &= 0x3F;
4893 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
4895 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); /* Get colordepth */
4896 colorth >>= 1;
4897 if(!colorth) colorth++;
4900 } else {
4902 CRT1ModeNo = 0xfe;
4903 VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
4904 data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
4905 switch(data2) { /* Get color depth */
4906 case 0 : colorth = 1; break;
4907 case 1 : colorth = 1; break;
4908 case 2 : colorth = 2; break;
4909 case 3 : colorth = 2; break;
4910 case 4 : colorth = 3; break;
4911 case 5 : colorth = 4; break;
4912 default: colorth = 2;
4917 if(CRT1ModeNo >= 0x13) {
4918 if(HwInfo->jChipType == SIS_300) {
4919 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
4920 } else {
4921 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
4923 index &= 0x07;
4924 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
4926 data2 = (colorth * VCLK) / MCLK;
4928 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4929 temp = ((temp & 0x00FF) >> 6) << 1;
4930 if(temp == 0) temp = 1;
4931 temp <<= 2;
4932 temp &= 0xff;
4934 data2 = temp - data2;
4936 if((28 * 16) % data2) {
4937 data2 = (28 * 16) / data2;
4938 data2++;
4939 } else {
4940 data2 = (28 * 16) / data2;
4943 if(HwInfo->jChipType == SIS_300) {
4945 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
4946 tempah &= 0x62;
4947 tempah >>= 1;
4948 tempal = tempah;
4949 tempah >>= 3;
4950 tempal |= tempah;
4951 tempal &= 0x07;
4952 tempcl = ThTiming[tempal];
4953 tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
4954 tempbx >>= 6;
4955 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4956 tempah >>= 4;
4957 tempah &= 0x0c;
4958 tempbx |= tempah;
4959 tempbx <<= 1;
4960 tempal = ThLowB[tempbx + 1];
4961 tempal *= tempcl;
4962 tempal += ThLowB[tempbx];
4963 data = tempal;
4965 } else if(HwInfo->jChipType == SIS_730) {
4967 #ifndef LINUX_XF86
4968 SiS_SetRegLong(0xcf8,0x80000050);
4969 eax = SiS_GetRegLong(0xcfc);
4970 #else
4971 eax = pciReadLong(0x00000000, 0x50);
4972 #endif
4973 tempal = (USHORT)(eax >> 8);
4974 tempal &= 0x06;
4975 tempal <<= 5;
4977 #ifndef LINUX_XF86
4978 SiS_SetRegLong(0xcf8,0x800000A0);
4979 eax = SiS_GetRegLong(0xcfc);
4980 #else
4981 eax = pciReadLong(0x00000000, 0xA0);
4982 #endif
4983 temp = (USHORT)(eax >> 28);
4984 temp &= 0x0F;
4985 tempal |= temp;
4987 tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
4988 tempbx = 0; /* -- do it like the BIOS anyway... */
4989 tempax = tempbx;
4990 tempbx &= 0xc0;
4991 tempbx >>= 6;
4992 tempax &= 0x0f;
4993 tempax *= 3;
4994 tempbx += tempax;
4996 data = LatencyFactor730[tempbx];
4997 data += 15;
4998 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4999 if(!(temp & 0x80)) data += 5;
5001 } else {
5003 index = 0;
5004 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5005 if(temp & 0x0080) index += 12;
5007 #ifndef LINUX_XF86
5008 SiS_SetRegLong(0xcf8,0x800000A0);
5009 eax = SiS_GetRegLong(0xcfc);
5010 #else
5011 /* We use pci functions X offers. We use tag 0, because
5012 * we want to read/write to the host bridge (which is always
5013 * 00:00.0 on 630, 730 and 540), not the VGA device.
5015 eax = pciReadLong(0x00000000, 0xA0);
5016 #endif
5017 temp = (USHORT)(eax >> 24);
5018 if(!(temp&0x01)) index += 24;
5020 #ifndef LINUX_XF86
5021 SiS_SetRegLong(0xcf8,0x80000050);
5022 eax = SiS_GetRegLong(0xcfc);
5023 #else
5024 eax = pciReadLong(0x00000000, 0x50);
5025 #endif
5026 temp=(USHORT)(eax >> 24);
5027 if(temp & 0x01) index += 6;
5029 temp = (temp & 0x0F) >> 1;
5030 index += temp;
5032 data = LatencyFactor[index];
5033 data += 15;
5034 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5035 if(!(temp & 0x80)) data += 5;
5038 data += data2; /* CRT1 Request Period */
5040 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5041 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5043 if(!SiS_Pr->UseCustomMode) {
5045 CRT2ModeNo = ModeNo;
5046 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5048 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
5050 index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
5051 refreshratetableindex,HwInfo);
5052 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5054 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5055 if(SiS_Pr->SiS_UseROM) {
5056 if(ROMAddr[0x220] & 0x01) {
5057 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5062 } else {
5064 CRT2ModeNo = 0xfe;
5065 VCLK = SiS_Pr->CSRClock; /* Get VCLK */
5069 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
5070 colorth >>= 1;
5071 if(!colorth) colorth++;
5073 data = data * VCLK * colorth;
5074 if(data % (MCLK << 4)) {
5075 data = data / (MCLK << 4);
5076 data++;
5077 } else {
5078 data = data / (MCLK << 4);
5081 if(data <= 6) data = 6;
5082 if(data > 0x14) data = 0x14;
5084 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
5085 if(HwInfo->jChipType == SIS_300) {
5086 if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
5087 else temp = (temp & (~0x1F)) | 0x16;
5088 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
5089 temp = (temp & (~0x1F)) | 0x13;
5091 } else {
5092 if( ( (HwInfo->jChipType == SIS_630) ||
5093 (HwInfo->jChipType == SIS_730) ) &&
5094 (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5096 temp = (temp & (~0x1F)) | 0x1b;
5097 } else {
5098 temp = (temp & (~0x1F)) | 0x16;
5101 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5103 if( (HwInfo->jChipType == SIS_630) &&
5104 (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
5106 if(data > 0x13) data = 0x13;
5108 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5110 } else { /* If mode <= 0x13, we just restore everything */
5112 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5113 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5117 #endif
5119 /* Set CRT2 FIFO on 315/330 series */
5120 #ifdef SIS315H
5121 static void
5122 SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
5124 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5125 if( (HwInfo->jChipType == SIS_760) &&
5126 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5127 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5128 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5129 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5130 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5131 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5132 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5133 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5134 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5135 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5136 } else {
5137 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5141 #endif
5143 static USHORT
5144 SiS_GetVGAHT2(SiS_Private *SiS_Pr)
5146 ULONG tempax,tempbx;
5148 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5149 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5150 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5151 return((USHORT)tempax);
5154 /* Set Part 1 / SiS bridge slave mode */
5155 static void
5156 SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5157 PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
5159 USHORT push1,push2;
5160 USHORT tempax,tempbx,tempcx,temp;
5161 USHORT resinfo,modeflag,xres=0;
5162 unsigned char p1_7, p1_8;
5164 if(ModeNo <= 0x13) {
5165 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5166 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5167 } else if(SiS_Pr->UseCustomMode) {
5168 modeflag = SiS_Pr->CModeFlag;
5169 resinfo = 0;
5170 xres = SiS_Pr->CHDisplay;
5171 } else {
5172 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5173 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5174 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5177 /* The following is only done if bridge is in slave mode: */
5179 if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
5180 if(xres >= 1600) {
5181 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5185 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
5187 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
5189 if(modeflag & Charx8Dot) tempcx = 0x08;
5190 else tempcx = 0x09;
5192 tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
5193 if(modeflag & HalfDCLK) tempax >>= 1;
5194 tempax = ((tempax / tempcx) - 1) & 0xff;
5195 tempbx = tempax;
5197 temp = tempax;
5198 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5200 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5201 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
5202 temp += 2;
5205 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5206 if(resinfo == SIS_RI_800x600) temp -= 2;
5208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
5210 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
5212 tempax = 0xFFFF;
5213 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5214 if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5215 if(modeflag & HalfDCLK) tempax >>= 1;
5216 tempax = (tempax / tempcx) - 5;
5217 tempcx = tempax;
5219 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5220 temp = tempcx - 1;
5221 if(!(modeflag & HalfDCLK)) {
5222 temp -= 6;
5223 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5224 temp -= 2;
5225 if(ModeNo > 0x13) temp -= 10;
5228 } else {
5229 tempcx = (tempcx + tempbx) >> 1;
5230 temp = (tempcx & 0x00FF) + 2;
5231 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5232 temp--;
5233 if(!(modeflag & HalfDCLK)) {
5234 if((modeflag & Charx8Dot)) {
5235 temp += 4;
5236 if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5237 if(HwInfo->jChipType >= SIS_315H) {
5238 if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5242 } else {
5243 if(!(modeflag & HalfDCLK)) {
5244 temp -= 4;
5245 if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
5246 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
5247 if(SiS_Pr->SiS_VGAHDE >= 800) {
5248 temp -= 7;
5249 if(HwInfo->jChipType < SIS_315H) {
5250 if(SiS_Pr->SiS_ModeType == ModeEGA) {
5251 if(SiS_Pr->SiS_VGAVDE == 1024) {
5252 temp += 15;
5253 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
5254 temp += 7;
5258 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5259 if(SiS_Pr->SiS_VGAHDE >= 1280) {
5260 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5269 p1_7 = temp;
5270 p1_8 = 0x00;
5272 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5273 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5274 if(ModeNo <= 0x01) {
5275 p1_7 = 0x2a;
5276 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5277 else p1_8 = 0x41;
5278 } else if(SiS_Pr->SiS_ModeType == ModeText) {
5279 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5280 else p1_7 = 0x55;
5281 p1_8 = 0x00;
5282 } else if(ModeNo <= 0x13) {
5283 if(modeflag & HalfDCLK) {
5284 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5285 p1_7 = 0x30;
5286 p1_8 = 0x03;
5287 } else {
5288 p1_7 = 0x2f;
5289 p1_8 = 0x02;
5291 } else {
5292 p1_7 = 0x5b;
5293 p1_8 = 0x03;
5295 } else if( ((HwInfo->jChipType >= SIS_315H) &&
5296 ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5297 ((HwInfo->jChipType < SIS_315H) &&
5298 (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5299 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5300 p1_7 = 0x30,
5301 p1_8 = 0x03;
5302 } else {
5303 p1_7 = 0x2f;
5304 p1_8 = 0x03;
5310 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
5311 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
5312 p1_7 = 0x63;
5313 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
5315 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5316 if(!(modeflag & HalfDCLK)) {
5317 p1_7 = 0xb2;
5318 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
5319 p1_7 = 0xab;
5322 } else {
5323 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
5324 if(modeflag & HalfDCLK) p1_7 = 0x30;
5329 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */
5330 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */
5332 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */
5334 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
5336 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */
5338 tempcx = 0x121;
5339 tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */
5340 if (tempbx == 357) tempbx = 350;
5341 else if(tempbx == 360) tempbx = 350;
5342 else if(tempbx == 375) tempbx = 350;
5343 else if(tempbx == 405) tempbx = 400;
5344 else if(tempbx == 420) tempbx = 400;
5345 else if(tempbx == 525) tempbx = 480;
5346 push2 = tempbx;
5347 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5348 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5349 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5350 if (tempbx == 350) tempbx += 5;
5351 else if(tempbx == 480) tempbx += 5;
5355 tempbx -= 2;
5356 temp = tempbx & 0x00FF;
5357 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
5359 tempbx = push2;
5360 tempbx--;
5361 temp = tempbx & 0x00FF;
5362 #if 0
5363 /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5364 if(xxx()) {
5365 if(temp == 0xdf) temp = 0xda;
5367 #endif
5368 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5370 temp = 0;
5371 if(modeflag & DoubleScanMode) temp |= 0x80;
5372 if(HwInfo->jChipType >= SIS_661) {
5373 if(tempbx & 0x0200) temp |= 0x20;
5374 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5375 if(tempbx & 0x0100) tempcx |= 0x000a;
5376 if(tempbx & 0x0400) tempcx |= 0x1200;
5377 } else {
5378 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5379 if(tempbx & 0x0100) tempcx |= 0x0002;
5380 if(tempbx & 0x0400) tempcx |= 0x0600;
5383 if(tempbx & 0x0200) tempcx |= 0x0040;
5385 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */
5387 tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
5389 if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
5390 if(resinfo != SIS_RI_1280x1024) {
5391 tempbx += (tempax << 1);
5393 } else if(HwInfo->jChipType >= SIS_315H) {
5394 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5395 tempbx += (tempax << 1);
5399 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5400 tempbx -= 10;
5401 } else {
5402 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5403 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5404 tempbx += 40;
5405 if(HwInfo->jChipType >= SIS_315H) {
5406 if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5411 tempax >>= 2;
5412 tempax++;
5413 tempax += tempbx;
5414 push1 = tempax;
5415 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5416 if(tempbx <= 513) {
5417 if(tempax >= 513) tempbx = 513;
5420 temp = tempbx & 0x00FF;
5421 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */
5423 tempbx--;
5424 temp = tempbx & 0x00FF;
5425 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5427 if(tempbx & 0x0100) tempcx |= 0x0008;
5429 if(tempbx & 0x0200) {
5430 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5432 tempbx++;
5434 if(tempbx & 0x0100) tempcx |= 0x0004;
5435 if(tempbx & 0x0200) tempcx |= 0x0080;
5436 if(tempbx & 0x0400) {
5437 if(HwInfo->jChipType >= SIS_661) tempcx |= 0x0800;
5438 else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5439 else tempcx |= 0x0C00;
5442 tempbx = push1;
5443 temp = tempbx & 0x000F;
5444 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
5446 if(tempbx & 0x0010) tempcx |= 0x2000;
5448 temp = tempcx & 0x00FF;
5449 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
5451 temp = (tempcx & 0xFF00) >> 8;
5452 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */
5454 tempax = modeflag;
5455 temp = (tempax & 0xFF00) >> 8;
5456 temp = (temp >> 1) & 0x09;
5457 if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01; /* Always 8 dotclock */
5458 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
5460 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */
5462 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */
5464 temp = 0x00;
5465 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5466 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
5467 temp = 0x80;
5470 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
5472 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5473 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
5476 /* Setup panel link
5477 * This is used for LVDS, LCDA and Chrontel TV output
5478 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5480 static void
5481 SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5482 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5484 USHORT modeflag,resinfo;
5485 USHORT push2,tempax,tempbx,tempcx,temp;
5486 ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
5487 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5488 #ifdef SIS300
5489 USHORT crt2crtc;
5490 #endif
5491 #ifdef SIS315H
5492 USHORT pushcx;
5493 #endif
5495 if(ModeNo <= 0x13) {
5496 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5497 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5498 #ifdef SIS300
5499 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5500 #endif
5501 } else if(SiS_Pr->UseCustomMode) {
5502 modeflag = SiS_Pr->CModeFlag;
5503 resinfo = 0;
5504 #ifdef SIS300
5505 crt2crtc = 0;
5506 #endif
5507 } else {
5508 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5509 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5510 #ifdef SIS300
5511 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5512 #endif
5515 /* is lvds if really LVDS, or SiS 301B-DH with external LVDS transmitter */
5516 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
5517 ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBType & VB_NoLCD))) {
5518 islvds = TRUE;
5521 /* is really sis if sis bridge, but not 301B-DH */
5522 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5523 issis = TRUE;
5526 if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5527 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5528 chkdclkfirst = TRUE;
5532 #ifdef SIS315H
5533 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5534 if(IS_SIS330) {
5535 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5536 } else if(IS_SIS740) {
5537 if(islvds) {
5538 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5539 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5540 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5541 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5543 } else {
5544 if(islvds) {
5545 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5546 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5547 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5548 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5549 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
5550 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5551 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5552 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5558 #endif
5560 /* Horizontal */
5562 tempax = SiS_Pr->SiS_LCDHDES;
5563 if(islvds) {
5564 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5565 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5566 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5567 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5568 tempax -= 8;
5574 temp = (tempax & 0x0007);
5575 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5576 temp = (tempax >> 3) & 0x00FF;
5577 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5579 tempbx = SiS_Pr->SiS_HDE;
5580 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5581 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
5582 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
5583 tempbx >>= 1;
5585 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5586 tempbx = SiS_Pr->PanelXRes;
5590 tempax += tempbx;
5591 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5593 temp = tempax;
5594 if(temp & 0x07) temp += 8;
5595 temp >>= 3;
5596 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5598 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5600 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5601 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5602 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5606 tempcx += tempax;
5607 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5609 temp = (tempcx >> 3) & 0x00FF;
5610 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5611 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5612 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5613 switch(ModeNo) {
5614 case 0x04:
5615 case 0x05:
5616 case 0x0d: temp = 0x56; break;
5617 case 0x10: temp = 0x60; break;
5618 case 0x13: temp = 0x5f; break;
5619 case 0x40:
5620 case 0x41:
5621 case 0x4f:
5622 case 0x43:
5623 case 0x44:
5624 case 0x62:
5625 case 0x56:
5626 case 0x53:
5627 case 0x5d:
5628 case 0x5e: temp = 0x54; break;
5633 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5635 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5636 temp += 2;
5637 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5638 temp += 8;
5639 if(SiS_Pr->PanelHRE != 999) {
5640 temp = tempcx + SiS_Pr->PanelHRE;
5641 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5642 temp >>= 3;
5645 } else {
5646 temp += 10;
5649 temp &= 0x1F;
5650 temp |= ((tempcx & 0x07) << 5);
5651 #if 0
5652 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
5653 #endif
5654 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5656 /* Vertical */
5658 tempax = SiS_Pr->SiS_VGAVDE;
5659 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5660 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5661 tempax = SiS_Pr->PanelYRes;
5665 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5666 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5668 push2 = tempbx;
5670 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5671 if(HwInfo->jChipType < SIS_315H) {
5672 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5673 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5674 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5678 if(islvds) tempcx >>= 1;
5679 else tempcx >>= 2;
5681 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5682 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5683 (SiS_Pr->PanelVRS != 999) ) {
5684 tempcx = SiS_Pr->PanelVRS;
5685 tempbx += tempcx;
5686 if(issis) tempbx++;
5687 } else {
5688 tempbx += tempcx;
5689 if(HwInfo->jChipType < SIS_315H) tempbx++;
5690 else if(issis) tempbx++;
5693 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; /* BPLVRS */
5695 temp = tempbx & 0x00FF;
5696 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5697 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5698 if(ModeNo == 0x10) temp = 0xa9;
5701 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
5703 tempcx >>= 3;
5704 tempcx++;
5706 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5707 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5708 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5712 tempcx += tempbx;
5713 temp = tempcx & 0x000F;
5714 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5716 temp = ((tempbx >> 8) & 0x07) << 3;
5717 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5718 if(SiS_Pr->SiS_HDE != 640) {
5719 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5721 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5722 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5723 tempbx = 0x87;
5724 if((HwInfo->jChipType >= SIS_315H) ||
5725 (HwInfo->jChipRevision >= 0x30)) {
5726 tempbx = 0x07;
5727 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5728 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5730 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
5731 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5732 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5733 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5734 } else {
5735 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5739 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5741 tempbx = push2; /* BPLVDEE */
5743 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5745 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5746 switch(SiS_Pr->SiS_LCDResInfo) {
5747 case Panel_640x480:
5748 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5749 tempcx = SiS_Pr->SiS_VGAVDE;
5750 break;
5751 case Panel_800x600:
5752 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5753 if(resinfo == SIS_RI_800x600) tempcx++;
5755 break;
5756 case Panel_1024x600:
5757 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5758 if(resinfo == SIS_RI_1024x600) tempcx++;
5759 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5760 if(resinfo == SIS_RI_800x600) tempcx++;
5763 break;
5764 case Panel_1024x768:
5765 if(HwInfo->jChipType < SIS_315H) {
5766 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5767 if(resinfo == SIS_RI_1024x768) tempcx++;
5770 break;
5774 temp = ((tempbx >> 8) & 0x07) << 3;
5775 temp = temp | ((tempcx >> 8) & 0x07);
5776 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5777 /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++; */
5778 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5779 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5781 /* Vertical scaling */
5783 if(HwInfo->jChipType < SIS_315H) {
5785 #ifdef SIS300 /* 300 series */
5786 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5787 temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
5788 tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
5789 if(temp) tempeax++;
5791 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5793 temp = (USHORT)(tempeax & 0x00FF);
5794 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5795 tempvcfact = temp;
5796 #endif /* SIS300 */
5798 } else {
5800 #ifdef SIS315H /* 315 series */
5801 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5802 tempebx = SiS_Pr->SiS_VDE;
5803 temp = (tempeax % tempebx);
5804 tempeax = tempeax / tempebx;
5805 if(temp) tempeax++;
5806 tempvcfact = tempeax;
5808 temp = (USHORT)(tempeax & 0x00FF);
5809 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5810 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5811 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5812 temp = (USHORT)((tempeax & 0x00030000) >> 16);
5813 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5816 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
5817 temp = (USHORT)(tempeax & 0x00FF);
5818 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5819 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5820 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5821 temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
5822 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5823 temp = 0;
5824 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5825 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5827 #endif
5831 /* Horizontal scaling */
5833 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5834 if(chkdclkfirst) {
5835 if(modeflag & HalfDCLK) tempeax >>= 1;
5837 tempebx = tempeax << 16;
5838 if(SiS_Pr->SiS_HDE == tempeax) {
5839 tempecx = 0xFFFF;
5840 } else {
5841 tempecx = tempebx / SiS_Pr->SiS_HDE;
5842 if(HwInfo->jChipType >= SIS_315H) {
5843 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5847 if(HwInfo->jChipType >= SIS_315H) {
5848 tempeax = (tempebx / tempecx) - 1;
5849 } else {
5850 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5852 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5853 temp = (USHORT)(tempecx & 0x00FF);
5854 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5856 if(HwInfo->jChipType >= SIS_315H) {
5857 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5858 tempbx = (USHORT)(tempeax & 0xFFFF);
5859 } else {
5860 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5861 tempbx = tempvcfact & 0x3f;
5862 if(tempbx == 0) tempbx = 64;
5863 tempeax /= tempbx;
5864 tempbx = (USHORT)(tempeax & 0xFFFF);
5866 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5867 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5868 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5869 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5872 temp = ((tempbx >> 8) & 0x07) << 3;
5873 temp = temp | ((tempecx >> 8) & 0x07);
5874 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5875 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5877 tempecx >>= 16; /* BPLHCFACT */
5878 if(!chkdclkfirst) {
5879 if(modeflag & HalfDCLK) tempecx >>= 1;
5881 temp = (USHORT)((tempecx & 0xFF00) >> 8);
5882 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5883 temp = (USHORT)(tempecx & 0x00FF);
5884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5886 #ifdef SIS315H
5887 if(HwInfo->jChipType >= SIS_315H) {
5888 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5889 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
5890 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5892 } else {
5893 if(islvds) {
5894 if(HwInfo->jChipType == SIS_740) {
5895 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5896 } else {
5897 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5902 #endif
5904 #ifdef SIS300
5905 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5906 int i;
5907 UCHAR TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5908 UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5909 UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5911 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5912 for(i=0; i<5; i++) {
5913 SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
5915 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5916 if(ModeNo == 0x13) {
5917 for(i=0; i<4; i++) {
5918 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5920 } else if(ModeNo == 0x10) {
5921 for(i=0; i<4; i++) {
5922 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5923 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5927 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5929 #endif
5931 #ifdef SIS315H
5932 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5933 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5934 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5935 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5936 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5937 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5938 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5939 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5940 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5941 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5942 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5943 tempax += 64;
5944 temp = tempax & 0x00FF;
5945 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
5946 temp = ((tempax & 0xFF00) >> 8) << 3;
5947 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5948 tempax += 32; /* Blpe=lBlps+32 */
5949 temp = tempax & 0x00FF;
5950 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
5951 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
5952 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */
5953 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
5955 tempax = SiS_Pr->SiS_VDE;
5956 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5957 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5958 tempax >>= 1;
5959 temp = tempax & 0x00FF;
5960 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
5961 temp = ((tempax & 0xFF00) >> 8) << 3;
5962 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5964 tempeax = SiS_Pr->SiS_HDE;
5965 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5966 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
5967 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5968 tempebx = 128;
5969 temp = (USHORT)(tempeax % tempebx);
5970 tempeax = tempeax / tempebx;
5971 if(temp) tempeax++;
5972 temp = (USHORT)(tempeax & 0x003F);
5973 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
5974 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5975 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5976 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5977 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
5979 tempax = SiS_Pr->SiS_HDE;
5980 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5981 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5982 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5983 pushcx = tempax;
5984 temp = tempax & 0x00FF;
5985 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5986 temp = ((tempax & 0xFF00) >> 8) << 3;
5987 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5989 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5990 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5991 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5992 tempeax = (tempax * pushcx);
5993 tempebx = 0x00100000 + tempeax;
5994 temp = (USHORT)tempebx & 0x000000FF;
5995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5996 temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
5997 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5998 temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
5999 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6000 temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
6001 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6003 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6004 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6005 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6006 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6007 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6009 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6010 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6011 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6012 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6013 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6014 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6015 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6016 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6017 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6018 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6019 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6020 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6021 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6022 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6023 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6024 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6025 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6026 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6027 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6028 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6029 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6032 #endif /* SIS315H */
6035 /* Set Part 1 */
6036 static void
6037 SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6038 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
6040 #if defined(SIS300) || defined(SIS315H)
6041 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
6042 #endif
6043 USHORT temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6044 USHORT pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6045 #ifdef SIS315H
6046 USHORT tempbl=0;
6047 #endif
6049 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6050 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6051 return;
6054 if(ModeNo <= 0x13) {
6055 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6056 } else if(SiS_Pr->UseCustomMode) {
6057 modeflag = SiS_Pr->CModeFlag;
6058 } else {
6059 CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
6060 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6061 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6064 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
6066 if( ! ((HwInfo->jChipType >= SIS_315H) &&
6067 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6068 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6070 if(HwInfo->jChipType < SIS_315H ) {
6071 #ifdef SIS300
6072 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
6073 #endif
6074 } else {
6075 #ifdef SIS315H
6076 SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
6077 #endif
6080 /* 1. Horizontal setup */
6082 if(HwInfo->jChipType < SIS_315H ) {
6084 #ifdef SIS300 /* ------------- 300 series --------------*/
6086 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6087 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6089 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6090 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6092 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6093 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6095 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6096 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6097 tempbx = pushbx + tempcx;
6098 tempcx <<= 1;
6099 tempcx += tempbx;
6101 bridgeadd = 12;
6103 #endif /* SIS300 */
6105 } else {
6107 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6109 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6110 if(modeflag & HalfDCLK) {
6111 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6112 tempcx >>= 1;
6113 } else {
6114 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6115 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6116 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6117 tempcx = SiS_Pr->SiS_HT - tempax;
6121 tempcx--;
6122 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6123 temp = (tempcx >> 4) & 0xF0;
6124 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6126 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6127 tempbx = SiS_Pr->SiS_VGAHDE;
6128 tempcx -= tempbx;
6129 tempcx >>= 2;
6130 if(modeflag & HalfDCLK) {
6131 tempbx >>= 1;
6132 tempcx >>= 1;
6134 tempbx += 16;
6136 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6138 pushbx = tempbx;
6139 tempcx >>= 1;
6140 tempbx += tempcx;
6141 tempcx += tempbx;
6143 bridgeadd = 16;
6145 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6146 if(HwInfo->jChipType >= SIS_661) {
6147 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6148 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6149 if(resinfo == SIS_RI_1280x1024) {
6150 tempcx = (tempcx & 0xff00) | 0x30;
6151 } else if(resinfo == SIS_RI_1600x1200) {
6152 tempcx = (tempcx & 0xff00) | 0xff;
6158 #endif /* SIS315H */
6160 } /* 315/330 series */
6162 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6164 if(SiS_Pr->UseCustomMode) {
6165 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6166 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6167 tempax = SiS_Pr->SiS_VGAHT;
6168 if(modeflag & HalfDCLK) tempax >>= 1;
6169 tempax--;
6170 if(tempcx > tempax) tempcx = tempax;
6173 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6174 unsigned char cr4, cr14, cr5, cr15;
6175 if(SiS_Pr->UseCustomMode) {
6176 cr4 = SiS_Pr->CCRT1CRTC[4];
6177 cr14 = SiS_Pr->CCRT1CRTC[14];
6178 cr5 = SiS_Pr->CCRT1CRTC[5];
6179 cr15 = SiS_Pr->CCRT1CRTC[15];
6180 } else {
6181 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6182 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6183 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6184 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6186 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6187 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6188 tempcx &= 0x00FF;
6189 tempcx |= (tempbx & 0xFF00);
6190 tempbx += bridgeadd;
6191 tempcx += bridgeadd;
6192 tempax = SiS_Pr->SiS_VGAHT;
6193 if(modeflag & HalfDCLK) tempax >>= 1;
6194 tempax--;
6195 if(tempcx > tempax) tempcx = tempax;
6198 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6199 tempbx = 1040;
6200 tempcx = 1044; /* HWCursor bug! */
6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6207 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6209 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6210 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6212 /* 2. Vertical setup */
6214 tempcx = SiS_Pr->SiS_VGAVT - 1;
6215 temp = tempcx & 0x00FF;
6217 if(HwInfo->jChipType < SIS_661) {
6218 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6219 if(HwInfo->jChipType < SIS_315H) {
6220 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6221 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6222 temp--;
6225 } else {
6226 temp--;
6228 } else if(HwInfo->jChipType >= SIS_315H) {
6229 temp--;
6232 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6234 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6235 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6237 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6238 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6240 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
6241 tempbx++;
6242 tempax = tempbx;
6243 tempcx++;
6244 tempcx -= tempax;
6245 tempcx >>= 2;
6246 tempbx += tempcx;
6247 if(tempcx < 4) tempcx = 4;
6248 tempcx >>= 2;
6249 tempcx += tempbx;
6250 tempcx++;
6251 } else {
6252 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6253 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6256 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6257 if(SiS_Pr->UseCustomMode) {
6258 tempbx = SiS_Pr->CVSyncStart;
6259 tempcx = SiS_Pr->CVSyncEnd;
6261 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6262 unsigned char cr8, cr7, cr13;
6263 if(SiS_Pr->UseCustomMode) {
6264 cr8 = SiS_Pr->CCRT1CRTC[8];
6265 cr7 = SiS_Pr->CCRT1CRTC[7];
6266 cr13 = SiS_Pr->CCRT1CRTC[13];
6267 tempcx = SiS_Pr->CCRT1CRTC[9];
6268 } else {
6269 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6270 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6271 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6272 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6274 tempbx = cr8;
6275 if(cr7 & 0x04) tempbx |= 0x0100;
6276 if(cr7 & 0x80) tempbx |= 0x0200;
6277 if(cr13 & 0x08) tempbx |= 0x0400;
6280 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6282 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6283 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6285 /* 3. Panel delay compensation */
6287 if(HwInfo->jChipType < SIS_315H) {
6289 #ifdef SIS300 /* ---------- 300 series -------------- */
6291 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6292 temp = 0x20;
6293 if(HwInfo->jChipType == SIS_300) {
6294 temp = 0x10;
6295 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6296 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6298 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6299 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6301 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6302 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6303 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6304 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6305 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6306 else temp = 0x20;
6308 if(SiS_Pr->SiS_UseROM) {
6309 if(ROMAddr[0x220] & 0x80) {
6310 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6311 temp = ROMAddr[0x221];
6312 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6313 temp = ROMAddr[0x222];
6314 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6315 temp = ROMAddr[0x223];
6316 else
6317 temp = ROMAddr[0x224];
6318 temp &= 0x3c;
6321 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6322 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6325 } else {
6326 temp = 0x20;
6327 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6328 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6330 if(SiS_Pr->SiS_UseROM) {
6331 if(ROMAddr[0x220] & 0x80) {
6332 temp = ROMAddr[0x220] & 0x3c;
6335 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6336 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6340 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6342 #endif /* SIS300 */
6344 } else {
6346 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6348 if(HwInfo->jChipType < SIS_661) {
6350 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6352 if(HwInfo->jChipType == SIS_740) temp = 0x03;
6353 else temp = 0x00;
6355 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6356 tempbl = 0xF0;
6357 if(HwInfo->jChipType == SIS_650) {
6358 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6359 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6363 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6364 temp = 0x08;
6365 tempbl = 0;
6366 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6367 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6371 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6374 } /* < 661 */
6376 tempax = 0;
6377 if(modeflag & DoubleScanMode) tempax |= 0x80;
6378 if(modeflag & HalfDCLK) tempax |= 0x40;
6379 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6381 #endif /* SIS315H */
6385 } /* Slavemode */
6387 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6388 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6389 /* For 301BDH with LCD, we set up the Panel Link */
6390 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6391 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6392 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6394 } else {
6395 if(HwInfo->jChipType < SIS_315H) {
6396 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6397 } else {
6398 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6399 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6400 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6402 } else {
6403 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6409 /*********************************************/
6410 /* SET PART 2 REGISTER GROUP */
6411 /*********************************************/
6413 #ifdef SIS315H
6414 static UCHAR *
6415 SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
6417 const UCHAR *tableptr = NULL;
6418 USHORT a, b, p = 0;
6420 a = SiS_Pr->SiS_VGAHDE;
6421 b = SiS_Pr->SiS_HDE;
6422 if(tabletype) {
6423 a = SiS_Pr->SiS_VGAVDE;
6424 b = SiS_Pr->SiS_VDE;
6427 if(a < b) {
6428 tableptr = SiS_Part2CLVX_1;
6429 } else if(a == b) {
6430 tableptr = SiS_Part2CLVX_2;
6431 } else {
6432 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6433 tableptr = SiS_Part2CLVX_4;
6434 } else {
6435 tableptr = SiS_Part2CLVX_3;
6437 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6438 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6439 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6440 else tableptr = SiS_Part2CLVX_5;
6441 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6442 tableptr = SiS_Part2CLVX_6;
6444 do {
6445 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6446 p += 0x42;
6447 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6448 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6450 p += 2;
6451 return((UCHAR *)&tableptr[p]);
6454 static void
6455 SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6456 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
6458 UCHAR *tableptr;
6459 int i, j;
6460 UCHAR temp;
6462 if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
6464 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
6465 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6466 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6468 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6469 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
6470 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6471 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6474 temp = 0x10;
6475 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6476 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6479 static BOOLEAN
6480 SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
6481 USHORT RefreshRateTableIndex,USHORT *CRT2Index,
6482 USHORT *ResIndex,PSIS_HW_INFO HwInfo)
6485 if(HwInfo->jChipType < SIS_315H) return FALSE;
6487 if(ModeNo <= 0x13)
6488 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6489 else
6490 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6492 (*ResIndex) &= 0x3f;
6493 (*CRT2Index) = 0;
6495 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6496 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6497 (*CRT2Index) = 200;
6501 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6502 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6503 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6506 return(((*CRT2Index) != 0));
6508 #endif
6510 #ifdef SIS300
6511 static void
6512 SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
6514 USHORT tempcx;
6515 const UCHAR atable[] = {
6516 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6517 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6520 if(!SiS_Pr->UseCustomMode) {
6521 if( ( ( (HwInfo->jChipType == SIS_630) ||
6522 (HwInfo->jChipType == SIS_730) ) &&
6523 (HwInfo->jChipRevision > 2) ) &&
6524 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6525 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6526 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6527 if(ModeNo == 0x13) {
6528 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6529 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6530 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6531 } else {
6532 if((crt2crtc & 0x3F) == 4) {
6533 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6534 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6535 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6536 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6537 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6542 if(HwInfo->jChipType < SIS_315H) {
6543 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6544 crt2crtc &= 0x1f;
6545 tempcx = 0;
6546 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6547 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6548 tempcx += 7;
6551 tempcx += crt2crtc;
6552 if(crt2crtc >= 4) {
6553 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6556 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6557 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6558 if(crt2crtc == 4) {
6559 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6563 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6564 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6570 /* For ECS A907. Highly preliminary. */
6571 static void
6572 SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6573 USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
6574 USHORT ModeNo)
6576 USHORT crt2crtc, resindex;
6577 int i,j;
6578 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6580 if(HwInfo->jChipType != SIS_300) return;
6581 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6582 if(SiS_Pr->UseCustomMode) return;
6584 if(ModeNo <= 0x13) {
6585 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6586 } else {
6587 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6590 resindex = crt2crtc & 0x3F;
6591 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6592 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6594 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6595 if(ModeNo > 0x13) {
6596 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6597 resindex = 4;
6600 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6601 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6602 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6603 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6605 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6606 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6608 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6609 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6611 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6612 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6614 #endif
6616 static void
6617 SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
6619 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6620 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6621 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6623 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6624 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6625 const UCHAR specialtv[] = {
6626 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6627 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6628 0x58,0xe4,0x73,0xda,0x13
6630 int i, j;
6631 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6632 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6634 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6635 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6636 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6637 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6638 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6639 } else {
6640 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6641 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6645 } else {
6646 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6647 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6648 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6649 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6650 } else {
6651 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6652 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6657 static void
6658 SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6660 USHORT temp;
6662 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6663 if(SiS_Pr->SiS_VGAVDE == 525) {
6664 temp = 0xc3;
6665 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6666 temp++;
6667 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
6669 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6670 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6671 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6672 temp = 0x4d;
6673 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6674 temp++;
6675 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
6677 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6681 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6682 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6683 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
6684 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6685 /* Not always for LV, see SetGrp2 */
6687 temp = 1;
6688 if(ModeNo <= 0x13) temp = 3;
6689 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6691 #if 0
6692 /* 651+301C, for 1280x768 - do I really need that? */
6693 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6694 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6695 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6696 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6697 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6698 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6699 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6700 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6701 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6702 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6703 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6704 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6705 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6706 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6707 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6708 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6712 #endif
6716 static void
6717 SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
6718 PSIS_HW_INFO HwInfo)
6720 USHORT i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6721 USHORT push2, modeflag, crt2crtc, bridgeoffset;
6722 ULONG longtemp;
6723 const UCHAR *PhasePoint;
6724 const UCHAR *TimingPoint;
6725 #ifdef SIS315H
6726 USHORT resindex, CRT2Index;
6727 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6729 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6730 #endif
6732 if(ModeNo <= 0x13) {
6733 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6734 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6735 } else if(SiS_Pr->UseCustomMode) {
6736 modeflag = SiS_Pr->CModeFlag;
6737 crt2crtc = 0;
6738 } else {
6739 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6740 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6743 temp = 0;
6744 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6745 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6746 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6747 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6749 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6751 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6753 PhasePoint = SiS_Pr->SiS_PALPhase;
6754 TimingPoint = SiS_Pr->SiS_PALTiming;
6756 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6758 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6759 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6760 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6761 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6762 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6763 #if 0
6764 if(!(modeflag & Charx8Dot)) TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
6765 #endif
6769 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6771 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) TimingPoint = &SiS_YPbPrTable[2][0];
6772 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
6773 else TimingPoint = &SiS_YPbPrTable[0][0];
6775 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6777 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6779 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6780 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6781 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6782 PhasePoint = SiS_Pr->SiS_PALPhase2;
6785 } else {
6787 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6788 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6789 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6790 PhasePoint = SiS_Pr->SiS_PALPhase;
6793 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6794 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6795 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6796 PhasePoint = SiS_Pr->SiS_NTSCPhase2;
6797 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6798 PhasePoint = SiS_Pr->SiS_PALPhase2;
6804 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6805 PhasePoint = SiS_Pr->SiS_PALMPhase;
6806 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6807 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6808 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6809 PhasePoint = SiS_Pr->SiS_PALMPhase2;
6813 if(SiS_Pr->SiS_TVMode & TVSetPALN) {
6814 PhasePoint = SiS_Pr->SiS_PALNPhase;
6815 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6816 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6817 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6818 PhasePoint = SiS_Pr->SiS_PALNPhase2;
6822 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6823 PhasePoint = SiS_Pr->SiS_SpecialPhase;
6824 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6825 PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
6826 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6827 PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
6831 for(i=0x31, j=0; i<=0x34; i++, j++) {
6832 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
6835 for(i=0x01, j=0; i<=0x2D; i++, j++) {
6836 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6838 for(i=0x39; i<=0x45; i++, j++) {
6839 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6842 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6843 if(SiS_Pr->SiS_ModeType != ModeText) {
6844 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6848 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6850 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6851 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6852 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6853 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6855 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6856 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6857 else tempax = 440; /* NTSC, YPbPr 525, 750 */
6859 if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
6860 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6861 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6863 tempax -= SiS_Pr->SiS_VDE;
6864 tempax >>= 2;
6865 tempax &= 0x00ff;
6867 temp = tempax + (USHORT)TimingPoint[0];
6868 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6870 temp = tempax + (USHORT)TimingPoint[1];
6871 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6873 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6874 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6875 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 19 */
6876 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 52 */
6877 } else {
6878 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6879 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6885 tempcx = SiS_Pr->SiS_HT;
6886 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6887 tempcx--;
6888 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
6889 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6890 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6892 tempcx = SiS_Pr->SiS_HT >> 1;
6893 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6894 tempcx += 7;
6895 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6896 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6898 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6899 tempbx += tempcx;
6900 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6901 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6903 tempbx += 8;
6904 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6905 tempbx -= 4;
6906 tempcx = tempbx;
6908 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6910 j += 2;
6911 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6912 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6913 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6915 tempcx += 8;
6916 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6917 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6919 tempcx = SiS_Pr->SiS_HT >> 1;
6920 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6921 j += 2;
6922 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6923 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6925 tempcx -= 11;
6926 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6927 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6929 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6931 tempbx = SiS_Pr->SiS_VDE;
6932 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6933 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6934 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6935 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6936 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6937 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6938 tempbx >>= 1;
6939 if(HwInfo->jChipType >= SIS_315H) {
6940 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6941 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6942 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6943 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6944 if(crt2crtc == 4) tempbx++;
6948 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6949 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6950 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6952 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6953 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6957 tempbx -= 2;
6958 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6960 temp = (tempcx >> 8) & 0x0F;
6961 temp |= ((tempbx >> 2) & 0xC0);
6962 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6963 temp |= 0x10;
6964 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6966 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6968 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
6969 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6972 #if 0
6973 /* TEST qqqq */
6974 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6975 for(i=0x01, j=0; i<=0x2D; i++, j++) {
6976 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6978 for(i=0x39; i<=0x45; i++, j++) {
6979 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6982 #endif
6984 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6985 tempbx = SiS_Pr->SiS_VDE;
6986 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6987 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6988 tempbx >>= 1;
6990 tempbx -= 3;
6991 temp = ((tempbx >> 3) & 0x60) | 0x18;
6992 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6993 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6995 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
6996 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7000 tempbx = 0;
7001 if(!(modeflag & HalfDCLK)) {
7002 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7003 tempax = 0;
7004 tempbx |= 0x20;
7008 tempch = tempcl = 0x01;
7009 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7010 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7011 if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
7012 tempch = 0x19;
7013 tempcl = 0x20;
7014 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7015 tempch = 0x14;
7016 tempbx &= ~0x20;
7022 if(!(tempbx & 0x20)) {
7023 if(modeflag & HalfDCLK) tempcl <<= 1;
7024 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7025 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
7026 tempax = longtemp / SiS_Pr->SiS_HDE;
7027 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7028 tempbx |= ((tempax >> 8) & 0x1F);
7029 tempcx = tempax >> 13;
7032 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7033 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7035 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7037 tempcx &= 0x07;
7038 if(tempbx & 0x20) tempcx = 0;
7039 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7041 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7042 tempbx = 0x0382;
7043 tempcx = 0x007e;
7044 } else {
7045 tempbx = 0x0369;
7046 tempcx = 0x0061;
7048 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7049 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7050 temp = (tempcx & 0x0300) >> 6;
7051 temp |= ((tempbx >> 8) & 0x03);
7052 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7053 temp |= 0x10;
7054 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7055 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7057 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7059 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7060 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7062 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7064 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
7065 temp = 0;
7066 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7067 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7072 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7073 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7074 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7075 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7077 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7080 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7081 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7082 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7086 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7088 /* From here: Part2 LCD setup */
7090 tempbx = SiS_Pr->SiS_HDE;
7091 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7092 tempbx--; /* RHACTE = HDE - 1 */
7093 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7094 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7096 temp = 0x01;
7097 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7098 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7099 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7100 temp = 0x02;
7101 if(HwInfo->jChipType >= SIS_315H) {
7102 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7103 temp = 0x01;
7109 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7111 tempbx = SiS_Pr->SiS_VDE - 1;
7112 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7113 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7115 tempcx = SiS_Pr->SiS_VT - 1;
7116 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7117 temp = (tempcx >> 3) & 0xE0;
7118 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7119 /* Enable dithering; only do this for 32bpp mode */
7120 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7121 temp |= 0x10;
7124 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7126 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7127 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7129 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7130 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7132 #ifdef SIS315H
7133 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7134 &CRT2Index, &resindex, HwInfo)) {
7135 switch(CRT2Index) {
7136 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7137 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7138 default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
7141 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7142 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7143 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7144 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7146 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7147 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7149 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7150 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7152 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7153 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7155 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7158 } else {
7159 #endif
7161 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7162 /* Clevo dual-link 1024x768 */
7163 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7164 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7166 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7167 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7168 tempbx = SiS_Pr->SiS_VDE - 1;
7169 tempcx = SiS_Pr->SiS_VT - 1;
7170 } else {
7171 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7172 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7174 } else {
7175 tempbx = SiS_Pr->PanelYRes;
7176 tempcx = SiS_Pr->SiS_VT;
7177 tempax = 1;
7178 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7179 tempax = SiS_Pr->PanelYRes;
7180 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7181 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7182 tempax = tempcx = 0;
7183 } else {
7184 tempax -= SiS_Pr->SiS_VDE;
7186 tempax >>= 1;
7188 tempcx -= tempax; /* lcdvdes */
7189 tempbx -= tempax; /* lcdvdee */
7192 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7194 #ifdef TWDEBUG
7195 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7196 #endif
7198 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7199 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7201 temp = (tempbx >> 5) & 0x38;
7202 temp |= ((tempcx >> 8) & 0x07);
7203 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7205 tempax = SiS_Pr->SiS_VDE;
7206 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7207 tempax = SiS_Pr->PanelYRes;
7209 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7210 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7211 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7212 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7216 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7217 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7218 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7219 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7220 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7221 if(tempax % 4) { tempax >>= 2; tempax++; }
7222 else { tempax >>= 2; }
7223 tempbx -= (tempax - 1);
7224 } else {
7225 tempbx -= 10;
7226 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7230 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7231 tempbx++;
7232 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7233 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7234 tempbx = 770;
7235 tempcx = 3;
7240 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7242 if(SiS_Pr->UseCustomMode) {
7243 tempbx = SiS_Pr->CVSyncStart;
7246 #ifdef TWDEBUG
7247 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7248 #endif
7250 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7252 temp = (tempbx >> 4) & 0xF0;
7253 tempbx += (tempcx + 1);
7254 temp |= (tempbx & 0x0F);
7256 if(SiS_Pr->UseCustomMode) {
7257 temp &= 0xf0;
7258 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7261 #ifdef TWDEBUG
7262 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7263 #endif
7265 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7267 #ifdef SIS300
7268 SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
7269 #endif
7271 bridgeoffset = 7;
7272 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) bridgeoffset += 2;
7273 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
7274 if(SiS_IsDualLink(SiS_Pr, HwInfo)) bridgeoffset++;
7276 temp = 0;
7277 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7278 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7279 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7280 if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
7283 temp += bridgeoffset;
7284 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7285 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7287 tempcx = SiS_Pr->SiS_HT;
7288 tempax = tempbx = SiS_Pr->SiS_HDE;
7289 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7290 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7291 tempax = SiS_Pr->PanelXRes;
7292 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7295 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7296 tempcx >>= 1;
7297 tempbx >>= 1;
7298 tempax >>= 1;
7301 #ifdef TWDEBUG
7302 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7303 #endif
7305 tempbx += bridgeoffset;
7307 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7308 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7310 tempcx = (tempcx - tempax) >> 2;
7312 tempbx += tempcx;
7313 push2 = tempbx;
7315 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7316 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7317 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7318 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7323 if(SiS_Pr->UseCustomMode) {
7324 tempbx = SiS_Pr->CHSyncStart;
7325 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7326 tempbx += bridgeoffset;
7329 #ifdef TWDEBUG
7330 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7331 #endif
7333 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7334 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7336 tempbx = push2;
7338 tempcx <<= 1;
7339 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7340 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7342 tempbx += tempcx;
7344 if(SiS_Pr->UseCustomMode) {
7345 tempbx = SiS_Pr->CHSyncEnd;
7346 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7347 tempbx += bridgeoffset;
7350 #ifdef TWDEBUG
7351 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7352 #endif
7354 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7356 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7358 #ifdef SIS300
7359 SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7360 #endif
7361 #ifdef SIS315H
7362 } /* CRT2-LCD from table */
7363 #endif
7366 /*********************************************/
7367 /* SET PART 3 REGISTER GROUP */
7368 /*********************************************/
7370 static void
7371 SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7372 PSIS_HW_INFO HwInfo)
7374 USHORT i;
7375 const UCHAR *tempdi;
7377 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7379 #ifndef SIS_CP
7380 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7381 #else
7382 SIS_CP_INIT301_CP
7383 #endif
7385 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7386 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7387 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7388 } else {
7389 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7390 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7393 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7394 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7395 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7396 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7399 tempdi = NULL;
7400 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7401 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7402 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7403 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7405 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7406 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7407 tempdi = SiS_HiTVGroup3_1;
7408 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7411 if(tempdi) {
7412 for(i=0; i<=0x3E; i++) {
7413 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7415 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
7416 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7417 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7422 #ifdef SIS_CP
7423 SIS_CP_INIT301_CP2
7424 #endif
7427 /*********************************************/
7428 /* SET PART 4 REGISTER GROUP */
7429 /*********************************************/
7431 #ifdef SIS315H
7432 static void
7433 SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
7435 USHORT temp, temp1, temp2;
7437 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7438 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7439 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7440 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7441 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7442 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7443 temp = (USHORT)((int)(temp) + shift);
7444 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7445 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7446 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7447 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7448 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7449 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7452 static void
7453 SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7454 USHORT ModeNo, USHORT ModeIdIndex)
7456 USHORT temp, temp1, resinfo = 0;
7458 if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
7459 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7461 if(ModeNo > 0x13) {
7462 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7465 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7466 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7467 if(!(temp & 0x01)) {
7468 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7469 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7470 if(HwInfo->jChipType < SIS_661) {
7471 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7473 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7474 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7475 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7476 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7477 else temp = 0x0402;
7478 if(HwInfo->jChipType >= SIS_661) {
7479 temp1 = 0;
7480 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7481 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7482 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7483 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7484 } else {
7485 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7486 if(temp1 == 0x01) temp |= 0x01;
7487 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7488 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7490 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7492 if(HwInfo->jChipType >= SIS_661) { /* ? */
7493 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7494 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7495 if(resinfo == SIS_RI_1024x768) {
7496 SiS_ShiftXPos(SiS_Pr, 97);
7497 } else {
7498 SiS_ShiftXPos(SiS_Pr, 111);
7500 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7501 SiS_ShiftXPos(SiS_Pr, 136);
7507 #endif
7509 static void
7510 SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7511 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7513 USHORT vclkindex;
7514 USHORT temp, reg1, reg2;
7516 if(SiS_Pr->UseCustomMode) {
7517 reg1 = SiS_Pr->CSR2B;
7518 reg2 = SiS_Pr->CSR2C;
7519 } else {
7520 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7521 HwInfo);
7522 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7523 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7526 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7527 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7528 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7529 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7530 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7531 } else {
7532 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7533 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7535 } else {
7536 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7537 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7538 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7540 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7541 temp = 0x08;
7542 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7543 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7546 static void
7547 SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7548 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7550 USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
7551 ULONG tempebx,tempeax,templong;
7553 if(ModeNo <= 0x13) {
7554 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7555 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7556 } else if(SiS_Pr->UseCustomMode) {
7557 modeflag = SiS_Pr->CModeFlag;
7558 resinfo = 0;
7559 } else {
7560 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7561 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7564 if(HwInfo->jChipType >= SIS_315H) {
7565 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7566 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7567 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7572 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
7573 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7574 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7578 if(HwInfo->jChipType >= SIS_315H) {
7579 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7580 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7581 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7582 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7585 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7586 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7587 #ifdef SET_EMI
7588 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7589 #endif
7590 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7593 return;
7597 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7599 tempbx = SiS_Pr->SiS_RVBHCMAX;
7600 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7602 temp = (tempbx >> 1) & 0x80;
7604 tempcx = SiS_Pr->SiS_VGAHT - 1;
7605 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7607 temp |= ((tempcx >> 5) & 0x78);
7609 tempcx = SiS_Pr->SiS_VGAVT - 1;
7610 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7611 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7613 temp |= ((tempcx >> 8) & 0x07);
7614 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7616 tempbx = SiS_Pr->SiS_VGAHDE;
7617 if(modeflag & HalfDCLK) tempbx >>= 1;
7618 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7620 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7621 temp = 0;
7622 if(tempbx > 800) temp = 0x60;
7623 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7624 temp = 0;
7625 if(tempbx == 1024) temp = 0xA0;
7626 else if(tempbx > 1024) temp = 0xC0;
7627 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7628 temp = 0;
7629 if(tempbx >= 1280) temp = 0x40;
7630 else if(tempbx >= 1024) temp = 0x20;
7631 } else {
7632 temp = 0x80;
7633 if(tempbx >= 1024) temp = 0xA0;
7636 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7637 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
7640 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7642 tempeax = SiS_Pr->SiS_VGAVDE;
7643 tempebx = SiS_Pr->SiS_VDE;
7644 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7645 if(!(temp & 0xE0)) tempebx >>=1;
7648 tempcx = SiS_Pr->SiS_RVBHRS;
7649 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7650 tempcx >>= 8;
7651 tempcx |= 0x40;
7653 if(tempeax <= tempebx) {
7654 tempcx ^= 0x40;
7655 } else {
7656 tempeax -= tempebx;
7659 tempeax *= (256 * 1024);
7660 templong = tempeax % tempebx;
7661 tempeax /= tempebx;
7662 if(templong) tempeax++;
7664 temp = (USHORT)(tempeax & 0x000000FF);
7665 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7666 temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
7667 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7668 temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
7669 temp |= (tempcx & 0x4F);
7670 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7672 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7674 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7676 /* Calc Linebuffer max address and set/clear decimode */
7677 tempbx = 0;
7678 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7679 tempax = SiS_Pr->SiS_VGAHDE;
7680 if(modeflag & HalfDCLK) tempax >>= 1;
7681 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
7682 if(tempax > 800) {
7683 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7684 tempax -= 800;
7685 } else { /* 651+301C: Only if TVNoHiviNoYPbPr */
7686 tempbx = 0x08;
7687 if(tempax == 1024) tempax *= 25;
7688 else tempax *= 20;
7689 temp = tempax % 32;
7690 tempax /= 32;
7691 if(temp) tempax++;
7692 tempax++;
7693 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
7694 (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7695 if(resinfo == SIS_RI_1024x768) {
7696 /* Otherwise white line at right edge */
7697 tempax = (tempax & 0xff00) | 0x20;
7702 tempax--;
7703 temp = ((tempax >> 4) & 0x30) | tempbx;
7704 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7705 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7707 temp = 0x0036; tempbx = 0xD0;
7708 if((IS_SIS550650740660) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
7709 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7711 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7712 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7713 temp |= 0x01;
7714 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7715 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7716 temp &= ~0x01;
7721 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7723 tempbx = SiS_Pr->SiS_HT >> 1;
7724 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7725 tempbx -= 2;
7726 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7727 temp = (tempbx >> 5) & 0x38;
7728 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7730 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7731 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7732 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7733 /* LCD-too-dark-error-source, see FinalizeLCD() */
7735 if(HwInfo->jChipType >= SIS_315H) {
7736 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7737 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7740 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7741 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7742 #ifdef SET_EMI
7743 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7744 #endif
7745 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7749 } /* 301B */
7751 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
7754 /*********************************************/
7755 /* SET PART 5 REGISTER GROUP */
7756 /*********************************************/
7758 static void
7759 SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7760 PSIS_HW_INFO HwInfo)
7763 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7765 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7766 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7767 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7768 SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
7773 /*********************************************/
7774 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7775 /*********************************************/
7777 static void
7778 SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7779 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7781 USHORT tempah,i,modeflag,j;
7782 USHORT ResIndex,DisplayType;
7783 const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
7785 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7786 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7788 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7789 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7790 (SiS_Pr->SiS_CustomT == CUT_PANEL848))
7791 return;
7793 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7794 &ResIndex, &DisplayType))) {
7795 return;
7798 if(HwInfo->jChipType < SIS_315H) {
7799 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7802 switch(DisplayType) {
7803 case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
7804 case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
7805 case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
7806 case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
7807 case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
7808 case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
7809 case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
7810 case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
7811 case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
7812 case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
7813 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
7814 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
7815 case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
7816 case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
7817 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
7818 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
7819 case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
7820 case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
7821 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7822 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7823 case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7824 case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7825 case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */
7826 case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7827 case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7828 case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7829 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7830 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break;
7831 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break;
7832 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break;
7833 case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break;
7834 case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break;
7835 case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break;
7836 case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break;
7837 case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break;
7838 case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1; break;
7839 case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break;
7840 case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break;
7841 case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break;
7842 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7843 case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7844 case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break;
7845 case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break;
7846 case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break;
7847 case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break;
7848 case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7849 default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
7852 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7854 tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
7855 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
7857 for(i=0x02,j=1;i<=0x05;i++,j++){
7858 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7859 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7861 for(i=0x06,j=5;i<=0x07;i++,j++){
7862 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7863 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7865 for(i=0x10,j=7;i<=0x11;i++,j++){
7866 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7867 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7869 for(i=0x15,j=9;i<=0x16;i++,j++){
7870 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7871 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7873 for(i=0x0A,j=11;i<=0x0C;i++,j++){
7874 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7875 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7878 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
7879 tempah &= 0xE0;
7880 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7882 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
7883 tempah &= 0x01;
7884 tempah <<= 5;
7885 if(modeflag & DoubleScanMode) tempah |= 0x080;
7886 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7889 /*********************************************/
7890 /* SET CRT2 ECLK */
7891 /*********************************************/
7893 static void
7894 SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7895 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7897 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
7898 USHORT clkbase, vclkindex=0;
7899 UCHAR sr2b, sr2c;
7901 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
7902 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7903 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
7904 RefreshRateTableIndex--;
7906 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7907 RefreshRateTableIndex, HwInfo);
7908 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7909 } else {
7910 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7911 RefreshRateTableIndex, HwInfo);
7914 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7915 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7917 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7918 if(SiS_Pr->SiS_UseROM) {
7919 if(ROMAddr[0x220] & 0x01) {
7920 sr2b = ROMAddr[0x227];
7921 sr2c = ROMAddr[0x228];
7926 clkbase = 0x02B;
7927 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7928 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7929 clkbase += 3;
7933 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7934 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7935 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7936 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7937 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7938 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7939 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7940 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7941 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7944 /*********************************************/
7945 /* SET UP CHRONTEL CHIPS */
7946 /*********************************************/
7948 static void
7949 SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7950 USHORT RefreshRateTableIndex)
7952 #if defined(SIS300) || defined(SIS315H)
7953 USHORT temp, tempbx;
7954 #endif
7955 USHORT tempcl;
7956 USHORT TVType, resindex;
7957 const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
7959 if(ModeNo <= 0x13)
7960 tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7961 else
7962 tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7964 TVType = 0;
7965 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7966 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7967 TVType += 2;
7968 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7969 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7971 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7972 TVType = 4;
7973 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7974 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7975 TVType = 6;
7976 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7979 switch(TVType) {
7980 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7981 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7982 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
7983 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7984 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7985 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7986 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7987 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7988 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7989 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7991 resindex = tempcl & 0x3F;
7993 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7995 #ifdef SIS300
7997 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7999 /* We don't support modes >800x600 */
8000 if (resindex > 5) return;
8002 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8003 SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8004 SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/
8005 } else {
8006 SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8007 SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/
8010 temp = CHTVRegData[resindex].Reg[0];
8011 tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */
8012 SiS_SetCH700x(SiS_Pr,tempbx);
8013 temp = CHTVRegData[resindex].Reg[1];
8014 tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */
8015 SiS_SetCH700x(SiS_Pr,tempbx);
8016 temp = CHTVRegData[resindex].Reg[2];
8017 tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */
8018 SiS_SetCH700x(SiS_Pr,tempbx);
8019 temp = CHTVRegData[resindex].Reg[3];
8020 tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */
8021 SiS_SetCH700x(SiS_Pr,tempbx);
8022 temp = CHTVRegData[resindex].Reg[4];
8023 tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */
8024 SiS_SetCH700x(SiS_Pr,tempbx);
8026 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8027 minimum text enhancement (S3-2=10),
8028 maximum flicker filter for Chroma channel (S5-4=10)
8029 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8031 SiS_SetCH700x(SiS_Pr,0x2801);
8033 /* Set video bandwidth
8034 High bandwith Luma composite video filter(S0=1)
8035 low bandwith Luma S-video filter (S2-1=00)
8036 disable peak filter in S-video channel (S3=0)
8037 high bandwidth Chroma Filter (S5-4=11)
8038 =00110001=0x31
8040 SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */
8042 /* Register 0x3D does not exist in non-macrovision register map
8043 (Maybe this is a macrovision register?)
8045 #ifndef SIS_CP
8046 SiS_SetCH70xx(SiS_Pr,0x003D);
8047 #endif
8049 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8050 all other bits a read-only. Macrovision?
8052 SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
8054 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8055 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8057 SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
8059 /* Clear DSEN
8061 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
8063 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8064 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8065 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8066 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8067 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on, no need to set FSCI */
8068 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8069 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8070 SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
8071 SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
8072 SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
8073 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
8074 SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
8075 SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
8076 SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
8077 SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF); /* Loop filter on for mode 23 */
8078 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8080 } else {
8081 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8082 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8083 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8084 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8085 #if 0
8086 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8087 SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */
8088 SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0); /* 198b3a63 */
8089 SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
8090 SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
8091 SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
8092 SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
8093 SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
8094 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */
8095 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8096 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8097 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8098 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8101 } else { /* ---- PAL ---- */
8102 /* We don't play around with FSCI in PAL mode */
8103 if(resindex == 0x04) {
8104 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8105 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8106 } else {
8107 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8108 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8112 #endif /* 300 */
8114 } else {
8116 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8118 #ifdef SIS315H
8120 /* We don't support modes >1024x768 */
8121 if (resindex > 6) return;
8123 temp = CHTVRegData[resindex].Reg[0];
8124 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8125 temp |= 0x10;
8127 tempbx=((temp & 0x00FF) << 8) | 0x00;
8128 SiS_SetCH701x(SiS_Pr,tempbx);
8130 temp = CHTVRegData[resindex].Reg[1];
8131 tempbx=((temp & 0x00FF) << 8) | 0x01;
8132 SiS_SetCH701x(SiS_Pr,tempbx);
8134 temp = CHTVRegData[resindex].Reg[2];
8135 tempbx=((temp & 0x00FF) << 8) | 0x02;
8136 SiS_SetCH701x(SiS_Pr,tempbx);
8138 temp = CHTVRegData[resindex].Reg[3];
8139 tempbx=((temp & 0x00FF) << 8) | 0x04;
8140 SiS_SetCH701x(SiS_Pr,tempbx);
8142 temp = CHTVRegData[resindex].Reg[4];
8143 tempbx=((temp & 0x00FF) << 8) | 0x03;
8144 SiS_SetCH701x(SiS_Pr,tempbx);
8146 temp = CHTVRegData[resindex].Reg[5];
8147 tempbx=((temp & 0x00FF) << 8) | 0x05;
8148 SiS_SetCH701x(SiS_Pr,tempbx);
8150 temp = CHTVRegData[resindex].Reg[6];
8151 tempbx=((temp & 0x00FF) << 8) | 0x06;
8152 SiS_SetCH701x(SiS_Pr,tempbx);
8154 temp = CHTVRegData[resindex].Reg[7];
8155 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8156 temp = 0x66;
8158 tempbx=((temp & 0x00FF) << 8) | 0x07;
8159 SiS_SetCH701x(SiS_Pr,tempbx);
8161 temp = CHTVRegData[resindex].Reg[8];
8162 tempbx=((temp & 0x00FF) << 8) | 0x08;
8163 SiS_SetCH701x(SiS_Pr,tempbx);
8165 temp = CHTVRegData[resindex].Reg[9];
8166 tempbx=((temp & 0x00FF) << 8) | 0x15;
8167 SiS_SetCH701x(SiS_Pr,tempbx);
8169 temp = CHTVRegData[resindex].Reg[10];
8170 tempbx=((temp & 0x00FF) << 8) | 0x1f;
8171 SiS_SetCH701x(SiS_Pr,tempbx);
8173 temp = CHTVRegData[resindex].Reg[11];
8174 tempbx=((temp & 0x00FF) << 8) | 0x0c;
8175 SiS_SetCH701x(SiS_Pr,tempbx);
8177 temp = CHTVRegData[resindex].Reg[12];
8178 tempbx=((temp & 0x00FF) << 8) | 0x0d;
8179 SiS_SetCH701x(SiS_Pr,tempbx);
8181 temp = CHTVRegData[resindex].Reg[13];
8182 tempbx=((temp & 0x00FF) << 8) | 0x0e;
8183 SiS_SetCH701x(SiS_Pr,tempbx);
8185 temp = CHTVRegData[resindex].Reg[14];
8186 tempbx=((temp & 0x00FF) << 8) | 0x0f;
8187 SiS_SetCH701x(SiS_Pr,tempbx);
8189 temp = CHTVRegData[resindex].Reg[15];
8190 tempbx=((temp & 0x00FF) << 8) | 0x10;
8191 SiS_SetCH701x(SiS_Pr,tempbx);
8193 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8194 /* D1 should be set for PAL, PAL-N and NTSC-J,
8195 but I won't do that for PAL unless somebody
8196 tells me to do so. Since the BIOS uses
8197 non-default CIV values and blacklevels,
8198 this might be compensated anyway.
8200 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8201 SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
8203 #endif /* 315 */
8207 #ifdef SIS_CP
8208 SIS_CP_INIT301_CP3
8209 #endif
8213 void
8214 SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8216 USHORT temp;
8218 /* Enable Chrontel 7019 LCD panel backlight */
8219 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8220 if(HwInfo->jChipType == SIS_740) {
8221 SiS_SetCH701x(SiS_Pr,0x6566);
8222 } else {
8223 temp = SiS_GetCH701x(SiS_Pr,0x66);
8224 temp |= 0x20;
8225 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8230 void
8231 SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
8233 USHORT temp;
8235 /* Disable Chrontel 7019 LCD panel backlight */
8236 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8237 temp = SiS_GetCH701x(SiS_Pr,0x66);
8238 temp &= 0xDF;
8239 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8243 #ifdef SIS315H /* ----------- 315 series only ---------- */
8245 static void
8246 SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8248 UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8249 UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8250 UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8251 UCHAR asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8252 UCHAR asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8253 UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8254 UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8255 UCHAR *tableptr = NULL;
8256 int i;
8258 /* Set up Power up/down timing */
8260 if(HwInfo->jChipType == SIS_740) {
8261 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8262 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8263 else tableptr = table1024_740;
8264 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8265 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8266 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8267 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8268 else tableptr = table1400_740;
8269 } else return;
8270 } else {
8271 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8272 tableptr = table1024_650;
8273 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8274 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8275 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8276 tableptr = table1400_650;
8277 } else return;
8280 for(i=0; i<5; i++) {
8281 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8285 static void
8286 SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8288 UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8289 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
8290 UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8291 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
8292 UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8293 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8294 UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8295 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8296 UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8297 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
8298 UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8299 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
8300 UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8301 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
8302 UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8303 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
8304 UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8305 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
8306 UCHAR *tableptr = NULL;
8307 USHORT tempbh;
8308 int i;
8310 if(HwInfo->jChipType == SIS_740) {
8311 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8312 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8313 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8314 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8315 else return;
8316 } else {
8317 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8318 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8319 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8320 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8321 else return;
8324 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8325 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8326 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8327 if(tempbh == 0xc8) {
8328 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8329 } else if(tempbh == 0xdb) {
8330 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8331 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8332 } else if(tempbh == 0xde) {
8333 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8337 if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
8338 else tempbh = 0x0c;
8340 for(i = 0; i < tempbh; i++) {
8341 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8343 SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
8344 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8345 tempbh |= 0xc0;
8346 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
8348 if(HwInfo->jChipType == SIS_740) {
8349 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8350 tempbh &= 0xfb;
8351 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
8352 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8353 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8354 tempbh |= 0x40;
8355 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
8356 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8357 tempbh &= 0x3f;
8358 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
8362 static void
8363 SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
8365 unsigned char temp, temp1;
8367 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8368 SiS_SetCH701x(SiS_Pr,0x3e49);
8369 temp = SiS_GetCH701x(SiS_Pr,0x47);
8370 temp &= 0x7f; /* Use external VSYNC */
8371 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8372 SiS_LongDelay(SiS_Pr,3);
8373 temp = SiS_GetCH701x(SiS_Pr,0x47);
8374 temp |= 0x80; /* Use internal VSYNC */
8375 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8376 SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
8379 void
8380 SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8382 USHORT temp;
8384 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8385 if(HwInfo->jChipType == SIS_740) {
8386 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8387 temp |= 0x04; /* Invert XCLK phase */
8388 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8390 if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
8391 temp = SiS_GetCH701x(SiS_Pr,0x01);
8392 temp &= 0x3f;
8393 temp |= 0x80; /* Enable YPrPb (HDTV) */
8394 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8396 if(SiS_IsChScart(SiS_Pr, HwInfo)) {
8397 temp = SiS_GetCH701x(SiS_Pr,0x01);
8398 temp &= 0x3f;
8399 temp |= 0xc0; /* Enable SCART + CVBS */
8400 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8402 if(HwInfo->jChipType == SIS_740) {
8403 SiS_ChrontelResetVSync(SiS_Pr);
8404 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8405 } else {
8406 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8407 temp = SiS_GetCH701x(SiS_Pr,0x49);
8408 if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
8409 temp = SiS_GetCH701x(SiS_Pr,0x73);
8410 temp |= 0x60;
8411 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
8413 temp = SiS_GetCH701x(SiS_Pr,0x47);
8414 temp &= 0x7f;
8415 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8416 SiS_LongDelay(SiS_Pr,2);
8417 temp = SiS_GetCH701x(SiS_Pr,0x47);
8418 temp |= 0x80;
8419 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8424 void
8425 SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8427 USHORT temp;
8429 /* Complete power down of LVDS */
8430 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8431 if(HwInfo->jChipType == SIS_740) {
8432 SiS_LongDelay(SiS_Pr,1);
8433 SiS_GenericDelay(SiS_Pr,0x16ff);
8434 SiS_SetCH701x(SiS_Pr,0xac76);
8435 SiS_SetCH701x(SiS_Pr,0x0066);
8436 } else {
8437 SiS_LongDelay(SiS_Pr,2);
8438 temp = SiS_GetCH701x(SiS_Pr,0x76);
8439 temp &= 0xfc;
8440 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8441 SiS_SetCH701x(SiS_Pr,0x0066);
8446 static void
8447 SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8449 USHORT temp;
8451 if(HwInfo->jChipType == SIS_740) {
8453 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8454 temp &= 0x01;
8455 if(!temp) {
8457 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8458 temp = SiS_GetCH701x(SiS_Pr,0x49);
8459 SiS_SetCH701x(SiS_Pr,0x3e49);
8461 /* Reset Chrontel 7019 datapath */
8462 SiS_SetCH701x(SiS_Pr,0x1048);
8463 SiS_LongDelay(SiS_Pr,1);
8464 SiS_SetCH701x(SiS_Pr,0x1848);
8466 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8467 SiS_ChrontelResetVSync(SiS_Pr);
8468 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
8471 } else {
8473 /* Clear/set/clear GPIO */
8474 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8475 temp &= 0xef;
8476 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8477 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8478 temp |= 0x10;
8479 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8480 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8481 temp &= 0xef;
8482 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8483 temp = SiS_GetCH701x(SiS_Pr,0x61);
8484 if(!temp) {
8485 SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
8489 } else { /* 650 */
8490 /* Reset Chrontel 7019 datapath */
8491 SiS_SetCH701x(SiS_Pr,0x1048);
8492 SiS_LongDelay(SiS_Pr,1);
8493 SiS_SetCH701x(SiS_Pr,0x1848);
8497 void
8498 SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8500 USHORT temp;
8502 if(HwInfo->jChipType == SIS_740) {
8504 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8505 SiS_ChrontelResetVSync(SiS_Pr);
8508 } else {
8510 SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
8511 temp = SiS_GetCH701x(SiS_Pr,0x49);
8512 temp &= 1;
8513 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8514 temp = SiS_GetCH701x(SiS_Pr,0x47);
8515 temp &= 0x70;
8516 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
8517 SiS_LongDelay(SiS_Pr,3);
8518 temp = SiS_GetCH701x(SiS_Pr,0x47);
8519 temp |= 0x80;
8520 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
8526 static void
8527 SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
8529 USHORT temp,temp1;
8531 if(HwInfo->jChipType == SIS_740) {
8533 temp = SiS_GetCH701x(SiS_Pr,0x61);
8534 if(temp < 1) {
8535 temp++;
8536 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8538 SiS_SetCH701x(SiS_Pr,0x4566); /* Panel power on */
8539 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on */
8540 SiS_LongDelay(SiS_Pr,1);
8541 SiS_GenericDelay(SiS_Pr,0x16ff);
8543 } else { /* 650 */
8545 temp1 = 0;
8546 temp = SiS_GetCH701x(SiS_Pr,0x61);
8547 if(temp < 2) {
8548 temp++;
8549 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8550 temp1 = 1;
8552 SiS_SetCH701x(SiS_Pr,0xac76);
8553 temp = SiS_GetCH701x(SiS_Pr,0x66);
8554 temp |= 0x5f;
8555 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8556 if(ModeNo > 0x13) {
8557 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8558 SiS_GenericDelay(SiS_Pr,0x3ff);
8559 } else {
8560 SiS_GenericDelay(SiS_Pr,0x2ff);
8562 } else {
8563 if(!temp1)
8564 SiS_GenericDelay(SiS_Pr,0x2ff);
8566 temp = SiS_GetCH701x(SiS_Pr,0x76);
8567 temp |= 0x03;
8568 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8569 temp = SiS_GetCH701x(SiS_Pr,0x66);
8570 temp &= 0x7f;
8571 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8572 SiS_LongDelay(SiS_Pr,1);
8577 static void
8578 SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8580 USHORT temp,tempcl,tempch;
8582 SiS_LongDelay(SiS_Pr, 1);
8583 tempcl = 3;
8584 tempch = 0;
8586 do {
8587 temp = SiS_GetCH701x(SiS_Pr,0x66);
8588 temp &= 0x04; /* PLL stable? -> bail out */
8589 if(temp == 0x04) break;
8591 if(HwInfo->jChipType == SIS_740) {
8592 /* Power down LVDS output, PLL normal operation */
8593 SiS_SetCH701x(SiS_Pr,0xac76);
8596 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8598 if(tempcl == 0) {
8599 if(tempch == 3) break;
8600 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8601 tempcl = 3;
8602 tempch++;
8604 tempcl--;
8605 temp = SiS_GetCH701x(SiS_Pr,0x76);
8606 temp &= 0xfb; /* Reset PLL */
8607 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8608 SiS_LongDelay(SiS_Pr,2);
8609 temp = SiS_GetCH701x(SiS_Pr,0x76);
8610 temp |= 0x04; /* PLL normal operation */
8611 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8612 if(HwInfo->jChipType == SIS_740) {
8613 SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */
8614 } else {
8615 SiS_SetCH701x(SiS_Pr,0x6078);
8617 SiS_LongDelay(SiS_Pr,2);
8618 } while(0);
8620 SiS_SetCH701x(SiS_Pr,0x0077); /* MV? */
8623 void
8624 SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8626 USHORT temp;
8628 temp = SiS_GetCH701x(SiS_Pr,0x03);
8629 temp |= 0x80; /* Set datapath 1 to TV */
8630 temp &= 0xbf; /* Set datapath 2 to LVDS */
8631 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8633 if(HwInfo->jChipType == SIS_740) {
8635 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8636 temp &= 0xfb; /* Normal XCLK phase */
8637 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8639 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8641 temp = SiS_GetCH701x(SiS_Pr,0x64);
8642 temp |= 0x40; /* ? Bit not defined */
8643 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
8645 temp = SiS_GetCH701x(SiS_Pr,0x03);
8646 temp &= 0x3f; /* D1 input to both LVDS and TV */
8647 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8649 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8650 SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
8651 SiS_LongDelay(SiS_Pr, 1);
8652 SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
8653 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8654 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8655 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8656 } else {
8657 temp = SiS_GetCH701x(SiS_Pr,0x66);
8658 if(temp != 0x45) {
8659 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8660 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8661 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8665 } else { /* 650 */
8667 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8668 SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
8669 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8670 SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
8671 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on, LVDS normal operation */
8676 #endif /* 315 series */
8678 /*********************************************/
8679 /* MAIN: SET CRT2 REGISTER GROUP */
8680 /*********************************************/
8682 BOOLEAN
8683 SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8685 #ifdef SIS300
8686 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8687 #endif
8688 USHORT ModeIdIndex, RefreshRateTableIndex;
8689 #if 0
8690 USHORT temp;
8691 #endif
8693 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8695 if(!SiS_Pr->UseCustomMode) {
8696 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8697 } else {
8698 ModeIdIndex = 0;
8701 /* Used for shifting CR33 */
8702 SiS_Pr->SiS_SelectCRT2Rate = 4;
8704 SiS_UnLockCRT2(SiS_Pr, HwInfo);
8706 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8708 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8710 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8711 SiS_DisableBridge(SiS_Pr,HwInfo);
8712 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
8713 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8715 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8718 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8719 SiS_LockCRT2(SiS_Pr, HwInfo);
8720 SiS_DisplayOn(SiS_Pr);
8721 return TRUE;
8724 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8726 /* Set up Panel Link for LVDS and LCDA */
8727 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8728 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8729 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8730 ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
8731 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8734 #ifdef LINUX_XF86
8735 #ifdef TWDEBUG
8736 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8737 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8738 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8739 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8740 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8741 #endif
8742 #endif
8744 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8745 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
8748 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8750 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8752 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8753 #ifdef SIS315H
8754 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8755 #endif
8756 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8757 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8758 #ifdef SIS315H
8759 SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8760 #endif
8761 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8763 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8765 /* For 301BDH (Panel link initialization): */
8766 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8767 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
8768 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8769 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8770 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
8771 RefreshRateTableIndex,HwInfo);
8775 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
8776 RefreshRateTableIndex,HwInfo);
8780 } else {
8782 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8784 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8785 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8788 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8790 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8791 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8792 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8793 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8794 #ifdef SIS315H
8795 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8796 #endif
8799 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8800 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8807 #ifdef SIS300
8808 if(HwInfo->jChipType < SIS_315H) {
8809 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8810 if(SiS_Pr->SiS_UseOEM) {
8811 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8812 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8813 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8814 RefreshRateTableIndex);
8816 } else {
8817 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8818 RefreshRateTableIndex);
8821 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8822 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8823 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8824 SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8826 if(HwInfo->jChipType == SIS_730) {
8827 SiS_DisplayOn(SiS_Pr);
8831 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8832 if(HwInfo->jChipType != SIS_730) {
8833 SiS_DisplayOn(SiS_Pr);
8837 #endif
8839 #ifdef SIS315H
8840 if(HwInfo->jChipType >= SIS_315H) {
8841 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8842 if(HwInfo->jChipType < SIS_661) {
8843 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8844 SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8845 } else {
8846 SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8848 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8851 #endif
8853 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8854 SiS_EnableBridge(SiS_Pr, HwInfo);
8857 SiS_DisplayOn(SiS_Pr);
8859 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8860 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8861 /* Disable LCD panel when using TV */
8862 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
8863 } else {
8864 /* Disable TV when using LCD */
8865 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
8869 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8870 SiS_LockCRT2(SiS_Pr,HwInfo);
8873 return TRUE;
8877 /*********************************************/
8878 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8879 /*********************************************/
8881 void
8882 SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8884 /* Switch on LCD backlight on SiS30xLV */
8885 SiS_DDC2Delay(SiS_Pr,0xff00);
8886 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8887 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8888 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
8890 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8891 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8895 void
8896 SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8898 /* Switch off LCD backlight on SiS30xLV */
8899 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8900 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
8901 SiS_DDC2Delay(SiS_Pr,0xe000);
8904 /*********************************************/
8905 /* DDC RELATED FUNCTIONS */
8906 /*********************************************/
8908 static void
8909 SiS_SetupDDCN(SiS_Private *SiS_Pr)
8911 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8912 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8913 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8914 SiS_Pr->SiS_DDC_NData &= 0x0f;
8915 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8919 #ifdef SIS300
8920 static UCHAR *
8921 SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
8923 int i, j, num;
8924 USHORT tempah,temp;
8925 UCHAR *mydataptr;
8927 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8928 mydataptr = dataptr;
8929 num = *mydataptr++;
8930 if(!num) return mydataptr;
8931 if(i) {
8932 SiS_SetStop(SiS_Pr);
8933 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
8935 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8936 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8937 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8938 if(temp) continue; /* (ERROR: no ack) */
8939 tempah = *mydataptr++;
8940 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8941 if(temp) continue; /* (ERROR: no ack) */
8942 for(j=0; j<num; j++) {
8943 tempah = *mydataptr++;
8944 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8945 if(temp) break;
8947 if(temp) continue;
8948 if(SiS_SetStop(SiS_Pr)) continue;
8949 return mydataptr;
8951 return NULL;
8954 static BOOLEAN
8955 SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
8957 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8958 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8959 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8960 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8961 SiS_SetupDDCN(SiS_Pr);
8963 SiS_SetSwitchDDC2(SiS_Pr);
8965 while(*dataptr) {
8966 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8967 if(!dataptr) return FALSE;
8969 #ifdef TWDEBUG
8970 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
8971 #endif
8972 return TRUE;
8974 #endif
8976 /* The Chrontel 700x is connected to the 630/730 via
8977 * the 630/730's DDC/I2C port.
8979 * On 630(S)T chipset, the index changed from 0x11 to
8980 * 0x0a, possibly for working around the DDC problems
8983 static BOOLEAN
8984 SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
8986 USHORT tempah,temp,i;
8988 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8989 if(i) {
8990 SiS_SetStop(SiS_Pr);
8991 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8993 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8994 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8995 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8996 if(temp) continue; /* (ERROR: no ack) */
8997 tempah = tempbx & 0x00FF; /* Write RAB */
8998 tempah |= myor; /* (700x: set bit 7, see datasheet) */
8999 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9000 if(temp) continue; /* (ERROR: no ack) */
9001 tempah = (tempbx & 0xFF00) >> 8;
9002 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
9003 if(temp) continue; /* (ERROR: no ack) */
9004 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9005 SiS_Pr->SiS_ChrontelInit = 1;
9006 return TRUE;
9008 return FALSE;
9011 #ifdef SIS300
9012 /* Write Trumpion register */
9013 void
9014 SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9016 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9017 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9018 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9019 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9020 SiS_SetupDDCN(SiS_Pr);
9021 SiS_SetChReg(SiS_Pr, tempbx, 0);
9023 #endif
9025 /* Write to Chrontel 700x */
9026 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9027 void
9028 SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9030 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9032 if(!(SiS_Pr->SiS_ChrontelInit)) {
9033 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9034 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9035 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9036 SiS_SetupDDCN(SiS_Pr);
9039 if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
9040 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9041 SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */
9042 SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
9043 SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
9044 SiS_SetupDDCN(SiS_Pr);
9046 SiS_SetChReg(SiS_Pr, tempbx, 0x80);
9050 /* Write to Chrontel 701x */
9051 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9052 void
9053 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9055 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9056 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9057 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9058 SiS_SetupDDCN(SiS_Pr);
9059 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9060 SiS_SetChReg(SiS_Pr, tempbx, 0);
9063 void
9064 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9066 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9067 SiS_SetCH700x(SiS_Pr,tempbx);
9068 else
9069 SiS_SetCH701x(SiS_Pr,tempbx);
9072 static USHORT
9073 SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
9075 USHORT tempah,temp,i;
9077 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9078 if(i) {
9079 SiS_SetStop(SiS_Pr);
9080 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9082 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9083 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9084 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9085 if(temp) continue; /* (ERROR: no ack) */
9086 tempah = SiS_Pr->SiS_DDC_ReadAddr | myor; /* Write RAB (700x: | 0x80) */
9087 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9088 if(temp) continue; /* (ERROR: no ack) */
9089 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9090 tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
9091 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
9092 if(temp) continue; /* (ERROR: no ack) */
9093 tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
9094 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9095 SiS_Pr->SiS_ChrontelInit = 1;
9096 return(tempah);
9098 return 0xFFFF;
9101 #ifdef SIS300
9102 /* Read from Trumpion */
9103 USHORT
9104 SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9106 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB */
9107 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9108 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9109 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9110 SiS_SetupDDCN(SiS_Pr);
9111 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9112 return(SiS_GetChReg(SiS_Pr,0));
9114 #endif
9116 /* Read from Chrontel 700x */
9117 /* Parameter is [Register no (S7-S0)] */
9118 USHORT
9119 SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9121 USHORT result;
9123 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9125 if(!(SiS_Pr->SiS_ChrontelInit)) {
9126 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9127 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9128 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9129 SiS_SetupDDCN(SiS_Pr);
9132 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9134 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9135 (!SiS_Pr->SiS_ChrontelInit) ) {
9137 SiS_Pr->SiS_DDC_Index = 0x0a;
9138 SiS_Pr->SiS_DDC_Data = 0x80;
9139 SiS_Pr->SiS_DDC_Clk = 0x40;
9140 SiS_SetupDDCN(SiS_Pr);
9142 result = SiS_GetChReg(SiS_Pr,0x80);
9144 return(result);
9147 /* Read from Chrontel 701x */
9148 /* Parameter is [Register no (S7-S0)] */
9149 USHORT
9150 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9152 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9153 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9154 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9155 SiS_SetupDDCN(SiS_Pr);
9156 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9158 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9160 return(SiS_GetChReg(SiS_Pr,0));
9163 /* Read from Chrontel 70xx */
9164 /* Parameter is [Register no (S7-S0)] */
9165 USHORT
9166 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9168 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9169 return(SiS_GetCH700x(SiS_Pr, tempbx));
9170 else
9171 return(SiS_GetCH701x(SiS_Pr, tempbx));
9174 /* Our own DDC functions */
9175 USHORT
9176 SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9177 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
9179 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9180 unsigned char flag, cr32;
9181 USHORT temp = 0, myadaptnum = adaptnum;
9183 if(adaptnum != 0) {
9184 if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
9185 if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9188 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9190 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9192 SiS_Pr->SiS_DDC_SecAddr = 0;
9193 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9194 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9195 SiS_Pr->SiS_DDC_Index = 0x11;
9196 flag = 0xff;
9198 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9200 #if 0
9201 if(VBFlags & VB_SISBRIDGE) {
9202 if(myadaptnum == 0) {
9203 if(!(cr32 & 0x20)) {
9204 myadaptnum = 2;
9205 if(!(cr32 & 0x10)) {
9206 myadaptnum = 1;
9207 if(!(cr32 & 0x08)) {
9208 myadaptnum = 0;
9214 #endif
9216 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9218 if(myadaptnum != 0) {
9219 flag = 0;
9220 if(VBFlags & VB_SISBRIDGE) {
9221 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9222 SiS_Pr->SiS_DDC_Index = 0x0f;
9226 if(!(VBFlags & VB_301)) {
9227 if((cr32 & 0x80) && (checkcr32)) {
9228 if(myadaptnum >= 1) {
9229 if(!(cr32 & 0x08)) {
9230 myadaptnum = 1;
9231 if(!(cr32 & 0x10)) return 0xFFFF;
9237 temp = 4 - (myadaptnum * 2);
9238 if(flag) temp = 0;
9240 } else { /* 315/330 series */
9242 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9244 if(VBFlags & VB_SISBRIDGE) {
9245 if(myadaptnum == 2) {
9246 myadaptnum = 1;
9250 if(myadaptnum == 1) {
9251 flag = 0;
9252 if(VBFlags & VB_SISBRIDGE) {
9253 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9254 SiS_Pr->SiS_DDC_Index = 0x0f;
9258 if((cr32 & 0x80) && (checkcr32)) {
9259 if(myadaptnum >= 1) {
9260 if(!(cr32 & 0x08)) {
9261 myadaptnum = 1;
9262 if(!(cr32 & 0x10)) return 0xFFFF;
9267 temp = myadaptnum;
9268 if(myadaptnum == 1) {
9269 temp = 0;
9270 if(VBFlags & VB_LVDS) flag = 0xff;
9273 if(flag) temp = 0;
9276 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9277 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9279 SiS_SetupDDCN(SiS_Pr);
9281 #ifdef TWDEBUG
9282 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9283 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9284 #endif
9286 return 0;
9289 USHORT
9290 SiS_WriteDABDDC(SiS_Private *SiS_Pr)
9292 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9293 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9294 return 0xFFFF;
9296 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9297 return 0xFFFF;
9299 return(0);
9302 USHORT
9303 SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
9305 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9306 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9307 return 0xFFFF;
9309 return(0);
9312 USHORT
9313 SiS_PrepareDDC(SiS_Private *SiS_Pr)
9315 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9316 if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
9317 return(0);
9320 void
9321 SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
9323 SiS_SetSCLKLow(SiS_Pr);
9324 if(yesno) {
9325 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9326 SiS_Pr->SiS_DDC_Index,
9327 SiS_Pr->SiS_DDC_NData,
9328 SiS_Pr->SiS_DDC_Data);
9329 } else {
9330 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9331 SiS_Pr->SiS_DDC_Index,
9332 SiS_Pr->SiS_DDC_NData,
9335 SiS_SetSCLKHigh(SiS_Pr);
9338 USHORT
9339 SiS_DoProbeDDC(SiS_Private *SiS_Pr)
9341 unsigned char mask, value;
9342 USHORT temp, ret=0;
9343 BOOLEAN failed = FALSE;
9345 SiS_SetSwitchDDC2(SiS_Pr);
9346 if(SiS_PrepareDDC(SiS_Pr)) {
9347 SiS_SetStop(SiS_Pr);
9348 #ifdef TWDEBUG
9349 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9350 #endif
9351 return(0xFFFF);
9353 mask = 0xf0;
9354 value = 0x20;
9355 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9356 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9357 SiS_SendACK(SiS_Pr, 0);
9358 if(temp == 0) {
9359 mask = 0xff;
9360 value = 0xff;
9361 } else {
9362 failed = TRUE;
9363 ret = 0xFFFF;
9364 #ifdef TWDEBUG
9365 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9366 #endif
9369 if(failed == FALSE) {
9370 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9371 SiS_SendACK(SiS_Pr, 1);
9372 temp &= mask;
9373 if(temp == value) ret = 0;
9374 else {
9375 ret = 0xFFFF;
9376 #ifdef TWDEBUG
9377 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9378 #endif
9379 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9380 if(temp == 0x30) ret = 0;
9384 SiS_SetStop(SiS_Pr);
9385 return(ret);
9388 USHORT
9389 SiS_ProbeDDC(SiS_Private *SiS_Pr)
9391 USHORT flag;
9393 flag = 0x180;
9394 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9395 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9396 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9397 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9398 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9399 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9400 if(!(flag & 0x1a)) flag = 0;
9401 return(flag);
9404 USHORT
9405 SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9407 USHORT flag, length, i;
9408 unsigned char chksum,gotcha;
9410 if(DDCdatatype > 4) return 0xFFFF;
9412 flag = 0;
9413 SiS_SetSwitchDDC2(SiS_Pr);
9414 if(!(SiS_PrepareDDC(SiS_Pr))) {
9415 length = 127;
9416 if(DDCdatatype != 1) length = 255;
9417 chksum = 0;
9418 gotcha = 0;
9419 for(i=0; i<length; i++) {
9420 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9421 chksum += buffer[i];
9422 gotcha |= buffer[i];
9423 SiS_SendACK(SiS_Pr, 0);
9425 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9426 chksum += buffer[i];
9427 SiS_SendACK(SiS_Pr, 1);
9428 if(gotcha) flag = (USHORT)chksum;
9429 else flag = 0xFFFF;
9430 } else {
9431 flag = 0xFFFF;
9433 SiS_SetStop(SiS_Pr);
9434 return(flag);
9437 /* Our private DDC functions
9439 It complies somewhat with the corresponding VESA function
9440 in arguments and return values.
9442 Since this is probably called before the mode is changed,
9443 we use our pre-detected pSiS-values instead of SiS_Pr as
9444 regards chipset and video bridge type.
9446 Arguments:
9447 adaptnum: 0=CRT1, 1=LCD, 2=VGA2
9448 CRT2 DDC is only supported on SiS301, 301B, 302B.
9449 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9450 buffer: ptr to 256 data bytes which will be filled with read data.
9452 Returns 0xFFFF if error, otherwise
9453 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9454 if DDCdatatype = 0: Returns supported DDC modes
9457 USHORT
9458 SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9459 USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
9461 unsigned char sr1f,cr17=1;
9462 USHORT result;
9464 if(adaptnum > 2) return 0xFFFF;
9465 if(DDCdatatype > 4) return 0xFFFF;
9466 if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
9467 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
9469 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9470 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9471 if(VGAEngine == SIS_300_VGA) {
9472 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9473 if(!cr17) {
9474 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9475 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9476 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9479 if((sr1f) || (!cr17)) {
9480 SiS_WaitRetrace1(SiS_Pr);
9481 SiS_WaitRetrace1(SiS_Pr);
9482 SiS_WaitRetrace1(SiS_Pr);
9483 SiS_WaitRetrace1(SiS_Pr);
9486 if(DDCdatatype == 0) {
9487 result = SiS_ProbeDDC(SiS_Pr);
9488 } else {
9489 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9491 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9492 if(VGAEngine == SIS_300_VGA) {
9493 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9495 return result;
9498 #ifdef LINUX_XF86
9500 static BOOLEAN
9501 checkedid1(unsigned char *buffer)
9503 /* Check header */
9504 if((buffer[0] != 0x00) ||
9505 (buffer[1] != 0xff) ||
9506 (buffer[2] != 0xff) ||
9507 (buffer[3] != 0xff) ||
9508 (buffer[4] != 0xff) ||
9509 (buffer[5] != 0xff) ||
9510 (buffer[6] != 0xff) ||
9511 (buffer[7] != 0x00))
9512 return FALSE;
9514 /* Check EDID version and revision */
9515 if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
9517 /* Check week of manufacture for sanity */
9518 if(buffer[0x10] > 53) return FALSE;
9520 /* Check year of manufacture for sanity */
9521 if(buffer[0x11] > 40) return FALSE;
9523 return TRUE;
9526 static BOOLEAN
9527 checkedid2(unsigned char *buffer)
9529 USHORT year = buffer[6] | (buffer[7] << 8);
9531 /* Check EDID version */
9532 if((buffer[0] & 0xf0) != 0x20) return FALSE;
9534 /* Check week of manufacture for sanity */
9535 if(buffer[5] > 53) return FALSE;
9537 /* Check year of manufacture for sanity */
9538 if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
9540 return TRUE;
9543 /* Sense the LCD parameters (CR36, CR37) via DDC */
9544 /* SiS30x(B) only */
9545 USHORT
9546 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
9548 USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
9549 USHORT index, myindex, lumsize, numcodes;
9550 unsigned char cr37=0, seekcode;
9551 BOOLEAN checkexpand = FALSE;
9552 int retry, i;
9553 unsigned char buffer[256];
9555 for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
9556 SiS_Pr->CP_HaveCustomData = FALSE;
9557 SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
9558 SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
9559 SiS_Pr->CP_PreferredIndex = -1;
9561 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
9562 if(pSiS->VBFlags & VB_30xBDH) return 0;
9564 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
9566 SiS_Pr->SiS_DDC_SecAddr = 0x00;
9568 /* Probe supported DA's */
9569 flag = SiS_ProbeDDC(SiS_Pr);
9570 #ifdef TWDEBUG
9571 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
9572 "CRT2 DDC capabilities 0x%x\n", flag);
9573 #endif
9574 if(flag & 0x10) {
9575 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
9576 DDCdatatype = 4;
9577 } else if(flag & 0x08) {
9578 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
9579 DDCdatatype = 3;
9580 } else if(flag & 0x02) {
9581 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
9582 DDCdatatype = 1;
9583 } else return 0; /* no DDC support (or no device attached) */
9585 /* Read the entire EDID */
9586 retry = 2;
9587 do {
9588 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
9589 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9590 "CRT2: DDC read failed (attempt %d), %s\n",
9591 (3-retry), (retry == 1) ? "giving up" : "retrying");
9592 retry--;
9593 if(retry == 0) return 0xFFFF;
9594 } else break;
9595 } while(1);
9597 #ifdef TWDEBUG
9598 for(i=0; i<256; i+=16) {
9599 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9600 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
9601 buffer[i], buffer[i+1], buffer[i+2], buffer[i+3],
9602 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
9603 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
9604 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
9606 #endif
9608 /* Analyze EDID and retrieve LCD panel information */
9609 paneltype = 0;
9610 switch(DDCdatatype) {
9611 case 1: /* Analyze EDID V1 */
9612 /* Catch a few clear cases: */
9613 if(!(checkedid1(buffer))) {
9614 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9615 "CRT2: EDID corrupt\n");
9616 return 0;
9619 if(!(buffer[0x14] & 0x80)) {
9620 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9621 "CRT2: Attached display expects analog input (0x%02x)\n",
9622 buffer[0x14]);
9623 return 0;
9626 if((buffer[0x18] & 0x18) != 0x08) {
9627 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9628 "CRT2: Attached display is not of RGB but of %s type (0x%02x)\n",
9629 ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
9630 ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
9631 "undefined"),
9632 buffer[0x18]);
9633 return 0;
9636 /* Now analyze the first Detailed Timing Block and see
9637 * if the preferred timing mode is stored there. If so,
9638 * check if this is a standard panel for which we already
9639 * know the timing.
9642 paneltype = Panel_Custom;
9643 checkexpand = FALSE;
9645 if(buffer[0x18] & 0x02) {
9647 xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
9648 yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
9650 SiS_Pr->CP_PreferredX = xres;
9651 SiS_Pr->CP_PreferredY = yres;
9653 switch(xres) {
9654 #if 0 /* Treat as custom */
9655 case 800:
9656 if(yres == 600) {
9657 paneltype = Panel_800x600;
9658 checkexpand = TRUE;
9660 break;
9661 #endif
9662 case 1024:
9663 if(yres == 768) {
9664 paneltype = Panel_1024x768;
9665 checkexpand = TRUE;
9667 break;
9668 case 1280:
9669 if(yres == 1024) {
9670 paneltype = Panel_1280x1024;
9671 checkexpand = TRUE;
9672 } else if(yres == 960) {
9673 if(pSiS->VGAEngine == SIS_300_VGA) {
9674 paneltype = Panel300_1280x960;
9675 } else {
9676 paneltype = Panel310_1280x960;
9678 } else if(yres == 768) {
9679 if( ((buffer[0x36] | (buffer[0x37] << 8)) == 8100) &&
9680 ((buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8)) == (1688 - 1280)) &&
9681 ((buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8)) == (802 - 768)) ) {
9682 paneltype = Panel_1280x768;
9683 checkexpand = FALSE;
9684 cr37 |= 0x10;
9687 break;
9688 case 1400:
9689 if(pSiS->VGAEngine == SIS_315_VGA) {
9690 if(yres == 1050) {
9691 paneltype = Panel310_1400x1050;
9692 checkexpand = TRUE;
9695 break;
9696 #if 0 /* Treat this as custom, as we have no valid timing data yet */
9697 case 1600:
9698 if(pSiS->VGAEngine == SIS_315_VGA) {
9699 if(pSiS->VBFlags & VB_301C) {
9700 if(yres == 1200) {
9701 paneltype = Panel310_1600x1200;
9702 checkexpand = TRUE;
9706 break;
9707 #endif
9710 if(paneltype != Panel_Custom) {
9711 if((buffer[0x47] & 0x18) == 0x18) {
9712 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
9713 } else {
9714 /* What now? There is no digital separate output timing... */
9715 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9716 "CRT2: Unable to retrieve Sync polarity information\n");
9717 cr37 |= 0xc0; /* Default */
9723 /* If we still don't know what panel this is, we take it
9724 * as a custom panel and derive the timing data from the
9725 * detailed timing blocks
9727 if(paneltype == Panel_Custom) {
9729 BOOLEAN havesync = FALSE;
9730 int i, temp, base = 0x36;
9731 unsigned long estpack;
9732 unsigned short estx[] = {
9733 720, 720, 640, 640, 640, 640, 800, 800,
9734 800, 800, 832,1024,1024,1024,1024,1280,
9735 1152
9737 unsigned short esty[] = {
9738 400, 400, 480, 480, 480, 480, 600, 600,
9739 600, 600, 624, 768, 768, 768, 768,1024,
9743 paneltype = 0;
9744 SiS_Pr->CP_Supports64048075 = TRUE;
9746 /* Find the maximum resolution */
9748 /* 1. From Established timings */
9749 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
9750 for(i=16; i>=0; i--) {
9751 if(estpack & (1 << i)) {
9752 if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
9753 if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
9757 /* 2. From Standard Timings */
9758 for(i=0x26; i < 0x36; i+=2) {
9759 if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
9760 temp = (buffer[i] + 31) * 8;
9761 if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
9762 switch((buffer[i+1] & 0xc0) >> 6) {
9763 case 0x03: temp = temp * 9 / 16; break;
9764 case 0x02: temp = temp * 4 / 5; break;
9765 case 0x01: temp = temp * 3 / 4; break;
9767 if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
9771 /* Now extract the Detailed Timings and convert them into modes */
9773 for(i = 0; i < 4; i++, base += 18) {
9775 /* Is this a detailed timing block or a monitor descriptor? */
9776 if(buffer[base] || buffer[base+1] || buffer[base+2]) {
9778 xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
9779 yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
9781 SiS_Pr->CP_HDisplay[i] = xres;
9782 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
9783 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
9784 SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
9785 SiS_Pr->CP_HBlankStart[i] = xres + 1;
9786 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
9788 SiS_Pr->CP_VDisplay[i] = yres;
9789 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
9790 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
9791 SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
9792 SiS_Pr->CP_VBlankStart[i] = yres + 1;
9793 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
9795 SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
9797 SiS_Pr->CP_DataValid[i] = TRUE;
9799 /* Sort out invalid timings, interlace and too high clocks */
9800 if((SiS_Pr->CP_HDisplay[i] & 7) ||
9801 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
9802 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
9803 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
9804 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
9805 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
9806 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
9807 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
9808 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
9809 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
9810 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
9811 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
9812 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
9813 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
9814 ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200))) ||
9815 (buffer[base+17] & 0x80)) {
9817 SiS_Pr->CP_DataValid[i] = FALSE;
9819 } else {
9821 paneltype = Panel_Custom;
9823 SiS_Pr->CP_HaveCustomData = TRUE;
9825 if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
9826 if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
9827 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
9829 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
9830 SiS_Pr->CP_PreferredIndex = i;
9833 SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
9834 SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
9836 /* By default we drive the LCD at 75Hz in 640x480 mode; if
9837 * the panel does not provide this mode, use 60hz
9839 if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
9841 /* We must assume the panel can scale, since we have
9842 * no scaling data
9844 checkexpand = FALSE;
9845 cr37 |= 0x10;
9847 /* Extract the sync polarisation information. This only works
9848 * if the Flags indicate a digital separate output.
9850 if((buffer[base+17] & 0x18) == 0x18) {
9851 SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
9852 SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
9853 SiS_Pr->CP_SyncValid[i] = TRUE;
9854 if(!havesync) {
9855 cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
9856 havesync = TRUE;
9858 } else {
9859 SiS_Pr->CP_SyncValid[i] = FALSE;
9864 if(!havesync) {
9865 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9866 "CRT2: Unable to retrieve Sync polarity information\n");
9870 if(paneltype && checkexpand) {
9871 /* If any of the Established low-res modes is supported, the
9872 * panel can scale automatically. For 800x600 panels, we only
9873 * check the even lower ones.
9875 if(paneltype == Panel_800x600) {
9876 if(buffer[0x23] & 0xfc) cr37 |= 0x10;
9877 } else {
9878 if(buffer[0x23]) cr37 |= 0x10;
9882 break;
9884 case 3: /* Analyze EDID V2 */
9885 case 4:
9886 index = 0;
9888 if(!(checkedid2(buffer))) {
9889 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9890 "CRT2: EDID corrupt\n");
9891 return 0;
9894 if((buffer[0x41] & 0x0f) == 0x03) {
9895 index = 0x42 + 3;
9896 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9897 "CRT2: Display supports TMDS input on primary interface\n");
9898 } else if((buffer[0x41] & 0xf0) == 0x30) {
9899 index = 0x46 + 3;
9900 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9901 "CRT2: Display supports TMDS input on secondary interface\n");
9902 } else {
9903 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9904 "CRT2: Display does not support TMDS video interface (0x%02x)\n",
9905 buffer[0x41]);
9906 return 0;
9909 paneltype = Panel_Custom;
9910 SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
9911 SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
9912 switch(xres) {
9913 #if 0
9914 case 800:
9915 if(yres == 600) {
9916 paneltype = Panel_800x600;
9917 checkexpand = TRUE;
9919 break;
9920 #endif
9921 case 1024:
9922 if(yres == 768) {
9923 paneltype = Panel_1024x768;
9924 checkexpand = TRUE;
9926 break;
9927 case 1280:
9928 if(yres == 960) {
9929 if(pSiS->VGAEngine == SIS_315_VGA) {
9930 paneltype = Panel310_1280x960;
9931 } else {
9932 paneltype = Panel300_1280x960;
9934 } else if(yres == 1024) {
9935 paneltype = Panel_1280x1024;
9936 checkexpand = TRUE;
9938 /* 1280x768 treated as custom here */
9939 break;
9940 case 1400:
9941 if(pSiS->VGAEngine == SIS_315_VGA) {
9942 if(yres == 1050) {
9943 paneltype = Panel310_1400x1050;
9944 checkexpand = TRUE;
9947 break;
9948 #if 0 /* Treat this one as custom since we have no timing data yet */
9949 case 1600:
9950 if(pSiS->VGAEngine == SIS_315_VGA) {
9951 if(pSiS->VBFlags & VB_301C) {
9952 if(yres == 1200) {
9953 paneltype = Panel310_1600x1200;
9954 checkexpand = TRUE;
9958 break;
9959 #endif
9962 /* Determine if RGB18 or RGB24 */
9963 if(index) {
9964 if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
9965 cr37 |= 0x01;
9969 if(checkexpand) {
9970 /* TODO - for now, we let the panel scale */
9971 cr37 |= 0x10;
9974 /* Now seek 4-Byte Timing codes and extract sync pol info */
9975 index = 0x80;
9976 if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
9977 lumsize = buffer[0x80] & 0x1f;
9978 if(buffer[0x80] & 0x80) lumsize *= 3;
9979 lumsize++; /* luminance header byte */
9980 index += lumsize;
9982 index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */
9983 index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */
9984 numcodes = (buffer[0x7f] & 0xf8) >> 3;
9985 if(numcodes) {
9986 myindex = index;
9987 seekcode = (xres - 256) / 16;
9988 for(i=0; i<numcodes; i++) {
9989 if(buffer[myindex] == seekcode) break;
9990 myindex += 4;
9992 if(buffer[myindex] == seekcode) {
9993 cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
9994 } else {
9995 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9996 "CRT2: Unable to retrieve Sync polarity information\n");
9998 } else {
9999 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10000 "CRT2: Unable to retrieve Sync polarity information\n");
10003 /* Now seek the detailed timing descriptions for custom panels */
10004 if(paneltype == Panel_Custom) {
10006 SiS_Pr->CP_Supports64048075 = TRUE;
10008 index += (numcodes * 4);
10009 numcodes = buffer[0x7f] & 0x07;
10010 for(i=0; i<numcodes; i++, index += 18) {
10011 xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
10012 yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
10014 SiS_Pr->CP_HDisplay[i] = xres;
10015 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
10016 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
10017 SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
10018 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10019 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10021 SiS_Pr->CP_VDisplay[i] = yres;
10022 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10023 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10024 SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10025 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10026 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10028 SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10030 SiS_Pr->CP_DataValid[i] = TRUE;
10032 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10033 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10034 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10035 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10036 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10037 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10038 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10039 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10040 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10041 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10042 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10043 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10044 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10045 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10046 ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200))) ||
10047 (buffer[index + 17] & 0x80)) {
10049 SiS_Pr->CP_DataValid[i] = FALSE;
10051 } else {
10053 SiS_Pr->CP_HaveCustomData = TRUE;
10055 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10057 if((SiS_Pr->CP_MaxX == xres) && (SiS_Pr->CP_MaxY == yres)) {
10058 SiS_Pr->CP_PreferredIndex = i;
10061 SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10062 SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10063 SiS_Pr->CP_SyncValid[i] = TRUE;
10065 SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10066 SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10068 /* We must assume the panel can scale, since we have
10069 * no scaling data
10071 cr37 |= 0x10;
10078 break;
10082 /* 1280x960 panels are always RGB24, unable to scale and use
10083 * high active sync polarity
10085 if(pSiS->VGAEngine == SIS_315_VGA) {
10086 if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10087 } else {
10088 if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10091 for(i = 0; i < 7; i++) {
10092 if(SiS_Pr->CP_DataValid[i]) {
10093 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10094 "Non-standard LCD timing data no. %d:\n", i);
10095 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10096 " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10097 SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10098 SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10099 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10100 " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10101 SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10102 SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10103 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10104 " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10105 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10106 " To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10107 SiS_Pr->CP_HDisplay[i],
10108 SiS_Pr->CP_VDisplay[i]);
10112 if(paneltype) {
10113 if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10114 if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10115 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10116 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
10117 cr37 &= 0xf1;
10118 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
10119 SiS_Pr->PanelSelfDetected = TRUE;
10120 #ifdef TWDEBUG
10121 xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
10122 "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10123 #endif
10124 } else {
10125 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
10126 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
10128 return 0;
10131 USHORT
10132 SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10134 USHORT DDCdatatype,flag;
10135 BOOLEAN foundcrt = FALSE;
10136 int retry;
10137 unsigned char buffer[256];
10139 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10141 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10143 SiS_Pr->SiS_DDC_SecAddr = 0x00;
10145 /* Probe supported DA's */
10146 flag = SiS_ProbeDDC(SiS_Pr);
10147 if(flag & 0x10) {
10148 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
10149 DDCdatatype = 4;
10150 } else if(flag & 0x08) {
10151 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
10152 DDCdatatype = 3;
10153 } else if(flag & 0x02) {
10154 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
10155 DDCdatatype = 1;
10156 } else {
10157 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10158 "Do DDC answer\n");
10159 return 0; /* no DDC support (or no device attached) */
10162 /* Read the entire EDID */
10163 retry = 2;
10164 do {
10165 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10166 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10167 "CRT2: DDC read failed (attempt %d), %s\n",
10168 (3-retry), (retry == 1) ? "giving up" : "retrying");
10169 retry--;
10170 if(retry == 0) return 0xFFFF;
10171 } else break;
10172 } while(1);
10174 /* Analyze EDID. We don't have many chances to
10175 * distinguish a flat panel from a CRT...
10177 switch(DDCdatatype) {
10178 case 1:
10179 if(!(checkedid1(buffer))) {
10180 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10181 "CRT2: EDID corrupt\n");
10182 return 0;
10184 if(buffer[0x14] & 0x80) { /* Display uses digital input */
10185 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10186 "CRT2: Attached display expects digital input\n");
10187 return 0;
10189 SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10190 SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10191 foundcrt = TRUE;
10192 break;
10193 case 3:
10194 case 4:
10195 if(!(checkedid2(buffer))) {
10196 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10197 "CRT2: EDID corrupt\n");
10198 return 0;
10200 if( ((buffer[0x41] & 0x0f) != 0x01) && /* Display does not support analog input */
10201 ((buffer[0x41] & 0x0f) != 0x02) &&
10202 ((buffer[0x41] & 0xf0) != 0x10) &&
10203 ((buffer[0x41] & 0xf0) != 0x20) ) {
10204 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10205 "CRT2: Attached display does not support analog input (0x%02x)\n",
10206 buffer[0x41]);
10207 return 0;
10209 SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10210 SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10211 foundcrt = TRUE;
10212 break;
10215 if(foundcrt) {
10216 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10218 return(0);
10221 #endif
10223 void
10224 SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10226 USHORT tempbl;
10228 tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10229 tempbl = (((tempbl & tempbh) << 8) | tempax);
10230 SiS_SetCH70xx(SiS_Pr,tempbl);
10233 /* Generic I2C functions for Chrontel & DDC --------- */
10235 void
10236 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10238 SiS_SetSCLKHigh(SiS_Pr);
10239 SiS_WaitRetrace1(SiS_Pr);
10241 SiS_SetSCLKLow(SiS_Pr);
10242 SiS_WaitRetrace1(SiS_Pr);
10245 USHORT
10246 SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
10248 SiS_WaitRetrace1(SiS_Pr);
10249 return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10252 /* Set I2C start condition */
10253 /* This is done by a SD high-to-low transition while SC is high */
10254 USHORT
10255 SiS_SetStart(SiS_Private *SiS_Pr)
10257 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10258 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10259 SiS_Pr->SiS_DDC_Index,
10260 SiS_Pr->SiS_DDC_NData,
10261 SiS_Pr->SiS_DDC_Data); /* SD->high */
10262 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10263 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10264 SiS_Pr->SiS_DDC_Index,
10265 SiS_Pr->SiS_DDC_NData,
10266 0x00); /* SD->low = start condition */
10267 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10268 return 0;
10271 /* Set I2C stop condition */
10272 /* This is done by a SD low-to-high transition while SC is high */
10273 USHORT
10274 SiS_SetStop(SiS_Private *SiS_Pr)
10276 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10277 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10278 SiS_Pr->SiS_DDC_Index,
10279 SiS_Pr->SiS_DDC_NData,
10280 0x00); /* SD->low */
10281 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10282 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10283 SiS_Pr->SiS_DDC_Index,
10284 SiS_Pr->SiS_DDC_NData,
10285 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
10286 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
10287 return 0;
10290 /* Write 8 bits of data */
10291 USHORT
10292 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10294 USHORT i,flag,temp;
10296 flag = 0x80;
10297 for(i=0; i<8; i++) {
10298 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
10299 if(tempax & flag) {
10300 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10301 SiS_Pr->SiS_DDC_Index,
10302 SiS_Pr->SiS_DDC_NData,
10303 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
10304 } else {
10305 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10306 SiS_Pr->SiS_DDC_Index,
10307 SiS_Pr->SiS_DDC_NData,
10308 0x00); /* Write bit (0) to SD */
10310 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
10311 flag >>= 1;
10313 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
10314 return(temp);
10317 USHORT
10318 SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10320 USHORT i,temp,getdata;
10322 getdata=0;
10323 for(i=0; i<8; i++) {
10324 getdata <<= 1;
10325 SiS_SetSCLKLow(SiS_Pr);
10326 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10327 SiS_Pr->SiS_DDC_Index,
10328 SiS_Pr->SiS_DDC_NData,
10329 SiS_Pr->SiS_DDC_Data);
10330 SiS_SetSCLKHigh(SiS_Pr);
10331 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10332 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
10334 return(getdata);
10337 USHORT
10338 SiS_SetSCLKLow(SiS_Private *SiS_Pr)
10340 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10341 SiS_Pr->SiS_DDC_Index,
10342 SiS_Pr->SiS_DDC_NClk,
10343 0x00); /* SetSCLKLow() */
10344 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10345 return 0;
10348 USHORT
10349 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
10351 USHORT temp, watchdog=1000;
10353 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10354 SiS_Pr->SiS_DDC_Index,
10355 SiS_Pr->SiS_DDC_NClk,
10356 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
10357 do {
10358 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10359 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
10360 if (!watchdog) {
10361 #ifdef TWDEBUG
10362 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
10363 #endif
10364 return 0xFFFF;
10366 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10367 return 0;
10370 /* Check I2C acknowledge */
10371 /* Returns 0 if ack ok, non-0 if ack not ok */
10372 USHORT
10373 SiS_CheckACK(SiS_Private *SiS_Pr)
10375 USHORT tempah;
10377 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
10378 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10379 SiS_Pr->SiS_DDC_Index,
10380 SiS_Pr->SiS_DDC_NData,
10381 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
10382 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
10383 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
10384 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
10385 if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */
10386 else return(0);
10389 /* End of I2C functions ----------------------- */
10392 /* =============== SiS 315/330 O.E.M. ================= */
10394 #ifdef SIS315H
10396 static USHORT
10397 GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10399 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10400 USHORT romptr;
10402 if(HwInfo->jChipType < SIS_330) {
10403 romptr = SISGETROMW(0x128);
10404 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10405 romptr = SISGETROMW(0x12a);
10406 } else {
10407 romptr = SISGETROMW(0x1a8);
10408 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10409 romptr = SISGETROMW(0x1aa);
10411 return(romptr);
10414 static USHORT
10415 GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10417 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10418 USHORT romptr;
10420 if(HwInfo->jChipType < SIS_330) {
10421 romptr = SISGETROMW(0x120);
10422 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10423 romptr = SISGETROMW(0x122);
10424 } else {
10425 romptr = SISGETROMW(0x1a0);
10426 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10427 romptr = SISGETROMW(0x1a2);
10429 return(romptr);
10432 static USHORT
10433 GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10435 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10436 USHORT romptr;
10438 if(HwInfo->jChipType < SIS_330) {
10439 romptr = SISGETROMW(0x114);
10440 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10441 romptr = SISGETROMW(0x11a);
10442 } else {
10443 romptr = SISGETROMW(0x194);
10444 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10445 romptr = SISGETROMW(0x19a);
10447 return(romptr);
10450 static USHORT
10451 GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10453 USHORT index;
10455 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10456 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
10457 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
10458 index >>= 4;
10459 index *= 3;
10460 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10461 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10462 return index;
10467 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
10468 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
10469 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
10470 index--;
10471 index *= 3;
10472 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10473 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10474 return index;
10477 static USHORT
10478 GetLCDPtrIndex(SiS_Private *SiS_Pr)
10480 USHORT index;
10482 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
10483 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10484 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10485 return index;
10488 static USHORT
10489 GetTVPtrIndex(SiS_Private *SiS_Pr)
10491 USHORT index;
10493 index = 0;
10494 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10495 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
10497 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
10499 index <<= 1;
10501 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
10502 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10503 index++;
10506 return index;
10509 static ULONG
10510 GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10512 USHORT index = 0, temp = 0;
10514 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10515 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
10516 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
10517 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
10518 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
10519 index = 4;
10520 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
10521 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
10524 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10525 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
10526 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10527 index += addme;
10528 temp++;
10530 temp += 0x0100;
10532 return(ULONG)(index | (temp << 16));
10535 static ULONG
10536 GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
10538 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
10541 #if 0
10542 static ULONG
10543 GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
10545 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
10547 #endif
10549 static int
10550 GetOEMTVPtr661(SiS_Private *SiS_Pr)
10552 int index = 0;
10554 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
10555 if(SiS_Pr->SiS_ROMNew) {
10556 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
10557 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
10558 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
10559 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
10560 } else {
10561 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
10562 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
10563 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
10564 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
10567 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
10569 return index;
10572 static void
10573 SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10575 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10576 USHORT delay=0,index,myindex,temp,romptr=0;
10577 BOOLEAN dochiptest = TRUE;
10579 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10580 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
10581 } else {
10582 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
10585 /* Find delay (from ROM, internal tables, PCI subsystem) */
10587 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
10589 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10590 romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
10592 if(romptr) delay = ROMAddr[romptr];
10593 else {
10594 delay = 0x04;
10595 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10596 if(IS_SIS650) {
10597 delay = 0x0a;
10598 } else if(IS_SIS740) {
10599 delay = 0x00;
10600 } else if(HwInfo->jChipType < SIS_330) {
10601 delay = 0x0c;
10602 } else {
10603 delay = 0x0c;
10605 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10606 delay = 0x00;
10610 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
10612 BOOLEAN gotitfrompci = FALSE;
10614 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
10616 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10617 if(SiS_Pr->PDC != -1) {
10618 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
10619 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
10620 return;
10622 } else {
10623 if(SiS_Pr->PDCA != -1) {
10624 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10625 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10626 return;
10630 /* Custom Panel? */
10632 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10633 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10634 delay = 0x00;
10635 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10636 delay = 0x20;
10638 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10639 } else {
10640 delay = 0x0c;
10641 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
10642 else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10643 if(IS_SIS740) delay = 0x01;
10644 else delay = 0x03;
10646 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10648 return;
10651 /* This is a piece of typical SiS crap: They code the OEM LCD
10652 * delay into the code, at no defined place in the BIOS.
10653 * We now have to start doing a PCI subsystem check here.
10656 switch(SiS_Pr->SiS_CustomT) {
10657 case CUT_COMPAQ1280:
10658 case CUT_COMPAQ12802:
10659 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10660 gotitfrompci = TRUE;
10661 dochiptest = FALSE;
10662 delay = 0x03;
10664 break;
10665 case CUT_CLEVO1400:
10666 case CUT_CLEVO14002:
10667 gotitfrompci = TRUE;
10668 dochiptest = FALSE;
10669 delay = 0x02;
10670 break;
10671 case CUT_CLEVO1024:
10672 case CUT_CLEVO10242:
10673 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10674 gotitfrompci = TRUE;
10675 dochiptest = FALSE;
10676 delay = 0x33;
10677 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10678 delay &= 0x0f;
10680 break;
10683 /* Could we find it through the PCI ID? If no, use ROM or table */
10685 if(!gotitfrompci) {
10687 index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
10688 myindex = GetLCDPtrIndex(SiS_Pr);
10690 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10692 if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
10694 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10695 /* Always use the second pointer on 650; some BIOSes */
10696 /* still carry old 301 data at the first location */
10697 /* romptr = SISGETROMW(0x120); */
10698 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10699 romptr = SISGETROMW(0x122);
10700 if(!romptr) return;
10701 delay = ROMAddr[(romptr + index)];
10702 } else {
10703 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10706 } else {
10708 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10709 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10710 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10714 } else if(SiS_Pr->SiS_UseROM &&
10715 (!(SiS_Pr->SiS_ROMNew)) &&
10716 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10717 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10718 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
10720 /* Data for 1280x1024 wrong in 301B BIOS */
10721 romptr = GetLCDromptr(SiS_Pr, HwInfo);
10722 if(!romptr) return;
10723 delay = ROMAddr[(romptr + index)];
10725 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10727 if(IS_SIS740) delay = 0x03;
10728 else delay = 0x00;
10730 } else {
10732 delay = SiS310_LCDDelayCompensation_301[myindex];
10733 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10734 if(IS_SIS740) delay = 0x01;
10735 else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10736 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10737 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10738 if(IS_SIS740) delay = 0x01; /* ? */
10739 else delay = 0x03;
10740 } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10741 if(IS_SIS740) delay = 0x01;
10742 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10747 } /* got it from PCI */
10749 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10750 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10751 dochiptest = FALSE;
10754 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10756 index = GetTVPtrIndex(SiS_Pr);
10758 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10760 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
10762 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10763 /* Always use the second pointer on 650; some BIOSes */
10764 /* still carry old 301 data at the first location */
10765 /* romptr = SISGETROMW(0x114); */
10766 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10767 romptr = SISGETROMW(0x11a);
10768 if(!romptr) return;
10769 delay = ROMAddr[romptr + index];
10771 } else {
10773 delay = SiS310_TVDelayCompensation_301B[index];
10777 } else {
10779 switch(SiS_Pr->SiS_CustomT) {
10780 case CUT_COMPAQ1280:
10781 case CUT_COMPAQ12802:
10782 case CUT_CLEVO1400:
10783 case CUT_CLEVO14002:
10784 delay = 0x02;
10785 dochiptest = FALSE;
10786 break;
10787 case CUT_CLEVO1024:
10788 case CUT_CLEVO10242:
10789 delay = 0x03;
10790 dochiptest = FALSE;
10791 break;
10792 default:
10793 delay = SiS310_TVDelayCompensation_651301LV[index];
10794 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10795 delay = SiS310_TVDelayCompensation_651302LV[index];
10800 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10802 romptr = GetTVromptr(SiS_Pr, HwInfo);
10803 if(!romptr) return;
10804 delay = ROMAddr[romptr + index];
10806 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10808 delay = SiS310_TVDelayCompensation_LVDS[index];
10810 } else {
10812 delay = SiS310_TVDelayCompensation_301[index];
10813 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10814 if(IS_SIS740) {
10815 delay = SiS310_TVDelayCompensation_740301B[index];
10816 /* LV: use 301 data? BIOS bug? */
10817 } else {
10818 delay = SiS310_TVDelayCompensation_301B[index];
10819 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10825 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
10826 delay &= 0x0f;
10827 dochiptest = FALSE;
10830 } else return;
10832 /* Write delay */
10834 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10836 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
10838 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10839 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
10840 delay &= 0x0f;
10841 delay |= 0xb0;
10842 } else if(temp == 6) {
10843 delay &= 0x0f;
10844 delay |= 0xc0;
10845 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
10846 delay = 0x35;
10848 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10850 } else {
10852 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10856 } else { /* LVDS */
10858 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10859 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10860 } else {
10861 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10862 delay <<= 4;
10863 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10864 } else {
10865 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10873 static void
10874 SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10875 USHORT ModeNo,USHORT ModeIdIndex)
10877 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10878 USHORT index,temp,temp1,romptr=0;
10880 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10882 if(ModeNo<=0x13)
10883 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10884 else
10885 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10887 temp = GetTVPtrIndex(SiS_Pr);
10888 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10889 temp1 = temp;
10891 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10892 if(HwInfo->jChipType >= SIS_661) {
10893 temp1 = GetOEMTVPtr661(SiS_Pr);
10894 temp1 >>= 1;
10895 romptr = SISGETROMW(0x260);
10896 if(HwInfo->jChipType >= SIS_760) {
10897 romptr = SISGETROMW(0x360);
10899 } else if(HwInfo->jChipType >= SIS_330) {
10900 romptr = SISGETROMW(0x192);
10901 } else {
10902 romptr = SISGETROMW(0x112);
10906 if(romptr) {
10907 temp1 <<= 1;
10908 temp = ROMAddr[romptr + temp1 + index];
10909 } else {
10910 temp = SiS310_TVAntiFlick1[temp][index];
10912 temp <<= 4;
10914 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10917 static void
10918 SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10919 USHORT ModeNo,USHORT ModeIdIndex)
10921 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10922 USHORT index,temp,temp1,romptr=0;
10924 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10926 if(ModeNo <= 0x13)
10927 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10928 else
10929 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10931 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10932 if(HwInfo->jChipType >= SIS_661) {
10933 romptr = SISGETROMW(0x26c);
10934 if(HwInfo->jChipType >= SIS_760) {
10935 romptr = SISGETROMW(0x36c);
10937 temp1 = GetOEMTVPtr661(SiS_Pr);
10938 temp1 >>= 1;
10939 } else if(HwInfo->jChipType >= SIS_330) {
10940 romptr = SISGETROMW(0x1a4);
10941 } else {
10942 romptr = SISGETROMW(0x124);
10946 if(romptr) {
10947 temp1 <<= 1;
10948 temp = ROMAddr[romptr + temp1 + index];
10949 } else {
10950 temp = SiS310_TVEdge1[temp][index];
10952 temp <<= 5;
10953 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10956 static void
10957 SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10958 USHORT ModeNo,USHORT ModeIdIndex)
10960 USHORT index, temp, i, j;
10962 if(ModeNo <= 0x13) {
10963 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10964 } else {
10965 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10968 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10970 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10971 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10972 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10973 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10975 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10976 for(i=0x35, j=0; i<=0x38; i++, j++) {
10977 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10979 for(i=0x48; i<=0x4A; i++, j++) {
10980 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10982 } else {
10983 for(i=0x35, j=0; i<=0x38; i++, j++) {
10984 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10989 static void
10990 SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10991 USHORT ModeNo,USHORT ModeIdIndex)
10993 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10994 USHORT index,temp,i,j,resinfo,romptr=0;
10995 ULONG lindex;
10997 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10999 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
11000 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
11002 if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
11003 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
11004 lindex <<= 2;
11005 for(j=0, i=0x31; i<=0x34; i++, j++) {
11006 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
11008 return;
11011 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
11012 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
11014 if(ModeNo<=0x13) {
11015 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11016 } else {
11017 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11020 temp = GetTVPtrIndex(SiS_Pr);
11021 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
11022 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
11024 if(SiS_Pr->SiS_UseROM) {
11025 romptr = SISGETROMW(0x116);
11026 if(HwInfo->jChipType >= SIS_330) {
11027 romptr = SISGETROMW(0x196);
11029 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11030 romptr = SISGETROMW(0x11c);
11031 if(HwInfo->jChipType >= SIS_330) {
11032 romptr = SISGETROMW(0x19c);
11034 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11035 romptr = SISGETROMW(0x116);
11036 if(HwInfo->jChipType >= SIS_330) {
11037 romptr = SISGETROMW(0x196);
11042 if(romptr) {
11043 romptr += (temp << 2);
11044 for(j=0, i=0x31; i<=0x34; i++, j++) {
11045 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11047 } else {
11048 index = temp % 2;
11049 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
11050 for(j=0, i=0x31; i<=0x34; i++, j++) {
11051 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
11052 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11053 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11054 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
11055 else
11056 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11060 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11061 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11062 if((resinfo == SIS_RI_640x480) ||
11063 (resinfo == SIS_RI_800x600)) {
11064 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
11065 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
11066 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
11067 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
11068 } else if(resinfo == SIS_RI_1024x768) {
11069 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
11070 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
11071 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
11072 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
11078 void
11079 SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11080 USHORT ModeNo,USHORT ModeIdIndex)
11082 SetDelayComp(SiS_Pr,HwInfo,ModeNo);
11084 if(SiS_Pr->UseCustomMode) return;
11086 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11087 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11088 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11089 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11090 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11091 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11096 static void
11097 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11098 USHORT ModeIdIndex, USHORT RTI)
11100 USHORT delay = 0, romptr = 0, index;
11101 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11103 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11104 return;
11106 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
11108 if(SiS_Pr->SiS_ROMNew) {
11109 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
11110 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
11111 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
11112 index = 25;
11113 if(SiS_Pr->UseCustomMode) {
11114 index = SiS_Pr->CSRClock;
11115 } else if(ModeNo > 0x13) {
11116 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
11117 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
11119 if(index < 25) index = 25;
11120 index = ((index / 25) - 1) << 1;
11121 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
11122 index++;
11124 romptr = SISGETROMW(0x104); /* 0x4ae */
11125 delay = ROMAddr[romptr + index];
11126 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
11127 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11128 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11129 } else {
11130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11131 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11133 return;
11137 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
11139 if(SiS_Pr->UseCustomMode) delay = 0x04;
11140 else if(ModeNo <= 0x13) delay = 0x04;
11141 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
11142 delay |= (delay << 8);
11144 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11146 /* 3. TV */
11148 index = GetOEMTVPtr661(SiS_Pr);
11149 if(SiS_Pr->SiS_ROMNew) {
11150 romptr = SISGETROMW(0x106); /* 0x4ba */
11151 delay = ROMAddr[romptr + index];
11152 } else {
11153 delay = 0x04;
11156 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11158 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
11160 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
11161 ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
11163 /* For LV, the BIOS must know about the correct value */
11164 delay = ROMAddr[romptr + 0x0d]; /* LCD */
11165 delay |= (ROMAddr[romptr + 0x0c] << 8); /* LCDA */
11167 } else {
11169 /* TMDS: Set our own, since BIOS has no idea - TODO: Find out about values */
11170 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11171 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
11172 delay = 0x0404;
11173 } else if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
11174 delay = 0x0404;
11175 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
11176 delay = 0x1004;
11177 } else
11178 delay = 0x0000;
11181 /* Override by detected or user-set values */
11182 /* (but only if, for some reason, we can't read value from BIOS) */
11183 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
11184 delay = SiS_Pr->PDC & 0x1f;
11186 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
11187 delay = (SiS_Pr->PDCA & 0x1f) << 8;
11194 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11195 delay >>= 8;
11196 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11197 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11198 } else {
11199 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11200 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11204 static void
11205 SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
11207 USHORT infoflag;
11208 UCHAR temp;
11210 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11212 if(ModeNo <= 0x13) {
11213 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
11214 } else if(SiS_Pr->UseCustomMode) {
11215 infoflag = SiS_Pr->CInfoFlag;
11216 } else {
11217 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
11219 infoflag &= 0xc0;
11221 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
11222 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
11223 temp &= 0x3f;
11224 temp |= infoflag;
11225 } else {
11226 if(temp & 0x20) infoflag = temp;
11228 if(temp & 0x01) infoflag |= 0x01;
11230 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11231 temp = 0x0c;
11232 if(infoflag & 0x01) temp ^= 0x14; /* BIOS: 18, wrong */
11233 temp |= (infoflag >> 6);
11234 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
11235 } else {
11236 temp = 0;
11237 if(infoflag & 0x01) temp |= 0x80;
11238 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
11239 temp = 0x30;
11240 if(infoflag & 0x01) temp = 0x20;
11241 infoflag &= 0xc0;
11242 temp |= infoflag;
11243 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
11249 static void
11250 SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11252 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11253 USHORT romptr, temp1, temp2;
11255 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11256 if(SiS_Pr->LVDSHL != -1) {
11257 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11261 if(SiS_Pr->SiS_ROMNew) {
11263 if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
11264 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11265 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
11266 temp2 = 0xfc;
11267 if(SiS_Pr->LVDSHL != -1) {
11268 temp1 &= 0xfc;
11269 temp2 = 0xf3;
11271 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
11273 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11274 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
11275 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
11282 void
11283 SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11284 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
11286 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11288 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11290 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11291 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11292 SetPanelParms661(SiS_Pr,HwInfo);
11295 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11296 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11297 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11298 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11299 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11300 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11306 /* FinalizeLCD
11307 * This finalizes some CRT2 registers for the very panel used.
11308 * If we have a backup if these registers, we use it; otherwise
11309 * we set the register according to most BIOSes. However, this
11310 * function looks quite different in every BIOS, so you better
11311 * pray that we have a backup...
11313 void
11314 SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11315 PSIS_HW_INFO HwInfo)
11317 USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
11318 USHORT resinfo,modeflag;
11320 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
11322 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11323 if(SiS_Pr->LVDSHL != -1) {
11324 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11328 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11329 if(SiS_Pr->UseCustomMode) return;
11331 switch(SiS_Pr->SiS_CustomT) {
11332 case CUT_COMPAQ1280:
11333 case CUT_COMPAQ12802:
11334 case CUT_CLEVO1400:
11335 case CUT_CLEVO14002:
11336 return;
11339 if(ModeNo <= 0x13) {
11340 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11341 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11342 } else {
11343 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11344 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11347 if(IS_SIS650) {
11348 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
11349 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11350 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
11351 } else {
11352 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
11357 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11358 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11359 /* Maybe all panels? */
11360 if(SiS_Pr->LVDSHL == -1) {
11361 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11363 return;
11367 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
11368 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11369 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11370 if(SiS_Pr->LVDSHL == -1) {
11371 /* Maybe all panels? */
11372 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11374 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11375 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11376 if(tempch == 3) {
11377 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11378 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11379 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11380 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11383 return;
11388 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11389 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11390 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
11391 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
11392 #ifdef SET_EMI
11393 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
11394 #endif
11395 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
11397 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
11398 if(SiS_Pr->LVDSHL == -1) {
11399 /* Maybe ACER only? */
11400 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11403 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11404 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11405 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
11406 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
11407 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11408 if(tempch == 0x03) {
11409 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11410 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11411 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11412 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11414 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
11415 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
11416 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
11417 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
11418 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
11419 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
11420 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
11421 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
11422 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
11423 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
11424 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
11425 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
11426 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
11427 if(ModeNo <= 0x13) {
11428 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
11429 if((resinfo == 0) || (resinfo == 2)) return;
11430 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
11431 if((resinfo == 1) || (resinfo == 3)) return;
11433 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11434 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
11435 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
11436 #if 0
11437 tempbx = 806; /* 0x326 */ /* other older BIOSes */
11438 tempbx--;
11439 temp = tempbx & 0xff;
11440 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
11441 temp = (tempbx >> 8) & 0x03;
11442 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
11443 #endif
11445 } else if(ModeNo <= 0x13) {
11446 if(ModeNo <= 1) {
11447 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
11448 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
11449 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11450 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11452 if(!(modeflag & HalfDCLK)) {
11453 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
11454 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
11455 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
11456 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
11457 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
11458 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11459 if(ModeNo == 0x12) {
11460 switch(tempch) {
11461 case 0:
11462 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11463 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11464 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
11465 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11466 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
11467 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11468 break;
11469 case 2:
11470 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11471 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11472 break;
11473 case 3:
11474 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11475 break;
11481 } else {
11482 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
11483 tempcl &= 0x0f;
11484 tempbh &= 0x70;
11485 tempbh >>= 4;
11486 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
11487 tempbx = (tempbh << 8) | tempbl;
11488 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11489 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
11490 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
11491 tempbx = 770;
11492 } else {
11493 if(tempbx > 770) tempbx = 770;
11494 if(SiS_Pr->SiS_VGAVDE < 600) {
11495 tempax = 768 - SiS_Pr->SiS_VGAVDE;
11496 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
11497 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
11498 tempbx -= tempax;
11501 } else return;
11503 temp = tempbx & 0xff;
11504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
11505 temp = ((tempbx & 0xff00) >> 4) | tempcl;
11506 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
11511 #endif
11513 /* ================= SiS 300 O.E.M. ================== */
11515 #ifdef SIS300
11517 void
11518 SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11519 USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
11521 USHORT crt2crtc=0, modeflag, myindex=0;
11522 UCHAR temp;
11523 int i;
11525 if(ModeNo <= 0x13) {
11526 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11527 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
11528 } else {
11529 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11530 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
11533 crt2crtc &= 0x3f;
11535 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
11536 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
11539 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
11540 if(modeflag & HalfDCLK) myindex = 1;
11542 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
11543 for(i=0; i<7; i++) {
11544 if(barco_p1[myindex][crt2crtc][i][0]) {
11545 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
11546 barco_p1[myindex][crt2crtc][i][0],
11547 barco_p1[myindex][crt2crtc][i][2],
11548 barco_p1[myindex][crt2crtc][i][1]);
11552 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
11553 if(temp & 0x80) {
11554 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
11555 temp++;
11556 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
11561 static USHORT
11562 GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
11564 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11565 USHORT tempbx=0,romptr=0;
11566 UCHAR customtable300[] = {
11567 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11568 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11570 UCHAR customtable630[] = {
11571 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11572 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11575 if(HwInfo->jChipType == SIS_300) {
11577 tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
11578 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11579 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11580 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11582 if(SiS_Pr->SiS_UseROM) {
11583 if(ROMAddr[0x235] & 0x80) {
11584 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11585 if(Flag) {
11586 romptr = SISGETROMW(0x255);
11587 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11588 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11589 if(tempbx == 0xFF) return 0xFFFF;
11591 tempbx <<= 1;
11592 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11596 } else {
11598 if(Flag) {
11599 if(SiS_Pr->SiS_UseROM) {
11600 romptr = SISGETROMW(0x255);
11601 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11602 else tempbx = 0xff;
11603 } else {
11604 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11606 if(tempbx == 0xFF) return 0xFFFF;
11607 tempbx <<= 2;
11608 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11609 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11610 return tempbx;
11612 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11613 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11614 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11616 return tempbx;
11619 static void
11620 SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11621 USHORT ModeNo,USHORT ModeIdIndex)
11623 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11624 USHORT index,temp,romptr=0;
11626 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11628 if(SiS_Pr->SiS_UseROM) {
11629 if(!(ROMAddr[0x237] & 0x01)) return;
11630 if(!(ROMAddr[0x237] & 0x02)) return;
11631 romptr = SISGETROMW(0x24b);
11634 /* The Panel Compensation Delay should be set according to tables
11635 * here. Unfortunately, various BIOS versions don't case about
11636 * a uniform way using eg. ROM byte 0x220, but use different
11637 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11638 * Thus we don't set this if the user select a custom pdc or if
11639 * we otherwise detected a valid pdc.
11641 if(SiS_Pr->PDC != -1) return;
11643 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
11645 if(SiS_Pr->UseCustomMode)
11646 index = 0;
11647 else
11648 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11650 if(HwInfo->jChipType != SIS_300) {
11651 if(romptr) {
11652 romptr += (temp * 2);
11653 romptr = SISGETROMW(romptr);
11654 romptr += index;
11655 temp = ROMAddr[romptr];
11656 } else {
11657 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11658 temp = SiS300_OEMLCDDelay2[temp][index];
11659 } else {
11660 temp = SiS300_OEMLCDDelay3[temp][index];
11663 } else {
11664 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11665 if(romptr) {
11666 romptr += (temp * 2);
11667 romptr = SISGETROMW(romptr);
11668 romptr += index;
11669 temp = ROMAddr[romptr];
11670 } else {
11671 temp = SiS300_OEMLCDDelay5[temp][index];
11673 } else {
11674 if(SiS_Pr->SiS_UseROM) {
11675 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11676 if(romptr) {
11677 romptr += (temp * 2);
11678 romptr = SISGETROMW(romptr);
11679 romptr += index;
11680 temp = ROMAddr[romptr];
11681 } else {
11682 temp = SiS300_OEMLCDDelay4[temp][index];
11684 } else {
11685 temp = SiS300_OEMLCDDelay4[temp][index];
11689 temp &= 0x3c;
11690 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11693 static void
11694 SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11695 USHORT ModeNo,USHORT ModeIdIndex)
11697 #if 0 /* Unfinished; Data table missing */
11698 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11699 USHORT index,temp;
11701 if((SiS_Pr->SiS_UseROM) {
11702 if(!(ROMAddr[0x237] & 0x01)) return;
11703 if(!(ROMAddr[0x237] & 0x04)) return;
11704 /* No rom pointer in BIOS header! */
11707 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
11708 if(temp = 0xFFFF) return;
11710 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11711 for(i=0x14, j=0; i<=0x17; i++, j++) {
11712 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11714 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11716 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11717 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11718 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11719 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11720 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11721 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11723 #endif
11726 static USHORT
11727 GetOEMTVPtr(SiS_Private *SiS_Pr)
11729 USHORT index;
11731 index = 0;
11732 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11733 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11734 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11735 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11736 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11737 } else {
11738 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11739 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11741 return index;
11744 static void
11745 SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11746 USHORT ModeNo,USHORT ModeIdIndex)
11748 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11749 USHORT index,temp,romptr=0;
11751 if(SiS_Pr->SiS_UseROM) {
11752 if(!(ROMAddr[0x238] & 0x01)) return;
11753 if(!(ROMAddr[0x238] & 0x02)) return;
11754 romptr = SISGETROMW(0x241);
11757 temp = GetOEMTVPtr(SiS_Pr);
11759 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11761 if(romptr) {
11762 romptr += (temp * 2);
11763 romptr = SISGETROMW(romptr);
11764 romptr += index;
11765 temp = ROMAddr[romptr];
11766 } else {
11767 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11768 temp = SiS300_OEMTVDelay301[temp][index];
11769 } else {
11770 temp = SiS300_OEMTVDelayLVDS[temp][index];
11773 temp &= 0x3c;
11774 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11777 static void
11778 SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11779 USHORT ModeNo, USHORT ModeIdIndex)
11781 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11782 USHORT index,temp,romptr=0;
11784 if(SiS_Pr->SiS_UseROM) {
11785 if(!(ROMAddr[0x238] & 0x01)) return;
11786 if(!(ROMAddr[0x238] & 0x04)) return;
11787 romptr = SISGETROMW(0x243);
11790 temp = GetOEMTVPtr(SiS_Pr);
11792 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11794 if(romptr) {
11795 romptr += (temp * 2);
11796 romptr = SISGETROMW(romptr);
11797 romptr += index;
11798 temp = ROMAddr[romptr];
11799 } else {
11800 temp = SiS300_OEMTVFlicker[temp][index];
11802 temp &= 0x70;
11803 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11806 static void
11807 SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11808 USHORT ModeNo,USHORT ModeIdIndex)
11810 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11811 USHORT index,i,j,temp,romptr=0;
11813 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11815 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11817 if(SiS_Pr->SiS_UseROM) {
11818 if(!(ROMAddr[0x238] & 0x01)) return;
11819 if(!(ROMAddr[0x238] & 0x08)) return;
11820 romptr = SISGETROMW(0x245);
11823 temp = GetOEMTVPtr(SiS_Pr);
11825 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11827 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11828 for(i=0x31, j=0; i<=0x34; i++, j++) {
11829 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11831 } else {
11832 if(romptr) {
11833 romptr += (temp * 2);
11834 romptr = SISGETROMW(romptr);
11835 romptr += (index * 4);
11836 for(i=0x31, j=0; i<=0x34; i++, j++) {
11837 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11839 } else {
11840 for(i=0x31, j=0; i<=0x34; i++, j++) {
11841 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11847 static void
11848 SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11849 USHORT ModeNo,USHORT ModeIdIndex)
11851 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11852 USHORT index,temp,i,j,romptr=0;
11854 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11856 if(SiS_Pr->SiS_UseROM) {
11857 if(!(ROMAddr[0x238] & 0x01)) return;
11858 if(!(ROMAddr[0x238] & 0x10)) return;
11859 romptr = SISGETROMW(0x247);
11862 temp = GetOEMTVPtr(SiS_Pr);
11864 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11865 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11866 /* NTSCJ uses NTSC filters */
11868 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11870 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11871 for(i=0x35, j=0; i<=0x38; i++, j++) {
11872 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11874 for(i=0x48; i<=0x4A; i++, j++) {
11875 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11877 } else {
11878 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11879 romptr += (temp * 2);
11880 romptr = SISGETROMW(romptr);
11881 romptr += (index * 4);
11882 for(i=0x35, j=0; i<=0x38; i++, j++) {
11883 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11885 } else {
11886 for(i=0x35, j=0; i<=0x38; i++, j++) {
11887 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11893 static USHORT
11894 SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
11896 USHORT ModeIdIndex;
11897 UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
11899 if(*ModeNo <= 5) *ModeNo |= 1;
11901 for(ModeIdIndex=0; ; ModeIdIndex++) {
11902 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11903 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11906 if(*ModeNo != 0x07) {
11907 if(*ModeNo > 0x03) return ModeIdIndex;
11908 if(VGAINFO & 0x80) return ModeIdIndex;
11909 ModeIdIndex++;
11912 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11913 /* else 350 lines */
11914 return ModeIdIndex;
11917 void
11918 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11919 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
11921 USHORT OEMModeIdIndex=0;
11923 if(!SiS_Pr->UseCustomMode) {
11924 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11925 if(!(OEMModeIdIndex)) return;
11928 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11929 SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11930 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11931 SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11934 if(SiS_Pr->UseCustomMode) return;
11935 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11936 SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
11937 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11938 SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11939 SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11940 SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11944 #endif