4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730,
6 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
12 * If distributed as part of the Linux kernel, the following license terms
15 * * This program is free software; you can redistribute it and/or modify
16 * * it under the terms of the GNU General Public License as published by
17 * * the Free Software Foundation; either version 2 of the named License,
18 * * or any later version.
20 * * This program is distributed in the hope that it will be useful,
21 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * * GNU General Public License for more details.
25 * * You should have received a copy of the GNU General Public License
26 * * along with this program; if not, write to the Free Software
27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
29 * Otherwise, the following license terms apply:
31 * * Redistribution and use in source and binary forms, with or without
32 * * modification, are permitted provided that the following conditions
34 * * 1) Redistributions of source code must retain the above copyright
35 * * notice, this list of conditions and the following disclaimer.
36 * * 2) Redistributions in binary form must reproduce the above copyright
37 * * notice, this list of conditions and the following disclaimer in the
38 * * documentation and/or other materials provided with the distribution.
39 * * 3) The name of the author may not be used to endorse or promote products
40 * * derived from this software without specific prior written permission.
42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 * Author: Thomas Winischhofer <thomas@winischhofer.net>
55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
65 #define SET_EMI /* 302LV/ELV: Set EMI values */
69 #define SET_PWD /* 301/302LV: Set PWD */
72 #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
73 #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
74 #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
86 #define SiS_I2CDELAY 1000
87 #define SiS_I2CDELAYSHORT 150
89 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
90 #ifdef SIS_LINUX_KERNEL
91 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
94 /*********************************************/
95 /* HELPER: Lock/Unlock CRT2 */
96 /*********************************************/
99 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
101 if(SiS_Pr->ChipType == XGI_20)
103 else if(SiS_Pr->ChipType >= SIS_315H)
104 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
106 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
109 #ifdef SIS_LINUX_KERNEL
113 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
115 if(SiS_Pr->ChipType == XGI_20)
117 else if(SiS_Pr->ChipType >= SIS_315H)
118 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
120 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
123 /*********************************************/
124 /* HELPER: Write SR11 */
125 /*********************************************/
128 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
130 if(SiS_Pr->ChipType >= SIS_661) {
134 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
137 /*********************************************/
138 /* HELPER: Get Pointer to LCD structure */
139 /*********************************************/
142 static unsigned char *
143 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
145 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
146 unsigned char *myptr = NULL;
147 unsigned short romindex = 0, reg = 0, idx = 0;
149 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
150 * due to the variaty of panels the BIOS doesn't know about.
151 * Exception: If the BIOS has better knowledge (such as in case
152 * of machines with a 301C and a panel that does not support DDC)
153 * use the BIOS data as well.
156 if((SiS_Pr->SiS_ROMNew) &&
157 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
159 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
162 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
165 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
167 romindex = SISGETROMW(0x100);
170 myptr = &ROMAddr[romindex];
176 static unsigned short
177 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
179 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
180 unsigned short romptr = 0;
182 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
183 * due to the variaty of panels the BIOS doesn't know about.
184 * Exception: If the BIOS has better knowledge (such as in case
185 * of machines with a 301C and a panel that does not support DDC)
186 * use the BIOS data as well.
189 if((SiS_Pr->SiS_ROMNew) &&
190 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
191 romptr = SISGETROMW(0x102);
192 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
199 /*********************************************/
200 /* Adjust Rate for CRT2 */
201 /*********************************************/
204 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
205 unsigned short RRTI, unsigned short *i)
207 unsigned short checkmask=0, modeid, infoflag;
209 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
211 if(SiS_Pr->SiS_VBType & VB_SISVB) {
213 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
215 checkmask |= SupportRAMDAC2;
216 if(SiS_Pr->ChipType >= SIS_315H) {
217 checkmask |= SupportRAMDAC2_135;
218 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
219 checkmask |= SupportRAMDAC2_162;
220 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
221 checkmask |= SupportRAMDAC2_202;
226 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
228 checkmask |= SupportLCD;
229 if(SiS_Pr->ChipType >= SIS_315H) {
230 if(SiS_Pr->SiS_VBType & VB_SISVB) {
231 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
232 if(modeid == 0x2e) checkmask |= Support64048060Hz;
237 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
239 checkmask |= SupportHiVision;
241 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
243 checkmask |= SupportTV;
244 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
245 checkmask |= SupportTV1024;
246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
247 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
248 checkmask |= SupportYPbPr750p;
257 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
258 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
259 checkmask |= SupportCHTV;
263 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
264 checkmask |= SupportLCD;
269 /* Look backwards in table for matching CRT2 mode */
270 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
271 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
272 if(infoflag & checkmask) return TRUE;
276 /* Look through the whole mode-section of the table from the beginning
277 * for a matching CRT2 mode if no mode was found yet.
279 for((*i) = 0; ; (*i)++) {
280 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
281 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
282 if(infoflag & checkmask) return TRUE;
287 /*********************************************/
289 /*********************************************/
292 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
294 unsigned short RRTI,i,backup_i;
295 unsigned short modeflag,index,temp,backupindex;
296 static const unsigned short LCDRefreshIndex[] = {
297 0x00, 0x00, 0x01, 0x01,
298 0x01, 0x01, 0x01, 0x01,
299 0x01, 0x01, 0x01, 0x01,
300 0x01, 0x01, 0x01, 0x01,
301 0x00, 0x00, 0x00, 0x00
304 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
305 if(ModeNo == 0xfe) return 0;
308 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
310 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
313 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
314 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
315 if(modeflag & HalfDCLK) return 0;
319 if(ModeNo < 0x14) return 0xFFFF;
321 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
324 if(index > 0) index--;
326 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
327 if(SiS_Pr->SiS_VBType & VB_SISVB) {
328 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
329 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
330 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
332 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
333 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
334 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
335 if(index > temp) index = temp;
339 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
340 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
341 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
346 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
347 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
349 if(SiS_Pr->ChipType >= SIS_315H) {
350 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
351 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
352 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
353 if(backupindex <= 1) RRTI++;
360 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
361 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
362 temp &= ModeTypeMask;
363 if(temp < SiS_Pr->SiS_ModeType) break;
366 } while(index != 0xFFFF);
368 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
369 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
370 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
371 if(temp & InterlaceMode) i++;
377 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
379 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
387 /*********************************************/
388 /* STORE CRT2 INFO in CR34 */
389 /*********************************************/
392 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
394 unsigned short temp1, temp2;
396 /* Store CRT1 ModeNo in CR34 */
397 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
398 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
399 temp2 = ~(SetInSlaveMode >> 8);
400 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
403 /*********************************************/
404 /* HELPER: GET SOME DATA FROM BIOS ROM */
405 /*********************************************/
409 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
411 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
412 unsigned short temp,temp1;
414 if(SiS_Pr->SiS_UseROM) {
415 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
416 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
417 temp1 = SISGETROMW(0x23b);
418 if(temp1 & temp) return TRUE;
425 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
427 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
428 unsigned short temp,temp1;
430 if(SiS_Pr->SiS_UseROM) {
431 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
432 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
433 temp1 = SISGETROMW(0x23d);
434 if(temp1 & temp) return TRUE;
441 /*********************************************/
442 /* HELPER: DELAY FUNCTIONS */
443 /*********************************************/
446 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
450 for(i = 0; i < delaytime; i++) {
451 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
455 #if defined(SIS300) || defined(SIS315H)
457 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
459 SiS_DDC2Delay(SiS_Pr, delay * 36);
465 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
468 SiS_GenericDelay(SiS_Pr, 6623);
473 #if defined(SIS300) || defined(SIS315H)
475 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
478 SiS_GenericDelay(SiS_Pr, 66);
484 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
486 #if defined(SIS300) || defined(SIS315H)
487 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
488 unsigned short PanelID, DelayIndex, Delay=0;
491 if(SiS_Pr->ChipType < SIS_315H) {
495 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
496 if(SiS_Pr->SiS_VBType & VB_SISVB) {
497 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
498 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
500 DelayIndex = PanelID >> 4;
501 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
504 if(DelayTime >= 2) DelayTime -= 2;
505 if(!(DelayTime & 0x01)) {
506 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
508 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
510 if(SiS_Pr->SiS_UseROM) {
511 if(ROMAddr[0x220] & 0x40) {
512 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
513 else Delay = (unsigned short)ROMAddr[0x226];
517 SiS_ShortDelay(SiS_Pr, Delay);
525 if((SiS_Pr->ChipType >= SIS_661) ||
526 (SiS_Pr->ChipType <= SIS_315PRO) ||
527 (SiS_Pr->ChipType == SIS_330) ||
528 (SiS_Pr->SiS_ROMNew)) {
530 if(!(DelayTime & 0x01)) {
531 SiS_DDC2Delay(SiS_Pr, 0x1000);
533 SiS_DDC2Delay(SiS_Pr, 0x4000);
536 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
537 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
538 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
540 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
541 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
542 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
543 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
545 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
546 DelayIndex = PanelID & 0x0f;
548 DelayIndex = PanelID >> 4;
550 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
553 if(DelayTime >= 2) DelayTime -= 2;
554 if(!(DelayTime & 0x01)) {
555 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
557 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
559 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
560 if(ROMAddr[0x13c] & 0x40) {
561 if(!(DelayTime & 0x01)) {
562 Delay = (unsigned short)ROMAddr[0x17e];
564 Delay = (unsigned short)ROMAddr[0x17f];
569 SiS_ShortDelay(SiS_Pr, Delay);
572 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
574 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
575 if(!(DelayTime & 0x01)) {
576 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
578 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
581 SiS_DDC2Delay(SiS_Pr, Delay);
592 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
595 for(i = 0; i < DelayLoop; i++) {
596 SiS_PanelDelay(SiS_Pr, DelayTime);
601 /*********************************************/
602 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
603 /*********************************************/
606 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
608 unsigned short watchdog;
610 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
611 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
614 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
616 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
619 #if defined(SIS300) || defined(SIS315H)
621 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
623 unsigned short watchdog;
626 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
628 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
633 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
635 if(SiS_Pr->ChipType < SIS_315H) {
637 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
638 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
640 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
641 SiS_WaitRetrace1(SiS_Pr);
643 SiS_WaitRetrace2(SiS_Pr, 0x25);
648 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
649 SiS_WaitRetrace1(SiS_Pr);
651 SiS_WaitRetrace2(SiS_Pr, 0x30);
658 SiS_VBWait(struct SiS_Private *SiS_Pr)
660 unsigned short tempal,temp,i,j;
663 for(i = 0; i < 3; i++) {
664 for(j = 0; j < 100; j++) {
665 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
667 if((tempal & 0x08)) continue;
670 if(!(tempal & 0x08)) continue;
679 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
681 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
684 SiS_WaitRetrace1(SiS_Pr);
688 /*********************************************/
690 /*********************************************/
694 SiS_Is301B(struct SiS_Private *SiS_Pr)
696 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
702 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
704 if(SiS_Pr->ChipType == SIS_730) {
705 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return TRUE;
707 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return TRUE;
712 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
715 if(SiS_Pr->ChipType >= SIS_315H) {
716 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
717 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return TRUE;
725 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
730 if(SiS_Pr->ChipType >= SIS_315H) {
731 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
732 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
740 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
742 if(SiS_IsVAMode(SiS_Pr)) return TRUE;
743 if(SiS_CRT2IsLCD(SiS_Pr)) return TRUE;
749 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
752 if(SiS_Pr->ChipType >= SIS_315H) {
753 if((SiS_CRT2IsLCD(SiS_Pr)) ||
754 (SiS_IsVAMode(SiS_Pr))) {
755 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
764 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
766 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
767 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
768 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
776 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
778 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
785 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
787 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
788 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
796 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
800 if(SiS_Pr->ChipType == SIS_650) {
801 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
802 /* Check for revision != A0 only */
803 if((flag == 0xe0) || (flag == 0xc0) ||
804 (flag == 0xb0) || (flag == 0x90)) return FALSE;
805 } else if(SiS_Pr->ChipType >= SIS_661) return FALSE;
812 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
814 if(SiS_Pr->ChipType >= SIS_315H) {
816 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return TRUE;
824 SiS_IsChScart(struct SiS_Private *SiS_Pr)
826 if(SiS_Pr->ChipType >= SIS_315H) {
828 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return TRUE;
836 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
840 if(SiS_Pr->ChipType >= SIS_315H) {
841 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
842 if(flag & SetCRT2ToTV) return TRUE;
843 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
844 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
845 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
847 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
848 if(flag & SetCRT2ToTV) return TRUE;
856 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
860 if(SiS_Pr->ChipType >= SIS_315H) {
861 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
862 if(flag & SetCRT2ToLCD) return TRUE;
863 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
864 if(flag & SetToLCDA) return TRUE;
866 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
867 if(flag & SetCRT2ToLCD) return TRUE;
874 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
878 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
880 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
881 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
882 if((flag == 1) || (flag == 2)) return TRUE;
888 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
892 if(SiS_HaveBridge(SiS_Pr)) {
893 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
894 if(SiS_Pr->ChipType < SIS_315H) {
896 if((flag == 0x80) || (flag == 0x20)) return TRUE;
899 if((flag == 0x40) || (flag == 0x10)) return TRUE;
906 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
908 unsigned short flag1;
910 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
911 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
915 /*********************************************/
916 /* GET VIDEO BRIDGE CONFIG INFO */
917 /*********************************************/
919 /* Setup general purpose IO for Chrontel communication */
922 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
924 unsigned int acpibase;
927 if(!(SiS_Pr->SiS_ChSW)) return;
929 #ifdef SIS_LINUX_KERNEL
930 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
932 acpibase = pciReadLong(0x00000800, 0x74);
935 if(!acpibase) return;
936 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
938 SiS_SetRegShort((acpibase + 0x3c), temp);
939 temp = SiS_GetRegShort((acpibase + 0x3c));
940 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
942 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
943 SiS_SetRegShort((acpibase + 0x3a), temp);
944 temp = SiS_GetRegShort((acpibase + 0x3a));
949 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
950 unsigned short ModeIdIndex, int checkcrt2mode)
952 unsigned short tempax, tempbx, temp;
953 unsigned short modeflag, resinfo = 0;
955 SiS_Pr->SiS_SetFlag = 0;
957 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
959 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
961 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
962 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
967 if(SiS_HaveBridge(SiS_Pr)) {
969 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
971 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
972 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
976 if(SiS_Pr->ChipType >= SIS_315H) {
977 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
979 /* Mode 0x03 is never in driver mode */
980 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
982 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
983 /* Reset LCDA setting if not driver mode */
984 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
987 if(SiS_Pr->SiS_UseLCDA) {
988 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
989 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
990 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
995 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
996 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
997 tempbx |= SetCRT2ToLCDA;
1001 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1002 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1003 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1004 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1005 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1006 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1007 tempbx |= SetCRT2ToYPbPr525750;
1012 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1013 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1014 if(temp & SetToLCDA) {
1015 tempbx |= SetCRT2ToLCDA;
1017 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1018 if(temp & EnableCHYPbPr) {
1019 tempbx |= SetCRT2ToCHYPbPr;
1025 #endif /* SIS315H */
1027 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1028 tempbx &= ~(SetCRT2ToRAMDAC);
1031 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1032 temp = SetCRT2ToSVIDEO |
1039 SetCRT2ToYPbPr525750;
1041 if(SiS_Pr->ChipType >= SIS_315H) {
1042 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1043 temp = SetCRT2ToAVIDEO |
1050 temp = SetCRT2ToLCDA |
1054 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1055 temp = SetCRT2ToTV | SetCRT2ToLCD;
1057 temp = SetCRT2ToLCD;
1062 if(!(tempbx & temp)) {
1063 tempax = DisableCRT2Display;
1067 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1069 unsigned short clearmask = ( DriverMode |
1070 DisableCRT2Display |
1078 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1079 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1080 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1081 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1082 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1083 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1087 if(SiS_Pr->ChipType >= SIS_315H) {
1088 if(tempbx & SetCRT2ToLCDA) {
1089 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1092 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1093 if(tempbx & SetCRT2ToTV) {
1094 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1097 if(tempbx & SetCRT2ToLCD) {
1098 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1100 if(SiS_Pr->ChipType >= SIS_315H) {
1101 if(tempbx & SetCRT2ToLCDA) {
1102 tempbx |= SetCRT2ToLCD;
1108 if(tempax & DisableCRT2Display) {
1109 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1110 tempbx = SetSimuScanMode | DisableCRT2Display;
1114 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1116 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1117 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1118 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1119 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1120 modeflag &= (~CRT2Mode);
1124 if(!(tempbx & SetSimuScanMode)) {
1125 if(tempbx & SwitchCRT2) {
1126 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1127 if(resinfo != SIS_RI_1600x1200) {
1128 tempbx |= SetSimuScanMode;
1132 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1133 if(!(tempbx & DriverMode)) {
1134 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1135 tempbx |= SetSimuScanMode;
1142 if(!(tempbx & DisableCRT2Display)) {
1143 if(tempbx & DriverMode) {
1144 if(tempbx & SetSimuScanMode) {
1145 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1146 if(resinfo != SIS_RI_1600x1200) {
1147 tempbx |= SetInSlaveMode;
1152 tempbx |= SetInSlaveMode;
1158 SiS_Pr->SiS_VBInfo = tempbx;
1161 if(SiS_Pr->ChipType == SIS_630) {
1162 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1166 #ifdef SIS_LINUX_KERNEL
1168 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1169 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1172 #ifdef SIS_XORG_XF86
1174 xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1175 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1180 /*********************************************/
1181 /* DETERMINE YPbPr MODE */
1182 /*********************************************/
1185 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1190 /* Note: This variable is only used on 30xLV systems.
1191 * CR38 has a different meaning on LVDS/CH7019 systems.
1192 * On 661 and later, these bits moved to CR35.
1194 * On 301, 301B, only HiVision 1080i is supported.
1195 * On 30xLV, 301C, only YPbPr 1080i is supported.
1198 SiS_Pr->SiS_YPbPr = 0;
1199 if(SiS_Pr->ChipType >= SIS_661) return;
1201 if(SiS_Pr->SiS_VBType) {
1202 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1203 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1207 if(SiS_Pr->ChipType >= SIS_315H) {
1208 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1209 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1211 switch((temp >> 4)) {
1212 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1213 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1214 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1215 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1223 /*********************************************/
1224 /* DETERMINE TVMode flag */
1225 /*********************************************/
1228 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1230 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1231 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1232 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1234 SiS_Pr->SiS_TVMode = 0;
1236 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1237 if(SiS_Pr->UseCustomMode) return;
1240 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1243 if(SiS_Pr->ChipType < SIS_661) {
1245 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1247 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1249 if((SiS_Pr->ChipType == SIS_630) ||
1250 (SiS_Pr->ChipType == SIS_730)) {
1253 } else if(SiS_Pr->ChipType >= SIS_315H) {
1255 if(SiS_Pr->ChipType < XGI_20) {
1257 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1261 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1262 OutputSelect = ROMAddr[romindex];
1263 if(!(OutputSelect & EnablePALMN)) {
1264 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1267 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1268 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1269 if(temp1 & EnablePALM) { /* 0x40 */
1270 SiS_Pr->SiS_TVMode |= TVSetPALM;
1271 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1272 } else if(temp1 & EnablePALN) { /* 0x80 */
1273 SiS_Pr->SiS_TVMode |= TVSetPALN;
1276 if(temp1 & EnableNTSCJ) { /* 0x40 */
1277 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1281 /* Translate HiVision/YPbPr to our new flags */
1282 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1283 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1284 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1285 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1286 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1287 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1288 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1289 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1290 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1291 SiS_Pr->SiS_TVMode |= TVSetPAL;
1294 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1295 if(SiS_Pr->SiS_CHOverScan) {
1296 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1297 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1298 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1299 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1301 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1302 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1303 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1304 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1307 if(SiS_Pr->SiS_CHSOverScan) {
1308 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1311 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1312 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1313 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1314 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1315 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1317 if(temp & EnableNTSCJ) {
1318 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1324 } else { /* 661 and later */
1326 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1328 SiS_Pr->SiS_TVMode |= TVSetPAL;
1330 SiS_Pr->SiS_TVMode |= TVSetPALN;
1331 } else if(temp1 & 0x04) {
1332 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1333 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1335 SiS_Pr->SiS_TVMode |= TVSetPALM;
1339 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1342 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1343 if(SiS_Pr->SiS_CHOverScan) {
1344 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1345 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1349 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1350 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1352 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1353 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1354 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1355 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1356 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1358 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1359 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1360 SiS_Pr->SiS_TVMode |= TVAspect169;
1362 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1364 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1365 SiS_Pr->SiS_TVMode |= TVAspect169;
1367 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1370 SiS_Pr->SiS_TVMode |= TVAspect43;
1377 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1379 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1381 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1382 SiS_Pr->SiS_TVMode |= TVSetPAL;
1383 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1384 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1385 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1386 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1390 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1391 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1392 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1396 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1397 if(resinfo == SIS_RI_1024x768) {
1398 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1399 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1400 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1401 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1406 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1407 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1408 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1409 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1410 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1411 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1412 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1413 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1414 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1420 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1422 #ifdef SIS_XORG_XF86
1424 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1429 /*********************************************/
1431 /*********************************************/
1433 static unsigned short
1434 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1436 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1437 /* Translate my LCDResInfo to BIOS value */
1439 case Panel_1280x768_2: temp = Panel_1280x768; break;
1440 case Panel_1280x800_2: temp = Panel_1280x800; break;
1441 case Panel_1280x854: temp = Panel661_1280x854; break;
1447 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1450 unsigned char *ROMAddr;
1451 unsigned short temp;
1453 #ifdef SIS_XORG_XF86
1455 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1456 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1457 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1458 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1459 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1460 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1461 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1465 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1466 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1467 SiS_Pr->SiS_NeedRomModeData = TRUE;
1468 SiS_Pr->PanelHT = temp;
1470 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1471 SiS_Pr->SiS_NeedRomModeData = TRUE;
1472 SiS_Pr->PanelVT = temp;
1474 SiS_Pr->PanelHRS = SISGETROMW(10);
1475 SiS_Pr->PanelHRE = SISGETROMW(12);
1476 SiS_Pr->PanelVRS = SISGETROMW(14);
1477 SiS_Pr->PanelVRE = SISGETROMW(16);
1478 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1479 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1480 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1481 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1482 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1483 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1484 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1486 #ifdef SIS_XORG_XF86
1488 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1489 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1490 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1491 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1492 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1493 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1494 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1503 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1504 const unsigned char *nonscalingmodes)
1507 while(nonscalingmodes[i] != 0xff) {
1508 if(nonscalingmodes[i++] == resinfo) {
1509 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1510 (SiS_Pr->UsePanelScaler == -1)) {
1511 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1519 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1521 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1522 BOOLEAN panelcanscale = FALSE;
1524 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1525 static const unsigned char SiS300SeriesLCDRes[] =
1526 { 0, 1, 2, 3, 7, 4, 5, 8,
1527 0, 0, 10, 0, 0, 0, 0, 15 };
1530 unsigned char *myptr = NULL;
1533 SiS_Pr->SiS_LCDResInfo = 0;
1534 SiS_Pr->SiS_LCDTypeInfo = 0;
1535 SiS_Pr->SiS_LCDInfo = 0;
1536 SiS_Pr->PanelHRS = 999; /* HSync start */
1537 SiS_Pr->PanelHRE = 999; /* HSync end */
1538 SiS_Pr->PanelVRS = 999; /* VSync start */
1539 SiS_Pr->PanelVRE = 999; /* VSync end */
1540 SiS_Pr->SiS_NeedRomModeData = FALSE;
1542 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1543 SiS_Pr->Alternate1600x1200 = FALSE;
1545 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1547 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1549 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1550 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1551 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1552 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1555 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1557 /* For broken BIOSes: Assume 1024x768 */
1558 if(temp == 0) temp = 0x02;
1560 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1561 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1562 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1563 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1565 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1569 if(SiS_Pr->ChipType < SIS_315H) {
1570 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1571 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1572 if(temp < 0x0f) temp &= 0x07;
1574 /* Translate 300 series LCDRes to 315 series for unified usage */
1575 temp = SiS300SeriesLCDRes[temp];
1579 /* Translate to our internal types */
1581 if(SiS_Pr->ChipType == SIS_550) {
1582 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1583 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1584 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1585 } else if(SiS_Pr->ChipType >= SIS_661) {
1586 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1590 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1591 if(temp == Panel310_1280x768) {
1592 temp = Panel_1280x768_2;
1594 if(SiS_Pr->SiS_ROMNew) {
1595 if(temp == Panel661_1280x800) {
1596 temp = Panel_1280x800_2;
1601 SiS_Pr->SiS_LCDResInfo = temp;
1604 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1605 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1606 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1607 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1608 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1609 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1610 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1615 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1616 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1617 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1619 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1620 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1623 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1624 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1625 /* Need temp below! */
1627 /* These must/can't scale no matter what */
1628 switch(SiS_Pr->SiS_LCDResInfo) {
1629 case Panel_320x240_1:
1630 case Panel_320x240_2:
1631 case Panel_320x240_3:
1632 case Panel_1280x960:
1633 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1636 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1639 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
1641 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1642 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1644 /* Dual link, Pass 1:1 BIOS default, etc. */
1646 if(SiS_Pr->ChipType >= SIS_661) {
1647 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1648 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1650 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1651 if(SiS_Pr->SiS_ROMNew) {
1652 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1653 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1654 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1657 } else if(SiS_Pr->ChipType >= SIS_315H) {
1658 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1659 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1661 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1662 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1663 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1664 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1665 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1666 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1668 } else if(!(SiS_Pr->SiS_ROMNew)) {
1669 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1670 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1671 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1672 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1674 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1675 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1676 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1677 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1678 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1686 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1687 /* Always center screen on LVDS (if scaling is disabled) */
1688 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1689 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1690 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1691 /* Always center screen on SiS LVDS (if scaling is disabled) */
1692 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1694 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1695 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1696 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1700 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1701 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1703 switch(SiS_Pr->SiS_LCDResInfo) {
1704 case Panel_320x240_1:
1705 case Panel_320x240_2:
1706 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1707 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1708 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1709 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1711 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1712 SiS_Pr->PanelVRE = 3;
1713 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1714 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1716 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1717 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1718 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1719 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1720 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1721 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1723 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1724 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1725 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1726 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1727 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1728 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1730 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1731 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1732 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1733 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1734 if(SiS_Pr->ChipType < SIS_315H) {
1735 SiS_Pr->PanelHRS = 23;
1736 SiS_Pr->PanelVRE = 5;
1738 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1739 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1740 SiS_GetLCDInfoBIOS(SiS_Pr);
1742 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1743 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1744 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1745 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1746 if(SiS_Pr->ChipType < SIS_315H) {
1747 SiS_Pr->PanelHRS = 23;
1748 SiS_Pr->PanelVRE = 5;
1750 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1751 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1753 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1755 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1756 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1757 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1758 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1759 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1760 /* Data above for TMDS (projector); get from BIOS for LVDS */
1761 SiS_GetLCDInfoBIOS(SiS_Pr);
1763 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1764 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1765 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1766 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1767 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1769 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1770 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1771 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1772 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1773 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1776 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1777 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1778 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1779 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1780 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1781 SiS_GetLCDInfoBIOS(SiS_Pr);
1783 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1784 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1785 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1786 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1787 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1788 SiS_GetLCDInfoBIOS(SiS_Pr);
1790 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1791 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1792 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1793 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1794 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1795 SiS_GetLCDInfoBIOS(SiS_Pr);
1797 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1798 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1799 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1800 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1801 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1802 SiS_GetLCDInfoBIOS(SiS_Pr);
1804 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1805 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1806 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1807 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1808 if(resinfo == SIS_RI_1280x1024) {
1809 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1810 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1813 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1814 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1815 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1816 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1817 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1818 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1819 SiS_GetLCDInfoBIOS(SiS_Pr);
1821 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1822 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1823 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1824 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1825 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1826 SiS_GetLCDInfoBIOS(SiS_Pr);
1828 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1829 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1830 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1831 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1832 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1833 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1834 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1835 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1836 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1837 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1838 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1839 SiS_Pr->Alternate1600x1200 = TRUE;
1841 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1842 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1843 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1844 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1846 SiS_GetLCDInfoBIOS(SiS_Pr);
1848 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1849 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1850 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1851 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1852 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1853 SiS_GetLCDInfoBIOS(SiS_Pr);
1855 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1856 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1858 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1859 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1861 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1862 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1864 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1865 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1866 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1867 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1868 if(SiS_Pr->CP_PreferredIndex != -1) {
1869 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1870 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1871 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1872 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1873 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1874 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1875 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1876 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1877 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1878 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1879 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1880 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1881 if(SiS_Pr->CP_PrefClock) {
1883 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1884 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1885 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1886 else idx = VCLK_CUSTOM_315;
1887 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1888 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1889 SiS_Pr->SiS_VCLKData[idx].SR2B =
1890 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1891 SiS_Pr->SiS_VCLKData[idx].SR2C =
1892 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1896 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1897 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1902 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1903 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1904 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1905 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1906 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1907 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1908 SiS_Pr->PanelHRS = 999;
1909 SiS_Pr->PanelHRE = 999;
1912 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1913 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1914 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1915 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1916 SiS_Pr->PanelVRS = 999;
1917 SiS_Pr->PanelVRE = 999;
1920 /* DontExpand overrule */
1921 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1923 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1924 /* No scaling for this mode on any panel (LCD=CRT2)*/
1925 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1928 switch(SiS_Pr->SiS_LCDResInfo) {
1931 case Panel_1152x864:
1932 case Panel_1280x768: /* TMDS only */
1933 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1936 case Panel_800x600: {
1937 static const unsigned char nonscalingmodes[] = {
1938 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1940 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1943 case Panel_1024x768: {
1944 static const unsigned char nonscalingmodes[] = {
1945 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1946 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1949 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1952 case Panel_1280x720: {
1953 static const unsigned char nonscalingmodes[] = {
1954 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1955 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1958 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1959 if(SiS_Pr->PanelHT == 1650) {
1960 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1964 case Panel_1280x768_2: { /* LVDS only */
1965 static const unsigned char nonscalingmodes[] = {
1966 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1967 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1968 SIS_RI_1152x768,0xff
1970 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1972 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1973 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1979 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1980 static const unsigned char nonscalingmodes[] = {
1981 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1982 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1983 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1985 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1988 case Panel_1280x800_2: { /* SiS LVDS */
1989 static const unsigned char nonscalingmodes[] = {
1990 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1991 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1992 SIS_RI_1152x768,0xff
1994 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1996 case SIS_RI_1280x720:
1997 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1998 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2004 case Panel_1280x854: { /* SiS LVDS */
2005 static const unsigned char nonscalingmodes[] = {
2006 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2007 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2008 SIS_RI_1152x768,0xff
2010 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2012 case SIS_RI_1280x720:
2013 case SIS_RI_1280x768:
2014 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2015 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2021 case Panel_1280x960: {
2022 static const unsigned char nonscalingmodes[] = {
2023 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2024 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2025 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2026 SIS_RI_1280x854,0xff
2028 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2031 case Panel_1280x1024: {
2032 static const unsigned char nonscalingmodes[] = {
2033 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2034 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2035 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2036 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2038 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2041 case Panel_1400x1050: {
2042 static const unsigned char nonscalingmodes[] = {
2043 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2044 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2045 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2046 SIS_RI_1280x960,0xff
2048 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2050 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2051 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2054 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2059 case Panel_1600x1200: {
2060 static const unsigned char nonscalingmodes[] = {
2061 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2062 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2063 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2064 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2066 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2069 case Panel_1680x1050: {
2070 static const unsigned char nonscalingmodes[] = {
2071 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2072 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2073 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2074 SIS_RI_1360x1024,0xff
2076 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2083 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2084 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2085 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2089 if(SiS_Pr->ChipType < SIS_315H) {
2090 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2091 if(SiS_Pr->SiS_UseROM) {
2092 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2093 if(!(ROMAddr[0x235] & 0x02)) {
2094 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2098 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2099 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2100 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2108 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2109 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2112 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2113 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2116 switch(SiS_Pr->SiS_LCDResInfo) {
2118 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2120 case Panel_1280x800:
2121 /* Don't pass 1:1 by default (TMDS special) */
2122 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2124 case Panel_1280x960:
2125 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2128 if((!SiS_Pr->CP_PrefClock) ||
2129 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2130 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2135 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2136 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2139 /* (In)validate LCDPass11 flag */
2140 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2141 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2145 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2147 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2148 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2149 if(ModeNo == 0x12) {
2150 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2151 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2153 } else if(ModeNo > 0x13) {
2154 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2155 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2156 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2157 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2165 if(modeflag & HalfDCLK) {
2166 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2167 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2168 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2169 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2170 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2171 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2172 } else if(ModeNo > 0x13) {
2173 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2174 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2175 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2176 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2184 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2185 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2186 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2189 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2192 #ifdef SIS_LINUX_KERNEL
2194 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2195 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2198 #ifdef SIS_XORG_XF86
2199 xf86DrvMsgVerb(0, X_PROBED, 4,
2200 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2201 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2205 /*********************************************/
2207 /*********************************************/
2210 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2211 unsigned short RefreshRateTableIndex)
2213 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2214 unsigned short modeflag, resinfo, tempbx;
2215 const unsigned char *CHTVVCLKPtr = NULL;
2217 if(ModeNo <= 0x13) {
2218 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2219 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2220 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2221 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2222 VCLKIndexGENCRT = VCLKIndexGEN;
2224 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2225 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2226 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2227 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2228 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2229 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2232 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2234 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2237 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2239 if(SiS_Pr->ChipType < SIS_315H) {
2240 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2241 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2242 VCLKIndex = VCLKIndexGEN;
2245 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2246 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2248 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2249 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2250 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2251 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2252 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2253 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2254 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2255 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2256 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2257 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2258 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2259 default: VCLKIndex = VCLKIndexGEN;
2262 if(ModeNo <= 0x13) {
2263 if(SiS_Pr->ChipType <= SIS_315PRO) {
2264 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2266 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2269 if(SiS_Pr->ChipType <= SIS_315PRO) {
2270 if(VCLKIndex == 0) VCLKIndex = 0x41;
2271 if(VCLKIndex == 1) VCLKIndex = 0x43;
2272 if(VCLKIndex == 4) VCLKIndex = 0x44;
2277 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2279 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2280 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2281 else VCLKIndex = HiTVVCLK;
2282 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2283 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2284 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2285 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2286 else VCLKIndex = TVVCLK;
2288 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2289 else VCLKIndex += TVCLKBASE_315;
2293 VCLKIndex = VCLKIndexGENCRT;
2294 if(SiS_Pr->ChipType < SIS_315H) {
2296 if( (SiS_Pr->ChipType == SIS_630) &&
2297 (SiS_Pr->ChipRevision >= 0x30)) {
2298 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2300 /* Better VGA2 clock for 1280x1024@75 */
2301 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2306 } else { /* If not programming CRT2 */
2308 VCLKIndex = VCLKIndexGENCRT;
2309 if(SiS_Pr->ChipType < SIS_315H) {
2311 if( (SiS_Pr->ChipType != SIS_630) &&
2312 (SiS_Pr->ChipType != SIS_300) ) {
2313 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2321 VCLKIndex = CRT2Index;
2323 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2325 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2329 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2330 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2332 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2333 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2335 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2337 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2338 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2340 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2344 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2345 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2346 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2347 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2348 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2349 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2350 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2351 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2352 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2353 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2355 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2357 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2359 if(SiS_Pr->ChipType < SIS_315H) {
2360 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2362 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2366 /* Special Timing: Barco iQ Pro R series */
2367 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2369 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2370 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2371 if(SiS_Pr->ChipType < SIS_315H) {
2372 VCLKIndex = VCLK34_300;
2373 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2375 VCLKIndex = VCLK34_315;
2376 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2383 VCLKIndex = VCLKIndexGENCRT;
2384 if(SiS_Pr->ChipType < SIS_315H) {
2386 if( (SiS_Pr->ChipType == SIS_630) &&
2387 (SiS_Pr->ChipRevision >= 0x30) ) {
2388 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2394 } else { /* if not programming CRT2 */
2396 VCLKIndex = VCLKIndexGENCRT;
2397 if(SiS_Pr->ChipType < SIS_315H) {
2399 if( (SiS_Pr->ChipType != SIS_630) &&
2400 (SiS_Pr->ChipType != SIS_300) ) {
2401 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2404 if(SiS_Pr->ChipType == SIS_730) {
2405 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2406 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2416 #ifdef SIS_XORG_XF86
2418 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2425 /*********************************************/
2426 /* SET CRT2 MODE TYPE REGISTERS */
2427 /*********************************************/
2430 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2432 unsigned short i, j, modeflag, tempah=0;
2434 #if defined(SIS300) || defined(SIS315H)
2435 unsigned short tempbl;
2438 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2439 unsigned short tempah2, tempbl2;
2442 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2444 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2446 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2447 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2451 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2452 if(SiS_Pr->ChipType >= SIS_315H) {
2453 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2456 tempcl = SiS_Pr->SiS_ModeType;
2458 if(SiS_Pr->ChipType < SIS_315H) {
2460 #ifdef SIS300 /* ---- 300 series ---- */
2462 /* For 301BDH: (with LCD via LVDS) */
2463 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2464 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2467 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2471 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2477 tempah = ((0x10 >> tempcl) | 0x80);
2479 } else tempah = 0x80;
2481 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2487 #ifdef SIS315H /* ------- 315/330 series ------ */
2492 tempah = (0x08 >> tempcl);
2493 if (tempah == 0) tempah = 1;
2496 } else tempah = 0x40;
2498 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2500 #endif /* SIS315H */
2504 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2506 if(SiS_Pr->ChipType < SIS_315H) {
2507 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2510 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2511 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2512 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2514 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2516 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2522 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2525 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2528 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2530 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2535 if(SiS_Pr->ChipType < SIS_315H) {
2537 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2539 tempah = (tempah << 5) & 0xFF;
2540 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2541 tempah = (tempah >> 5) & 0xFF;
2545 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2546 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2547 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2552 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2557 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2558 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2561 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2562 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2563 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2569 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2572 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2573 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2576 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2578 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2579 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2584 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2588 if(SiS_Pr->ChipType >= SIS_315H) {
2591 /* LVDS can only be slave in 8bpp modes */
2593 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2594 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2599 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2601 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2603 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2605 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2612 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2617 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2619 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2628 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2630 if(SiS_Pr->ChipType >= SIS_315H) {
2633 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2635 /* The following is nearly unpreditable and varies from machine
2636 * to machine. Especially the 301DH seems to be a real trouble
2637 * maker. Some BIOSes simply set the registers (like in the
2638 * NoLCD-if-statements here), some set them according to the
2639 * LCDA stuff. It is very likely that some machines are not
2640 * treated correctly in the following, very case-orientated
2641 * code. What do I do then...?
2644 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2647 tempah = 0x04; /* For all bridges */
2649 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2651 if(SiS_IsDualEdge(SiS_Pr)) {
2655 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2658 /* The following two are responsible for eventually wrong colors
2659 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2660 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2661 * in a 650 box (Jake). What is the criteria?
2662 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2663 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2664 * chipset than the bridge revision.
2667 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2670 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2671 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2675 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2676 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2677 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2678 /* Fixes "TV-blue-bug" on 315+301 */
2679 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2680 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2681 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2682 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2683 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2684 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2685 tempah = 0x30; tempah2 = 0xc0;
2686 tempbl = 0xcf; tempbl2 = 0x3f;
2687 if(SiS_Pr->SiS_TVBlue == 0) {
2688 tempah = tempah2 = 0x00;
2689 } else if(SiS_Pr->SiS_TVBlue == -1) {
2690 /* Set on 651/M650, clear on 315/650 */
2691 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2692 tempah = tempah2 = 0x00;
2695 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2696 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2698 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2699 tempbl = 0xcf; tempbl2 = 0x3f;
2700 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2701 tempah = tempah2 = 0x00;
2702 if(SiS_IsDualEdge(SiS_Pr)) {
2703 tempbl = tempbl2 = 0xff;
2706 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2707 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2712 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2713 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2717 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2719 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2721 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2724 #endif /* SIS315H */
2726 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2729 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2731 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2732 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2733 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2734 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2736 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2742 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2743 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2744 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2745 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2752 if(SiS_Pr->ChipType >= SIS_315H) {
2754 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2758 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2760 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2762 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2764 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2765 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2768 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2770 } else if(SiS_Pr->ChipType == SIS_550) {
2772 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2773 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2784 /*********************************************/
2785 /* GET RESOLUTION DATA */
2786 /*********************************************/
2789 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2792 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2794 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2798 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2800 unsigned short xres, yres, modeflag=0, resindex;
2802 if(SiS_Pr->UseCustomMode) {
2803 xres = SiS_Pr->CHDisplay;
2804 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2805 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2806 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2807 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2811 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2813 if(ModeNo <= 0x13) {
2814 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2815 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2817 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2818 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2819 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2822 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2824 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2825 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2826 if(yres == 350) yres = 400;
2828 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2829 if(ModeNo == 0x12) yres = 400;
2833 if(modeflag & HalfDCLK) xres <<= 1;
2834 if(modeflag & DoubleScanMode) yres <<= 1;
2838 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2840 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2841 switch(SiS_Pr->SiS_LCDResInfo) {
2842 case Panel_1024x768:
2843 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2844 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2845 if(yres == 350) yres = 357;
2846 if(yres == 400) yres = 420;
2847 if(yres == 480) yres = 525;
2851 case Panel_1280x1024:
2852 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2853 /* BIOS bug - does this regardless of scaling */
2854 if(yres == 400) yres = 405;
2856 if(yres == 350) yres = 360;
2857 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2858 if(yres == 360) yres = 375;
2861 case Panel_1600x1200:
2862 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2863 if(yres == 1024) yres = 1056;
2871 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2872 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2873 if(xres == 720) xres = 640;
2875 } else if(xres == 720) xres = 640;
2877 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2879 if(SiS_Pr->ChipType >= SIS_315H) {
2880 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2882 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2884 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2888 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2889 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2892 /*********************************************/
2893 /* GET CRT2 TIMING DATA */
2894 /*********************************************/
2897 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2898 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2899 unsigned short *ResIndex)
2901 unsigned short tempbx=0, tempal=0, resinfo=0;
2903 if(ModeNo <= 0x13) {
2904 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2906 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2907 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2910 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2912 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2914 tempbx = SiS_Pr->SiS_LCDResInfo;
2915 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2918 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2919 if (resinfo == SIS_RI_1280x800) tempal = 9;
2920 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2921 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2922 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2923 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2924 if (resinfo == SIS_RI_1280x768) tempal = 9;
2927 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2928 /* Pass 1:1 only (center-screen handled outside) */
2929 /* This is never called for the panel's native resolution */
2930 /* since Pass1:1 will not be set in this case */
2932 if(ModeNo >= 0x13) {
2933 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2938 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2939 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2940 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2942 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2950 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2951 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2953 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2955 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2957 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2958 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2959 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2961 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2963 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2965 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2973 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2975 case SIS_RI_720x480:
2977 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
2979 case SIS_RI_720x576:
2980 case SIS_RI_768x576:
2981 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2983 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2984 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
2987 case SIS_RI_800x480:
2990 case SIS_RI_512x384:
2991 case SIS_RI_1024x768:
2993 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2994 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
2997 case SIS_RI_1280x720:
2998 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2999 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
3006 *CRT2Index = tempbx;
3009 } else { /* LVDS, 301B-DH (if running on LCD) */
3012 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3015 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3017 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3018 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3020 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3021 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3024 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3029 switch(SiS_Pr->SiS_LCDResInfo) {
3030 case Panel_640x480: tempbx = 12; break;
3031 case Panel_320x240_1: tempbx = 10; break;
3032 case Panel_320x240_2:
3033 case Panel_320x240_3: tempbx = 14; break;
3034 case Panel_800x600: tempbx = 16; break;
3035 case Panel_1024x600: tempbx = 18; break;
3036 case Panel_1152x768:
3037 case Panel_1024x768: tempbx = 20; break;
3038 case Panel_1280x768: tempbx = 22; break;
3039 case Panel_1280x1024: tempbx = 24; break;
3040 case Panel_1400x1050: tempbx = 26; break;
3041 case Panel_1600x1200: tempbx = 28; break;
3043 case Panel_Barco1366: tempbx = 80; break;
3047 switch(SiS_Pr->SiS_LCDResInfo) {
3048 case Panel_320x240_1:
3049 case Panel_320x240_2:
3050 case Panel_320x240_3:
3054 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3057 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3060 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3062 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3063 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3065 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3071 (*CRT2Index) = tempbx;
3072 (*ResIndex) = tempal & 0x1F;
3077 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3078 unsigned short RefreshRateTableIndex)
3080 unsigned short tempax=0, tempbx=0, index, dotclock;
3081 unsigned short temp1=0, modeflag=0, tempcx=0;
3083 SiS_Pr->SiS_RVBHCMAX = 1;
3084 SiS_Pr->SiS_RVBHCFACT = 1;
3086 if(ModeNo <= 0x13) {
3088 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3089 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3091 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3092 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3093 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3095 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3099 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3100 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3102 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3103 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3105 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3106 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3110 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3116 if(temp1 & 0x01) tempbx |= 0x0100;
3117 if(temp1 & 0x20) tempbx |= 0x0200;
3121 if(modeflag & HalfDCLK) tempax <<= 1;
3125 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3126 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3130 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3131 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3133 unsigned short ResIndex;
3135 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3136 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3137 if(SiS_Pr->UseCustomMode) {
3138 ResIndex = SiS_Pr->CHTotal;
3139 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3140 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3141 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3144 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3146 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3148 if(ResIndex == 0x09) {
3149 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3150 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3152 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3153 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3154 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3155 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3158 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3159 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3162 /* This handles custom modes and custom panels */
3163 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3164 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3165 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3166 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3167 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3168 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3173 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3174 unsigned short RefreshRateTableIndex)
3176 unsigned short CRT2Index, ResIndex, backup;
3177 const struct SiS_LVDSData *LVDSData = NULL;
3179 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3181 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3182 SiS_Pr->SiS_RVBHCMAX = 1;
3183 SiS_Pr->SiS_RVBHCFACT = 1;
3184 SiS_Pr->SiS_NewFlickerMode = 0;
3185 SiS_Pr->SiS_RVBHRS = 50;
3186 SiS_Pr->SiS_RY1COE = 0;
3187 SiS_Pr->SiS_RY2COE = 0;
3188 SiS_Pr->SiS_RY3COE = 0;
3189 SiS_Pr->SiS_RY4COE = 0;
3190 SiS_Pr->SiS_RVBHRS2 = 0;
3193 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3196 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3197 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3202 /* 301BDH needs LVDS Data */
3203 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3204 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3205 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3208 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3209 &CRT2Index, &ResIndex);
3211 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3214 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3215 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3216 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3217 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3218 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3219 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3221 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3222 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3223 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3224 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3225 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3227 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3228 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3229 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3230 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3231 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3232 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3233 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3234 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3235 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3239 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3240 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3241 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3242 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3244 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3247 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3248 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3249 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3250 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3251 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3252 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3253 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3255 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3256 if(ResIndex < 0x08) {
3257 SiS_Pr->SiS_HDE = 1280;
3258 SiS_Pr->SiS_VDE = 1024;
3268 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3269 unsigned short RefreshRateTableIndex)
3271 unsigned char *ROMAddr = NULL;
3272 unsigned short tempax, tempbx, modeflag, romptr=0;
3273 unsigned short resinfo, CRT2Index, ResIndex;
3274 const struct SiS_LCDData *LCDPtr = NULL;
3275 const struct SiS_TVData *TVPtr = NULL;
3280 if(ModeNo <= 0x13) {
3281 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3282 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3283 } else if(SiS_Pr->UseCustomMode) {
3284 modeflag = SiS_Pr->CModeFlag;
3287 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3288 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3290 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3291 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3292 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3293 (resinfo661 >= 0) &&
3294 (SiS_Pr->SiS_NeedRomModeData) ) {
3295 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3296 if((romptr = (SISGETROMW(21)))) {
3297 romptr += (resinfo661 * 10);
3298 ROMAddr = SiS_Pr->VirtualRomBase;
3305 SiS_Pr->SiS_NewFlickerMode = 0;
3306 SiS_Pr->SiS_RVBHRS = 50;
3307 SiS_Pr->SiS_RY1COE = 0;
3308 SiS_Pr->SiS_RY2COE = 0;
3309 SiS_Pr->SiS_RY3COE = 0;
3310 SiS_Pr->SiS_RY4COE = 0;
3311 SiS_Pr->SiS_RVBHRS2 = 0;
3313 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3315 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3317 if(SiS_Pr->UseCustomMode) {
3319 SiS_Pr->SiS_RVBHCMAX = 1;
3320 SiS_Pr->SiS_RVBHCFACT = 1;
3321 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3322 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3324 tempax = SiS_Pr->CHTotal;
3325 if(modeflag & HalfDCLK) tempax <<= 1;
3326 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3327 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3331 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3335 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3337 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3338 &CRT2Index,&ResIndex);
3341 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3342 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3343 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3344 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3345 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3346 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3347 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3348 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3349 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3350 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3351 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3352 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3353 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3354 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3357 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3358 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3359 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3360 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3361 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3362 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3363 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3364 if(modeflag & HalfDCLK) {
3365 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3366 if(SiS_Pr->SiS_RVBHRS2) {
3367 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3368 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3369 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3370 else SiS_Pr->SiS_RVBHRS2 += tempax;
3373 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3375 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3377 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3379 if((resinfo == SIS_RI_960x600) ||
3380 (resinfo == SIS_RI_1024x768) ||
3381 (resinfo == SIS_RI_1280x1024) ||
3382 (resinfo == SIS_RI_1280x720)) {
3383 SiS_Pr->SiS_NewFlickerMode = 0x40;
3386 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3388 SiS_Pr->SiS_HT = ExtHiTVHT;
3389 SiS_Pr->SiS_VT = ExtHiTVVT;
3390 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3391 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3392 SiS_Pr->SiS_HT = StHiTVHT;
3393 SiS_Pr->SiS_VT = StHiTVVT;
3397 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3399 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3400 SiS_Pr->SiS_HT = 1650;
3401 SiS_Pr->SiS_VT = 750;
3402 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3403 SiS_Pr->SiS_HT = NTSCHT;
3404 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3405 SiS_Pr->SiS_VT = NTSCVT;
3407 SiS_Pr->SiS_HT = NTSCHT;
3408 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3409 SiS_Pr->SiS_VT = NTSCVT;
3414 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3415 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3416 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3417 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3419 if(modeflag & HalfDCLK) {
3420 SiS_Pr->SiS_RY1COE = 0x00;
3421 SiS_Pr->SiS_RY2COE = 0xf4;
3422 SiS_Pr->SiS_RY3COE = 0x10;
3423 SiS_Pr->SiS_RY4COE = 0x38;
3426 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3427 SiS_Pr->SiS_HT = NTSCHT;
3428 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3429 SiS_Pr->SiS_VT = NTSCVT;
3431 SiS_Pr->SiS_HT = PALHT;
3432 SiS_Pr->SiS_VT = PALVT;
3437 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3439 SiS_Pr->SiS_RVBHCMAX = 1;
3440 SiS_Pr->SiS_RVBHCFACT = 1;
3442 if(SiS_Pr->UseCustomMode) {
3444 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3445 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3447 tempax = SiS_Pr->CHTotal;
3448 if(modeflag & HalfDCLK) tempax <<= 1;
3449 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3450 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3454 BOOLEAN gotit = FALSE;
3456 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3458 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3459 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3460 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3461 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3464 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3467 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3468 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3469 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3470 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3471 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3472 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3473 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3474 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3475 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3476 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3477 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3478 else SiS_Pr->SiS_RVBHRS2 += tempax;
3480 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3482 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3483 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3484 SiS_Pr->SiS_RVBHCMAX = 1;
3485 SiS_Pr->SiS_RVBHCFACT = 1;
3486 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3487 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3488 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3489 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3490 SiS_Pr->SiS_RVBHRS2 = 0;
3499 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3500 &CRT2Index,&ResIndex);
3503 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3504 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3505 case Panel_1280x720 :
3506 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3507 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3508 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3509 case Panel_1280x800 :
3510 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3511 case Panel_1280x800_2 :
3512 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3513 case Panel_1280x854 :
3514 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3515 case Panel_1280x960 :
3516 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3517 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3518 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3519 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3520 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3521 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3522 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3523 case Panel_1680x1050 :
3524 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3525 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3527 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3528 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3530 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3533 #ifdef SIS_XORG_XF86
3535 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3539 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3540 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3541 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3542 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3543 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3544 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3548 tempax = SiS_Pr->PanelXRes;
3549 tempbx = SiS_Pr->PanelYRes;
3551 switch(SiS_Pr->SiS_LCDResInfo) {
3552 case Panel_1024x768:
3553 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3554 if(SiS_Pr->ChipType < SIS_315H) {
3555 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3556 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3559 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3560 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3561 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3562 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3563 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3564 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3567 case Panel_1280x960:
3568 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3569 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3570 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3572 case Panel_1280x1024:
3573 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3574 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3575 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3577 case Panel_1600x1200:
3578 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3579 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3580 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3585 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3586 tempax = SiS_Pr->SiS_VGAHDE;
3587 tempbx = SiS_Pr->SiS_VGAVDE;
3590 SiS_Pr->SiS_HDE = tempax;
3591 SiS_Pr->SiS_VDE = tempbx;
3597 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3598 unsigned short RefreshRateTableIndex)
3601 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3603 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3604 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3606 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3607 /* Need LVDS Data for LCD on 301B-DH */
3608 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3610 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3616 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3621 /*********************************************/
3622 /* GET LVDS DES (SKEW) DATA */
3623 /*********************************************/
3625 static const struct SiS_LVDSDes *
3626 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3628 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3631 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3633 if(SiS_Pr->ChipType < SIS_315H) {
3634 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3635 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3636 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3637 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3638 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3640 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3641 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3642 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3643 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3654 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3655 unsigned short RefreshRateTableIndex)
3657 unsigned short modeflag, ResIndex;
3658 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3660 SiS_Pr->SiS_LCDHDES = 0;
3661 SiS_Pr->SiS_LCDVDES = 0;
3663 /* Some special cases */
3664 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3667 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3668 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3669 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3670 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3676 /* 640x480 on LVDS */
3677 if(SiS_Pr->ChipType < SIS_315H) {
3678 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3679 SiS_Pr->SiS_LCDHDES = 8;
3680 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3681 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3682 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3689 if( (SiS_Pr->UseCustomMode) ||
3690 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3691 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3692 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3693 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3697 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3698 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3700 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3703 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3704 /* non-pass 1:1 only, see above */
3705 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3706 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3708 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3709 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3712 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3713 switch(SiS_Pr->SiS_CustomT) {
3714 case CUT_UNIWILL1024:
3715 case CUT_UNIWILL10242:
3717 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3718 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3722 switch(SiS_Pr->SiS_LCDResInfo) {
3723 case Panel_1280x1024:
3724 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3725 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3728 case Panel_1280x800: /* Verified for Averatec 6240 */
3729 case Panel_1280x800_2: /* Verified for Asus A4L */
3730 case Panel_1280x854: /* Not verified yet FIXME */
3731 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3739 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3741 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3742 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3745 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3747 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3748 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3750 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3752 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3753 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3755 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3756 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3758 if(SiS_Pr->ChipType < SIS_315H) {
3759 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3761 switch(SiS_Pr->SiS_LCDResInfo) {
3763 case Panel_1024x768:
3764 case Panel_1280x1024:
3765 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3767 case Panel_1400x1050:
3768 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3776 if(SiS_Pr->ChipType < SIS_315H) {
3778 switch(SiS_Pr->SiS_LCDResInfo) {
3780 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3781 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3783 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3784 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3785 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3786 else SiS_Pr->SiS_LCDVDES -= 4;
3789 case Panel_1024x768:
3790 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3791 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3793 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3794 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3795 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3798 case Panel_1024x600:
3800 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3801 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3802 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3804 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3809 switch(SiS_Pr->SiS_LCDTypeInfo) {
3811 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3813 case 3: /* 640x480 only? */
3814 SiS_Pr->SiS_LCDHDES = 8;
3815 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3816 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3817 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3823 switch(SiS_Pr->SiS_LCDResInfo) {
3824 case Panel_1024x768:
3825 case Panel_1280x1024:
3826 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3827 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3830 case Panel_320x240_1:
3831 case Panel_320x240_2:
3832 case Panel_320x240_3:
3833 SiS_Pr->SiS_LCDVDES = 524;
3840 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3841 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3842 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3843 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3844 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3845 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3846 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3847 if(SiS_Pr->ChipType < SIS_315H) {
3848 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3851 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3852 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3853 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3854 if(!(modeflag & HalfDCLK)) {
3855 SiS_Pr->SiS_LCDHDES = 320;
3856 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3857 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3868 /*********************************************/
3869 /* DISABLE VIDEO BRIDGE */
3870 /*********************************************/
3874 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3878 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3879 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3880 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3881 unsigned short temp;
3883 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3885 (SiS_Pr->SiS_PWDOffset) ) {
3886 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3887 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3888 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3889 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3890 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3892 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3896 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3897 #ifdef SIS_XORG_XF86
3899 xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
3908 /* NEVER use any variables (VBInfo), this will be called
3909 * from outside the context of modeswitch!
3910 * MUST call getVBType before calling this
3913 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3916 unsigned short tempah, pushax=0, modenum;
3918 unsigned short temp=0;
3920 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3922 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3924 if(SiS_Pr->ChipType < SIS_315H) {
3926 #ifdef SIS300 /* 300 series */
3928 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3929 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3930 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3932 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3934 SiS_PanelDelay(SiS_Pr, 3);
3936 if(SiS_Is301B(SiS_Pr)) {
3937 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3938 SiS_ShortDelay(SiS_Pr,1);
3940 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3941 SiS_DisplayOff(SiS_Pr);
3942 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3943 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3944 SiS_UnLockCRT2(SiS_Pr);
3945 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3946 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3947 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3949 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3950 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3951 SiS_PanelDelay(SiS_Pr, 2);
3952 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3953 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3955 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3963 #ifdef SIS315H /* 315 series */
3966 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3967 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3969 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3971 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3974 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3975 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3976 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3981 didpwd = SiS_HandlePWD(SiS_Pr);
3983 if( (modenum <= 0x13) ||
3984 (SiS_IsVAMode(SiS_Pr)) ||
3985 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3987 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3988 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3990 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3995 SiS_DDC2Delay(SiS_Pr,0xff00);
3996 SiS_DDC2Delay(SiS_Pr,0xe000);
3997 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3998 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4000 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4002 SiS_PanelDelay(SiS_Pr, 3);
4007 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4008 /* if(SiS_Pr->ChipType < SIS_340) {*/
4010 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4011 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4015 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4016 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4020 if(SiS_IsDualEdge(SiS_Pr)) {
4022 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4024 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4026 if((SiS_IsVAMode(SiS_Pr)) ||
4027 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4029 SiS_DisplayOff(SiS_Pr);
4030 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4031 SiS_PanelDelay(SiS_Pr, 2);
4033 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4034 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4038 if((!(SiS_IsVAMode(SiS_Pr))) ||
4039 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4041 if(!(SiS_IsDualEdge(SiS_Pr))) {
4042 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4043 SiS_DisplayOff(SiS_Pr);
4045 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4047 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4048 SiS_PanelDelay(SiS_Pr, 2);
4051 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4052 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4053 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4054 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4055 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4059 if(SiS_IsNotM650orLater(SiS_Pr)) {
4060 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4063 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4065 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4066 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4067 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4069 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4071 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4073 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4077 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4078 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4079 if(SiS_IsVAorLCD(SiS_Pr)) {
4080 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4087 #endif /* SIS315H */
4091 } else { /* ============ For 301 ================ */
4093 if(SiS_Pr->ChipType < SIS_315H) {
4095 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4096 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4097 SiS_PanelDelay(SiS_Pr, 3);
4102 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4103 SiS_DisplayOff(SiS_Pr);
4105 if(SiS_Pr->ChipType >= SIS_315H) {
4106 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4109 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4111 if(SiS_Pr->ChipType >= SIS_315H) {
4112 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4113 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4114 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4115 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4118 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4119 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4120 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4121 SiS_PanelDelay(SiS_Pr, 2);
4122 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4129 } else { /* ============ For LVDS =============*/
4131 if(SiS_Pr->ChipType < SIS_315H) {
4133 #ifdef SIS300 /* 300 series */
4135 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4136 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4139 if(SiS_Pr->ChipType == SIS_730) {
4140 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4141 SiS_WaitVBRetrace(SiS_Pr);
4143 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4144 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4145 SiS_PanelDelay(SiS_Pr, 3);
4148 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4149 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4150 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4151 SiS_WaitVBRetrace(SiS_Pr);
4152 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4153 SiS_DisplayOff(SiS_Pr);
4155 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4156 SiS_PanelDelay(SiS_Pr, 3);
4162 SiS_DisplayOff(SiS_Pr);
4164 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4166 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4167 SiS_UnLockCRT2(SiS_Pr);
4168 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4169 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4171 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4172 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4173 SiS_PanelDelay(SiS_Pr, 2);
4174 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4181 #ifdef SIS315H /* 315 series */
4183 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4184 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4185 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4189 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4191 if(SiS_Pr->ChipType == SIS_740) {
4192 temp = SiS_GetCH701x(SiS_Pr,0x61);
4194 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4195 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4198 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4199 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4200 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4204 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4205 (SiS_IsVAMode(SiS_Pr)) ) {
4206 SiS_Chrontel701xBLOff(SiS_Pr);
4207 SiS_Chrontel701xOff(SiS_Pr);
4210 if(SiS_Pr->ChipType != SIS_740) {
4211 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4212 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4213 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4219 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4220 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4221 SiS_PanelDelay(SiS_Pr, 3);
4224 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4225 (!(SiS_IsDualEdge(SiS_Pr))) ||
4226 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4227 SiS_DisplayOff(SiS_Pr);
4230 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4231 (!(SiS_IsDualEdge(SiS_Pr))) ||
4232 (!(SiS_IsVAMode(SiS_Pr))) ) {
4233 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4236 if(SiS_Pr->ChipType == SIS_740) {
4237 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4240 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4242 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4243 (!(SiS_IsDualEdge(SiS_Pr))) ||
4244 (!(SiS_IsVAMode(SiS_Pr))) ) {
4245 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4248 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4249 if(SiS_CRT2IsLCD(SiS_Pr)) {
4250 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4251 if(SiS_Pr->ChipType == SIS_550) {
4252 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4253 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4257 if(SiS_Pr->ChipType == SIS_740) {
4258 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4259 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4261 } else if(SiS_IsVAMode(SiS_Pr)) {
4262 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4266 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4267 if(SiS_IsDualEdge(SiS_Pr)) {
4268 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4270 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4274 SiS_UnLockCRT2(SiS_Pr);
4276 if(SiS_Pr->ChipType == SIS_550) {
4277 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4278 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4279 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4280 (!(SiS_IsDualEdge(SiS_Pr))) ||
4281 (!(SiS_IsVAMode(SiS_Pr))) ) {
4282 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4285 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4286 if(SiS_CRT2IsLCD(SiS_Pr)) {
4287 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4288 SiS_PanelDelay(SiS_Pr, 2);
4289 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4294 #endif /* SIS315H */
4302 /*********************************************/
4303 /* ENABLE VIDEO BRIDGE */
4304 /*********************************************/
4306 /* NEVER use any variables (VBInfo), this will be called
4307 * from outside the context of a mode switch!
4308 * MUST call getVBType before calling this
4310 #ifdef SIS_LINUX_KERNEL
4314 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4316 unsigned short temp=0, tempah;
4318 unsigned short temp1, pushax=0;
4319 BOOLEAN delaylong = FALSE;
4322 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4324 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4326 if(SiS_Pr->ChipType < SIS_315H) {
4328 #ifdef SIS300 /* 300 series */
4330 if(SiS_CRT2IsLCD(SiS_Pr)) {
4331 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4332 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4333 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4334 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4336 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4337 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4338 SiS_PanelDelay(SiS_Pr, 0);
4343 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4344 (SiS_CRT2IsLCD(SiS_Pr))) {
4346 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4347 SiS_DisplayOn(SiS_Pr);
4348 SiS_UnLockCRT2(SiS_Pr);
4349 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4350 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4351 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4353 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4355 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4356 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4357 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4358 SiS_PanelDelay(SiS_Pr, 1);
4360 SiS_WaitVBRetrace(SiS_Pr);
4361 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4367 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4368 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4369 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4370 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4372 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4373 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4374 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4375 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4376 SiS_DisplayOn(SiS_Pr);
4377 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4378 if(SiS_CRT2IsLCD(SiS_Pr)) {
4379 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4380 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4381 SiS_PanelDelay(SiS_Pr, 1);
4383 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4395 #ifdef SIS315H /* 315 series */
4398 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4400 /* unsigned short emidelay=0; */
4403 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4404 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4406 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4407 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4412 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4413 /*if(SiS_Pr->ChipType < SIS_340) { */
4415 if(SiS_LCDAEnabled(SiS_Pr)) {
4416 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4419 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4423 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4425 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4426 SiS_DisplayOff(SiS_Pr);
4427 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4429 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4432 didpwd = SiS_HandlePWD(SiS_Pr);
4434 if(SiS_IsVAorLCD(SiS_Pr)) {
4436 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4437 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4438 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4439 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4440 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4441 SiS_GenericDelay(SiS_Pr, 17664);
4445 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4446 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4447 SiS_GenericDelay(SiS_Pr, 17664);
4452 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4453 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4459 if(!(SiS_IsVAMode(SiS_Pr))) {
4461 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4462 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4463 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4464 if(!(tempah & SetCRT2ToRAMDAC)) {
4465 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4468 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4470 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4472 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4473 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4475 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4476 SiS_PanelDelay(SiS_Pr, 2);
4481 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4485 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4486 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4488 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4489 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4490 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4491 /* Enable "LVDS PLL power on" (even on 301C) */
4492 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4493 /* Enable "LVDS Driver Power on" (even on 301C) */
4494 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4499 if(SiS_IsDualEdge(SiS_Pr)) {
4501 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4503 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4505 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4507 SiS_PanelDelay(SiS_Pr, 2);
4509 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4510 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4512 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4514 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4515 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4516 SiS_GenericDelay(SiS_Pr, 2048);
4519 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4521 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4523 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4525 if(SiS_Pr->SiS_ROMNew) {
4526 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4527 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4529 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4531 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4532 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4533 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4534 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4535 /* emidelay = SISGETROMW((romptr + 0x22)); */
4536 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4541 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4542 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4543 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4544 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4545 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4546 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4547 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4548 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4549 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4551 if(SiS_Pr->HaveEMI) {
4552 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4553 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4558 /* EMI_30 is read at driver start; however, the BIOS sets this
4559 * (if it is used) only if the LCD is in use. In case we caught
4560 * the machine while on TV output, this bit is not set and we
4561 * don't know if it should be set - hence our detection is wrong.
4562 * Work-around this here:
4565 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4566 switch((cr36 & 0x0f)) {
4569 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4570 if(!SiS_Pr->HaveEMI) {
4571 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4572 if((cr36 & 0xf0) == 0x30) {
4573 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4577 case 3: /* 1280x1024 */
4578 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4579 if(!SiS_Pr->HaveEMI) {
4580 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4581 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4582 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4586 case 9: /* 1400x1050 */
4588 if(!SiS_Pr->HaveEMI) {
4589 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4590 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4591 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4595 case 11: /* 1600x1200 - unknown */
4597 if(!SiS_Pr->HaveEMI) {
4598 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4603 /* BIOS values don't work so well sometimes */
4604 if(!SiS_Pr->OverruleEMI) {
4606 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4607 if((cr36 & 0x0f) == 0x09) {
4608 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4613 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4614 if((cr36 & 0x0f) == 0x03) {
4615 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4620 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4621 if((cr36 & 0x0f) == 0x02) {
4622 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4623 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4624 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4625 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4631 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4632 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4633 SiS_GenericDelay(SiS_Pr, 2048);
4635 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4636 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4637 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4638 #endif /* SET_EMI */
4640 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4643 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4644 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4646 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4647 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4649 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4652 SiS_WaitVBRetrace(SiS_Pr);
4653 SiS_WaitVBRetrace(SiS_Pr);
4654 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4655 SiS_GenericDelay(SiS_Pr, 1280);
4657 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4658 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4665 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4666 if(SiS_IsVAorLCD(SiS_Pr)) {
4667 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4669 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4671 SiS_WaitVBRetrace(SiS_Pr);
4672 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4673 SiS_GenericDelay(SiS_Pr, 2048);
4674 SiS_WaitVBRetrace(SiS_Pr);
4677 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4679 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4684 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4685 SiS_DisplayOn(SiS_Pr);
4686 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4690 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4691 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4694 #endif /* SIS315H */
4698 } else { /* ============ For 301 ================ */
4700 if(SiS_Pr->ChipType < SIS_315H) {
4701 if(SiS_CRT2IsLCD(SiS_Pr)) {
4702 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4703 SiS_PanelDelay(SiS_Pr, 0);
4707 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4708 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4709 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4710 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4712 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4714 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4716 if(SiS_Pr->ChipType >= SIS_315H) {
4717 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4718 if(!(temp & 0x80)) {
4719 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4723 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4725 SiS_VBLongWait(SiS_Pr);
4726 SiS_DisplayOn(SiS_Pr);
4727 if(SiS_Pr->ChipType >= SIS_315H) {
4728 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4730 SiS_VBLongWait(SiS_Pr);
4732 if(SiS_Pr->ChipType < SIS_315H) {
4733 if(SiS_CRT2IsLCD(SiS_Pr)) {
4734 SiS_PanelDelay(SiS_Pr, 1);
4735 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4741 } else { /* =================== For LVDS ================== */
4743 if(SiS_Pr->ChipType < SIS_315H) {
4745 #ifdef SIS300 /* 300 series */
4747 if(SiS_CRT2IsLCD(SiS_Pr)) {
4748 if(SiS_Pr->ChipType == SIS_730) {
4749 SiS_PanelDelay(SiS_Pr, 1);
4750 SiS_PanelDelay(SiS_Pr, 1);
4751 SiS_PanelDelay(SiS_Pr, 1);
4753 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4754 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4755 SiS_PanelDelay(SiS_Pr, 0);
4759 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4760 SiS_DisplayOn(SiS_Pr);
4761 SiS_UnLockCRT2(SiS_Pr);
4762 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4763 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4764 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4766 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4769 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4770 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4771 SiS_WaitVBRetrace(SiS_Pr);
4772 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4776 if(SiS_CRT2IsLCD(SiS_Pr)) {
4777 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4778 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4779 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4780 SiS_PanelDelay(SiS_Pr, 1);
4781 SiS_PanelDelay(SiS_Pr, 1);
4783 SiS_WaitVBRetrace(SiS_Pr);
4784 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4793 #ifdef SIS315H /* 315 series */
4795 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4796 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4797 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4801 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4802 if(SiS_CRT2IsLCD(SiS_Pr)) {
4803 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4804 SiS_PanelDelay(SiS_Pr, 0);
4808 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4809 SiS_UnLockCRT2(SiS_Pr);
4811 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4813 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4814 temp = SiS_GetCH701x(SiS_Pr,0x66);
4816 SiS_Chrontel701xBLOff(SiS_Pr);
4819 if(SiS_Pr->ChipType != SIS_550) {
4820 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4823 if(SiS_Pr->ChipType == SIS_740) {
4824 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4825 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4826 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4831 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4832 if(!(temp1 & 0x80)) {
4833 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4836 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4838 SiS_Chrontel701xBLOn(SiS_Pr);
4842 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4843 if(SiS_CRT2IsLCD(SiS_Pr)) {
4844 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4845 if(SiS_Pr->ChipType == SIS_550) {
4846 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4847 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4850 } else if(SiS_IsVAMode(SiS_Pr)) {
4851 if(SiS_Pr->ChipType != SIS_740) {
4852 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4856 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4857 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4860 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4861 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4862 SiS_Chrontel701xOn(SiS_Pr);
4864 if( (SiS_IsVAMode(SiS_Pr)) ||
4865 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4866 SiS_ChrontelDoSomething1(SiS_Pr);
4870 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4871 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4872 if( (SiS_IsVAMode(SiS_Pr)) ||
4873 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4874 SiS_Chrontel701xBLOn(SiS_Pr);
4875 SiS_ChrontelInitTVVSync(SiS_Pr);
4878 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4879 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4880 if(SiS_CRT2IsLCD(SiS_Pr)) {
4881 SiS_PanelDelay(SiS_Pr, 1);
4882 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4887 #endif /* SIS315H */
4895 /*********************************************/
4896 /* SET PART 1 REGISTER GROUP */
4897 /*********************************************/
4899 /* Set CRT2 OFFSET / PITCH */
4901 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4902 unsigned short RRTI)
4904 unsigned short offset;
4907 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4909 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4911 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4912 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4914 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4915 if(offset & 0x07) temp++;
4916 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4919 /* Set CRT2 sync and PanelLink mode */
4921 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4923 unsigned short tempah=0, tempbl, infoflag;
4927 if(SiS_Pr->UseCustomMode) {
4928 infoflag = SiS_Pr->CInfoFlag;
4930 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4933 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4935 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4937 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4938 tempah = SiS_Pr->SiS_LCDInfo;
4939 } else tempah = infoflag >> 8;
4942 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4943 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4944 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4945 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4948 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4949 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4950 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4951 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4952 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4955 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4956 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4960 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4961 if(SiS_Pr->ChipType >= SIS_315H) {
4964 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4965 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4967 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4970 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4973 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4975 if(SiS_Pr->ChipType < SIS_315H) {
4977 #ifdef SIS300 /* ---- 300 series --- */
4979 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4981 tempah = infoflag >> 8;
4983 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4984 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4985 tempah = SiS_Pr->SiS_LCDInfo;
4986 tempbl = (tempah >> 6) & 0x03;
4991 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4993 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4994 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4995 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4998 } else { /* 630 - 301 */
5000 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5001 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5002 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5010 #ifdef SIS315H /* ------- 315 series ------ */
5012 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
5015 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5016 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5017 tempah = infoflag >> 8;
5018 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5019 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5021 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
5022 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5023 tempah = infoflag >> 8;
5026 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5027 tempbl = (tempah >> 6) & 0x03;
5029 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5033 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5034 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
5035 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5036 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5037 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5038 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5042 } else { /* 315 - TMDS */
5044 tempah = tempbl = infoflag >> 8;
5045 if(!SiS_Pr->UseCustomMode) {
5047 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5048 if(ModeNo <= 0x13) {
5049 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5052 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5053 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5054 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5055 tempah = SiS_Pr->SiS_LCDInfo;
5056 tempbl = (tempah >> 6) & 0x03;
5063 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5064 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5065 /* Imitate BIOS bug */
5066 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5068 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5071 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5073 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5074 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5075 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5076 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5082 #endif /* SIS315H */
5087 /* Set CRT2 FIFO on 300/540/630/730 */
5090 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5092 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5093 unsigned short temp, index, modeidindex, refreshratetableindex;
5094 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5095 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5096 unsigned int data, pci50, pciA0;
5097 static const unsigned char colortharray[] = {
5101 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5103 if(!SiS_Pr->CRT1UsesCustomMode) {
5105 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5106 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5107 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5108 SiS_Pr->SiS_SelectCRT2Rate = 0;
5109 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5111 if(CRT1ModeNo >= 0x13) {
5113 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5114 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5116 /* Get colordepth */
5117 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5118 if(!colorth) colorth++;
5126 VCLK = SiS_Pr->CSRClock_CRT1;
5128 /* Get color depth */
5129 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5133 if(CRT1ModeNo >= 0x13) {
5135 if(SiS_Pr->ChipType == SIS_300) {
5136 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5138 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5141 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5143 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5147 data2 = temp - ((colorth * VCLK) / MCLK);
5149 temp = (28 * 16) % data2;
5150 data2 = (28 * 16) / data2;
5153 if(SiS_Pr->ChipType == SIS_300) {
5155 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5156 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5160 #ifdef SIS_LINUX_KERNEL
5161 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5162 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5164 pci50 = pciReadLong(0x00000000, 0x50);
5165 pciA0 = pciReadLong(0x00000000, 0xA0);
5168 if(SiS_Pr->ChipType == SIS_730) {
5170 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5171 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5173 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5174 index = 0; /* -- do it like the BIOS anyway... */
5181 index = (pci50 >> 1) & 0x07;
5183 if(pci50 & 0x01) index += 6;
5184 if(!(pciA0 & 0x01)) index += 24;
5186 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5190 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5191 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5195 data += data2; /* CRT1 Request Period */
5197 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5198 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5200 if(!SiS_Pr->UseCustomMode) {
5202 CRT2ModeNo = ModeNo;
5203 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5205 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5208 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5209 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5211 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5212 if(SiS_Pr->SiS_UseROM) {
5213 if(ROMAddr[0x220] & 0x01) {
5214 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5223 VCLK = SiS_Pr->CSRClock;
5227 /* Get colordepth */
5228 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5229 if(!colorth) colorth++;
5231 data = data * VCLK * colorth;
5232 temp = data % (MCLK << 4);
5233 data = data / (MCLK << 4);
5236 if(data < 6) data = 6;
5237 else if(data > 0x14) data = 0x14;
5239 if(SiS_Pr->ChipType == SIS_300) {
5241 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5245 if(( (SiS_Pr->ChipType == SIS_630) ||
5246 (SiS_Pr->ChipType == SIS_730) ) &&
5247 (SiS_Pr->ChipRevision >= 0x30))
5250 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5252 if((SiS_Pr->ChipType == SIS_630) &&
5253 (SiS_Pr->ChipRevision >= 0x30)) {
5254 if(data > 0x13) data = 0x13;
5256 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5258 } else { /* If mode <= 0x13, we just restore everything */
5260 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5261 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5267 /* Set CRT2 FIFO on 315/330 series */
5270 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5272 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5273 if( (SiS_Pr->ChipType == SIS_760) &&
5274 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5275 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5276 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5277 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5278 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5279 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5280 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5281 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5282 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5283 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5285 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5291 static unsigned short
5292 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5294 unsigned int tempax,tempbx;
5296 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5297 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5298 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5299 return (unsigned short)tempax;
5302 /* Set Part 1 / SiS bridge slave mode */
5304 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5305 unsigned short RefreshRateTableIndex)
5307 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5308 static const unsigned short CRTranslation[] = {
5309 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5310 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5311 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5312 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5313 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5314 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5317 if(ModeNo <= 0x13) {
5318 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5319 } else if(SiS_Pr->UseCustomMode) {
5320 modeflag = SiS_Pr->CModeFlag;
5321 xres = SiS_Pr->CHDisplay;
5323 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5324 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5327 /* The following is only done if bridge is in slave mode: */
5329 if(SiS_Pr->ChipType >= SIS_315H) {
5330 if(xres >= 1600) { /* BIOS: == 1600 */
5331 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5335 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5337 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5338 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5340 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5341 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5342 SiS_Pr->CHBlankStart += 16;
5345 SiS_Pr->CHBlankEnd = 32;
5346 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5347 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5350 temp = SiS_Pr->SiS_VGAHT - 96;
5351 if(!(modeflag & HalfDCLK)) temp -= 32;
5352 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5353 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5354 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5358 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5360 SiS_Pr->CHSyncStart = temp;
5362 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5364 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5366 VGAVDE = SiS_Pr->SiS_VGAVDE;
5367 if (VGAVDE == 357) VGAVDE = 350;
5368 else if(VGAVDE == 360) VGAVDE = 350;
5369 else if(VGAVDE == 375) VGAVDE = 350;
5370 else if(VGAVDE == 405) VGAVDE = 400;
5371 else if(VGAVDE == 420) VGAVDE = 400;
5372 else if(VGAVDE == 525) VGAVDE = 480;
5373 else if(VGAVDE == 1056) VGAVDE = 1024;
5374 SiS_Pr->CVDisplay = VGAVDE;
5376 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5378 SiS_Pr->CVBlankEnd = 1;
5379 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5381 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5382 SiS_Pr->CVSyncStart = VGAVDE + temp;
5385 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5387 SiS_CalcCRRegisters(SiS_Pr, 0);
5388 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5390 for(i = 0; i <= 7; i++) {
5391 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5393 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5394 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5396 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5397 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5399 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5400 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5403 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5404 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5406 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5407 if(modeflag & DoubleScanMode) temp |= 0x80;
5408 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5411 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5412 if(modeflag & HalfDCLK) temp |= 0x08;
5413 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5415 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5416 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5419 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5420 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5422 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5424 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5425 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5427 #ifdef SIS_XORG_XF86
5429 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
5430 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
5431 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
5432 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
5434 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5435 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
5436 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
5437 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
5438 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
5439 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5440 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
5441 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
5442 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
5443 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
5444 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
5450 * This is used for LVDS, LCDA and Chrontel TV output
5451 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5454 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5455 unsigned short RefreshRateTableIndex)
5457 unsigned short modeflag, resinfo = 0;
5458 unsigned short push2, tempax, tempbx, tempcx, temp;
5459 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5460 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5462 unsigned short crt2crtc = 0;
5465 unsigned short pushcx;
5468 if(ModeNo <= 0x13) {
5469 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5470 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5472 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5474 } else if(SiS_Pr->UseCustomMode) {
5475 modeflag = SiS_Pr->CModeFlag;
5477 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5478 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5480 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5484 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5485 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5489 /* is really sis if sis bridge, but not 301B-DH */
5490 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5494 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5495 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5496 chkdclkfirst = TRUE;
5501 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5503 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5504 } else if(IS_SIS740) {
5506 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5507 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5508 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5509 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5513 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5514 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5515 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5516 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5517 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5518 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5519 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5520 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5530 tempax = SiS_Pr->SiS_LCDHDES;
5532 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5533 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5534 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5535 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5542 temp = (tempax & 0x0007);
5543 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5544 temp = (tempax >> 3) & 0x00FF;
5545 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5547 tempbx = SiS_Pr->SiS_HDE;
5548 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5549 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5550 tempbx = SiS_Pr->PanelXRes;
5552 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5553 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5554 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5560 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5563 if(temp & 0x07) temp += 8;
5565 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5567 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5569 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5570 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5571 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5576 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5578 temp = (tempcx >> 3) & 0x00FF;
5579 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5580 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5581 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5585 case 0x0d: temp = 0x56; break;
5586 case 0x10: temp = 0x60; break;
5587 case 0x13: temp = 0x5f; break;
5597 case 0x5e: temp = 0x54; break;
5602 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5604 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5606 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5608 if(SiS_Pr->PanelHRE != 999) {
5609 temp = tempcx + SiS_Pr->PanelHRE;
5610 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5619 temp |= ((tempcx & 0x07) << 5);
5620 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5624 tempax = SiS_Pr->SiS_VGAVDE;
5625 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5626 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5627 tempax = SiS_Pr->PanelYRes;
5631 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5632 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5636 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5637 if(SiS_Pr->ChipType < SIS_315H) {
5638 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5639 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5640 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5644 if(islvds) tempcx >>= 1;
5647 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5648 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5649 (SiS_Pr->PanelVRS != 999) ) {
5650 tempcx = SiS_Pr->PanelVRS;
5655 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5656 else if(issis) tempbx++;
5659 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5661 temp = tempbx & 0x00FF;
5662 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5663 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5664 if(ModeNo == 0x10) temp = 0xa9;
5667 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5672 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5673 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5674 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5679 temp = tempcx & 0x000F;
5680 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5682 temp = ((tempbx >> 8) & 0x07) << 3;
5683 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5684 if(SiS_Pr->SiS_HDE != 640) {
5685 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5687 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5688 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5690 if((SiS_Pr->ChipType >= SIS_315H) ||
5691 (SiS_Pr->ChipRevision >= 0x30)) {
5693 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5694 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5696 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5697 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5698 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5699 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5701 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5705 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5707 tempbx = push2; /* BPLVDEE */
5709 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5711 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5712 switch(SiS_Pr->SiS_LCDResInfo) {
5714 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5715 tempcx = SiS_Pr->SiS_VGAVDE;
5718 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5719 if(resinfo == SIS_RI_800x600) tempcx++;
5722 case Panel_1024x600:
5723 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5724 if(resinfo == SIS_RI_1024x600) tempcx++;
5725 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5726 if(resinfo == SIS_RI_800x600) tempcx++;
5730 case Panel_1024x768:
5731 if(SiS_Pr->ChipType < SIS_315H) {
5732 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5733 if(resinfo == SIS_RI_1024x768) tempcx++;
5740 temp = ((tempbx >> 8) & 0x07) << 3;
5741 temp |= ((tempcx >> 8) & 0x07);
5742 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5743 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5744 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5746 /* Vertical scaling */
5748 if(SiS_Pr->ChipType < SIS_315H) {
5750 #ifdef SIS300 /* 300 series */
5751 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5752 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5753 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5756 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5758 temp = (unsigned short)(tempeax & 0x00FF);
5759 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5765 #ifdef SIS315H /* 315 series */
5766 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5767 tempebx = SiS_Pr->SiS_VDE;
5768 temp = (tempeax % tempebx);
5769 tempeax = tempeax / tempebx;
5771 tempvcfact = tempeax;
5773 temp = (unsigned short)(tempeax & 0x00FF);
5774 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5775 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5776 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5777 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5778 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5779 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5781 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5782 temp = (unsigned short)(tempeax & 0x00FF);
5783 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5784 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5785 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5786 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5787 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5789 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5790 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5796 /* Horizontal scaling */
5798 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5800 if(modeflag & HalfDCLK) tempeax >>= 1;
5802 tempebx = tempeax << 16;
5803 if(SiS_Pr->SiS_HDE == tempeax) {
5806 tempecx = tempebx / SiS_Pr->SiS_HDE;
5807 if(SiS_Pr->ChipType >= SIS_315H) {
5808 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5812 if(SiS_Pr->ChipType >= SIS_315H) {
5813 tempeax = (tempebx / tempecx) - 1;
5815 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5817 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5818 temp = (unsigned short)(tempecx & 0x00FF);
5819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5821 if(SiS_Pr->ChipType >= SIS_315H) {
5822 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5823 tempbx = (unsigned short)(tempeax & 0xFFFF);
5825 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5826 tempbx = tempvcfact & 0x3f;
5827 if(tempbx == 0) tempbx = 64;
5829 tempbx = (unsigned short)(tempeax & 0xFFFF);
5831 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5832 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5833 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5834 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5837 temp = ((tempbx >> 8) & 0x07) << 3;
5838 temp = temp | ((tempecx >> 8) & 0x07);
5839 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5840 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5842 tempecx >>= 16; /* BPLHCFACT */
5844 if(modeflag & HalfDCLK) tempecx >>= 1;
5846 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5847 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5848 temp = (unsigned short)(tempecx & 0x00FF);
5849 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5852 if(SiS_Pr->ChipType >= SIS_315H) {
5853 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5854 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5855 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5859 if(SiS_Pr->ChipType == SIS_740) {
5860 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5862 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5870 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5871 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5872 unsigned char *trumpdata;
5873 int i, j = crt2crtc;
5874 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5875 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5876 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5878 if(SiS_Pr->SiS_UseROM) {
5879 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5881 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5882 trumpdata = &SiS300_TrumpionData[j][0];
5885 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5886 for(i=0; i<5; i++) {
5887 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5889 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5890 if(ModeNo == 0x13) {
5891 for(i=0; i<4; i++) {
5892 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5894 } else if(ModeNo == 0x10) {
5895 for(i=0; i<4; i++) {
5896 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5897 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5901 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5906 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5907 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5909 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5910 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5911 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5912 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5913 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5914 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5915 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5916 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5917 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5919 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5920 temp = (tempax >> 8) << 3;
5921 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5922 tempax += 32; /* Blpe = lBlps+32 */
5923 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5924 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
5925 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5927 tempax = SiS_Pr->SiS_VDE;
5928 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5929 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5930 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5932 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5933 temp = (tempax >> 8) << 3;
5934 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5936 tempeax = SiS_Pr->SiS_HDE;
5937 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5938 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5939 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5940 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5941 temp = tempeax & 0x7f;
5944 temp = tempeax & 0x3f;
5945 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5946 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5947 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5948 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5949 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5951 tempax = SiS_Pr->SiS_HDE;
5952 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5953 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5954 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5955 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5957 temp = tempax & 0x00FF;
5958 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5959 temp = ((tempax & 0xFF00) >> 8) << 3;
5960 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5962 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5963 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5964 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5965 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5966 tempeax = tempax * pushcx;
5967 temp = tempeax & 0xFF;
5968 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5969 temp = (tempeax & 0xFF00) >> 8;
5970 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5971 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5972 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5973 temp = ((tempeax & 0x01000000) >> 24) << 7;
5974 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
5976 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5977 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5978 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5979 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5980 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5982 if(SiS_Pr->SiS_IF_DEF_FSTN) {
5983 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5984 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5985 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5986 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5987 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5988 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5989 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5990 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5991 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5992 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5994 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5996 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5997 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5998 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5999 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6000 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6001 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6002 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6005 #endif /* SIS315H */
6010 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6011 unsigned short RefreshRateTableIndex)
6013 #if defined(SIS300) || defined(SIS315H)
6014 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6016 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6017 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6019 unsigned short tempbl=0;
6022 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6023 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6027 if(ModeNo <= 0x13) {
6028 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6029 } else if(SiS_Pr->UseCustomMode) {
6030 modeflag = SiS_Pr->CModeFlag;
6032 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6033 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6034 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6037 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6039 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6040 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6041 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6043 if(SiS_Pr->ChipType < SIS_315H ) {
6045 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6049 SiS_SetCRT2FIFO_310(SiS_Pr);
6053 /* 1. Horizontal setup */
6055 if(SiS_Pr->ChipType < SIS_315H ) {
6057 #ifdef SIS300 /* ------------- 300 series --------------*/
6059 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6060 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6062 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6063 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6065 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6066 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6068 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6069 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6070 tempbx = pushbx + tempcx;
6080 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6082 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6083 if(modeflag & HalfDCLK) {
6084 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6087 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6088 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6089 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6090 tempcx = SiS_Pr->SiS_HT - tempax;
6095 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6096 temp = (tempcx >> 4) & 0xF0;
6097 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6099 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6100 tempbx = SiS_Pr->SiS_VGAHDE;
6103 if(modeflag & HalfDCLK) {
6109 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6118 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6119 if(SiS_Pr->ChipType >= SIS_661) {
6120 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6121 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6122 if(resinfo == SIS_RI_1280x1024) {
6123 tempcx = (tempcx & 0xff00) | 0x30;
6124 } else if(resinfo == SIS_RI_1600x1200) {
6125 tempcx = (tempcx & 0xff00) | 0xff;
6131 #endif /* SIS315H */
6133 } /* 315/330 series */
6135 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6137 if(SiS_Pr->UseCustomMode) {
6138 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6139 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6140 tempax = SiS_Pr->SiS_VGAHT;
6141 if(modeflag & HalfDCLK) tempax >>= 1;
6143 if(tempcx > tempax) tempcx = tempax;
6146 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6147 unsigned char cr4, cr14, cr5, cr15;
6148 if(SiS_Pr->UseCustomMode) {
6149 cr4 = SiS_Pr->CCRT1CRTC[4];
6150 cr14 = SiS_Pr->CCRT1CRTC[14];
6151 cr5 = SiS_Pr->CCRT1CRTC[5];
6152 cr15 = SiS_Pr->CCRT1CRTC[15];
6154 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6155 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6156 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6157 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6159 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6160 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6162 tempcx |= (tempbx & 0xFF00);
6163 tempbx += bridgeadd;
6164 tempcx += bridgeadd;
6165 tempax = SiS_Pr->SiS_VGAHT;
6166 if(modeflag & HalfDCLK) tempax >>= 1;
6168 if(tempcx > tempax) tempcx = tempax;
6171 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6173 tempcx = 1044; /* HWCursor bug! */
6178 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6180 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6182 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6183 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6185 /* 2. Vertical setup */
6187 tempcx = SiS_Pr->SiS_VGAVT - 1;
6188 temp = tempcx & 0x00FF;
6190 if(SiS_Pr->ChipType < SIS_661) {
6191 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6192 if(SiS_Pr->ChipType < SIS_315H) {
6193 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6194 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6201 } else if(SiS_Pr->ChipType >= SIS_315H) {
6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6207 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6210 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6211 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6213 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6220 if(tempcx < 4) tempcx = 4;
6225 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6226 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6229 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6230 if(SiS_Pr->UseCustomMode) {
6231 tempbx = SiS_Pr->CVSyncStart;
6232 tempcx = SiS_Pr->CVSyncEnd;
6234 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6235 unsigned char cr8, cr7, cr13;
6236 if(SiS_Pr->UseCustomMode) {
6237 cr8 = SiS_Pr->CCRT1CRTC[8];
6238 cr7 = SiS_Pr->CCRT1CRTC[7];
6239 cr13 = SiS_Pr->CCRT1CRTC[13];
6240 tempcx = SiS_Pr->CCRT1CRTC[9];
6242 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6243 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6244 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6245 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6248 if(cr7 & 0x04) tempbx |= 0x0100;
6249 if(cr7 & 0x80) tempbx |= 0x0200;
6250 if(cr13 & 0x08) tempbx |= 0x0400;
6253 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6255 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6256 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6258 /* 3. Panel delay compensation */
6260 if(SiS_Pr->ChipType < SIS_315H) {
6262 #ifdef SIS300 /* ---------- 300 series -------------- */
6264 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6266 if(SiS_Pr->ChipType == SIS_300) {
6268 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6269 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6271 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6272 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6274 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6275 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6276 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6277 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6278 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6281 if(SiS_Pr->SiS_UseROM) {
6282 if(ROMAddr[0x220] & 0x80) {
6283 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6284 temp = ROMAddr[0x221];
6285 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6286 temp = ROMAddr[0x222];
6287 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6288 temp = ROMAddr[0x223];
6290 temp = ROMAddr[0x224];
6293 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6294 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6299 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6300 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6302 if(SiS_Pr->SiS_UseROM) {
6303 if(ROMAddr[0x220] & 0x80) {
6304 temp = ROMAddr[0x220];
6307 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6308 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6314 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6320 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6322 if(SiS_Pr->ChipType < SIS_661) {
6324 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6326 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6329 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6331 if(SiS_Pr->ChipType == SIS_650) {
6332 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6333 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6337 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6340 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6341 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6345 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6351 if(modeflag & DoubleScanMode) tempax |= 0x80;
6352 if(modeflag & HalfDCLK) tempax |= 0x40;
6353 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6355 #endif /* SIS315H */
6361 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6362 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6363 /* For 301BDH with LCD, we set up the Panel Link */
6364 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6365 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6366 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6369 if(SiS_Pr->ChipType < SIS_315H) {
6370 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6372 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6373 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6374 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6377 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6383 /*********************************************/
6384 /* SET PART 2 REGISTER GROUP */
6385 /*********************************************/
6388 static unsigned char *
6389 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6391 const unsigned char *tableptr = NULL;
6392 unsigned short a, b, p = 0;
6394 a = SiS_Pr->SiS_VGAHDE;
6395 b = SiS_Pr->SiS_HDE;
6397 a = SiS_Pr->SiS_VGAVDE;
6398 b = SiS_Pr->SiS_VDE;
6402 tableptr = SiS_Part2CLVX_1;
6404 tableptr = SiS_Part2CLVX_2;
6406 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6407 tableptr = SiS_Part2CLVX_4;
6409 tableptr = SiS_Part2CLVX_3;
6411 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6412 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6413 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6414 else tableptr = SiS_Part2CLVX_5;
6415 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6416 tableptr = SiS_Part2CLVX_6;
6419 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6421 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6422 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6425 return ((unsigned char *)&tableptr[p]);
6429 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6430 unsigned short RefreshRateTableIndex)
6432 unsigned char *tableptr;
6436 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6438 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6439 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6440 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6442 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6443 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6444 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6445 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6449 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6450 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6454 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6455 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6456 unsigned short *ResIndex)
6459 if(SiS_Pr->ChipType < SIS_315H) return FALSE;
6462 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6464 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6466 (*ResIndex) &= 0x3f;
6469 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6470 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6475 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6476 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6477 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6480 return (((*CRT2Index) != 0));
6486 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6488 unsigned short tempcx;
6489 static const unsigned char atable[] = {
6490 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6491 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6494 if(!SiS_Pr->UseCustomMode) {
6495 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6496 (SiS_Pr->ChipType == SIS_730) ) &&
6497 (SiS_Pr->ChipRevision > 2) ) &&
6498 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6499 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6500 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6501 if(ModeNo == 0x13) {
6502 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6503 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6505 } else if((crt2crtc & 0x3F) == 4) {
6506 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6507 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6508 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6509 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6510 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6514 if(SiS_Pr->ChipType < SIS_315H) {
6515 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6518 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6519 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6525 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6528 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6529 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6531 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6535 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6536 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6542 /* For ECS A907. Highly preliminary. */
6544 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6545 unsigned short ModeNo)
6547 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6548 unsigned short crt2crtc, resindex;
6551 if(SiS_Pr->ChipType != SIS_300) return;
6552 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6553 if(SiS_Pr->UseCustomMode) return;
6555 if(ModeNo <= 0x13) {
6556 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6558 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6561 resindex = crt2crtc & 0x3F;
6562 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6563 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6565 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6567 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6571 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6572 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6573 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6574 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6576 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6577 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6579 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6580 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6582 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6583 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6588 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6590 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6591 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6592 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6594 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6595 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6596 const unsigned char specialtv[] = {
6597 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6598 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6599 0x58,0xe4,0x73,0xda,0x13
6602 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6603 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6605 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6606 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6607 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6608 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6609 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6611 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6612 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6617 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6618 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6619 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6620 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6622 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6623 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6629 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6631 unsigned short temp;
6633 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6634 if(SiS_Pr->SiS_VGAVDE == 525) {
6636 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6638 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6640 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6641 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6642 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6644 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6646 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6648 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6652 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6653 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6654 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6655 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6656 /* Not always for LV, see SetGrp2 */
6659 if(ModeNo <= 0x13) temp = 3;
6660 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6663 /* 651+301C, for 1280x768 - do I really need that? */
6664 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6665 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6666 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6667 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6668 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6669 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6670 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6671 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6672 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6673 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6674 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6675 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6676 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6677 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6678 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6679 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6688 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6689 unsigned short RefreshRateTableIndex)
6691 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6692 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6693 unsigned int longtemp, PhaseIndex;
6695 const unsigned char *TimingPoint;
6697 unsigned short resindex, CRT2Index;
6698 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6700 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6703 if(ModeNo <= 0x13) {
6704 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6705 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6706 } else if(SiS_Pr->UseCustomMode) {
6707 modeflag = SiS_Pr->CModeFlag;
6710 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6711 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6715 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6716 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6717 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6718 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6720 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6722 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6724 PhaseIndex = 0x01; /* SiS_PALPhase */
6725 TimingPoint = SiS_Pr->SiS_PALTiming;
6728 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6729 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6730 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6734 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6736 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6737 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6738 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6739 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6740 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6744 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6747 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6748 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6750 TimingPoint = &SiS_YPbPrTable[i][0];
6752 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6754 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6756 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6760 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6761 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6762 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6766 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6767 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6768 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6771 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6772 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6773 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6774 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6775 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6777 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6781 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6782 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6785 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6786 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6788 for(i = 0x39; i <= 0x45; i++, j++) {
6789 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6792 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6793 if(SiS_Pr->SiS_ModeType != ModeText) {
6794 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6798 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6800 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6801 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6802 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6803 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6805 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6806 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
6807 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6808 else tempax = 440; /* NTSC, YPbPr 525 */
6810 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6811 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6812 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6814 tempax -= SiS_Pr->SiS_VDE;
6816 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6821 temp = tempax + (unsigned short)TimingPoint[0];
6822 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6824 temp = tempax + (unsigned short)TimingPoint[1];
6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6827 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6828 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6829 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6830 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6832 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6833 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6839 tempcx = SiS_Pr->SiS_HT;
6840 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6842 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6843 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6844 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6846 tempcx = SiS_Pr->SiS_HT >> 1;
6847 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6849 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6850 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6852 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6854 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6855 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6858 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6862 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6865 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6866 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6867 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6870 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6871 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6873 tempcx = SiS_Pr->SiS_HT >> 1;
6874 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6876 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6877 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6880 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6881 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6883 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6885 tempbx = SiS_Pr->SiS_VDE;
6886 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6887 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6888 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6889 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6890 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6891 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6893 if(SiS_Pr->ChipType >= SIS_315H) {
6894 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6895 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6896 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6897 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6898 if(crt2crtc == 4) tempbx++;
6902 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6903 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6904 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6906 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6907 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6912 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6914 temp = (tempcx >> 8) & 0x0F;
6915 temp |= ((tempbx >> 2) & 0xC0);
6916 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6918 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6920 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6922 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6923 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6926 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6927 tempbx = SiS_Pr->SiS_VDE;
6928 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6929 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6933 temp = ((tempbx >> 3) & 0x60) | 0x18;
6934 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6935 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6937 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6938 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6943 if(!(modeflag & HalfDCLK)) {
6944 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6950 tempch = tempcl = 0x01;
6951 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6952 if(SiS_Pr->SiS_VGAHDE >= 960) {
6953 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6955 if(SiS_Pr->SiS_VGAHDE >= 1280) {
6958 } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6961 tempch = 25; /* OK */
6967 if(!(tempbx & 0x20)) {
6968 if(modeflag & HalfDCLK) tempcl <<= 1;
6969 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6970 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6971 tempax = longtemp / SiS_Pr->SiS_HDE;
6972 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6973 tempbx |= ((tempax >> 8) & 0x1F);
6974 tempcx = tempax >> 13;
6977 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6978 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6980 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6983 if(tempbx & 0x20) tempcx = 0;
6984 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6986 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6993 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6994 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6995 temp = (tempcx & 0x0300) >> 6;
6996 temp |= ((tempbx >> 8) & 0x03);
6997 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6999 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7000 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7002 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7004 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7005 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7007 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7009 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7011 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7012 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7017 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7018 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7019 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7020 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7022 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7025 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7026 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7027 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7031 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7033 /* From here: Part2 LCD setup */
7035 tempbx = SiS_Pr->SiS_HDE;
7036 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7037 tempbx--; /* RHACTE = HDE - 1 */
7038 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7039 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7042 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7043 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7044 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7046 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7052 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7054 tempbx = SiS_Pr->SiS_VDE - 1;
7055 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7056 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7058 tempcx = SiS_Pr->SiS_VT - 1;
7059 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7060 temp = (tempcx >> 3) & 0xE0;
7061 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7062 /* Enable dithering; only do this for 32bpp mode */
7063 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7067 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7069 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7070 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7072 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7073 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7076 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7077 &CRT2Index, &resindex)) {
7079 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7081 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7084 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7085 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7086 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7087 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7089 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7090 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7092 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7093 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7095 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7096 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7098 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7103 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7104 /* Clevo dual-link 1024x768 */
7105 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7106 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7108 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7109 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7110 tempbx = SiS_Pr->SiS_VDE - 1;
7111 tempcx = SiS_Pr->SiS_VT - 1;
7113 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7114 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7117 tempbx = SiS_Pr->PanelYRes;
7118 tempcx = SiS_Pr->SiS_VT;
7120 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7121 tempax = SiS_Pr->PanelYRes;
7122 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7123 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7124 tempax = tempcx = 0;
7126 tempax -= SiS_Pr->SiS_VDE;
7130 tempcx -= tempax; /* lcdvdes */
7131 tempbx -= tempax; /* lcdvdee */
7134 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7136 #ifdef SIS_XORG_XF86
7138 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7142 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7143 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7145 temp = (tempbx >> 5) & 0x38;
7146 temp |= ((tempcx >> 8) & 0x07);
7147 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7149 tempax = SiS_Pr->SiS_VDE;
7150 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7151 tempax = SiS_Pr->PanelYRes;
7153 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7154 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7155 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7156 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7160 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7161 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7162 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7163 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7164 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7165 if(tempax % 4) { tempax >>= 2; tempax++; }
7166 else { tempax >>= 2; }
7167 tempbx -= (tempax - 1);
7170 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7174 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7176 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7177 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7184 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7186 if(SiS_Pr->UseCustomMode) {
7187 tempbx = SiS_Pr->CVSyncStart;
7190 #ifdef SIS_XORG_XF86
7192 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7196 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7198 temp = (tempbx >> 4) & 0xF0;
7199 tempbx += (tempcx + 1);
7200 temp |= (tempbx & 0x0F);
7202 if(SiS_Pr->UseCustomMode) {
7204 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7207 #ifdef SIS_XORG_XF86
7209 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7213 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7216 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7220 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7221 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7222 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7223 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7224 /* Higher bridgeoffset shifts to the LEFT */
7227 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7228 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7229 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7230 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7233 temp += bridgeoffset;
7234 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7235 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7237 tempcx = SiS_Pr->SiS_HT;
7238 tempax = tempbx = SiS_Pr->SiS_HDE;
7239 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7240 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7241 tempax = SiS_Pr->PanelXRes;
7242 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7245 if(SiS_IsDualLink(SiS_Pr)) {
7251 #ifdef SIS_XORG_XF86
7253 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7257 tempbx += bridgeoffset;
7259 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7260 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7262 tempcx = (tempcx - tempax) >> 2;
7267 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7268 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7269 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7270 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7275 if(SiS_Pr->UseCustomMode) {
7276 tempbx = SiS_Pr->CHSyncStart;
7277 if(modeflag & HalfDCLK) tempbx <<= 1;
7278 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7279 tempbx += bridgeoffset;
7282 #ifdef SIS_XORG_XF86
7284 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7288 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7289 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7294 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7295 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7299 if(SiS_Pr->UseCustomMode) {
7300 tempbx = SiS_Pr->CHSyncEnd;
7301 if(modeflag & HalfDCLK) tempbx <<= 1;
7302 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7303 tempbx += bridgeoffset;
7306 #ifdef SIS_XORG_XF86
7308 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7312 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7314 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7317 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7320 } /* CRT2-LCD from table */
7324 /*********************************************/
7325 /* SET PART 3 REGISTER GROUP */
7326 /*********************************************/
7329 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7332 const unsigned char *tempdi;
7334 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7337 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7342 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7343 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7344 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7346 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7347 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7350 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7351 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7352 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7353 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7357 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7358 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7359 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7360 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7362 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7363 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7364 tempdi = SiS_HiTVGroup3_1;
7365 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7369 for(i=0; i<=0x3E; i++) {
7370 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7372 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7373 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7374 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7384 /*********************************************/
7385 /* SET PART 4 REGISTER GROUP */
7386 /*********************************************/
7391 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7393 unsigned short temp, temp1, temp2;
7395 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7396 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7397 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7398 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7399 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7400 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7401 temp = (unsigned short)((int)(temp) + shift);
7402 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7403 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7404 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7405 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7406 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7407 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7412 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7414 unsigned short temp, temp1, resinfo = 0;
7415 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7417 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7418 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7420 if(SiS_Pr->ChipType >= XGI_20) return;
7422 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7423 if(!(ROMAddr[0x61] & 0x04)) return;
7427 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7430 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7431 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7432 if(!(temp & 0x01)) {
7433 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7434 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7435 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7436 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7438 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7439 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7440 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7441 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7443 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7445 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7446 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7447 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7448 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7449 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7451 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7454 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7455 if(temp1 == 0x01) temp |= 0x01;
7456 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7457 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7458 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7460 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7465 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7466 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7467 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7468 if(resinfo == SIS_RI_1024x768) {
7469 SiS_ShiftXPos(SiS_Pr, 97);
7471 SiS_ShiftXPos(SiS_Pr, 111);
7473 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7474 SiS_ShiftXPos(SiS_Pr, 136);
7486 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7487 unsigned short RefreshRateTableIndex)
7489 unsigned short vclkindex, temp, reg1, reg2;
7491 if(SiS_Pr->UseCustomMode) {
7492 reg1 = SiS_Pr->CSR2B;
7493 reg2 = SiS_Pr->CSR2C;
7495 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7496 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7497 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7500 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7501 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7502 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7503 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7504 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7506 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7507 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7510 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7511 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7512 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7514 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7516 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7517 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7521 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7523 if(SiS_Pr->ChipType >= SIS_315H) {
7524 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7525 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7526 (SiS_IsVAMode(SiS_Pr))) {
7527 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7528 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7530 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7535 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7536 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7538 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7540 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7545 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7546 unsigned short RefreshRateTableIndex)
7548 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7549 unsigned int tempebx, tempeax, templong;
7551 if(ModeNo <= 0x13) {
7552 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7553 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7554 } else if(SiS_Pr->UseCustomMode) {
7555 modeflag = SiS_Pr->CModeFlag;
7558 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7559 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7562 if(SiS_Pr->ChipType >= SIS_315H) {
7563 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7564 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7565 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7570 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7571 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7572 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7576 if(SiS_Pr->ChipType >= SIS_315H) {
7577 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7578 SiS_SetDualLinkEtc(SiS_Pr);
7583 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7585 tempbx = SiS_Pr->SiS_RVBHCMAX;
7586 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7588 temp = (tempbx >> 1) & 0x80;
7590 tempcx = SiS_Pr->SiS_VGAHT - 1;
7591 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7593 temp |= ((tempcx >> 5) & 0x78);
7595 tempcx = SiS_Pr->SiS_VGAVT - 1;
7596 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7597 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7599 temp |= ((tempcx >> 8) & 0x07);
7600 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7602 tempbx = SiS_Pr->SiS_VGAHDE;
7603 if(modeflag & HalfDCLK) tempbx >>= 1;
7604 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7606 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7608 if(tempbx > 800) temp = 0x60;
7609 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7611 if(tempbx > 1024) temp = 0xC0;
7612 else if(tempbx >= 960) temp = 0xA0;
7613 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7615 if(tempbx >= 1280) temp = 0x40;
7616 else if(tempbx >= 1024) temp = 0x20;
7619 if(tempbx >= 1024) temp = 0xA0;
7622 temp |= SiS_Pr->Init_P4_0E;
7624 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7625 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7631 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7633 tempeax = SiS_Pr->SiS_VGAVDE;
7634 tempebx = SiS_Pr->SiS_VDE;
7635 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7636 if(!(temp & 0xE0)) tempebx >>=1;
7639 tempcx = SiS_Pr->SiS_RVBHRS;
7640 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7644 if(tempeax <= tempebx) {
7650 tempeax *= (256 * 1024);
7651 templong = tempeax % tempebx;
7653 if(templong) tempeax++;
7655 temp = (unsigned short)(tempeax & 0x000000FF);
7656 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7657 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7658 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7659 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7660 temp |= (tempcx & 0x4F);
7661 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7663 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7665 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7667 /* Calc Linebuffer max address and set/clear decimode */
7669 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7670 tempax = SiS_Pr->SiS_VGAHDE;
7671 if(modeflag & HalfDCLK) tempax >>= 1;
7672 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7674 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7678 if(tempax == 960) tempax *= 25; /* Correct */
7679 else if(tempax == 1024) tempax *= 25;
7685 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7686 if(resinfo == SIS_RI_1024x768 ||
7687 resinfo == SIS_RI_1024x576 ||
7688 resinfo == SIS_RI_1280x1024 ||
7689 resinfo == SIS_RI_1280x720) {
7690 /* Otherwise white line or garbage at right edge */
7691 tempax = (tempax & 0xff00) | 0x20;
7697 temp = ((tempax >> 4) & 0x30) | tempbx;
7698 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7699 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7701 temp = 0x0036; tempbx = 0xD0;
7702 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7703 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7705 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7706 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7708 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7709 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7715 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7717 tempbx = SiS_Pr->SiS_HT >> 1;
7718 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7720 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7721 temp = (tempbx >> 5) & 0x38;
7722 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7724 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7725 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7726 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7727 /* LCD-too-dark-error-source, see FinalizeLCD() */
7731 SiS_SetDualLinkEtc(SiS_Pr);
7735 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7738 /*********************************************/
7739 /* SET PART 5 REGISTER GROUP */
7740 /*********************************************/
7743 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7746 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7748 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7749 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7750 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7751 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7756 /*********************************************/
7757 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7758 /*********************************************/
7761 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7762 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7763 unsigned short *DisplayType)
7765 unsigned short modeflag = 0;
7766 BOOLEAN checkhd = TRUE;
7768 /* Pass 1:1 not supported here */
7770 if(ModeNo <= 0x13) {
7771 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7772 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7774 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7775 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7778 (*ResIndex) &= 0x3F;
7780 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7782 (*DisplayType) = 80;
7783 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7784 (*DisplayType) = 82;
7785 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7786 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7789 if((*DisplayType) != 84) {
7790 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7796 switch(SiS_Pr->SiS_LCDResInfo) {
7797 case Panel_320x240_1: (*DisplayType) = 50;
7800 case Panel_320x240_2: (*DisplayType) = 14;
7802 case Panel_320x240_3: (*DisplayType) = 18;
7804 case Panel_640x480: (*DisplayType) = 10;
7806 case Panel_1024x600: (*DisplayType) = 26;
7808 default: return TRUE;
7812 if(modeflag & HalfDCLK) (*DisplayType)++;
7815 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7816 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7825 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7826 unsigned short RefreshRateTableIndex)
7828 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7829 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7830 static const unsigned short CRIdx[] = {
7831 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7832 0x07, 0x10, 0x11, 0x15, 0x16
7835 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7836 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7837 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7838 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7841 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7842 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7843 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7845 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7846 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7849 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7851 if(SiS_Pr->ChipType < SIS_315H) {
7852 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7855 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7856 &ResIndex, &DisplayType))) {
7860 switch(DisplayType) {
7861 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7862 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7863 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7864 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7865 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7866 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7867 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7868 #if 0 /* Works better with calculated numbers */
7869 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7870 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7871 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7872 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7874 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7875 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7876 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7877 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7878 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7883 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7885 for(i = 0; i <= 10; i++) {
7886 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7887 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7890 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7891 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7892 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7895 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7896 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7898 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7899 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7901 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7902 if(modeflag & DoubleScanMode) tempah |= 0x80;
7903 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7907 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7912 /*********************************************/
7914 /*********************************************/
7917 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7918 unsigned short RefreshRateTableIndex)
7920 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7921 unsigned short clkbase, vclkindex = 0;
7922 unsigned char sr2b, sr2c;
7924 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7925 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7926 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7927 RefreshRateTableIndex--;
7929 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7930 RefreshRateTableIndex);
7931 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7933 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7934 RefreshRateTableIndex);
7937 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7938 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7940 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7941 if(SiS_Pr->SiS_UseROM) {
7942 if(ROMAddr[0x220] & 0x01) {
7943 sr2b = ROMAddr[0x227];
7944 sr2c = ROMAddr[0x228];
7950 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7951 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7956 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7957 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7958 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7959 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7960 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7961 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7962 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7963 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7964 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7967 /*********************************************/
7968 /* SET UP CHRONTEL CHIPS */
7969 /*********************************************/
7972 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7973 unsigned short RefreshRateTableIndex)
7975 unsigned short TVType, resindex;
7976 const struct SiS_CHTVRegData *CHTVRegData = NULL;
7979 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7981 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7986 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7987 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7989 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7990 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7992 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7994 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7995 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7997 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8002 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8003 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8004 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8005 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8006 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8007 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8008 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8009 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8010 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8011 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8015 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8019 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8021 /* We don't support modes >800x600 */
8022 if (resindex > 5) return;
8024 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8025 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8026 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
8028 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8029 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
8032 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
8033 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
8034 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
8035 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
8036 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
8038 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8039 minimum text enhancement (S3-2=10),
8040 maximum flicker filter for Chroma channel (S5-4=10)
8041 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8043 SiS_SetCH700x(SiS_Pr,0x01,0x28);
8045 /* Set video bandwidth
8046 High bandwidth Luma composite video filter(S0=1)
8047 low bandwidth Luma S-video filter (S2-1=00)
8048 disable peak filter in S-video channel (S3=0)
8049 high bandwidth Chroma Filter (S5-4=11)
8052 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
8054 /* Register 0x3D does not exist in non-macrovision register map
8055 (Maybe this is a macrovision register?)
8058 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8061 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8062 all other bits a read-only. Macrovision?
8064 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8066 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8067 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8069 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8073 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8075 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8076 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8077 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8078 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8079 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
8080 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8081 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8082 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8083 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8084 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8085 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8086 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8087 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8088 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8089 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
8090 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
8093 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8094 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8095 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8096 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8098 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8099 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
8100 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
8101 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8102 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8103 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8104 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8105 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8106 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
8107 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
8108 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8109 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8110 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8113 } else { /* ---- PAL ---- */
8114 /* We don't play around with FSCI in PAL mode */
8115 if(resindex == 0x04) {
8116 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8117 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8119 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8120 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8128 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8132 unsigned short temp;
8134 /* We don't support modes >1024x768 */
8135 if (resindex > 6) return;
8137 temp = CHTVRegData[resindex].Reg[0];
8138 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8139 SiS_SetCH701x(SiS_Pr,0x00,temp);
8141 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8142 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8143 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8144 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8145 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8146 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8148 temp = CHTVRegData[resindex].Reg[7];
8149 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8150 SiS_SetCH701x(SiS_Pr,0x07,temp);
8152 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8153 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8154 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8155 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8156 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8157 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8158 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8159 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8161 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8162 /* D1 should be set for PAL, PAL-N and NTSC-J,
8163 but I won't do that for PAL unless somebody
8164 tells me to do so. Since the BIOS uses
8165 non-default CIV values and blacklevels,
8166 this might be compensated anyway.
8168 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8169 SiS_SetCH701x(SiS_Pr,0x21,temp);
8181 #ifdef SIS315H /* ----------- 315 series only ---------- */
8184 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8186 unsigned short temp;
8188 /* Enable Chrontel 7019 LCD panel backlight */
8189 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8190 if(SiS_Pr->ChipType == SIS_740) {
8191 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8193 temp = SiS_GetCH701x(SiS_Pr,0x66);
8195 SiS_SetCH701x(SiS_Pr,0x66,temp);
8201 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8203 unsigned short temp;
8205 /* Disable Chrontel 7019 LCD panel backlight */
8206 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8207 temp = SiS_GetCH701x(SiS_Pr,0x66);
8209 SiS_SetCH701x(SiS_Pr,0x66,temp);
8214 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8216 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8217 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8218 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8219 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8220 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8221 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8222 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8223 const unsigned char *tableptr = NULL;
8226 /* Set up Power up/down timing */
8228 if(SiS_Pr->ChipType == SIS_740) {
8229 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8230 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8231 else tableptr = table1024_740;
8232 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8233 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8234 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8235 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8236 else tableptr = table1400_740;
8239 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8240 tableptr = table1024_650;
8241 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8242 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8243 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8244 tableptr = table1400_650;
8248 for(i=0; i<5; i++) {
8249 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8254 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8256 const unsigned char *tableptr = NULL;
8257 unsigned short tempbh;
8259 static const unsigned char regtable[] = {
8260 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8261 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8263 static const unsigned char table1024_740[] = {
8264 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8265 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8267 static const unsigned char table1280_740[] = {
8268 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8269 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8271 static const unsigned char table1400_740[] = {
8272 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8273 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8275 static const unsigned char table1600_740[] = {
8276 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8277 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8279 static const unsigned char table1024_650[] = {
8280 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8281 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8283 static const unsigned char table1280_650[] = {
8284 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8285 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8287 static const unsigned char table1400_650[] = {
8288 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8289 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8291 static const unsigned char table1600_650[] = {
8292 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8293 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8296 if(SiS_Pr->ChipType == SIS_740) {
8297 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8298 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8299 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8300 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8303 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8304 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8305 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8306 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8310 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8311 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8312 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8313 if(tempbh == 0xc8) {
8314 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8315 } else if(tempbh == 0xdb) {
8316 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8317 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8318 } else if(tempbh == 0xde) {
8319 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8323 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8326 for(i = 0; i < tempbh; i++) {
8327 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8329 SiS_ChrontelPowerSequencing(SiS_Pr);
8330 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8332 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8334 if(SiS_Pr->ChipType == SIS_740) {
8335 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8337 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8338 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8339 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8341 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8342 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8344 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8349 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8351 unsigned char temp, temp1;
8353 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8354 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8355 temp = SiS_GetCH701x(SiS_Pr,0x47);
8356 temp &= 0x7f; /* Use external VSYNC */
8357 SiS_SetCH701x(SiS_Pr,0x47,temp);
8358 SiS_LongDelay(SiS_Pr, 3);
8359 temp = SiS_GetCH701x(SiS_Pr,0x47);
8360 temp |= 0x80; /* Use internal VSYNC */
8361 SiS_SetCH701x(SiS_Pr,0x47,temp);
8362 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8366 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8368 unsigned short temp;
8370 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8371 if(SiS_Pr->ChipType == SIS_740) {
8372 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8373 temp |= 0x04; /* Invert XCLK phase */
8374 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8376 if(SiS_IsYPbPr(SiS_Pr)) {
8377 temp = SiS_GetCH701x(SiS_Pr,0x01);
8379 temp |= 0x80; /* Enable YPrPb (HDTV) */
8380 SiS_SetCH701x(SiS_Pr,0x01,temp);
8382 if(SiS_IsChScart(SiS_Pr)) {
8383 temp = SiS_GetCH701x(SiS_Pr,0x01);
8385 temp |= 0xc0; /* Enable SCART + CVBS */
8386 SiS_SetCH701x(SiS_Pr,0x01,temp);
8388 if(SiS_Pr->ChipType == SIS_740) {
8389 SiS_ChrontelResetVSync(SiS_Pr);
8390 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8392 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8393 temp = SiS_GetCH701x(SiS_Pr,0x49);
8394 if(SiS_IsYPbPr(SiS_Pr)) {
8395 temp = SiS_GetCH701x(SiS_Pr,0x73);
8397 SiS_SetCH701x(SiS_Pr,0x73,temp);
8399 temp = SiS_GetCH701x(SiS_Pr,0x47);
8401 SiS_SetCH701x(SiS_Pr,0x47,temp);
8402 SiS_LongDelay(SiS_Pr, 2);
8403 temp = SiS_GetCH701x(SiS_Pr,0x47);
8405 SiS_SetCH701x(SiS_Pr,0x47,temp);
8411 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8413 unsigned short temp;
8415 /* Complete power down of LVDS */
8416 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8417 if(SiS_Pr->ChipType == SIS_740) {
8418 SiS_LongDelay(SiS_Pr, 1);
8419 SiS_GenericDelay(SiS_Pr, 5887);
8420 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8421 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8423 SiS_LongDelay(SiS_Pr, 2);
8424 temp = SiS_GetCH701x(SiS_Pr,0x76);
8426 SiS_SetCH701x(SiS_Pr,0x76,temp);
8427 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8433 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8435 unsigned short temp;
8437 if(SiS_Pr->ChipType == SIS_740) {
8439 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8443 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8444 temp = SiS_GetCH701x(SiS_Pr,0x49);
8445 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8448 /* Reset Chrontel 7019 datapath */
8449 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8450 SiS_LongDelay(SiS_Pr, 1);
8451 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8453 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8454 SiS_ChrontelResetVSync(SiS_Pr);
8455 SiS_SetCH701x(SiS_Pr,0x49,temp);
8460 /* Clear/set/clear GPIO */
8461 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8463 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8464 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8466 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8467 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8469 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8470 temp = SiS_GetCH701x(SiS_Pr,0x61);
8472 SiS_SetCH701xForLCD(SiS_Pr);
8477 /* Reset Chrontel 7019 datapath */
8478 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8479 SiS_LongDelay(SiS_Pr, 1);
8480 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8485 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8487 unsigned short temp;
8489 if(SiS_Pr->ChipType == SIS_740) {
8491 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8492 SiS_ChrontelResetVSync(SiS_Pr);
8497 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8498 temp = SiS_GetCH701x(SiS_Pr,0x49);
8500 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8501 temp = SiS_GetCH701x(SiS_Pr,0x47);
8503 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8504 SiS_LongDelay(SiS_Pr, 3);
8505 temp = SiS_GetCH701x(SiS_Pr,0x47);
8507 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8514 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8516 unsigned short temp,temp1;
8518 if(SiS_Pr->ChipType == SIS_740) {
8520 temp = SiS_GetCH701x(SiS_Pr,0x61);
8523 SiS_SetCH701x(SiS_Pr,0x61,temp);
8525 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8526 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8527 SiS_LongDelay(SiS_Pr, 1);
8528 SiS_GenericDelay(SiS_Pr, 5887);
8533 temp = SiS_GetCH701x(SiS_Pr,0x61);
8536 SiS_SetCH701x(SiS_Pr,0x61,temp);
8539 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8540 temp = SiS_GetCH701x(SiS_Pr,0x66);
8542 SiS_SetCH701x(SiS_Pr,0x66,temp);
8544 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8545 SiS_GenericDelay(SiS_Pr, 1023);
8547 SiS_GenericDelay(SiS_Pr, 767);
8551 SiS_GenericDelay(SiS_Pr, 767);
8553 temp = SiS_GetCH701x(SiS_Pr,0x76);
8555 SiS_SetCH701x(SiS_Pr,0x76,temp);
8556 temp = SiS_GetCH701x(SiS_Pr,0x66);
8558 SiS_SetCH701x(SiS_Pr,0x66,temp);
8559 SiS_LongDelay(SiS_Pr, 1);
8565 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8567 unsigned short temp;
8569 SiS_LongDelay(SiS_Pr, 1);
8572 temp = SiS_GetCH701x(SiS_Pr,0x66);
8573 temp &= 0x04; /* PLL stable? -> bail out */
8574 if(temp == 0x04) break;
8576 if(SiS_Pr->ChipType == SIS_740) {
8577 /* Power down LVDS output, PLL normal operation */
8578 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8581 SiS_SetCH701xForLCD(SiS_Pr);
8583 temp = SiS_GetCH701x(SiS_Pr,0x76);
8584 temp &= 0xfb; /* Reset PLL */
8585 SiS_SetCH701x(SiS_Pr,0x76,temp);
8586 SiS_LongDelay(SiS_Pr, 2);
8587 temp = SiS_GetCH701x(SiS_Pr,0x76);
8588 temp |= 0x04; /* PLL normal operation */
8589 SiS_SetCH701x(SiS_Pr,0x76,temp);
8590 if(SiS_Pr->ChipType == SIS_740) {
8591 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8593 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8595 SiS_LongDelay(SiS_Pr, 2);
8598 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8602 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8604 unsigned short temp;
8606 temp = SiS_GetCH701x(SiS_Pr,0x03);
8607 temp |= 0x80; /* Set datapath 1 to TV */
8608 temp &= 0xbf; /* Set datapath 2 to LVDS */
8609 SiS_SetCH701x(SiS_Pr,0x03,temp);
8611 if(SiS_Pr->ChipType == SIS_740) {
8613 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8614 temp &= 0xfb; /* Normal XCLK phase */
8615 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8617 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8619 temp = SiS_GetCH701x(SiS_Pr,0x64);
8620 temp |= 0x40; /* ? Bit not defined */
8621 SiS_SetCH701x(SiS_Pr,0x64,temp);
8623 temp = SiS_GetCH701x(SiS_Pr,0x03);
8624 temp &= 0x3f; /* D1 input to both LVDS and TV */
8625 SiS_SetCH701x(SiS_Pr,0x03,temp);
8627 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8628 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8629 SiS_LongDelay(SiS_Pr, 1);
8630 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8631 SiS_ChrontelResetDB(SiS_Pr);
8632 SiS_ChrontelDoSomething2(SiS_Pr);
8633 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8635 temp = SiS_GetCH701x(SiS_Pr,0x66);
8637 SiS_ChrontelResetDB(SiS_Pr);
8638 SiS_ChrontelDoSomething2(SiS_Pr);
8639 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8645 SiS_ChrontelResetDB(SiS_Pr);
8646 SiS_ChrontelDoSomething2(SiS_Pr);
8647 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8648 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8649 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8654 #endif /* 315 series */
8656 /*********************************************/
8657 /* MAIN: SET CRT2 REGISTER GROUP */
8658 /*********************************************/
8661 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8664 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8666 unsigned short ModeIdIndex, RefreshRateTableIndex;
8668 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8670 if(!SiS_Pr->UseCustomMode) {
8671 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8676 /* Used for shifting CR33 */
8677 SiS_Pr->SiS_SelectCRT2Rate = 4;
8679 SiS_UnLockCRT2(SiS_Pr);
8681 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8683 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8685 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8686 SiS_DisableBridge(SiS_Pr);
8687 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8688 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8690 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8693 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8694 SiS_LockCRT2(SiS_Pr);
8695 SiS_DisplayOn(SiS_Pr);
8699 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8701 /* Set up Panel Link for LVDS and LCDA */
8702 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8703 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8704 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8705 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8706 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8709 #ifdef SIS_XORG_XF86
8711 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8712 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8713 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8714 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8715 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8719 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8720 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8723 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8725 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8727 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8729 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8731 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8732 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8734 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8736 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8738 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8740 /* For 301BDH (Panel link initialization): */
8741 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8743 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8744 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8745 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8748 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8754 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8756 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8758 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8760 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8761 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8762 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8763 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8765 SiS_SetCH701xForLCD(SiS_Pr);
8769 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8770 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8778 if(SiS_Pr->ChipType < SIS_315H) {
8779 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8780 if(SiS_Pr->SiS_UseOEM) {
8781 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8782 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8783 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8786 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8789 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8790 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8791 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8792 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8794 SiS_DisplayOn(SiS_Pr);
8801 if(SiS_Pr->ChipType >= SIS_315H) {
8802 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8803 if(SiS_Pr->ChipType < SIS_661) {
8804 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8805 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8807 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8809 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8814 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8815 SiS_EnableBridge(SiS_Pr);
8818 SiS_DisplayOn(SiS_Pr);
8820 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8821 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8822 /* Disable LCD panel when using TV */
8823 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8825 /* Disable TV when using LCD */
8826 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8830 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8831 SiS_LockCRT2(SiS_Pr);
8838 /*********************************************/
8839 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8840 /*********************************************/
8843 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8845 /* Switch on LCD backlight on SiS30xLV */
8846 SiS_DDC2Delay(SiS_Pr,0xff00);
8847 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8848 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8849 SiS_WaitVBRetrace(SiS_Pr);
8851 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8852 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8857 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8859 /* Switch off LCD backlight on SiS30xLV */
8860 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8861 SiS_DDC2Delay(SiS_Pr,0xff00);
8864 /*********************************************/
8865 /* DDC RELATED FUNCTIONS */
8866 /*********************************************/
8869 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8871 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8872 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8873 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8874 SiS_Pr->SiS_DDC_NData &= 0x0f;
8875 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8880 static unsigned char *
8881 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8884 unsigned short tempah,temp;
8885 unsigned char *mydataptr;
8887 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8888 mydataptr = dataptr;
8890 if(!num) return mydataptr;
8892 SiS_SetStop(SiS_Pr);
8893 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8895 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8896 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8897 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8898 if(temp) continue; /* (ERROR: no ack) */
8899 tempah = *mydataptr++;
8900 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8901 if(temp) continue; /* (ERROR: no ack) */
8902 for(j=0; j<num; j++) {
8903 tempah = *mydataptr++;
8904 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8908 if(SiS_SetStop(SiS_Pr)) continue;
8915 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8917 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8918 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8919 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8920 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8921 SiS_SetupDDCN(SiS_Pr);
8923 SiS_SetSwitchDDC2(SiS_Pr);
8926 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8927 if(!dataptr) return FALSE;
8929 #ifdef SIS_XORG_XF86
8931 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
8938 /* The Chrontel 700x is connected to the 630/730 via
8939 * the 630/730's DDC/I2C port.
8941 * On 630(S)T chipset, the index changed from 0x11 to
8942 * 0x0a, possibly for working around the DDC problems
8946 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8948 unsigned short temp, i;
8950 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8952 SiS_SetStop(SiS_Pr);
8953 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8955 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8956 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8957 if(temp) continue; /* (ERROR: no ack) */
8958 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
8959 if(temp) continue; /* (ERROR: no ack) */
8960 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
8961 if(temp) continue; /* (ERROR: no ack) */
8962 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
8963 SiS_Pr->SiS_ChrontelInit = 1;
8969 /* Write to Chrontel 700x */
8971 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8973 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8975 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8977 if(!(SiS_Pr->SiS_ChrontelInit)) {
8978 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8979 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8980 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8981 SiS_SetupDDCN(SiS_Pr);
8984 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
8985 (!(SiS_Pr->SiS_ChrontelInit)) ) {
8986 SiS_Pr->SiS_DDC_Index = 0x0a;
8987 SiS_Pr->SiS_DDC_Data = 0x80;
8988 SiS_Pr->SiS_DDC_Clk = 0x40;
8989 SiS_SetupDDCN(SiS_Pr);
8991 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
8995 /* Write to Chrontel 701x */
8996 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
8998 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9000 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9001 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9002 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9003 SiS_SetupDDCN(SiS_Pr);
9004 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9005 SiS_SetChReg(SiS_Pr, reg, val, 0);
9008 #ifdef SIS_LINUX_KERNEL
9012 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9014 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9015 SiS_SetCH700x(SiS_Pr, reg, val);
9017 SiS_SetCH701x(SiS_Pr, reg, val);
9020 static unsigned short
9021 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9023 unsigned short tempah, temp, i;
9025 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9027 SiS_SetStop(SiS_Pr);
9028 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9030 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9031 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9032 if(temp) continue; /* (ERROR: no ack) */
9033 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
9034 if(temp) continue; /* (ERROR: no ack) */
9035 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9036 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9037 if(temp) continue; /* (ERROR: no ack) */
9038 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
9039 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9040 SiS_Pr->SiS_ChrontelInit = 1;
9046 /* Read from Chrontel 700x */
9047 /* Parameter is [Register no (S7-S0)] */
9049 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9051 unsigned short result;
9053 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9055 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9057 if(!(SiS_Pr->SiS_ChrontelInit)) {
9058 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9059 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9060 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9061 SiS_SetupDDCN(SiS_Pr);
9064 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9066 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9067 (!SiS_Pr->SiS_ChrontelInit) ) {
9069 SiS_Pr->SiS_DDC_Index = 0x0a;
9070 SiS_Pr->SiS_DDC_Data = 0x80;
9071 SiS_Pr->SiS_DDC_Clk = 0x40;
9072 SiS_SetupDDCN(SiS_Pr);
9074 result = SiS_GetChReg(SiS_Pr,0x80);
9079 /* Read from Chrontel 701x */
9080 /* Parameter is [Register no (S7-S0)] */
9082 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9084 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9085 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9086 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9087 SiS_SetupDDCN(SiS_Pr);
9088 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9090 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9092 return SiS_GetChReg(SiS_Pr,0);
9095 /* Read from Chrontel 70xx */
9096 /* Parameter is [Register no (S7-S0)] */
9097 #ifdef SIS_LINUX_KERNEL
9101 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9103 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9104 return SiS_GetCH700x(SiS_Pr, tempbx);
9106 return SiS_GetCH701x(SiS_Pr, tempbx);
9110 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9111 unsigned char myor, unsigned short myand)
9113 unsigned short tempbl;
9115 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9116 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9119 /* Our own DDC functions */
9120 #ifndef SIS_XORG_XF86
9124 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9125 unsigned short adaptnum, unsigned short DDCdatatype, BOOLEAN checkcr32,
9126 unsigned int VBFlags2)
9128 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9129 unsigned char flag, cr32;
9130 unsigned short temp = 0, myadaptnum = adaptnum;
9133 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9134 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9137 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9139 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9141 SiS_Pr->SiS_DDC_SecAddr = 0;
9142 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9143 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9144 SiS_Pr->SiS_DDC_Index = 0x11;
9147 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9150 if(VBFlags2 & VB2_SISBRIDGE) {
9151 if(myadaptnum == 0) {
9152 if(!(cr32 & 0x20)) {
9154 if(!(cr32 & 0x10)) {
9156 if(!(cr32 & 0x08)) {
9165 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9167 if(myadaptnum != 0) {
9169 if(VBFlags2 & VB2_SISBRIDGE) {
9170 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9171 SiS_Pr->SiS_DDC_Index = 0x0f;
9175 if(!(VBFlags2 & VB2_301)) {
9176 if((cr32 & 0x80) && (checkcr32)) {
9177 if(myadaptnum >= 1) {
9178 if(!(cr32 & 0x08)) {
9180 if(!(cr32 & 0x10)) return 0xFFFF;
9186 temp = 4 - (myadaptnum * 2);
9189 } else { /* 315/330 series */
9191 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9193 if(VBFlags2 & VB2_SISBRIDGE) {
9194 if(myadaptnum == 2) {
9199 if(myadaptnum == 1) {
9201 if(VBFlags2 & VB2_SISBRIDGE) {
9202 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9203 SiS_Pr->SiS_DDC_Index = 0x0f;
9207 if((cr32 & 0x80) && (checkcr32)) {
9208 if(myadaptnum >= 1) {
9209 if(!(cr32 & 0x08)) {
9211 if(!(cr32 & 0x10)) return 0xFFFF;
9217 if(myadaptnum == 1) {
9219 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9225 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9226 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9228 SiS_SetupDDCN(SiS_Pr);
9230 #ifdef SIS_XORG_XF86
9232 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9233 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9239 static unsigned short
9240 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9242 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9243 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9246 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9252 static unsigned short
9253 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9255 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9256 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9262 static unsigned short
9263 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9265 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9266 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9271 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9273 SiS_SetSCLKLow(SiS_Pr);
9275 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9276 SiS_Pr->SiS_DDC_Index,
9277 SiS_Pr->SiS_DDC_NData,
9278 SiS_Pr->SiS_DDC_Data);
9280 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9281 SiS_Pr->SiS_DDC_Index,
9282 SiS_Pr->SiS_DDC_NData,
9285 SiS_SetSCLKHigh(SiS_Pr);
9288 static unsigned short
9289 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9291 unsigned char mask, value;
9292 unsigned short temp, ret=0;
9293 BOOLEAN failed = FALSE;
9295 SiS_SetSwitchDDC2(SiS_Pr);
9296 if(SiS_PrepareDDC(SiS_Pr)) {
9297 SiS_SetStop(SiS_Pr);
9298 #ifdef SIS_XORG_XF86
9300 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9307 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9308 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9309 SiS_SendACK(SiS_Pr, 0);
9316 #ifdef SIS_XORG_XF86
9318 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9323 if(failed == FALSE) {
9324 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9325 SiS_SendACK(SiS_Pr, 1);
9327 if(temp == value) ret = 0;
9330 #ifdef SIS_XORG_XF86
9332 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9335 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9336 if(temp == 0x30) ret = 0;
9340 SiS_SetStop(SiS_Pr);
9344 #ifndef SIS_XORG_XF86
9348 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9350 unsigned short flag;
9353 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9354 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9355 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9356 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9357 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9358 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9359 if(!(flag & 0x1a)) flag = 0;
9363 #ifndef SIS_XORG_XF86
9367 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9369 unsigned short flag, length, i;
9370 unsigned char chksum,gotcha;
9372 if(DDCdatatype > 4) return 0xFFFF;
9375 SiS_SetSwitchDDC2(SiS_Pr);
9376 if(!(SiS_PrepareDDC(SiS_Pr))) {
9378 if(DDCdatatype != 1) length = 255;
9381 for(i=0; i<length; i++) {
9382 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9383 chksum += buffer[i];
9384 gotcha |= buffer[i];
9385 SiS_SendACK(SiS_Pr, 0);
9387 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9388 chksum += buffer[i];
9389 SiS_SendACK(SiS_Pr, 1);
9390 if(gotcha) flag = (unsigned short)chksum;
9395 SiS_SetStop(SiS_Pr);
9399 /* Our private DDC functions
9401 It complies somewhat with the corresponding VESA function
9402 in arguments and return values.
9404 Since this is probably called before the mode is changed,
9405 we use our pre-detected pSiS-values instead of SiS_Pr as
9406 regards chipset and video bridge type.
9409 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9410 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9411 LCDA is CRT1, but DDC is read from CRT2 port.
9412 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9413 buffer: ptr to 256 data bytes which will be filled with read data.
9415 Returns 0xFFFF if error, otherwise
9416 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9417 if DDCdatatype = 0: Returns supported DDC modes
9421 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9422 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9423 unsigned int VBFlags2)
9425 unsigned char sr1f, cr17=1;
9426 unsigned short result;
9434 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9437 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE, VBFlags2) == 0xFFFF)
9440 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9441 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9442 if(VGAEngine == SIS_300_VGA) {
9443 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9445 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9446 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9447 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9450 if((sr1f) || (!cr17)) {
9451 SiS_WaitRetrace1(SiS_Pr);
9452 SiS_WaitRetrace1(SiS_Pr);
9453 SiS_WaitRetrace1(SiS_Pr);
9454 SiS_WaitRetrace1(SiS_Pr);
9457 if(DDCdatatype == 0) {
9458 result = SiS_ProbeDDC(SiS_Pr);
9460 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9461 if((!result) && (DDCdatatype == 1)) {
9462 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9463 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9464 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9465 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9466 (buffer[0x12] == 1)) {
9467 if(!SiS_Pr->DDCPortMixup) {
9469 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9471 if(buffer[0x14] & 0x80) result = 0xFFFE;
9477 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9478 if(VGAEngine == SIS_300_VGA) {
9479 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9484 /* Generic I2C functions for Chrontel & DDC --------- */
9487 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9489 SiS_SetSCLKHigh(SiS_Pr);
9490 SiS_WaitRetrace1(SiS_Pr);
9492 SiS_SetSCLKLow(SiS_Pr);
9493 SiS_WaitRetrace1(SiS_Pr);
9497 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9499 SiS_WaitRetrace1(SiS_Pr);
9500 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9503 /* Set I2C start condition */
9504 /* This is done by a SD high-to-low transition while SC is high */
9505 static unsigned short
9506 SiS_SetStart(struct SiS_Private *SiS_Pr)
9508 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9509 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9510 SiS_Pr->SiS_DDC_Index,
9511 SiS_Pr->SiS_DDC_NData,
9512 SiS_Pr->SiS_DDC_Data); /* SD->high */
9513 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9514 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9515 SiS_Pr->SiS_DDC_Index,
9516 SiS_Pr->SiS_DDC_NData,
9517 0x00); /* SD->low = start condition */
9518 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9522 /* Set I2C stop condition */
9523 /* This is done by a SD low-to-high transition while SC is high */
9524 static unsigned short
9525 SiS_SetStop(struct SiS_Private *SiS_Pr)
9527 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9528 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9529 SiS_Pr->SiS_DDC_Index,
9530 SiS_Pr->SiS_DDC_NData,
9531 0x00); /* SD->low */
9532 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9533 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9534 SiS_Pr->SiS_DDC_Index,
9535 SiS_Pr->SiS_DDC_NData,
9536 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9537 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9541 /* Write 8 bits of data */
9542 static unsigned short
9543 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9545 unsigned short i,flag,temp;
9548 for(i = 0; i < 8; i++) {
9549 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9551 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9552 SiS_Pr->SiS_DDC_Index,
9553 SiS_Pr->SiS_DDC_NData,
9554 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9556 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9557 SiS_Pr->SiS_DDC_Index,
9558 SiS_Pr->SiS_DDC_NData,
9559 0x00); /* Write bit (0) to SD */
9561 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9564 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9568 static unsigned short
9569 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9571 unsigned short i, temp, getdata;
9574 for(i = 0; i < 8; i++) {
9576 SiS_SetSCLKLow(SiS_Pr);
9577 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9578 SiS_Pr->SiS_DDC_Index,
9579 SiS_Pr->SiS_DDC_NData,
9580 SiS_Pr->SiS_DDC_Data);
9581 SiS_SetSCLKHigh(SiS_Pr);
9582 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9583 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9588 static unsigned short
9589 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9591 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9592 SiS_Pr->SiS_DDC_Index,
9593 SiS_Pr->SiS_DDC_NClk,
9594 0x00); /* SetSCLKLow() */
9595 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9599 static unsigned short
9600 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9602 unsigned short temp, watchdog=1000;
9604 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9605 SiS_Pr->SiS_DDC_Index,
9606 SiS_Pr->SiS_DDC_NClk,
9607 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9609 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9610 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9612 #ifdef SIS_XORG_XF86
9614 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
9619 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9623 /* Check I2C acknowledge */
9624 /* Returns 0 if ack ok, non-0 if ack not ok */
9625 static unsigned short
9626 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9628 unsigned short tempah;
9630 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9631 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9632 SiS_Pr->SiS_DDC_Index,
9633 SiS_Pr->SiS_DDC_NData,
9634 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9635 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9636 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9637 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9638 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9642 /* End of I2C functions ----------------------- */
9645 /* =============== SiS 315/330 O.E.M. ================= */
9649 static unsigned short
9650 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9652 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9653 unsigned short romptr;
9655 if(SiS_Pr->ChipType < SIS_330) {
9656 romptr = SISGETROMW(0x128);
9657 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9658 romptr = SISGETROMW(0x12a);
9660 romptr = SISGETROMW(0x1a8);
9661 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9662 romptr = SISGETROMW(0x1aa);
9667 static unsigned short
9668 GetLCDromptr(struct SiS_Private *SiS_Pr)
9670 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9671 unsigned short romptr;
9673 if(SiS_Pr->ChipType < SIS_330) {
9674 romptr = SISGETROMW(0x120);
9675 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9676 romptr = SISGETROMW(0x122);
9678 romptr = SISGETROMW(0x1a0);
9679 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9680 romptr = SISGETROMW(0x1a2);
9685 static unsigned short
9686 GetTVromptr(struct SiS_Private *SiS_Pr)
9688 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9689 unsigned short romptr;
9691 if(SiS_Pr->ChipType < SIS_330) {
9692 romptr = SISGETROMW(0x114);
9693 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9694 romptr = SISGETROMW(0x11a);
9696 romptr = SISGETROMW(0x194);
9697 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9698 romptr = SISGETROMW(0x19a);
9703 static unsigned short
9704 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9706 unsigned short index;
9708 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9709 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9710 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9713 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9714 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9720 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9721 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9722 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9723 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9724 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9726 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9730 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9731 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9735 static unsigned short
9736 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9738 unsigned short index;
9740 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9741 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9742 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9746 static unsigned short
9747 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9749 unsigned short index;
9752 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9753 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9755 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9759 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9760 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9768 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9770 unsigned short index = 0, temp = 0;
9772 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9773 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9774 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9775 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9776 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9778 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9779 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9782 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9783 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9784 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9790 return (unsigned int)(index | (temp << 16));
9794 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9796 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9801 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9803 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9808 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9812 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9813 if(SiS_Pr->SiS_ROMNew) {
9814 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9815 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9816 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9817 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9819 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9820 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9821 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9822 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9825 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9831 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9833 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9834 unsigned short delay=0,index,myindex,temp,romptr=0;
9835 BOOLEAN dochiptest = TRUE;
9837 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9838 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9840 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9843 /* Find delay (from ROM, internal tables, PCI subsystem) */
9845 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9847 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9848 romptr = GetRAMDACromptr(SiS_Pr);
9850 if(romptr) delay = ROMAddr[romptr];
9853 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9856 } else if(IS_SIS740) {
9858 } else if(SiS_Pr->ChipType < SIS_330) {
9863 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9868 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9870 BOOLEAN gotitfrompci = FALSE;
9872 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9875 if(SiS_Pr->PDC != -1) {
9876 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9877 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9881 if(SiS_Pr->PDCA != -1) {
9882 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9883 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9890 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9891 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9893 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9896 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9899 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9901 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9904 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9905 if(IS_SIS740) delay = 0x01;
9908 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9913 /* This is a piece of typical SiS crap: They code the OEM LCD
9914 * delay into the code, at no defined place in the BIOS.
9915 * We now have to start doing a PCI subsystem check here.
9918 switch(SiS_Pr->SiS_CustomT) {
9919 case CUT_COMPAQ1280:
9920 case CUT_COMPAQ12802:
9921 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9922 gotitfrompci = TRUE;
9928 case CUT_CLEVO14002:
9929 gotitfrompci = TRUE;
9934 case CUT_CLEVO10242:
9935 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9936 gotitfrompci = TRUE;
9939 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9945 /* Could we find it through the PCI ID? If no, use ROM or table */
9949 index = GetLCDPtrIndexBIOS(SiS_Pr);
9950 myindex = GetLCDPtrIndex(SiS_Pr);
9952 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9954 if(SiS_IsNotM650orLater(SiS_Pr)) {
9956 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9957 /* Always use the second pointer on 650; some BIOSes */
9958 /* still carry old 301 data at the first location */
9959 /* romptr = SISGETROMW(0x120); */
9960 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9961 romptr = SISGETROMW(0x122);
9963 delay = ROMAddr[(romptr + index)];
9965 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9970 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
9971 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
9972 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
9976 } else if(SiS_Pr->SiS_UseROM &&
9977 (!(SiS_Pr->SiS_ROMNew)) &&
9978 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
9979 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
9980 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
9981 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
9982 ((romptr = GetLCDromptr(SiS_Pr)))) {
9984 /* Data for 1280x1024 wrong in 301B BIOS */
9985 /* Data for 1600x1200 wrong in 301C BIOS */
9986 delay = ROMAddr[(romptr + index)];
9988 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9990 if(IS_SIS740) delay = 0x03;
9995 delay = SiS310_LCDDelayCompensation_301[myindex];
9996 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9997 if(IS_SIS740) delay = 0x01;
9998 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
9999 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10000 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10001 if(IS_SIS740) delay = 0x01; /* ? */
10003 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10004 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10005 if(IS_SIS740) delay = 0x01;
10006 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10011 } /* got it from PCI */
10013 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10014 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10015 dochiptest = FALSE;
10018 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10020 index = GetTVPtrIndex(SiS_Pr);
10022 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10024 if(SiS_IsNotM650orLater(SiS_Pr)) {
10026 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10027 /* Always use the second pointer on 650; some BIOSes */
10028 /* still carry old 301 data at the first location */
10029 /* romptr = SISGETROMW(0x114); */
10030 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10031 romptr = SISGETROMW(0x11a);
10032 if(!romptr) return;
10033 delay = ROMAddr[romptr + index];
10037 delay = SiS310_TVDelayCompensation_301B[index];
10043 switch(SiS_Pr->SiS_CustomT) {
10044 case CUT_COMPAQ1280:
10045 case CUT_COMPAQ12802:
10046 case CUT_CLEVO1400:
10047 case CUT_CLEVO14002:
10049 dochiptest = FALSE;
10051 case CUT_CLEVO1024:
10052 case CUT_CLEVO10242:
10054 dochiptest = FALSE;
10057 delay = SiS310_TVDelayCompensation_651301LV[index];
10058 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10059 delay = SiS310_TVDelayCompensation_651302LV[index];
10064 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10066 romptr = GetTVromptr(SiS_Pr);
10067 if(!romptr) return;
10068 delay = ROMAddr[romptr + index];
10070 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10072 delay = SiS310_TVDelayCompensation_LVDS[index];
10076 delay = SiS310_TVDelayCompensation_301[index];
10077 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10079 delay = SiS310_TVDelayCompensation_740301B[index];
10080 /* LV: use 301 data? BIOS bug? */
10082 delay = SiS310_TVDelayCompensation_301B[index];
10083 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10089 if(SiS_LCDAEnabled(SiS_Pr)) {
10091 dochiptest = FALSE;
10098 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10100 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10102 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10103 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
10106 } else if(temp == 6) {
10109 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
10112 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10116 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10120 } else { /* LVDS */
10122 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10123 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10125 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10127 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10129 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10138 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10140 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10141 unsigned short index,temp,temp1,romptr=0;
10143 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10146 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10148 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10150 temp = GetTVPtrIndex(SiS_Pr);
10151 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10154 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10155 if(SiS_Pr->ChipType >= SIS_661) {
10156 temp1 = GetOEMTVPtr661(SiS_Pr);
10158 romptr = SISGETROMW(0x260);
10159 if(SiS_Pr->ChipType >= SIS_760) {
10160 romptr = SISGETROMW(0x360);
10162 } else if(SiS_Pr->ChipType >= SIS_330) {
10163 romptr = SISGETROMW(0x192);
10165 romptr = SISGETROMW(0x112);
10171 temp = ROMAddr[romptr + temp1 + index];
10173 temp = SiS310_TVAntiFlick1[temp][index];
10177 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10181 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10183 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10184 unsigned short index,temp,temp1,romptr=0;
10186 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10189 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10191 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10193 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10194 if(SiS_Pr->ChipType >= SIS_661) {
10195 romptr = SISGETROMW(0x26c);
10196 if(SiS_Pr->ChipType >= SIS_760) {
10197 romptr = SISGETROMW(0x36c);
10199 temp1 = GetOEMTVPtr661(SiS_Pr);
10201 } else if(SiS_Pr->ChipType >= SIS_330) {
10202 romptr = SISGETROMW(0x1a4);
10204 romptr = SISGETROMW(0x124);
10210 temp = ROMAddr[romptr + temp1 + index];
10212 temp = SiS310_TVEdge1[temp][index];
10215 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10219 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10221 unsigned short index, temp, i, j;
10223 if(ModeNo <= 0x13) {
10224 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10226 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10229 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10231 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10232 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10233 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10234 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10236 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10237 for(i=0x35, j=0; i<=0x38; i++, j++) {
10238 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10240 for(i=0x48; i<=0x4A; i++, j++) {
10241 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10244 for(i=0x35, j=0; i<=0x38; i++, j++) {
10245 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10251 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10253 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10254 unsigned short index,temp,i,j,resinfo,romptr=0;
10255 unsigned int lindex;
10257 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10259 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10260 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10262 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10263 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10265 for(j=0, i=0x31; i<=0x34; i++, j++) {
10266 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10271 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10272 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10275 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10277 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10280 temp = GetTVPtrIndex(SiS_Pr);
10281 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10282 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10284 if(SiS_Pr->SiS_UseROM) {
10285 romptr = SISGETROMW(0x116);
10286 if(SiS_Pr->ChipType >= SIS_330) {
10287 romptr = SISGETROMW(0x196);
10289 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10290 romptr = SISGETROMW(0x11c);
10291 if(SiS_Pr->ChipType >= SIS_330) {
10292 romptr = SISGETROMW(0x19c);
10294 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10295 romptr = SISGETROMW(0x116);
10296 if(SiS_Pr->ChipType >= SIS_330) {
10297 romptr = SISGETROMW(0x196);
10303 romptr += (temp << 2);
10304 for(j=0, i=0x31; i<=0x34; i++, j++) {
10305 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10309 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10310 for(j=0, i=0x31; i<=0x34; i++, j++) {
10311 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10312 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10313 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10314 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10316 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10320 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10321 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10322 if((resinfo == SIS_RI_640x480) ||
10323 (resinfo == SIS_RI_800x600)) {
10324 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10325 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10326 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10327 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10328 } else if(resinfo == SIS_RI_1024x768) {
10329 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10330 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10331 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10332 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10339 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10340 unsigned short ModeIdIndex, unsigned short RTI)
10342 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10343 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10345 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10348 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10349 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10351 if(SiS_Pr->SiS_ROMNew) {
10352 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10353 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10354 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10356 if(SiS_Pr->UseCustomMode) {
10357 index = SiS_Pr->CSRClock;
10358 } else if(ModeNo > 0x13) {
10359 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10360 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10362 if(index < 25) index = 25;
10363 index = ((index / 25) - 1) << 1;
10364 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10367 romptr = SISGETROMW(0x104);
10368 delay = ROMAddr[romptr + index];
10369 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10370 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10371 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10373 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10374 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10380 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10382 if(SiS_Pr->UseCustomMode) delay = 0x04;
10383 else if(ModeNo <= 0x13) delay = 0x04;
10384 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10385 delay |= (delay << 8);
10387 if(SiS_Pr->ChipType >= XGI_20) {
10390 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10393 if(SiS_Pr->SiS_XGIROM) {
10394 index = GetTVPtrIndex(SiS_Pr);
10395 if((romptr = SISGETROMW(0x35e))) {
10396 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10397 delay |= (delay << 8);
10401 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10402 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10408 } else if(SiS_Pr->ChipType >= SIS_340) {
10411 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10414 /* TODO (eventually) */
10416 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10420 index = GetOEMTVPtr661(SiS_Pr);
10421 if(SiS_Pr->SiS_ROMNew) {
10422 romptr = SISGETROMW(0x106);
10423 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10424 delay = ROMAddr[romptr + index];
10427 if(index > 3) delay = 0;
10430 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10432 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10434 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10435 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10437 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10439 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10440 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10441 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10445 /* TMDS: Set our own, since BIOS has no idea */
10446 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10447 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10448 switch(SiS_Pr->SiS_LCDResInfo) {
10449 case Panel_1024x768: delay = 0x0008; break;
10450 case Panel_1280x720: delay = 0x0004; break;
10451 case Panel_1280x768:
10452 case Panel_1280x768_2:delay = 0x0004; break;
10453 case Panel_1280x800:
10454 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10455 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10456 case Panel_1280x1024: delay = 0x1e04; break;
10457 case Panel_1400x1050: delay = 0x0004; break;
10458 case Panel_1600x1200: delay = 0x0400; break;
10459 case Panel_1680x1050: delay = 0x0e04; break;
10461 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10463 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10465 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10467 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10475 /* Override by detected or user-set values */
10476 /* (but only if, for some reason, we can't read value from BIOS) */
10477 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10478 delay = SiS_Pr->PDC & 0x1f;
10480 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10481 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10488 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10491 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10493 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10494 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10499 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10501 unsigned short infoflag;
10502 unsigned char temp;
10504 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10506 if(ModeNo <= 0x13) {
10507 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10508 } else if(SiS_Pr->UseCustomMode) {
10509 infoflag = SiS_Pr->CInfoFlag;
10511 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10514 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10515 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10520 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10521 temp = (infoflag >> 6) | 0x0c;
10522 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10524 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10526 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10529 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10531 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10533 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10534 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10536 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10543 SetPanelParms661(struct SiS_Private *SiS_Pr)
10545 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10546 unsigned short romptr, temp1, temp2;
10548 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10549 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10552 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10553 if(SiS_Pr->LVDSHL != -1) {
10554 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10558 if(SiS_Pr->SiS_ROMNew) {
10560 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10561 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10562 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10564 if(SiS_Pr->LVDSHL != -1) {
10568 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10570 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10571 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10572 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10580 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10582 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10583 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10584 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10585 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10586 SetPanelParms661(SiS_Pr);
10589 SetDelayComp(SiS_Pr,ModeNo);
10592 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10593 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10594 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10595 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10596 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10597 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10603 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10604 unsigned short ModeIdIndex, unsigned short RRTI)
10606 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10608 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10610 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10611 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10612 SetPanelParms661(SiS_Pr);
10615 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10616 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10617 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10618 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10619 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10620 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10627 * This finalizes some CRT2 registers for the very panel used.
10628 * If we have a backup if these registers, we use it; otherwise
10629 * we set the register according to most BIOSes. However, this
10630 * function looks quite different in every BIOS, so you better
10631 * pray that we have a backup...
10634 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10636 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10637 unsigned short resinfo,modeflag;
10639 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10640 if(SiS_Pr->SiS_ROMNew) return;
10642 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10643 if(SiS_Pr->LVDSHL != -1) {
10644 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10648 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10649 if(SiS_Pr->UseCustomMode) return;
10651 switch(SiS_Pr->SiS_CustomT) {
10652 case CUT_COMPAQ1280:
10653 case CUT_COMPAQ12802:
10654 case CUT_CLEVO1400:
10655 case CUT_CLEVO14002:
10659 if(ModeNo <= 0x13) {
10660 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10661 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10663 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10664 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10668 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10669 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10670 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10672 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10677 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10678 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10679 /* Maybe all panels? */
10680 if(SiS_Pr->LVDSHL == -1) {
10681 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10687 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10688 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10689 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10690 if(SiS_Pr->LVDSHL == -1) {
10691 /* Maybe all panels? */
10692 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10694 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10695 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10697 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10698 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10699 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10700 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10708 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10709 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10710 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10711 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10713 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10715 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10717 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10718 if(SiS_Pr->LVDSHL == -1) {
10719 /* Maybe ACER only? */
10720 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10723 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10724 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10725 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10726 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10727 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10728 if(tempch == 0x03) {
10729 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10730 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10731 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10732 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10734 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
10735 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10736 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10737 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10738 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10739 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10740 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10741 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10742 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10743 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10744 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10745 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10746 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10747 if(ModeNo <= 0x13) {
10748 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10749 if((resinfo == 0) || (resinfo == 2)) return;
10750 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10751 if((resinfo == 1) || (resinfo == 3)) return;
10753 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10754 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10755 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10757 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10759 temp = tempbx & 0xff;
10760 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10761 temp = (tempbx >> 8) & 0x03;
10762 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10765 } else if(ModeNo <= 0x13) {
10767 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10768 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10769 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10770 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10772 if(!(modeflag & HalfDCLK)) {
10773 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10774 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10775 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10776 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10777 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10778 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10779 if(ModeNo == 0x12) {
10782 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10783 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10784 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10785 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10786 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10787 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10790 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10791 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10794 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10802 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10806 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10807 tempbx = (tempbh << 8) | tempbl;
10808 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10809 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10810 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10813 if(tempbx > 770) tempbx = 770;
10814 if(SiS_Pr->SiS_VGAVDE < 600) {
10815 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10816 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10817 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10823 temp = tempbx & 0xff;
10824 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10825 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10826 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10833 /* ================= SiS 300 O.E.M. ================== */
10838 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10839 unsigned short RefTabIndex)
10841 unsigned short crt2crtc=0, modeflag, myindex=0;
10842 unsigned char temp;
10845 if(ModeNo <= 0x13) {
10846 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10847 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10849 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10850 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10855 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10856 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10859 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10860 if(modeflag & HalfDCLK) myindex = 1;
10862 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10863 for(i=0; i<7; i++) {
10864 if(barco_p1[myindex][crt2crtc][i][0]) {
10865 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10866 barco_p1[myindex][crt2crtc][i][0],
10867 barco_p1[myindex][crt2crtc][i][2],
10868 barco_p1[myindex][crt2crtc][i][1]);
10872 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10874 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10876 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10881 static unsigned short
10882 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10884 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10885 unsigned short tempbx=0,romptr=0;
10886 static const unsigned char customtable300[] = {
10887 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10888 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10890 static const unsigned char customtable630[] = {
10891 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10892 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10895 if(SiS_Pr->ChipType == SIS_300) {
10897 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10898 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10900 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10901 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10902 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10904 if(SiS_Pr->SiS_UseROM) {
10905 if(ROMAddr[0x235] & 0x80) {
10906 tempbx = SiS_Pr->SiS_LCDTypeInfo;
10908 romptr = SISGETROMW(0x255);
10909 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10910 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10911 if(tempbx == 0xFF) return 0xFFFF;
10914 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10921 if(SiS_Pr->SiS_UseROM) {
10922 romptr = SISGETROMW(0x255);
10923 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10924 else tempbx = 0xff;
10926 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10928 if(tempbx == 0xFF) return 0xFFFF;
10930 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10931 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10934 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10935 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10936 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10944 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10946 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10947 unsigned short index,temp,romptr=0;
10949 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10951 if(SiS_Pr->SiS_UseROM) {
10952 if(!(ROMAddr[0x237] & 0x01)) return;
10953 if(!(ROMAddr[0x237] & 0x02)) return;
10954 romptr = SISGETROMW(0x24b);
10957 /* The Panel Compensation Delay should be set according to tables
10958 * here. Unfortunately, various BIOS versions don't care about
10959 * a uniform way using eg. ROM byte 0x220, but use different
10960 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10961 * Thus we don't set this if the user selected a custom pdc or if
10962 * we otherwise detected a valid pdc.
10964 if(SiS_Pr->PDC != -1) return;
10966 temp = GetOEMLCDPtr(SiS_Pr, 0);
10968 if(SiS_Pr->UseCustomMode)
10971 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
10973 if(SiS_Pr->ChipType != SIS_300) {
10975 romptr += (temp * 2);
10976 romptr = SISGETROMW(romptr);
10978 temp = ROMAddr[romptr];
10980 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10981 temp = SiS300_OEMLCDDelay2[temp][index];
10983 temp = SiS300_OEMLCDDelay3[temp][index];
10987 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
10989 romptr += (temp * 2);
10990 romptr = SISGETROMW(romptr);
10992 temp = ROMAddr[romptr];
10994 temp = SiS300_OEMLCDDelay5[temp][index];
10997 if(SiS_Pr->SiS_UseROM) {
10998 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11000 romptr += (temp * 2);
11001 romptr = SISGETROMW(romptr);
11003 temp = ROMAddr[romptr];
11005 temp = SiS300_OEMLCDDelay4[temp][index];
11008 temp = SiS300_OEMLCDDelay4[temp][index];
11013 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11017 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11019 #if 0 /* Unfinished; Data table missing */
11020 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11021 unsigned short index,temp;
11023 if((SiS_Pr->SiS_UseROM) {
11024 if(!(ROMAddr[0x237] & 0x01)) return;
11025 if(!(ROMAddr[0x237] & 0x04)) return;
11026 /* No rom pointer in BIOS header! */
11029 temp = GetOEMLCDPtr(SiS_Pr, 1);
11030 if(temp == 0xFFFF) return;
11032 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11033 for(i=0x14, j=0; i<=0x17; i++, j++) {
11034 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11036 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11038 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11039 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11040 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11041 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11042 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11043 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11048 static unsigned short
11049 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11051 unsigned short index;
11054 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11055 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11056 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11057 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11058 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11060 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11061 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11067 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11069 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11070 unsigned short index,temp,romptr=0;
11072 if(SiS_Pr->SiS_UseROM) {
11073 if(!(ROMAddr[0x238] & 0x01)) return;
11074 if(!(ROMAddr[0x238] & 0x02)) return;
11075 romptr = SISGETROMW(0x241);
11078 temp = GetOEMTVPtr(SiS_Pr);
11080 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11083 romptr += (temp * 2);
11084 romptr = SISGETROMW(romptr);
11086 temp = ROMAddr[romptr];
11088 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11089 temp = SiS300_OEMTVDelay301[temp][index];
11091 temp = SiS300_OEMTVDelayLVDS[temp][index];
11095 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11099 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11101 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11102 unsigned short index,temp,romptr=0;
11104 if(SiS_Pr->SiS_UseROM) {
11105 if(!(ROMAddr[0x238] & 0x01)) return;
11106 if(!(ROMAddr[0x238] & 0x04)) return;
11107 romptr = SISGETROMW(0x243);
11110 temp = GetOEMTVPtr(SiS_Pr);
11112 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11115 romptr += (temp * 2);
11116 romptr = SISGETROMW(romptr);
11118 temp = ROMAddr[romptr];
11120 temp = SiS300_OEMTVFlicker[temp][index];
11123 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11127 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11129 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11130 unsigned short index,i,j,temp,romptr=0;
11132 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11134 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11136 if(SiS_Pr->SiS_UseROM) {
11137 if(!(ROMAddr[0x238] & 0x01)) return;
11138 if(!(ROMAddr[0x238] & 0x08)) return;
11139 romptr = SISGETROMW(0x245);
11142 temp = GetOEMTVPtr(SiS_Pr);
11144 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11146 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11147 for(i=0x31, j=0; i<=0x34; i++, j++) {
11148 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11152 romptr += (temp * 2);
11153 romptr = SISGETROMW(romptr);
11154 romptr += (index * 4);
11155 for(i=0x31, j=0; i<=0x34; i++, j++) {
11156 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11159 for(i=0x31, j=0; i<=0x34; i++, j++) {
11160 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11167 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11169 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11170 unsigned short index,temp,i,j,romptr=0;
11172 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11174 if(SiS_Pr->SiS_UseROM) {
11175 if(!(ROMAddr[0x238] & 0x01)) return;
11176 if(!(ROMAddr[0x238] & 0x10)) return;
11177 romptr = SISGETROMW(0x247);
11180 temp = GetOEMTVPtr(SiS_Pr);
11182 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11183 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11184 /* NTSCJ uses NTSC filters */
11186 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11188 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11189 for(i=0x35, j=0; i<=0x38; i++, j++) {
11190 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11192 for(i=0x48; i<=0x4A; i++, j++) {
11193 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11196 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11197 romptr += (temp * 2);
11198 romptr = SISGETROMW(romptr);
11199 romptr += (index * 4);
11200 for(i=0x35, j=0; i<=0x38; i++, j++) {
11201 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11204 for(i=0x35, j=0; i<=0x38; i++, j++) {
11205 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11211 static unsigned short
11212 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11214 unsigned short ModeIdIndex;
11215 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11217 if(*ModeNo <= 5) *ModeNo |= 1;
11219 for(ModeIdIndex=0; ; ModeIdIndex++) {
11220 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11221 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11224 if(*ModeNo != 0x07) {
11225 if(*ModeNo > 0x03) return ModeIdIndex;
11226 if(VGAINFO & 0x80) return ModeIdIndex;
11230 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11231 /* else 350 lines */
11232 return ModeIdIndex;
11236 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11237 unsigned short RefTableIndex)
11239 unsigned short OEMModeIdIndex = 0;
11241 if(!SiS_Pr->UseCustomMode) {
11242 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11243 if(!(OEMModeIdIndex)) return;
11246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11247 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11248 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11249 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11252 if(SiS_Pr->UseCustomMode) return;
11253 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11254 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11255 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11256 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11257 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11258 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);