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)
448 while (delaytime-- > 0)
449 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
452 #if defined(SIS300) || defined(SIS315H)
454 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
456 SiS_DDC2Delay(SiS_Pr, delay * 36);
462 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
465 SiS_GenericDelay(SiS_Pr, 6623);
470 #if defined(SIS300) || defined(SIS315H)
472 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
475 SiS_GenericDelay(SiS_Pr, 66);
481 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
483 #if defined(SIS300) || defined(SIS315H)
484 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
485 unsigned short PanelID, DelayIndex, Delay=0;
488 if(SiS_Pr->ChipType < SIS_315H) {
492 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
493 if(SiS_Pr->SiS_VBType & VB_SISVB) {
494 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
495 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
497 DelayIndex = PanelID >> 4;
498 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
501 if(DelayTime >= 2) DelayTime -= 2;
502 if(!(DelayTime & 0x01)) {
503 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
505 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
507 if(SiS_Pr->SiS_UseROM) {
508 if(ROMAddr[0x220] & 0x40) {
509 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
510 else Delay = (unsigned short)ROMAddr[0x226];
514 SiS_ShortDelay(SiS_Pr, Delay);
522 if((SiS_Pr->ChipType >= SIS_661) ||
523 (SiS_Pr->ChipType <= SIS_315PRO) ||
524 (SiS_Pr->ChipType == SIS_330) ||
525 (SiS_Pr->SiS_ROMNew)) {
527 if(!(DelayTime & 0x01)) {
528 SiS_DDC2Delay(SiS_Pr, 0x1000);
530 SiS_DDC2Delay(SiS_Pr, 0x4000);
533 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
534 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
535 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
537 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
538 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
539 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
540 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
542 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
543 DelayIndex = PanelID & 0x0f;
545 DelayIndex = PanelID >> 4;
547 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
550 if(DelayTime >= 2) DelayTime -= 2;
551 if(!(DelayTime & 0x01)) {
552 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
554 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
556 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
557 if(ROMAddr[0x13c] & 0x40) {
558 if(!(DelayTime & 0x01)) {
559 Delay = (unsigned short)ROMAddr[0x17e];
561 Delay = (unsigned short)ROMAddr[0x17f];
566 SiS_ShortDelay(SiS_Pr, Delay);
569 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
571 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
572 if(!(DelayTime & 0x01)) {
573 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
575 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
578 SiS_DDC2Delay(SiS_Pr, Delay);
589 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
592 for(i = 0; i < DelayLoop; i++) {
593 SiS_PanelDelay(SiS_Pr, DelayTime);
598 /*********************************************/
599 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
600 /*********************************************/
603 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
605 unsigned short watchdog;
607 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
608 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
611 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
613 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
616 #if defined(SIS300) || defined(SIS315H)
618 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
620 unsigned short watchdog;
623 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
625 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
630 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
632 if(SiS_Pr->ChipType < SIS_315H) {
634 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
635 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
637 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
638 SiS_WaitRetrace1(SiS_Pr);
640 SiS_WaitRetrace2(SiS_Pr, 0x25);
645 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
646 SiS_WaitRetrace1(SiS_Pr);
648 SiS_WaitRetrace2(SiS_Pr, 0x30);
655 SiS_VBWait(struct SiS_Private *SiS_Pr)
657 unsigned short tempal,temp,i,j;
660 for(i = 0; i < 3; i++) {
661 for(j = 0; j < 100; j++) {
662 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
664 if((tempal & 0x08)) continue;
667 if(!(tempal & 0x08)) continue;
676 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
678 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
681 SiS_WaitRetrace1(SiS_Pr);
685 /*********************************************/
687 /*********************************************/
691 SiS_Is301B(struct SiS_Private *SiS_Pr)
693 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
699 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
701 if(SiS_Pr->ChipType == SIS_730) {
702 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
704 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
709 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
712 if(SiS_Pr->ChipType >= SIS_315H) {
713 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
714 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
722 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
727 if(SiS_Pr->ChipType >= SIS_315H) {
728 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
729 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
737 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
739 if(SiS_IsVAMode(SiS_Pr)) return true;
740 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
746 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
749 if(SiS_Pr->ChipType >= SIS_315H) {
750 if((SiS_CRT2IsLCD(SiS_Pr)) ||
751 (SiS_IsVAMode(SiS_Pr))) {
752 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
761 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
763 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
764 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
765 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
773 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
775 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
782 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
784 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
785 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
793 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
797 if(SiS_Pr->ChipType == SIS_650) {
798 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
799 /* Check for revision != A0 only */
800 if((flag == 0xe0) || (flag == 0xc0) ||
801 (flag == 0xb0) || (flag == 0x90)) return false;
802 } else if(SiS_Pr->ChipType >= SIS_661) return false;
809 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
811 if(SiS_Pr->ChipType >= SIS_315H) {
813 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
821 SiS_IsChScart(struct SiS_Private *SiS_Pr)
823 if(SiS_Pr->ChipType >= SIS_315H) {
825 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
833 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
837 if(SiS_Pr->ChipType >= SIS_315H) {
838 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
839 if(flag & SetCRT2ToTV) return true;
840 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
841 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
842 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
844 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
845 if(flag & SetCRT2ToTV) return true;
853 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
857 if(SiS_Pr->ChipType >= SIS_315H) {
858 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
859 if(flag & SetCRT2ToLCD) return true;
860 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
861 if(flag & SetToLCDA) return true;
863 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
864 if(flag & SetCRT2ToLCD) return true;
871 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
875 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
877 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
878 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
879 if((flag == 1) || (flag == 2)) return true;
885 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
889 if(SiS_HaveBridge(SiS_Pr)) {
890 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
891 if(SiS_Pr->ChipType < SIS_315H) {
893 if((flag == 0x80) || (flag == 0x20)) return true;
896 if((flag == 0x40) || (flag == 0x10)) return true;
903 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
905 unsigned short flag1;
907 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
908 if(flag1 & (SetInSlaveMode >> 8)) return true;
912 /*********************************************/
913 /* GET VIDEO BRIDGE CONFIG INFO */
914 /*********************************************/
916 /* Setup general purpose IO for Chrontel communication */
919 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
921 unsigned int acpibase;
924 if(!(SiS_Pr->SiS_ChSW)) return;
926 #ifdef SIS_LINUX_KERNEL
927 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
929 acpibase = pciReadLong(0x00000800, 0x74);
932 if(!acpibase) return;
933 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
935 SiS_SetRegShort((acpibase + 0x3c), temp);
936 temp = SiS_GetRegShort((acpibase + 0x3c));
937 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
939 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
940 SiS_SetRegShort((acpibase + 0x3a), temp);
941 temp = SiS_GetRegShort((acpibase + 0x3a));
946 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
947 unsigned short ModeIdIndex, int checkcrt2mode)
949 unsigned short tempax, tempbx, temp;
950 unsigned short modeflag, resinfo = 0;
952 SiS_Pr->SiS_SetFlag = 0;
954 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
956 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
958 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
959 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
964 if(SiS_HaveBridge(SiS_Pr)) {
966 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
968 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
969 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
973 if(SiS_Pr->ChipType >= SIS_315H) {
974 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
976 /* Mode 0x03 is never in driver mode */
977 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
979 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
980 /* Reset LCDA setting if not driver mode */
981 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
984 if(SiS_Pr->SiS_UseLCDA) {
985 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
986 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
987 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
992 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
993 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
994 tempbx |= SetCRT2ToLCDA;
998 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
999 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1000 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1001 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1002 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1003 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1004 tempbx |= SetCRT2ToYPbPr525750;
1009 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1010 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1011 if(temp & SetToLCDA) {
1012 tempbx |= SetCRT2ToLCDA;
1014 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1015 if(temp & EnableCHYPbPr) {
1016 tempbx |= SetCRT2ToCHYPbPr;
1022 #endif /* SIS315H */
1024 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1025 tempbx &= ~(SetCRT2ToRAMDAC);
1028 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1029 temp = SetCRT2ToSVIDEO |
1036 SetCRT2ToYPbPr525750;
1038 if(SiS_Pr->ChipType >= SIS_315H) {
1039 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1040 temp = SetCRT2ToAVIDEO |
1047 temp = SetCRT2ToLCDA |
1051 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1052 temp = SetCRT2ToTV | SetCRT2ToLCD;
1054 temp = SetCRT2ToLCD;
1059 if(!(tempbx & temp)) {
1060 tempax = DisableCRT2Display;
1064 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1066 unsigned short clearmask = ( DriverMode |
1067 DisableCRT2Display |
1075 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1076 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1077 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1078 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1079 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1080 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1084 if(SiS_Pr->ChipType >= SIS_315H) {
1085 if(tempbx & SetCRT2ToLCDA) {
1086 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1089 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1090 if(tempbx & SetCRT2ToTV) {
1091 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1094 if(tempbx & SetCRT2ToLCD) {
1095 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1097 if(SiS_Pr->ChipType >= SIS_315H) {
1098 if(tempbx & SetCRT2ToLCDA) {
1099 tempbx |= SetCRT2ToLCD;
1105 if(tempax & DisableCRT2Display) {
1106 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1107 tempbx = SetSimuScanMode | DisableCRT2Display;
1111 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1113 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1114 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1115 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1116 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1117 modeflag &= (~CRT2Mode);
1121 if(!(tempbx & SetSimuScanMode)) {
1122 if(tempbx & SwitchCRT2) {
1123 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1124 if(resinfo != SIS_RI_1600x1200) {
1125 tempbx |= SetSimuScanMode;
1129 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1130 if(!(tempbx & DriverMode)) {
1131 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1132 tempbx |= SetSimuScanMode;
1139 if(!(tempbx & DisableCRT2Display)) {
1140 if(tempbx & DriverMode) {
1141 if(tempbx & SetSimuScanMode) {
1142 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1143 if(resinfo != SIS_RI_1600x1200) {
1144 tempbx |= SetInSlaveMode;
1149 tempbx |= SetInSlaveMode;
1155 SiS_Pr->SiS_VBInfo = tempbx;
1158 if(SiS_Pr->ChipType == SIS_630) {
1159 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1163 #ifdef SIS_LINUX_KERNEL
1165 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1166 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1171 /*********************************************/
1172 /* DETERMINE YPbPr MODE */
1173 /*********************************************/
1176 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1181 /* Note: This variable is only used on 30xLV systems.
1182 * CR38 has a different meaning on LVDS/CH7019 systems.
1183 * On 661 and later, these bits moved to CR35.
1185 * On 301, 301B, only HiVision 1080i is supported.
1186 * On 30xLV, 301C, only YPbPr 1080i is supported.
1189 SiS_Pr->SiS_YPbPr = 0;
1190 if(SiS_Pr->ChipType >= SIS_661) return;
1192 if(SiS_Pr->SiS_VBType) {
1193 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1194 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1198 if(SiS_Pr->ChipType >= SIS_315H) {
1199 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1200 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1202 switch((temp >> 4)) {
1203 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1204 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1205 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1206 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1214 /*********************************************/
1215 /* DETERMINE TVMode flag */
1216 /*********************************************/
1219 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1221 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1222 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1223 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1225 SiS_Pr->SiS_TVMode = 0;
1227 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1228 if(SiS_Pr->UseCustomMode) return;
1231 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1234 if(SiS_Pr->ChipType < SIS_661) {
1236 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1238 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1240 if((SiS_Pr->ChipType == SIS_630) ||
1241 (SiS_Pr->ChipType == SIS_730)) {
1244 } else if(SiS_Pr->ChipType >= SIS_315H) {
1246 if(SiS_Pr->ChipType < XGI_20) {
1248 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1252 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1253 OutputSelect = ROMAddr[romindex];
1254 if(!(OutputSelect & EnablePALMN)) {
1255 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1258 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1259 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1260 if(temp1 & EnablePALM) { /* 0x40 */
1261 SiS_Pr->SiS_TVMode |= TVSetPALM;
1262 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1263 } else if(temp1 & EnablePALN) { /* 0x80 */
1264 SiS_Pr->SiS_TVMode |= TVSetPALN;
1267 if(temp1 & EnableNTSCJ) { /* 0x40 */
1268 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1272 /* Translate HiVision/YPbPr to our new flags */
1273 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1274 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1275 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1276 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1277 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1278 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1279 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1280 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1281 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1282 SiS_Pr->SiS_TVMode |= TVSetPAL;
1285 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1286 if(SiS_Pr->SiS_CHOverScan) {
1287 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1288 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1289 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1290 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1292 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1293 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1294 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1295 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1298 if(SiS_Pr->SiS_CHSOverScan) {
1299 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1302 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1303 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1304 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1305 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1306 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1308 if(temp & EnableNTSCJ) {
1309 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1315 } else { /* 661 and later */
1317 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1319 SiS_Pr->SiS_TVMode |= TVSetPAL;
1321 SiS_Pr->SiS_TVMode |= TVSetPALN;
1322 } else if(temp1 & 0x04) {
1323 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1324 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1326 SiS_Pr->SiS_TVMode |= TVSetPALM;
1330 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1333 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1334 if(SiS_Pr->SiS_CHOverScan) {
1335 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1336 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1340 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1341 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1343 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1344 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1345 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1346 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1347 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1349 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1350 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1351 SiS_Pr->SiS_TVMode |= TVAspect169;
1353 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1355 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1356 SiS_Pr->SiS_TVMode |= TVAspect169;
1358 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1361 SiS_Pr->SiS_TVMode |= TVAspect43;
1368 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1370 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1372 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1373 SiS_Pr->SiS_TVMode |= TVSetPAL;
1374 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1375 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1376 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1377 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1381 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1382 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1383 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1387 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1388 if(resinfo == SIS_RI_1024x768) {
1389 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1390 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1391 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1392 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1397 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1398 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1399 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1400 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1401 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1402 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1403 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1404 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1405 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1411 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1414 /*********************************************/
1416 /*********************************************/
1418 static unsigned short
1419 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1421 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1422 /* Translate my LCDResInfo to BIOS value */
1424 case Panel_1280x768_2: temp = Panel_1280x768; break;
1425 case Panel_1280x800_2: temp = Panel_1280x800; break;
1426 case Panel_1280x854: temp = Panel661_1280x854; break;
1432 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1435 unsigned char *ROMAddr;
1436 unsigned short temp;
1438 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1439 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1440 SiS_Pr->SiS_NeedRomModeData = true;
1441 SiS_Pr->PanelHT = temp;
1443 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1444 SiS_Pr->SiS_NeedRomModeData = true;
1445 SiS_Pr->PanelVT = temp;
1447 SiS_Pr->PanelHRS = SISGETROMW(10);
1448 SiS_Pr->PanelHRE = SISGETROMW(12);
1449 SiS_Pr->PanelVRS = SISGETROMW(14);
1450 SiS_Pr->PanelVRE = SISGETROMW(16);
1451 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1452 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1453 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1454 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1455 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1456 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1457 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1464 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1465 const unsigned char *nonscalingmodes)
1468 while(nonscalingmodes[i] != 0xff) {
1469 if(nonscalingmodes[i++] == resinfo) {
1470 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1471 (SiS_Pr->UsePanelScaler == -1)) {
1472 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1480 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1482 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1483 bool panelcanscale = false;
1485 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1486 static const unsigned char SiS300SeriesLCDRes[] =
1487 { 0, 1, 2, 3, 7, 4, 5, 8,
1488 0, 0, 10, 0, 0, 0, 0, 15 };
1491 unsigned char *myptr = NULL;
1494 SiS_Pr->SiS_LCDResInfo = 0;
1495 SiS_Pr->SiS_LCDTypeInfo = 0;
1496 SiS_Pr->SiS_LCDInfo = 0;
1497 SiS_Pr->PanelHRS = 999; /* HSync start */
1498 SiS_Pr->PanelHRE = 999; /* HSync end */
1499 SiS_Pr->PanelVRS = 999; /* VSync start */
1500 SiS_Pr->PanelVRE = 999; /* VSync end */
1501 SiS_Pr->SiS_NeedRomModeData = false;
1503 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1504 SiS_Pr->Alternate1600x1200 = false;
1506 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1508 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1510 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1511 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1512 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1513 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1516 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1518 /* For broken BIOSes: Assume 1024x768 */
1519 if(temp == 0) temp = 0x02;
1521 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1522 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1523 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1524 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1526 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1530 if(SiS_Pr->ChipType < SIS_315H) {
1531 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1532 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1533 if(temp < 0x0f) temp &= 0x07;
1535 /* Translate 300 series LCDRes to 315 series for unified usage */
1536 temp = SiS300SeriesLCDRes[temp];
1540 /* Translate to our internal types */
1542 if(SiS_Pr->ChipType == SIS_550) {
1543 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1544 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1545 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1546 } else if(SiS_Pr->ChipType >= SIS_661) {
1547 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1551 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1552 if(temp == Panel310_1280x768) {
1553 temp = Panel_1280x768_2;
1555 if(SiS_Pr->SiS_ROMNew) {
1556 if(temp == Panel661_1280x800) {
1557 temp = Panel_1280x800_2;
1562 SiS_Pr->SiS_LCDResInfo = temp;
1565 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1566 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1567 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1568 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1569 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1570 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1571 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1576 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1577 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1578 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1580 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1581 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1584 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1585 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1586 /* Need temp below! */
1588 /* These must/can't scale no matter what */
1589 switch(SiS_Pr->SiS_LCDResInfo) {
1590 case Panel_320x240_1:
1591 case Panel_320x240_2:
1592 case Panel_320x240_3:
1593 case Panel_1280x960:
1594 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1597 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1600 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1602 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1603 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1605 /* Dual link, Pass 1:1 BIOS default, etc. */
1607 if(SiS_Pr->ChipType >= SIS_661) {
1608 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1609 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1611 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1612 if(SiS_Pr->SiS_ROMNew) {
1613 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1614 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1615 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1618 } else if(SiS_Pr->ChipType >= SIS_315H) {
1619 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1620 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1622 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1623 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1624 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1625 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1626 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1627 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1629 } else if(!(SiS_Pr->SiS_ROMNew)) {
1630 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1631 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1632 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1633 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1635 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1636 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1637 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1638 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1639 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1647 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1648 /* Always center screen on LVDS (if scaling is disabled) */
1649 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1650 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1651 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1652 /* Always center screen on SiS LVDS (if scaling is disabled) */
1653 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1655 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1656 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1657 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1661 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1662 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1664 switch(SiS_Pr->SiS_LCDResInfo) {
1665 case Panel_320x240_1:
1666 case Panel_320x240_2:
1667 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1668 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1669 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1670 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1672 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1673 SiS_Pr->PanelVRE = 3;
1674 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1675 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1677 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1678 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1679 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1680 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1681 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1682 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1684 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1685 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1686 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1687 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1688 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1689 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1691 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1692 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1693 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1694 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1695 if(SiS_Pr->ChipType < SIS_315H) {
1696 SiS_Pr->PanelHRS = 23;
1697 SiS_Pr->PanelVRE = 5;
1699 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1700 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1701 SiS_GetLCDInfoBIOS(SiS_Pr);
1703 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1704 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1705 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1706 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1707 if(SiS_Pr->ChipType < SIS_315H) {
1708 SiS_Pr->PanelHRS = 23;
1709 SiS_Pr->PanelVRE = 5;
1711 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1712 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1714 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1716 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1717 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1718 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1719 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1720 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1721 /* Data above for TMDS (projector); get from BIOS for LVDS */
1722 SiS_GetLCDInfoBIOS(SiS_Pr);
1724 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1725 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1726 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1727 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1728 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1730 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1731 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1732 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1733 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1734 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1737 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1738 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1739 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1740 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1741 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1742 SiS_GetLCDInfoBIOS(SiS_Pr);
1744 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1745 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1746 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1747 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1748 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1749 SiS_GetLCDInfoBIOS(SiS_Pr);
1751 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1752 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1753 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1754 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1755 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1756 SiS_GetLCDInfoBIOS(SiS_Pr);
1758 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1759 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1760 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1761 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1762 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1763 SiS_GetLCDInfoBIOS(SiS_Pr);
1765 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1766 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1767 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1768 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1769 if(resinfo == SIS_RI_1280x1024) {
1770 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1771 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1774 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1775 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1776 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1777 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1778 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1779 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1780 SiS_GetLCDInfoBIOS(SiS_Pr);
1782 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1783 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1784 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1785 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1786 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1787 SiS_GetLCDInfoBIOS(SiS_Pr);
1789 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1790 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1791 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1792 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1793 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1794 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1795 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1796 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1797 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1798 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1799 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1800 SiS_Pr->Alternate1600x1200 = true;
1802 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1803 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1804 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1805 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1807 SiS_GetLCDInfoBIOS(SiS_Pr);
1809 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1810 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1811 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1812 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1813 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1814 SiS_GetLCDInfoBIOS(SiS_Pr);
1816 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1817 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1819 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1820 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1822 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1823 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1825 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1826 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1827 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1828 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1829 if(SiS_Pr->CP_PreferredIndex != -1) {
1830 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1831 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1832 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1833 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1834 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1835 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1836 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1837 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1838 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1839 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1840 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1841 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1842 if(SiS_Pr->CP_PrefClock) {
1844 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1845 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1846 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1847 else idx = VCLK_CUSTOM_315;
1848 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1849 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1850 SiS_Pr->SiS_VCLKData[idx].SR2B =
1851 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1852 SiS_Pr->SiS_VCLKData[idx].SR2C =
1853 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1857 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1858 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1863 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1864 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1865 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1866 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1867 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1868 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1869 SiS_Pr->PanelHRS = 999;
1870 SiS_Pr->PanelHRE = 999;
1873 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1874 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1875 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1876 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1877 SiS_Pr->PanelVRS = 999;
1878 SiS_Pr->PanelVRE = 999;
1881 /* DontExpand overrule */
1882 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1884 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1885 /* No scaling for this mode on any panel (LCD=CRT2)*/
1886 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1889 switch(SiS_Pr->SiS_LCDResInfo) {
1892 case Panel_1152x864:
1893 case Panel_1280x768: /* TMDS only */
1894 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1897 case Panel_800x600: {
1898 static const unsigned char nonscalingmodes[] = {
1899 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1901 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1904 case Panel_1024x768: {
1905 static const unsigned char nonscalingmodes[] = {
1906 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1907 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1910 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1913 case Panel_1280x720: {
1914 static const unsigned char nonscalingmodes[] = {
1915 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1916 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1919 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1920 if(SiS_Pr->PanelHT == 1650) {
1921 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1925 case Panel_1280x768_2: { /* LVDS only */
1926 static const unsigned char nonscalingmodes[] = {
1927 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1928 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1929 SIS_RI_1152x768,0xff
1931 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1933 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1934 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1940 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1941 static const unsigned char nonscalingmodes[] = {
1942 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1943 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1944 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1946 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1949 case Panel_1280x800_2: { /* SiS LVDS */
1950 static const unsigned char nonscalingmodes[] = {
1951 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1952 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1953 SIS_RI_1152x768,0xff
1955 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1957 case SIS_RI_1280x720:
1958 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1959 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1965 case Panel_1280x854: { /* SiS LVDS */
1966 static const unsigned char nonscalingmodes[] = {
1967 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1968 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1969 SIS_RI_1152x768,0xff
1971 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1973 case SIS_RI_1280x720:
1974 case SIS_RI_1280x768:
1975 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
1976 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1982 case Panel_1280x960: {
1983 static const unsigned char nonscalingmodes[] = {
1984 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1985 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1986 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1987 SIS_RI_1280x854,0xff
1989 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1992 case Panel_1280x1024: {
1993 static const unsigned char nonscalingmodes[] = {
1994 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1995 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1996 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1997 SIS_RI_1280x854,SIS_RI_1280x960,0xff
1999 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2002 case Panel_1400x1050: {
2003 static const unsigned char nonscalingmodes[] = {
2004 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2005 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2006 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2007 SIS_RI_1280x960,0xff
2009 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2011 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2012 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2015 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2020 case Panel_1600x1200: {
2021 static const unsigned char nonscalingmodes[] = {
2022 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2023 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2024 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2025 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2027 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2030 case Panel_1680x1050: {
2031 static const unsigned char nonscalingmodes[] = {
2032 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2033 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2034 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2035 SIS_RI_1360x1024,0xff
2037 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2044 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2045 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2046 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2050 if(SiS_Pr->ChipType < SIS_315H) {
2051 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2052 if(SiS_Pr->SiS_UseROM) {
2053 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2054 if(!(ROMAddr[0x235] & 0x02)) {
2055 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2059 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2060 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2061 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2069 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2070 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2073 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2074 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2077 switch(SiS_Pr->SiS_LCDResInfo) {
2079 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2081 case Panel_1280x800:
2082 /* Don't pass 1:1 by default (TMDS special) */
2083 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2085 case Panel_1280x960:
2086 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2089 if((!SiS_Pr->CP_PrefClock) ||
2090 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2091 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2096 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2097 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2100 /* (In)validate LCDPass11 flag */
2101 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2102 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2106 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2108 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2109 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2110 if(ModeNo == 0x12) {
2111 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2112 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2114 } else if(ModeNo > 0x13) {
2115 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2116 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2117 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2118 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2126 if(modeflag & HalfDCLK) {
2127 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2128 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2129 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2130 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2131 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2132 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2133 } else if(ModeNo > 0x13) {
2134 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2135 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2136 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2137 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2145 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2146 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2147 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2150 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2153 #ifdef SIS_LINUX_KERNEL
2155 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2156 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2161 /*********************************************/
2163 /*********************************************/
2166 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2167 unsigned short RefreshRateTableIndex)
2169 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2170 unsigned short modeflag, resinfo, tempbx;
2171 const unsigned char *CHTVVCLKPtr = NULL;
2173 if(ModeNo <= 0x13) {
2174 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2175 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2176 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2177 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2178 VCLKIndexGENCRT = VCLKIndexGEN;
2180 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2181 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2182 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2183 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2184 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2185 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2188 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2190 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2193 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2195 if(SiS_Pr->ChipType < SIS_315H) {
2196 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2197 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2198 VCLKIndex = VCLKIndexGEN;
2201 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2202 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2204 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2205 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2206 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2207 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2208 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2209 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2210 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2211 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2212 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2213 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2214 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2215 default: VCLKIndex = VCLKIndexGEN;
2218 if(ModeNo <= 0x13) {
2219 if(SiS_Pr->ChipType <= SIS_315PRO) {
2220 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2222 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2225 if(SiS_Pr->ChipType <= SIS_315PRO) {
2226 if(VCLKIndex == 0) VCLKIndex = 0x41;
2227 if(VCLKIndex == 1) VCLKIndex = 0x43;
2228 if(VCLKIndex == 4) VCLKIndex = 0x44;
2233 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2235 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2236 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2237 else VCLKIndex = HiTVVCLK;
2238 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2239 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2240 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2241 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2242 else VCLKIndex = TVVCLK;
2244 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2245 else VCLKIndex += TVCLKBASE_315;
2249 VCLKIndex = VCLKIndexGENCRT;
2250 if(SiS_Pr->ChipType < SIS_315H) {
2252 if( (SiS_Pr->ChipType == SIS_630) &&
2253 (SiS_Pr->ChipRevision >= 0x30)) {
2254 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2256 /* Better VGA2 clock for 1280x1024@75 */
2257 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2262 } else { /* If not programming CRT2 */
2264 VCLKIndex = VCLKIndexGENCRT;
2265 if(SiS_Pr->ChipType < SIS_315H) {
2267 if( (SiS_Pr->ChipType != SIS_630) &&
2268 (SiS_Pr->ChipType != SIS_300) ) {
2269 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2277 VCLKIndex = CRT2Index;
2279 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2281 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2285 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2286 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2288 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2289 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2291 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2293 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2294 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2296 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2300 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2301 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2302 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2303 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2304 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2305 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2306 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2307 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2308 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2309 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2311 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2313 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2315 if(SiS_Pr->ChipType < SIS_315H) {
2316 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2318 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2322 /* Special Timing: Barco iQ Pro R series */
2323 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2325 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2326 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2327 if(SiS_Pr->ChipType < SIS_315H) {
2328 VCLKIndex = VCLK34_300;
2329 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2331 VCLKIndex = VCLK34_315;
2332 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2339 VCLKIndex = VCLKIndexGENCRT;
2340 if(SiS_Pr->ChipType < SIS_315H) {
2342 if( (SiS_Pr->ChipType == SIS_630) &&
2343 (SiS_Pr->ChipRevision >= 0x30) ) {
2344 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2350 } else { /* if not programming CRT2 */
2352 VCLKIndex = VCLKIndexGENCRT;
2353 if(SiS_Pr->ChipType < SIS_315H) {
2355 if( (SiS_Pr->ChipType != SIS_630) &&
2356 (SiS_Pr->ChipType != SIS_300) ) {
2357 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2360 if(SiS_Pr->ChipType == SIS_730) {
2361 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2362 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2375 /*********************************************/
2376 /* SET CRT2 MODE TYPE REGISTERS */
2377 /*********************************************/
2380 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2382 unsigned short i, j, modeflag, tempah=0;
2384 #if defined(SIS300) || defined(SIS315H)
2385 unsigned short tempbl;
2388 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2389 unsigned short tempah2, tempbl2;
2392 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2394 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2396 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2397 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2401 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2402 if(SiS_Pr->ChipType >= SIS_315H) {
2403 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2406 tempcl = SiS_Pr->SiS_ModeType;
2408 if(SiS_Pr->ChipType < SIS_315H) {
2410 #ifdef SIS300 /* ---- 300 series ---- */
2412 /* For 301BDH: (with LCD via LVDS) */
2413 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2414 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2417 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2421 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2427 tempah = ((0x10 >> tempcl) | 0x80);
2429 } else tempah = 0x80;
2431 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2437 #ifdef SIS315H /* ------- 315/330 series ------ */
2442 tempah = (0x08 >> tempcl);
2443 if (tempah == 0) tempah = 1;
2446 } else tempah = 0x40;
2448 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2450 #endif /* SIS315H */
2454 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2456 if(SiS_Pr->ChipType < SIS_315H) {
2457 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2460 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2461 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2462 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2464 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2466 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2472 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2475 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2478 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2480 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2485 if(SiS_Pr->ChipType < SIS_315H) {
2487 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2489 tempah = (tempah << 5) & 0xFF;
2490 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2491 tempah = (tempah >> 5) & 0xFF;
2495 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2496 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2497 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2502 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2507 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2508 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2511 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2512 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2513 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2519 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2522 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2523 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2526 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2528 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2529 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2534 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2538 if(SiS_Pr->ChipType >= SIS_315H) {
2541 /* LVDS can only be slave in 8bpp modes */
2543 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2544 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2549 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2551 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2553 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2555 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2562 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2567 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2569 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2578 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2580 if(SiS_Pr->ChipType >= SIS_315H) {
2583 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2585 /* The following is nearly unpreditable and varies from machine
2586 * to machine. Especially the 301DH seems to be a real trouble
2587 * maker. Some BIOSes simply set the registers (like in the
2588 * NoLCD-if-statements here), some set them according to the
2589 * LCDA stuff. It is very likely that some machines are not
2590 * treated correctly in the following, very case-orientated
2591 * code. What do I do then...?
2594 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2597 tempah = 0x04; /* For all bridges */
2599 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2601 if(SiS_IsDualEdge(SiS_Pr)) {
2605 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2608 /* The following two are responsible for eventually wrong colors
2609 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2610 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2611 * in a 650 box (Jake). What is the criteria?
2612 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2613 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2614 * chipset than the bridge revision.
2617 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2620 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2621 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2625 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2626 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2627 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2628 /* Fixes "TV-blue-bug" on 315+301 */
2629 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2630 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2631 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2632 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2633 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2634 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2635 tempah = 0x30; tempah2 = 0xc0;
2636 tempbl = 0xcf; tempbl2 = 0x3f;
2637 if(SiS_Pr->SiS_TVBlue == 0) {
2638 tempah = tempah2 = 0x00;
2639 } else if(SiS_Pr->SiS_TVBlue == -1) {
2640 /* Set on 651/M650, clear on 315/650 */
2641 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2642 tempah = tempah2 = 0x00;
2645 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2646 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2648 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2649 tempbl = 0xcf; tempbl2 = 0x3f;
2650 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2651 tempah = tempah2 = 0x00;
2652 if(SiS_IsDualEdge(SiS_Pr)) {
2653 tempbl = tempbl2 = 0xff;
2656 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2657 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2662 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2663 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2667 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2669 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2671 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2674 #endif /* SIS315H */
2676 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2679 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2681 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2682 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2683 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2684 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2686 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2692 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2693 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2694 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2695 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2702 if(SiS_Pr->ChipType >= SIS_315H) {
2704 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2708 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2710 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2712 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2714 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2715 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2718 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2720 } else if(SiS_Pr->ChipType == SIS_550) {
2722 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2723 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2734 /*********************************************/
2735 /* GET RESOLUTION DATA */
2736 /*********************************************/
2739 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2742 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2744 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2748 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2750 unsigned short xres, yres, modeflag=0, resindex;
2752 if(SiS_Pr->UseCustomMode) {
2753 xres = SiS_Pr->CHDisplay;
2754 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2755 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2756 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2757 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2761 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2763 if(ModeNo <= 0x13) {
2764 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2765 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2767 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2768 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2769 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2772 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2774 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2775 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2776 if(yres == 350) yres = 400;
2778 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2779 if(ModeNo == 0x12) yres = 400;
2783 if(modeflag & HalfDCLK) xres <<= 1;
2784 if(modeflag & DoubleScanMode) yres <<= 1;
2788 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2790 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2791 switch(SiS_Pr->SiS_LCDResInfo) {
2792 case Panel_1024x768:
2793 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2794 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2795 if(yres == 350) yres = 357;
2796 if(yres == 400) yres = 420;
2797 if(yres == 480) yres = 525;
2801 case Panel_1280x1024:
2802 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2803 /* BIOS bug - does this regardless of scaling */
2804 if(yres == 400) yres = 405;
2806 if(yres == 350) yres = 360;
2807 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2808 if(yres == 360) yres = 375;
2811 case Panel_1600x1200:
2812 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2813 if(yres == 1024) yres = 1056;
2821 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2822 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2823 if(xres == 720) xres = 640;
2825 } else if(xres == 720) xres = 640;
2827 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2829 if(SiS_Pr->ChipType >= SIS_315H) {
2830 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2832 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2834 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2838 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2839 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2842 /*********************************************/
2843 /* GET CRT2 TIMING DATA */
2844 /*********************************************/
2847 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2848 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2849 unsigned short *ResIndex)
2851 unsigned short tempbx=0, tempal=0, resinfo=0;
2853 if(ModeNo <= 0x13) {
2854 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2856 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2857 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2860 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2862 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2864 tempbx = SiS_Pr->SiS_LCDResInfo;
2865 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2868 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2869 if (resinfo == SIS_RI_1280x800) tempal = 9;
2870 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2871 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2872 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2873 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2874 if (resinfo == SIS_RI_1280x768) tempal = 9;
2877 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2878 /* Pass 1:1 only (center-screen handled outside) */
2879 /* This is never called for the panel's native resolution */
2880 /* since Pass1:1 will not be set in this case */
2882 if(ModeNo >= 0x13) {
2883 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2888 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2889 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2890 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2892 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2900 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2901 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2903 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2905 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2907 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2908 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2909 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2911 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2913 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2915 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2923 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2925 case SIS_RI_720x480:
2927 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
2929 case SIS_RI_720x576:
2930 case SIS_RI_768x576:
2931 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2933 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2934 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
2937 case SIS_RI_800x480:
2940 case SIS_RI_512x384:
2941 case SIS_RI_1024x768:
2943 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2944 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
2947 case SIS_RI_1280x720:
2948 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2949 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
2956 *CRT2Index = tempbx;
2959 } else { /* LVDS, 301B-DH (if running on LCD) */
2962 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2965 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2967 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2968 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2970 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
2971 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
2974 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
2979 switch(SiS_Pr->SiS_LCDResInfo) {
2980 case Panel_640x480: tempbx = 12; break;
2981 case Panel_320x240_1: tempbx = 10; break;
2982 case Panel_320x240_2:
2983 case Panel_320x240_3: tempbx = 14; break;
2984 case Panel_800x600: tempbx = 16; break;
2985 case Panel_1024x600: tempbx = 18; break;
2986 case Panel_1152x768:
2987 case Panel_1024x768: tempbx = 20; break;
2988 case Panel_1280x768: tempbx = 22; break;
2989 case Panel_1280x1024: tempbx = 24; break;
2990 case Panel_1400x1050: tempbx = 26; break;
2991 case Panel_1600x1200: tempbx = 28; break;
2993 case Panel_Barco1366: tempbx = 80; break;
2997 switch(SiS_Pr->SiS_LCDResInfo) {
2998 case Panel_320x240_1:
2999 case Panel_320x240_2:
3000 case Panel_320x240_3:
3004 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3007 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3010 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3012 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3013 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3015 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3021 (*CRT2Index) = tempbx;
3022 (*ResIndex) = tempal & 0x1F;
3027 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3028 unsigned short RefreshRateTableIndex)
3030 unsigned short tempax=0, tempbx=0, index, dotclock;
3031 unsigned short temp1=0, modeflag=0, tempcx=0;
3033 SiS_Pr->SiS_RVBHCMAX = 1;
3034 SiS_Pr->SiS_RVBHCFACT = 1;
3036 if(ModeNo <= 0x13) {
3038 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3039 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3041 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3042 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3043 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3045 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3049 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3050 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3052 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3053 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3055 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3056 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3060 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3066 if(temp1 & 0x01) tempbx |= 0x0100;
3067 if(temp1 & 0x20) tempbx |= 0x0200;
3071 if(modeflag & HalfDCLK) tempax <<= 1;
3075 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3076 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3080 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3081 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3083 unsigned short ResIndex;
3085 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3086 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3087 if(SiS_Pr->UseCustomMode) {
3088 ResIndex = SiS_Pr->CHTotal;
3089 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3090 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3091 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3094 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3096 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3098 if(ResIndex == 0x09) {
3099 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3100 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3102 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3103 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3104 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3105 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3108 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3109 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3112 /* This handles custom modes and custom panels */
3113 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3114 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3115 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3116 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3117 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3118 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3123 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3124 unsigned short RefreshRateTableIndex)
3126 unsigned short CRT2Index, ResIndex, backup;
3127 const struct SiS_LVDSData *LVDSData = NULL;
3129 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3131 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3132 SiS_Pr->SiS_RVBHCMAX = 1;
3133 SiS_Pr->SiS_RVBHCFACT = 1;
3134 SiS_Pr->SiS_NewFlickerMode = 0;
3135 SiS_Pr->SiS_RVBHRS = 50;
3136 SiS_Pr->SiS_RY1COE = 0;
3137 SiS_Pr->SiS_RY2COE = 0;
3138 SiS_Pr->SiS_RY3COE = 0;
3139 SiS_Pr->SiS_RY4COE = 0;
3140 SiS_Pr->SiS_RVBHRS2 = 0;
3143 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3146 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3147 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3152 /* 301BDH needs LVDS Data */
3153 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3154 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3155 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3158 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3159 &CRT2Index, &ResIndex);
3161 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3164 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3165 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3166 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3167 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3168 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3169 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3171 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3172 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3173 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3174 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3175 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3177 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3178 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3179 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3180 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3181 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3182 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3183 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3184 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3185 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3189 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3190 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3191 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3192 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3194 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3197 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3198 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3199 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3200 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3201 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3202 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3203 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3205 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3206 if(ResIndex < 0x08) {
3207 SiS_Pr->SiS_HDE = 1280;
3208 SiS_Pr->SiS_VDE = 1024;
3218 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3219 unsigned short RefreshRateTableIndex)
3221 unsigned char *ROMAddr = NULL;
3222 unsigned short tempax, tempbx, modeflag, romptr=0;
3223 unsigned short resinfo, CRT2Index, ResIndex;
3224 const struct SiS_LCDData *LCDPtr = NULL;
3225 const struct SiS_TVData *TVPtr = NULL;
3230 if(ModeNo <= 0x13) {
3231 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3232 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3233 } else if(SiS_Pr->UseCustomMode) {
3234 modeflag = SiS_Pr->CModeFlag;
3237 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3238 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3240 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3241 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3242 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3243 (resinfo661 >= 0) &&
3244 (SiS_Pr->SiS_NeedRomModeData) ) {
3245 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3246 if((romptr = (SISGETROMW(21)))) {
3247 romptr += (resinfo661 * 10);
3248 ROMAddr = SiS_Pr->VirtualRomBase;
3255 SiS_Pr->SiS_NewFlickerMode = 0;
3256 SiS_Pr->SiS_RVBHRS = 50;
3257 SiS_Pr->SiS_RY1COE = 0;
3258 SiS_Pr->SiS_RY2COE = 0;
3259 SiS_Pr->SiS_RY3COE = 0;
3260 SiS_Pr->SiS_RY4COE = 0;
3261 SiS_Pr->SiS_RVBHRS2 = 0;
3263 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3265 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3267 if(SiS_Pr->UseCustomMode) {
3269 SiS_Pr->SiS_RVBHCMAX = 1;
3270 SiS_Pr->SiS_RVBHCFACT = 1;
3271 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3272 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3274 tempax = SiS_Pr->CHTotal;
3275 if(modeflag & HalfDCLK) tempax <<= 1;
3276 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3277 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3281 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3285 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3287 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3288 &CRT2Index,&ResIndex);
3291 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3292 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3293 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3294 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3295 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3296 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3297 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3298 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3299 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3300 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3301 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3302 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3303 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3304 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3307 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3308 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3309 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3310 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3311 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3312 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3313 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3314 if(modeflag & HalfDCLK) {
3315 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3316 if(SiS_Pr->SiS_RVBHRS2) {
3317 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3318 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3319 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3320 else SiS_Pr->SiS_RVBHRS2 += tempax;
3323 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3325 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3327 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3329 if((resinfo == SIS_RI_960x600) ||
3330 (resinfo == SIS_RI_1024x768) ||
3331 (resinfo == SIS_RI_1280x1024) ||
3332 (resinfo == SIS_RI_1280x720)) {
3333 SiS_Pr->SiS_NewFlickerMode = 0x40;
3336 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3338 SiS_Pr->SiS_HT = ExtHiTVHT;
3339 SiS_Pr->SiS_VT = ExtHiTVVT;
3340 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3341 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3342 SiS_Pr->SiS_HT = StHiTVHT;
3343 SiS_Pr->SiS_VT = StHiTVVT;
3347 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3349 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3350 SiS_Pr->SiS_HT = 1650;
3351 SiS_Pr->SiS_VT = 750;
3352 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3353 SiS_Pr->SiS_HT = NTSCHT;
3354 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3355 SiS_Pr->SiS_VT = NTSCVT;
3357 SiS_Pr->SiS_HT = NTSCHT;
3358 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3359 SiS_Pr->SiS_VT = NTSCVT;
3364 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3365 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3366 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3367 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3369 if(modeflag & HalfDCLK) {
3370 SiS_Pr->SiS_RY1COE = 0x00;
3371 SiS_Pr->SiS_RY2COE = 0xf4;
3372 SiS_Pr->SiS_RY3COE = 0x10;
3373 SiS_Pr->SiS_RY4COE = 0x38;
3376 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3377 SiS_Pr->SiS_HT = NTSCHT;
3378 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3379 SiS_Pr->SiS_VT = NTSCVT;
3381 SiS_Pr->SiS_HT = PALHT;
3382 SiS_Pr->SiS_VT = PALVT;
3387 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3389 SiS_Pr->SiS_RVBHCMAX = 1;
3390 SiS_Pr->SiS_RVBHCFACT = 1;
3392 if(SiS_Pr->UseCustomMode) {
3394 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3395 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3397 tempax = SiS_Pr->CHTotal;
3398 if(modeflag & HalfDCLK) tempax <<= 1;
3399 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3400 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3406 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3408 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3409 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3410 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3411 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3414 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3417 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3418 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3419 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3420 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3421 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3422 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3423 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3424 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3425 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3426 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3427 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3428 else SiS_Pr->SiS_RVBHRS2 += tempax;
3430 if(SiS_Pr->SiS_VGAHT) gotit = true;
3432 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3433 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3434 SiS_Pr->SiS_RVBHCMAX = 1;
3435 SiS_Pr->SiS_RVBHCFACT = 1;
3436 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3437 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3438 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3439 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3440 SiS_Pr->SiS_RVBHRS2 = 0;
3449 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3450 &CRT2Index,&ResIndex);
3453 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3454 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3455 case Panel_1280x720 :
3456 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3457 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3458 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3459 case Panel_1280x800 :
3460 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3461 case Panel_1280x800_2 :
3462 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3463 case Panel_1280x854 :
3464 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3465 case Panel_1280x960 :
3466 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3467 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3468 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3469 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3470 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3471 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3472 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3473 case Panel_1680x1050 :
3474 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3475 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3477 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3478 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3480 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3483 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3484 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3485 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3486 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3487 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3488 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3492 tempax = SiS_Pr->PanelXRes;
3493 tempbx = SiS_Pr->PanelYRes;
3495 switch(SiS_Pr->SiS_LCDResInfo) {
3496 case Panel_1024x768:
3497 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3498 if(SiS_Pr->ChipType < SIS_315H) {
3499 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3500 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3503 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3504 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3505 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3506 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3507 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3508 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3511 case Panel_1280x960:
3512 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3513 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3514 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3516 case Panel_1280x1024:
3517 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3518 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3519 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3521 case Panel_1600x1200:
3522 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3523 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3524 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3529 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3530 tempax = SiS_Pr->SiS_VGAHDE;
3531 tempbx = SiS_Pr->SiS_VGAVDE;
3534 SiS_Pr->SiS_HDE = tempax;
3535 SiS_Pr->SiS_VDE = tempbx;
3541 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3542 unsigned short RefreshRateTableIndex)
3545 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3547 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3548 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3550 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3551 /* Need LVDS Data for LCD on 301B-DH */
3552 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3554 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3560 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3565 /*********************************************/
3566 /* GET LVDS DES (SKEW) DATA */
3567 /*********************************************/
3569 static const struct SiS_LVDSDes *
3570 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3572 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3575 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3577 if(SiS_Pr->ChipType < SIS_315H) {
3578 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3579 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3580 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3581 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3582 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3584 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3585 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3586 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3587 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3598 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3599 unsigned short RefreshRateTableIndex)
3601 unsigned short modeflag, ResIndex;
3602 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3604 SiS_Pr->SiS_LCDHDES = 0;
3605 SiS_Pr->SiS_LCDVDES = 0;
3607 /* Some special cases */
3608 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3611 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3612 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3613 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3614 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3620 /* 640x480 on LVDS */
3621 if(SiS_Pr->ChipType < SIS_315H) {
3622 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3623 SiS_Pr->SiS_LCDHDES = 8;
3624 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3625 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3626 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3633 if( (SiS_Pr->UseCustomMode) ||
3634 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3635 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3636 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3637 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3641 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3642 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3644 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3647 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3648 /* non-pass 1:1 only, see above */
3649 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3650 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3652 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3653 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3656 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3657 switch(SiS_Pr->SiS_CustomT) {
3658 case CUT_UNIWILL1024:
3659 case CUT_UNIWILL10242:
3661 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3662 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3666 switch(SiS_Pr->SiS_LCDResInfo) {
3667 case Panel_1280x1024:
3668 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3669 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3672 case Panel_1280x800: /* Verified for Averatec 6240 */
3673 case Panel_1280x800_2: /* Verified for Asus A4L */
3674 case Panel_1280x854: /* Not verified yet FIXME */
3675 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3683 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3685 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3686 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3689 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3691 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3692 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3694 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3696 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3697 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3699 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3700 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3702 if(SiS_Pr->ChipType < SIS_315H) {
3703 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3705 switch(SiS_Pr->SiS_LCDResInfo) {
3707 case Panel_1024x768:
3708 case Panel_1280x1024:
3709 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3711 case Panel_1400x1050:
3712 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3720 if(SiS_Pr->ChipType < SIS_315H) {
3722 switch(SiS_Pr->SiS_LCDResInfo) {
3724 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3725 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3727 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3728 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3729 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3730 else SiS_Pr->SiS_LCDVDES -= 4;
3733 case Panel_1024x768:
3734 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3735 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3737 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3738 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3739 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3742 case Panel_1024x600:
3744 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3745 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3746 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3748 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3753 switch(SiS_Pr->SiS_LCDTypeInfo) {
3755 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3757 case 3: /* 640x480 only? */
3758 SiS_Pr->SiS_LCDHDES = 8;
3759 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3760 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3761 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3767 switch(SiS_Pr->SiS_LCDResInfo) {
3768 case Panel_1024x768:
3769 case Panel_1280x1024:
3770 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3771 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3774 case Panel_320x240_1:
3775 case Panel_320x240_2:
3776 case Panel_320x240_3:
3777 SiS_Pr->SiS_LCDVDES = 524;
3784 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3785 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3786 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3787 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3788 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3789 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3790 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3791 if(SiS_Pr->ChipType < SIS_315H) {
3792 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3795 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3796 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3797 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3798 if(!(modeflag & HalfDCLK)) {
3799 SiS_Pr->SiS_LCDHDES = 320;
3800 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3801 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3812 /*********************************************/
3813 /* DISABLE VIDEO BRIDGE */
3814 /*********************************************/
3818 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3822 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3823 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3824 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3825 unsigned short temp;
3827 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3829 (SiS_Pr->SiS_PWDOffset) ) {
3830 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3831 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3832 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3833 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3834 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3836 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3840 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3847 /* NEVER use any variables (VBInfo), this will be called
3848 * from outside the context of modeswitch!
3849 * MUST call getVBType before calling this
3852 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3855 unsigned short tempah, pushax=0, modenum;
3857 unsigned short temp=0;
3859 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3861 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3863 if(SiS_Pr->ChipType < SIS_315H) {
3865 #ifdef SIS300 /* 300 series */
3867 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3868 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3869 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3871 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3873 SiS_PanelDelay(SiS_Pr, 3);
3875 if(SiS_Is301B(SiS_Pr)) {
3876 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3877 SiS_ShortDelay(SiS_Pr,1);
3879 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3880 SiS_DisplayOff(SiS_Pr);
3881 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3882 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3883 SiS_UnLockCRT2(SiS_Pr);
3884 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3885 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3886 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3888 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3889 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3890 SiS_PanelDelay(SiS_Pr, 2);
3891 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3892 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3894 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3902 #ifdef SIS315H /* 315 series */
3905 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3906 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
3908 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3910 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3913 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3914 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3915 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3920 didpwd = SiS_HandlePWD(SiS_Pr);
3922 if( (modenum <= 0x13) ||
3923 (SiS_IsVAMode(SiS_Pr)) ||
3924 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3926 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3927 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3929 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3934 SiS_DDC2Delay(SiS_Pr,0xff00);
3935 SiS_DDC2Delay(SiS_Pr,0xe000);
3936 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3937 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3939 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3941 SiS_PanelDelay(SiS_Pr, 3);
3946 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
3947 /* if(SiS_Pr->ChipType < SIS_340) {*/
3949 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
3950 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3954 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3955 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3959 if(SiS_IsDualEdge(SiS_Pr)) {
3961 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
3963 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3965 if((SiS_IsVAMode(SiS_Pr)) ||
3966 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3968 SiS_DisplayOff(SiS_Pr);
3969 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3970 SiS_PanelDelay(SiS_Pr, 2);
3972 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3973 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3977 if((!(SiS_IsVAMode(SiS_Pr))) ||
3978 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3980 if(!(SiS_IsDualEdge(SiS_Pr))) {
3981 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3982 SiS_DisplayOff(SiS_Pr);
3984 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3986 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3987 SiS_PanelDelay(SiS_Pr, 2);
3990 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3991 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3992 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3993 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3994 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3998 if(SiS_IsNotM650orLater(SiS_Pr)) {
3999 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4002 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4004 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4005 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4006 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4008 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4010 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4012 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4016 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4017 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4018 if(SiS_IsVAorLCD(SiS_Pr)) {
4019 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4026 #endif /* SIS315H */
4030 } else { /* ============ For 301 ================ */
4032 if(SiS_Pr->ChipType < SIS_315H) {
4034 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4035 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4036 SiS_PanelDelay(SiS_Pr, 3);
4041 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4042 SiS_DisplayOff(SiS_Pr);
4044 if(SiS_Pr->ChipType >= SIS_315H) {
4045 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4048 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4050 if(SiS_Pr->ChipType >= SIS_315H) {
4051 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4052 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4053 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4054 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4057 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4058 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4059 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4060 SiS_PanelDelay(SiS_Pr, 2);
4061 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4068 } else { /* ============ For LVDS =============*/
4070 if(SiS_Pr->ChipType < SIS_315H) {
4072 #ifdef SIS300 /* 300 series */
4074 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4075 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4078 if(SiS_Pr->ChipType == SIS_730) {
4079 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4080 SiS_WaitVBRetrace(SiS_Pr);
4082 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4083 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4084 SiS_PanelDelay(SiS_Pr, 3);
4087 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4088 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4089 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4090 SiS_WaitVBRetrace(SiS_Pr);
4091 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4092 SiS_DisplayOff(SiS_Pr);
4094 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4095 SiS_PanelDelay(SiS_Pr, 3);
4101 SiS_DisplayOff(SiS_Pr);
4103 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4105 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4106 SiS_UnLockCRT2(SiS_Pr);
4107 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4108 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4110 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4111 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4112 SiS_PanelDelay(SiS_Pr, 2);
4113 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4120 #ifdef SIS315H /* 315 series */
4122 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4123 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4124 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4128 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4130 if(SiS_Pr->ChipType == SIS_740) {
4131 temp = SiS_GetCH701x(SiS_Pr,0x61);
4133 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4134 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4137 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4138 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4139 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4143 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4144 (SiS_IsVAMode(SiS_Pr)) ) {
4145 SiS_Chrontel701xBLOff(SiS_Pr);
4146 SiS_Chrontel701xOff(SiS_Pr);
4149 if(SiS_Pr->ChipType != SIS_740) {
4150 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4151 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4152 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4158 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4159 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4160 SiS_PanelDelay(SiS_Pr, 3);
4163 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4164 (!(SiS_IsDualEdge(SiS_Pr))) ||
4165 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4166 SiS_DisplayOff(SiS_Pr);
4169 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4170 (!(SiS_IsDualEdge(SiS_Pr))) ||
4171 (!(SiS_IsVAMode(SiS_Pr))) ) {
4172 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4175 if(SiS_Pr->ChipType == SIS_740) {
4176 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4179 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4181 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4182 (!(SiS_IsDualEdge(SiS_Pr))) ||
4183 (!(SiS_IsVAMode(SiS_Pr))) ) {
4184 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4187 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4188 if(SiS_CRT2IsLCD(SiS_Pr)) {
4189 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4190 if(SiS_Pr->ChipType == SIS_550) {
4191 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4192 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4196 if(SiS_Pr->ChipType == SIS_740) {
4197 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4198 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4200 } else if(SiS_IsVAMode(SiS_Pr)) {
4201 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4205 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4206 if(SiS_IsDualEdge(SiS_Pr)) {
4207 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4209 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4213 SiS_UnLockCRT2(SiS_Pr);
4215 if(SiS_Pr->ChipType == SIS_550) {
4216 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4217 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4218 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4219 (!(SiS_IsDualEdge(SiS_Pr))) ||
4220 (!(SiS_IsVAMode(SiS_Pr))) ) {
4221 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4224 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4225 if(SiS_CRT2IsLCD(SiS_Pr)) {
4226 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4227 SiS_PanelDelay(SiS_Pr, 2);
4228 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4233 #endif /* SIS315H */
4241 /*********************************************/
4242 /* ENABLE VIDEO BRIDGE */
4243 /*********************************************/
4245 /* NEVER use any variables (VBInfo), this will be called
4246 * from outside the context of a mode switch!
4247 * MUST call getVBType before calling this
4249 #ifdef SIS_LINUX_KERNEL
4253 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4255 unsigned short temp=0, tempah;
4257 unsigned short temp1, pushax=0;
4258 bool delaylong = false;
4261 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4263 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4265 if(SiS_Pr->ChipType < SIS_315H) {
4267 #ifdef SIS300 /* 300 series */
4269 if(SiS_CRT2IsLCD(SiS_Pr)) {
4270 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4271 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4272 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4273 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4275 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4276 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4277 SiS_PanelDelay(SiS_Pr, 0);
4282 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4283 (SiS_CRT2IsLCD(SiS_Pr))) {
4285 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4286 SiS_DisplayOn(SiS_Pr);
4287 SiS_UnLockCRT2(SiS_Pr);
4288 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4289 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4290 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4292 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4294 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4295 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4296 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4297 SiS_PanelDelay(SiS_Pr, 1);
4299 SiS_WaitVBRetrace(SiS_Pr);
4300 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4306 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4307 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4308 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4309 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4311 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4312 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4313 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4314 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4315 SiS_DisplayOn(SiS_Pr);
4316 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4317 if(SiS_CRT2IsLCD(SiS_Pr)) {
4318 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4319 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4320 SiS_PanelDelay(SiS_Pr, 1);
4322 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4334 #ifdef SIS315H /* 315 series */
4337 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4339 /* unsigned short emidelay=0; */
4342 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4343 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4345 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4346 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4351 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4352 /*if(SiS_Pr->ChipType < SIS_340) { */
4354 if(SiS_LCDAEnabled(SiS_Pr)) {
4355 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4358 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4362 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4364 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4365 SiS_DisplayOff(SiS_Pr);
4366 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4368 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4371 didpwd = SiS_HandlePWD(SiS_Pr);
4373 if(SiS_IsVAorLCD(SiS_Pr)) {
4375 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4376 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4377 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4378 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4379 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4380 SiS_GenericDelay(SiS_Pr, 17664);
4384 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4385 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4386 SiS_GenericDelay(SiS_Pr, 17664);
4391 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4392 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4398 if(!(SiS_IsVAMode(SiS_Pr))) {
4400 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4401 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4402 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4403 if(!(tempah & SetCRT2ToRAMDAC)) {
4404 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4407 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4409 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4411 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4412 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4414 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4415 SiS_PanelDelay(SiS_Pr, 2);
4420 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4424 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4425 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4427 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4428 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4429 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4430 /* Enable "LVDS PLL power on" (even on 301C) */
4431 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4432 /* Enable "LVDS Driver Power on" (even on 301C) */
4433 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4438 if(SiS_IsDualEdge(SiS_Pr)) {
4440 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4442 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4444 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4446 SiS_PanelDelay(SiS_Pr, 2);
4448 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4449 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4451 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4453 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4454 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4455 SiS_GenericDelay(SiS_Pr, 2048);
4458 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4460 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4462 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4464 if(SiS_Pr->SiS_ROMNew) {
4465 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4466 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4468 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4470 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4471 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4472 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4473 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4474 /* emidelay = SISGETROMW((romptr + 0x22)); */
4475 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4480 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4481 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4482 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4483 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4484 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4485 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4486 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4487 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4488 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4490 if(SiS_Pr->HaveEMI) {
4491 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4492 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4497 /* EMI_30 is read at driver start; however, the BIOS sets this
4498 * (if it is used) only if the LCD is in use. In case we caught
4499 * the machine while on TV output, this bit is not set and we
4500 * don't know if it should be set - hence our detection is wrong.
4501 * Work-around this here:
4504 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4505 switch((cr36 & 0x0f)) {
4508 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4509 if(!SiS_Pr->HaveEMI) {
4510 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4511 if((cr36 & 0xf0) == 0x30) {
4512 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4516 case 3: /* 1280x1024 */
4517 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4518 if(!SiS_Pr->HaveEMI) {
4519 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4520 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4521 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4525 case 9: /* 1400x1050 */
4527 if(!SiS_Pr->HaveEMI) {
4528 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4529 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4530 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4534 case 11: /* 1600x1200 - unknown */
4536 if(!SiS_Pr->HaveEMI) {
4537 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4542 /* BIOS values don't work so well sometimes */
4543 if(!SiS_Pr->OverruleEMI) {
4545 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4546 if((cr36 & 0x0f) == 0x09) {
4547 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4552 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4553 if((cr36 & 0x0f) == 0x03) {
4554 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4559 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4560 if((cr36 & 0x0f) == 0x02) {
4561 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4562 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4563 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4564 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4570 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4571 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4572 SiS_GenericDelay(SiS_Pr, 2048);
4574 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4575 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4576 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4577 #endif /* SET_EMI */
4579 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4582 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4583 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4585 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4586 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4588 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4591 SiS_WaitVBRetrace(SiS_Pr);
4592 SiS_WaitVBRetrace(SiS_Pr);
4593 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4594 SiS_GenericDelay(SiS_Pr, 1280);
4596 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4597 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4604 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4605 if(SiS_IsVAorLCD(SiS_Pr)) {
4606 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4608 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4610 SiS_WaitVBRetrace(SiS_Pr);
4611 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4612 SiS_GenericDelay(SiS_Pr, 2048);
4613 SiS_WaitVBRetrace(SiS_Pr);
4616 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4618 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4623 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4624 SiS_DisplayOn(SiS_Pr);
4625 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4629 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4630 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4633 #endif /* SIS315H */
4637 } else { /* ============ For 301 ================ */
4639 if(SiS_Pr->ChipType < SIS_315H) {
4640 if(SiS_CRT2IsLCD(SiS_Pr)) {
4641 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4642 SiS_PanelDelay(SiS_Pr, 0);
4646 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4647 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4648 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4649 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4651 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4653 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4655 if(SiS_Pr->ChipType >= SIS_315H) {
4656 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4657 if(!(temp & 0x80)) {
4658 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4662 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4664 SiS_VBLongWait(SiS_Pr);
4665 SiS_DisplayOn(SiS_Pr);
4666 if(SiS_Pr->ChipType >= SIS_315H) {
4667 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4669 SiS_VBLongWait(SiS_Pr);
4671 if(SiS_Pr->ChipType < SIS_315H) {
4672 if(SiS_CRT2IsLCD(SiS_Pr)) {
4673 SiS_PanelDelay(SiS_Pr, 1);
4674 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4680 } else { /* =================== For LVDS ================== */
4682 if(SiS_Pr->ChipType < SIS_315H) {
4684 #ifdef SIS300 /* 300 series */
4686 if(SiS_CRT2IsLCD(SiS_Pr)) {
4687 if(SiS_Pr->ChipType == SIS_730) {
4688 SiS_PanelDelay(SiS_Pr, 1);
4689 SiS_PanelDelay(SiS_Pr, 1);
4690 SiS_PanelDelay(SiS_Pr, 1);
4692 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4693 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4694 SiS_PanelDelay(SiS_Pr, 0);
4698 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4699 SiS_DisplayOn(SiS_Pr);
4700 SiS_UnLockCRT2(SiS_Pr);
4701 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4702 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4703 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4705 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4708 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4709 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4710 SiS_WaitVBRetrace(SiS_Pr);
4711 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4715 if(SiS_CRT2IsLCD(SiS_Pr)) {
4716 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4717 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4718 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4719 SiS_PanelDelay(SiS_Pr, 1);
4720 SiS_PanelDelay(SiS_Pr, 1);
4722 SiS_WaitVBRetrace(SiS_Pr);
4723 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4732 #ifdef SIS315H /* 315 series */
4734 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4735 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4736 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4740 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4741 if(SiS_CRT2IsLCD(SiS_Pr)) {
4742 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4743 SiS_PanelDelay(SiS_Pr, 0);
4747 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4748 SiS_UnLockCRT2(SiS_Pr);
4750 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4752 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4753 temp = SiS_GetCH701x(SiS_Pr,0x66);
4755 SiS_Chrontel701xBLOff(SiS_Pr);
4758 if(SiS_Pr->ChipType != SIS_550) {
4759 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4762 if(SiS_Pr->ChipType == SIS_740) {
4763 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4764 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4765 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4770 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4771 if(!(temp1 & 0x80)) {
4772 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4775 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4777 SiS_Chrontel701xBLOn(SiS_Pr);
4781 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4782 if(SiS_CRT2IsLCD(SiS_Pr)) {
4783 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4784 if(SiS_Pr->ChipType == SIS_550) {
4785 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4786 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4789 } else if(SiS_IsVAMode(SiS_Pr)) {
4790 if(SiS_Pr->ChipType != SIS_740) {
4791 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4795 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4796 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4799 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4800 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4801 SiS_Chrontel701xOn(SiS_Pr);
4803 if( (SiS_IsVAMode(SiS_Pr)) ||
4804 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4805 SiS_ChrontelDoSomething1(SiS_Pr);
4809 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4810 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4811 if( (SiS_IsVAMode(SiS_Pr)) ||
4812 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4813 SiS_Chrontel701xBLOn(SiS_Pr);
4814 SiS_ChrontelInitTVVSync(SiS_Pr);
4817 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4818 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4819 if(SiS_CRT2IsLCD(SiS_Pr)) {
4820 SiS_PanelDelay(SiS_Pr, 1);
4821 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4826 #endif /* SIS315H */
4834 /*********************************************/
4835 /* SET PART 1 REGISTER GROUP */
4836 /*********************************************/
4838 /* Set CRT2 OFFSET / PITCH */
4840 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4841 unsigned short RRTI)
4843 unsigned short offset;
4846 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4848 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4850 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4851 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4853 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4854 if(offset & 0x07) temp++;
4855 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4858 /* Set CRT2 sync and PanelLink mode */
4860 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4862 unsigned short tempah=0, tempbl, infoflag;
4866 if(SiS_Pr->UseCustomMode) {
4867 infoflag = SiS_Pr->CInfoFlag;
4869 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4872 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4876 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4877 tempah = SiS_Pr->SiS_LCDInfo;
4878 } else tempah = infoflag >> 8;
4881 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4882 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4883 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4884 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4887 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4888 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4889 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4890 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4891 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4894 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4895 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4899 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4900 if(SiS_Pr->ChipType >= SIS_315H) {
4903 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4904 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4906 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4909 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4912 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4914 if(SiS_Pr->ChipType < SIS_315H) {
4916 #ifdef SIS300 /* ---- 300 series --- */
4918 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4920 tempah = infoflag >> 8;
4922 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4923 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4924 tempah = SiS_Pr->SiS_LCDInfo;
4925 tempbl = (tempah >> 6) & 0x03;
4930 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4932 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4933 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4934 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4937 } else { /* 630 - 301 */
4939 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4940 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4941 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4949 #ifdef SIS315H /* ------- 315 series ------ */
4951 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
4954 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4955 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4956 tempah = infoflag >> 8;
4957 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4958 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4960 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4961 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4962 tempah = infoflag >> 8;
4965 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4966 tempbl = (tempah >> 6) & 0x03;
4968 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4972 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4973 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4974 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4975 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4976 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4977 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4981 } else { /* 315 - TMDS */
4983 tempah = tempbl = infoflag >> 8;
4984 if(!SiS_Pr->UseCustomMode) {
4986 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4987 if(ModeNo <= 0x13) {
4988 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4991 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4992 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4993 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4994 tempah = SiS_Pr->SiS_LCDInfo;
4995 tempbl = (tempah >> 6) & 0x03;
5002 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5003 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5004 /* Imitate BIOS bug */
5005 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5007 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5010 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5012 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5013 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5014 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5015 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5021 #endif /* SIS315H */
5026 /* Set CRT2 FIFO on 300/540/630/730 */
5029 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5031 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5032 unsigned short temp, index, modeidindex, refreshratetableindex;
5033 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5034 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5035 unsigned int data, pci50, pciA0;
5036 static const unsigned char colortharray[] = {
5040 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5042 if(!SiS_Pr->CRT1UsesCustomMode) {
5044 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5045 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5046 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5047 SiS_Pr->SiS_SelectCRT2Rate = 0;
5048 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5050 if(CRT1ModeNo >= 0x13) {
5052 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5053 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5055 /* Get colordepth */
5056 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5057 if(!colorth) colorth++;
5065 VCLK = SiS_Pr->CSRClock_CRT1;
5067 /* Get color depth */
5068 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5072 if(CRT1ModeNo >= 0x13) {
5074 if(SiS_Pr->ChipType == SIS_300) {
5075 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5077 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5080 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5082 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5086 data2 = temp - ((colorth * VCLK) / MCLK);
5088 temp = (28 * 16) % data2;
5089 data2 = (28 * 16) / data2;
5092 if(SiS_Pr->ChipType == SIS_300) {
5094 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5095 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5099 #ifdef SIS_LINUX_KERNEL
5100 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5101 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5103 pci50 = pciReadLong(0x00000000, 0x50);
5104 pciA0 = pciReadLong(0x00000000, 0xA0);
5107 if(SiS_Pr->ChipType == SIS_730) {
5109 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5110 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5112 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5113 index = 0; /* -- do it like the BIOS anyway... */
5120 index = (pci50 >> 1) & 0x07;
5122 if(pci50 & 0x01) index += 6;
5123 if(!(pciA0 & 0x01)) index += 24;
5125 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5129 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5130 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5134 data += data2; /* CRT1 Request Period */
5136 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5137 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5139 if(!SiS_Pr->UseCustomMode) {
5141 CRT2ModeNo = ModeNo;
5142 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5144 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5147 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5148 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5150 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5151 if(SiS_Pr->SiS_UseROM) {
5152 if(ROMAddr[0x220] & 0x01) {
5153 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5162 VCLK = SiS_Pr->CSRClock;
5166 /* Get colordepth */
5167 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5168 if(!colorth) colorth++;
5170 data = data * VCLK * colorth;
5171 temp = data % (MCLK << 4);
5172 data = data / (MCLK << 4);
5175 if(data < 6) data = 6;
5176 else if(data > 0x14) data = 0x14;
5178 if(SiS_Pr->ChipType == SIS_300) {
5180 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5184 if(( (SiS_Pr->ChipType == SIS_630) ||
5185 (SiS_Pr->ChipType == SIS_730) ) &&
5186 (SiS_Pr->ChipRevision >= 0x30))
5189 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5191 if((SiS_Pr->ChipType == SIS_630) &&
5192 (SiS_Pr->ChipRevision >= 0x30)) {
5193 if(data > 0x13) data = 0x13;
5195 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5197 } else { /* If mode <= 0x13, we just restore everything */
5199 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5200 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5206 /* Set CRT2 FIFO on 315/330 series */
5209 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5211 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5212 if( (SiS_Pr->ChipType == SIS_760) &&
5213 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5214 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5215 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5216 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5217 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5218 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5219 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5220 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5221 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5222 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5224 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5230 static unsigned short
5231 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5233 unsigned int tempax,tempbx;
5235 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5236 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5237 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5238 return (unsigned short)tempax;
5241 /* Set Part 1 / SiS bridge slave mode */
5243 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5244 unsigned short RefreshRateTableIndex)
5246 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5247 static const unsigned short CRTranslation[] = {
5248 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5249 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5250 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5251 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5252 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5253 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5256 if(ModeNo <= 0x13) {
5257 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5258 } else if(SiS_Pr->UseCustomMode) {
5259 modeflag = SiS_Pr->CModeFlag;
5260 xres = SiS_Pr->CHDisplay;
5262 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5263 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5266 /* The following is only done if bridge is in slave mode: */
5268 if(SiS_Pr->ChipType >= SIS_315H) {
5269 if(xres >= 1600) { /* BIOS: == 1600 */
5270 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5274 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5276 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5277 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5279 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5280 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5281 SiS_Pr->CHBlankStart += 16;
5284 SiS_Pr->CHBlankEnd = 32;
5285 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5286 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5289 temp = SiS_Pr->SiS_VGAHT - 96;
5290 if(!(modeflag & HalfDCLK)) temp -= 32;
5291 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5292 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5293 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5297 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5299 SiS_Pr->CHSyncStart = temp;
5301 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5303 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5305 VGAVDE = SiS_Pr->SiS_VGAVDE;
5306 if (VGAVDE == 357) VGAVDE = 350;
5307 else if(VGAVDE == 360) VGAVDE = 350;
5308 else if(VGAVDE == 375) VGAVDE = 350;
5309 else if(VGAVDE == 405) VGAVDE = 400;
5310 else if(VGAVDE == 420) VGAVDE = 400;
5311 else if(VGAVDE == 525) VGAVDE = 480;
5312 else if(VGAVDE == 1056) VGAVDE = 1024;
5313 SiS_Pr->CVDisplay = VGAVDE;
5315 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5317 SiS_Pr->CVBlankEnd = 1;
5318 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5320 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5321 SiS_Pr->CVSyncStart = VGAVDE + temp;
5324 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5326 SiS_CalcCRRegisters(SiS_Pr, 0);
5327 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5329 for(i = 0; i <= 7; i++) {
5330 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5332 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5333 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5335 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5336 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5338 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5339 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5342 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5343 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5345 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5346 if(modeflag & DoubleScanMode) temp |= 0x80;
5347 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5350 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5351 if(modeflag & HalfDCLK) temp |= 0x08;
5352 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5354 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5355 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5358 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5359 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5361 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5363 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5364 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5368 * This is used for LVDS, LCDA and Chrontel TV output
5369 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5372 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5373 unsigned short RefreshRateTableIndex)
5375 unsigned short modeflag, resinfo = 0;
5376 unsigned short push2, tempax, tempbx, tempcx, temp;
5377 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5378 bool islvds = false, issis = false, chkdclkfirst = false;
5380 unsigned short crt2crtc = 0;
5383 unsigned short pushcx;
5386 if(ModeNo <= 0x13) {
5387 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5388 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5390 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5392 } else if(SiS_Pr->UseCustomMode) {
5393 modeflag = SiS_Pr->CModeFlag;
5395 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5396 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5398 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5402 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5403 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5407 /* is really sis if sis bridge, but not 301B-DH */
5408 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5412 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5413 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5414 chkdclkfirst = true;
5419 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5421 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5422 } else if(IS_SIS740) {
5424 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5425 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5426 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5427 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5431 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5432 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5433 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5434 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5435 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5436 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5437 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5438 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5448 tempax = SiS_Pr->SiS_LCDHDES;
5450 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5451 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5452 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5453 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5460 temp = (tempax & 0x0007);
5461 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5462 temp = (tempax >> 3) & 0x00FF;
5463 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5465 tempbx = SiS_Pr->SiS_HDE;
5466 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5467 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5468 tempbx = SiS_Pr->PanelXRes;
5470 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5471 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5472 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5478 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5481 if(temp & 0x07) temp += 8;
5483 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5485 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5487 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5488 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5489 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5494 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5496 temp = (tempcx >> 3) & 0x00FF;
5497 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5498 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5499 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5503 case 0x0d: temp = 0x56; break;
5504 case 0x10: temp = 0x60; break;
5505 case 0x13: temp = 0x5f; break;
5515 case 0x5e: temp = 0x54; break;
5520 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5522 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5524 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5526 if(SiS_Pr->PanelHRE != 999) {
5527 temp = tempcx + SiS_Pr->PanelHRE;
5528 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5537 temp |= ((tempcx & 0x07) << 5);
5538 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5542 tempax = SiS_Pr->SiS_VGAVDE;
5543 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5544 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5545 tempax = SiS_Pr->PanelYRes;
5549 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5550 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5554 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5555 if(SiS_Pr->ChipType < SIS_315H) {
5556 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5557 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5558 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5562 if(islvds) tempcx >>= 1;
5565 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5566 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5567 (SiS_Pr->PanelVRS != 999) ) {
5568 tempcx = SiS_Pr->PanelVRS;
5573 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5574 else if(issis) tempbx++;
5577 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5579 temp = tempbx & 0x00FF;
5580 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5581 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5582 if(ModeNo == 0x10) temp = 0xa9;
5585 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5590 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5591 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5592 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5597 temp = tempcx & 0x000F;
5598 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5600 temp = ((tempbx >> 8) & 0x07) << 3;
5601 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5602 if(SiS_Pr->SiS_HDE != 640) {
5603 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5605 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5606 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5608 if((SiS_Pr->ChipType >= SIS_315H) ||
5609 (SiS_Pr->ChipRevision >= 0x30)) {
5611 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5612 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5614 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5615 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5616 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5617 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5619 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5623 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5625 tempbx = push2; /* BPLVDEE */
5627 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5629 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5630 switch(SiS_Pr->SiS_LCDResInfo) {
5632 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5633 tempcx = SiS_Pr->SiS_VGAVDE;
5636 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5637 if(resinfo == SIS_RI_800x600) tempcx++;
5640 case Panel_1024x600:
5641 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5642 if(resinfo == SIS_RI_1024x600) tempcx++;
5643 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5644 if(resinfo == SIS_RI_800x600) tempcx++;
5648 case Panel_1024x768:
5649 if(SiS_Pr->ChipType < SIS_315H) {
5650 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5651 if(resinfo == SIS_RI_1024x768) tempcx++;
5658 temp = ((tempbx >> 8) & 0x07) << 3;
5659 temp |= ((tempcx >> 8) & 0x07);
5660 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5661 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5664 /* Vertical scaling */
5666 if(SiS_Pr->ChipType < SIS_315H) {
5668 #ifdef SIS300 /* 300 series */
5669 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5670 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5671 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5674 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5676 temp = (unsigned short)(tempeax & 0x00FF);
5677 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5683 #ifdef SIS315H /* 315 series */
5684 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5685 tempebx = SiS_Pr->SiS_VDE;
5686 temp = (tempeax % tempebx);
5687 tempeax = tempeax / tempebx;
5689 tempvcfact = tempeax;
5691 temp = (unsigned short)(tempeax & 0x00FF);
5692 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5693 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5694 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5695 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5696 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5697 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5699 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5700 temp = (unsigned short)(tempeax & 0x00FF);
5701 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5702 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5703 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5704 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5705 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5707 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5708 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5714 /* Horizontal scaling */
5716 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5718 if(modeflag & HalfDCLK) tempeax >>= 1;
5720 tempebx = tempeax << 16;
5721 if(SiS_Pr->SiS_HDE == tempeax) {
5724 tempecx = tempebx / SiS_Pr->SiS_HDE;
5725 if(SiS_Pr->ChipType >= SIS_315H) {
5726 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5730 if(SiS_Pr->ChipType >= SIS_315H) {
5731 tempeax = (tempebx / tempecx) - 1;
5733 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5735 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5736 temp = (unsigned short)(tempecx & 0x00FF);
5737 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5739 if(SiS_Pr->ChipType >= SIS_315H) {
5740 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5741 tempbx = (unsigned short)(tempeax & 0xFFFF);
5743 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5744 tempbx = tempvcfact & 0x3f;
5745 if(tempbx == 0) tempbx = 64;
5747 tempbx = (unsigned short)(tempeax & 0xFFFF);
5749 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5750 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5751 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5752 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5755 temp = ((tempbx >> 8) & 0x07) << 3;
5756 temp = temp | ((tempecx >> 8) & 0x07);
5757 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5758 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5760 tempecx >>= 16; /* BPLHCFACT */
5762 if(modeflag & HalfDCLK) tempecx >>= 1;
5764 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5765 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5766 temp = (unsigned short)(tempecx & 0x00FF);
5767 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5770 if(SiS_Pr->ChipType >= SIS_315H) {
5771 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5772 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5773 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5777 if(SiS_Pr->ChipType == SIS_740) {
5778 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5780 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5788 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5789 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5790 unsigned char *trumpdata;
5791 int i, j = crt2crtc;
5792 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5793 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5794 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5796 if(SiS_Pr->SiS_UseROM) {
5797 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5799 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5800 trumpdata = &SiS300_TrumpionData[j][0];
5803 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5804 for(i=0; i<5; i++) {
5805 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5807 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5808 if(ModeNo == 0x13) {
5809 for(i=0; i<4; i++) {
5810 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5812 } else if(ModeNo == 0x10) {
5813 for(i=0; i<4; i++) {
5814 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5815 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5819 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5824 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5825 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5826 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5827 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5828 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5829 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5830 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5831 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5832 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5833 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5834 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5835 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5838 temp = (tempax >> 8) << 3;
5839 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5840 tempax += 32; /* Blpe = lBlps+32 */
5841 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5842 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
5843 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5845 tempax = SiS_Pr->SiS_VDE;
5846 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5847 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5848 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5850 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5851 temp = (tempax >> 8) << 3;
5852 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5854 tempeax = SiS_Pr->SiS_HDE;
5855 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5856 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5857 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5858 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5859 temp = tempeax & 0x7f;
5862 temp = tempeax & 0x3f;
5863 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5864 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5865 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5866 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5867 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5869 tempax = SiS_Pr->SiS_HDE;
5870 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5871 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5872 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5873 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5875 temp = tempax & 0x00FF;
5876 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5877 temp = ((tempax & 0xFF00) >> 8) << 3;
5878 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5880 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5881 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5882 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5883 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5884 tempeax = tempax * pushcx;
5885 temp = tempeax & 0xFF;
5886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5887 temp = (tempeax & 0xFF00) >> 8;
5888 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5889 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5890 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5891 temp = ((tempeax & 0x01000000) >> 24) << 7;
5892 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
5894 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5895 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5896 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5897 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5898 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5900 if(SiS_Pr->SiS_IF_DEF_FSTN) {
5901 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5902 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5903 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5904 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5905 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5906 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5907 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5909 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5910 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5911 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5912 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5913 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5914 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5915 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5916 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5917 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
5918 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
5919 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
5920 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
5923 #endif /* SIS315H */
5928 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5929 unsigned short RefreshRateTableIndex)
5931 #if defined(SIS300) || defined(SIS315H)
5932 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5934 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
5935 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
5937 unsigned short tempbl=0;
5940 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5941 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5945 if(ModeNo <= 0x13) {
5946 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5947 } else if(SiS_Pr->UseCustomMode) {
5948 modeflag = SiS_Pr->CModeFlag;
5950 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
5951 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5952 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5955 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5957 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
5958 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
5959 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
5961 if(SiS_Pr->ChipType < SIS_315H ) {
5963 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
5967 SiS_SetCRT2FIFO_310(SiS_Pr);
5971 /* 1. Horizontal setup */
5973 if(SiS_Pr->ChipType < SIS_315H ) {
5975 #ifdef SIS300 /* ------------- 300 series --------------*/
5977 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
5978 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
5980 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
5981 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
5983 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
5984 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
5986 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
5987 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
5988 tempbx = pushbx + tempcx;
5998 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6000 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6001 if(modeflag & HalfDCLK) {
6002 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6005 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6006 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6007 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6008 tempcx = SiS_Pr->SiS_HT - tempax;
6013 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6014 temp = (tempcx >> 4) & 0xF0;
6015 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6017 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6018 tempbx = SiS_Pr->SiS_VGAHDE;
6021 if(modeflag & HalfDCLK) {
6027 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6036 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6037 if(SiS_Pr->ChipType >= SIS_661) {
6038 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6039 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6040 if(resinfo == SIS_RI_1280x1024) {
6041 tempcx = (tempcx & 0xff00) | 0x30;
6042 } else if(resinfo == SIS_RI_1600x1200) {
6043 tempcx = (tempcx & 0xff00) | 0xff;
6049 #endif /* SIS315H */
6051 } /* 315/330 series */
6053 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6055 if(SiS_Pr->UseCustomMode) {
6056 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6057 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6058 tempax = SiS_Pr->SiS_VGAHT;
6059 if(modeflag & HalfDCLK) tempax >>= 1;
6061 if(tempcx > tempax) tempcx = tempax;
6064 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6065 unsigned char cr4, cr14, cr5, cr15;
6066 if(SiS_Pr->UseCustomMode) {
6067 cr4 = SiS_Pr->CCRT1CRTC[4];
6068 cr14 = SiS_Pr->CCRT1CRTC[14];
6069 cr5 = SiS_Pr->CCRT1CRTC[5];
6070 cr15 = SiS_Pr->CCRT1CRTC[15];
6072 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6073 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6074 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6075 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6077 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6078 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6080 tempcx |= (tempbx & 0xFF00);
6081 tempbx += bridgeadd;
6082 tempcx += bridgeadd;
6083 tempax = SiS_Pr->SiS_VGAHT;
6084 if(modeflag & HalfDCLK) tempax >>= 1;
6086 if(tempcx > tempax) tempcx = tempax;
6089 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6091 tempcx = 1044; /* HWCursor bug! */
6096 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6098 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6100 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6101 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6103 /* 2. Vertical setup */
6105 tempcx = SiS_Pr->SiS_VGAVT - 1;
6106 temp = tempcx & 0x00FF;
6108 if(SiS_Pr->ChipType < SIS_661) {
6109 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6110 if(SiS_Pr->ChipType < SIS_315H) {
6111 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6112 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6119 } else if(SiS_Pr->ChipType >= SIS_315H) {
6123 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6125 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6126 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6128 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6129 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6131 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6138 if(tempcx < 4) tempcx = 4;
6143 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6144 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6147 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6148 if(SiS_Pr->UseCustomMode) {
6149 tempbx = SiS_Pr->CVSyncStart;
6150 tempcx = SiS_Pr->CVSyncEnd;
6152 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6153 unsigned char cr8, cr7, cr13;
6154 if(SiS_Pr->UseCustomMode) {
6155 cr8 = SiS_Pr->CCRT1CRTC[8];
6156 cr7 = SiS_Pr->CCRT1CRTC[7];
6157 cr13 = SiS_Pr->CCRT1CRTC[13];
6158 tempcx = SiS_Pr->CCRT1CRTC[9];
6160 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6161 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6162 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6163 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6166 if(cr7 & 0x04) tempbx |= 0x0100;
6167 if(cr7 & 0x80) tempbx |= 0x0200;
6168 if(cr13 & 0x08) tempbx |= 0x0400;
6171 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6173 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6174 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6176 /* 3. Panel delay compensation */
6178 if(SiS_Pr->ChipType < SIS_315H) {
6180 #ifdef SIS300 /* ---------- 300 series -------------- */
6182 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6184 if(SiS_Pr->ChipType == SIS_300) {
6186 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6187 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6189 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6190 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6192 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6193 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6194 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6195 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6196 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6199 if(SiS_Pr->SiS_UseROM) {
6200 if(ROMAddr[0x220] & 0x80) {
6201 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6202 temp = ROMAddr[0x221];
6203 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6204 temp = ROMAddr[0x222];
6205 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6206 temp = ROMAddr[0x223];
6208 temp = ROMAddr[0x224];
6211 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6212 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6217 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6218 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6220 if(SiS_Pr->SiS_UseROM) {
6221 if(ROMAddr[0x220] & 0x80) {
6222 temp = ROMAddr[0x220];
6225 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6226 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6232 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6238 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6240 if(SiS_Pr->ChipType < SIS_661) {
6242 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6244 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6247 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6249 if(SiS_Pr->ChipType == SIS_650) {
6250 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6251 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6255 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6258 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6259 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6263 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6269 if(modeflag & DoubleScanMode) tempax |= 0x80;
6270 if(modeflag & HalfDCLK) tempax |= 0x40;
6271 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6273 #endif /* SIS315H */
6279 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6280 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6281 /* For 301BDH with LCD, we set up the Panel Link */
6282 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6283 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6284 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6287 if(SiS_Pr->ChipType < SIS_315H) {
6288 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6290 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6291 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6292 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6295 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6301 /*********************************************/
6302 /* SET PART 2 REGISTER GROUP */
6303 /*********************************************/
6306 static unsigned char *
6307 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6309 const unsigned char *tableptr = NULL;
6310 unsigned short a, b, p = 0;
6312 a = SiS_Pr->SiS_VGAHDE;
6313 b = SiS_Pr->SiS_HDE;
6315 a = SiS_Pr->SiS_VGAVDE;
6316 b = SiS_Pr->SiS_VDE;
6320 tableptr = SiS_Part2CLVX_1;
6322 tableptr = SiS_Part2CLVX_2;
6324 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6325 tableptr = SiS_Part2CLVX_4;
6327 tableptr = SiS_Part2CLVX_3;
6329 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6330 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6331 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6332 else tableptr = SiS_Part2CLVX_5;
6333 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6334 tableptr = SiS_Part2CLVX_6;
6337 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6339 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6340 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6343 return ((unsigned char *)&tableptr[p]);
6347 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6348 unsigned short RefreshRateTableIndex)
6350 unsigned char *tableptr;
6354 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6356 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6357 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6358 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6360 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6361 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6362 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6363 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6367 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6368 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6372 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6373 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6374 unsigned short *ResIndex)
6377 if(SiS_Pr->ChipType < SIS_315H) return false;
6380 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6382 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6384 (*ResIndex) &= 0x3f;
6387 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6388 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6393 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6394 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6395 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6398 return (((*CRT2Index) != 0));
6404 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6406 unsigned short tempcx;
6407 static const unsigned char atable[] = {
6408 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6409 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6412 if(!SiS_Pr->UseCustomMode) {
6413 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6414 (SiS_Pr->ChipType == SIS_730) ) &&
6415 (SiS_Pr->ChipRevision > 2) ) &&
6416 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6417 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6418 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6419 if(ModeNo == 0x13) {
6420 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6421 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6422 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6423 } else if((crt2crtc & 0x3F) == 4) {
6424 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6425 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6426 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6427 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6428 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6432 if(SiS_Pr->ChipType < SIS_315H) {
6433 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6436 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6437 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6443 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6446 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6447 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6449 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6453 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6454 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6460 /* For ECS A907. Highly preliminary. */
6462 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6463 unsigned short ModeNo)
6465 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6466 unsigned short crt2crtc, resindex;
6469 if(SiS_Pr->ChipType != SIS_300) return;
6470 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6471 if(SiS_Pr->UseCustomMode) return;
6473 if(ModeNo <= 0x13) {
6474 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6476 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6479 resindex = crt2crtc & 0x3F;
6480 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6481 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6483 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6485 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6489 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6490 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6491 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6492 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6494 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6495 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6497 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6498 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6500 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6501 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6506 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6508 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6509 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6510 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6512 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6513 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6514 const unsigned char specialtv[] = {
6515 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6516 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6517 0x58,0xe4,0x73,0xda,0x13
6520 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6521 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6523 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6524 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6525 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6526 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6527 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6529 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6530 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6535 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6536 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6537 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6538 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6540 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6541 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6547 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6549 unsigned short temp;
6551 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6552 if(SiS_Pr->SiS_VGAVDE == 525) {
6554 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6556 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6558 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6559 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6560 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6562 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6564 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6566 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6570 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6571 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6572 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6573 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6574 /* Not always for LV, see SetGrp2 */
6577 if(ModeNo <= 0x13) temp = 3;
6578 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6581 /* 651+301C, for 1280x768 - do I really need that? */
6582 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6583 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6584 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6585 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6586 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6587 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6588 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6589 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6590 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6591 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6592 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6593 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6594 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6595 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6596 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6597 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6606 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6607 unsigned short RefreshRateTableIndex)
6609 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6610 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6611 unsigned int longtemp, PhaseIndex;
6613 const unsigned char *TimingPoint;
6615 unsigned short resindex, CRT2Index;
6616 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6618 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6621 if(ModeNo <= 0x13) {
6622 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6623 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6624 } else if(SiS_Pr->UseCustomMode) {
6625 modeflag = SiS_Pr->CModeFlag;
6628 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6629 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6633 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6634 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6635 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6636 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6638 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6640 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6642 PhaseIndex = 0x01; /* SiS_PALPhase */
6643 TimingPoint = SiS_Pr->SiS_PALTiming;
6646 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6647 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6648 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6652 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6654 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6655 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6656 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6657 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6658 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6662 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6665 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6666 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6668 TimingPoint = &SiS_YPbPrTable[i][0];
6670 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6672 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6674 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6678 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6679 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6680 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6684 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6685 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6686 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6689 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6690 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6691 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6692 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6693 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6695 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6699 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6700 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6703 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6704 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6706 for(i = 0x39; i <= 0x45; i++, j++) {
6707 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6710 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6711 if(SiS_Pr->SiS_ModeType != ModeText) {
6712 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6716 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6718 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6719 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6720 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6723 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6724 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
6725 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6726 else tempax = 440; /* NTSC, YPbPr 525 */
6728 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6729 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6730 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6732 tempax -= SiS_Pr->SiS_VDE;
6734 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6739 temp = tempax + (unsigned short)TimingPoint[0];
6740 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6742 temp = tempax + (unsigned short)TimingPoint[1];
6743 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6745 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6746 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6747 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6748 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6750 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6751 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6757 tempcx = SiS_Pr->SiS_HT;
6758 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6760 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6761 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6762 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6764 tempcx = SiS_Pr->SiS_HT >> 1;
6765 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6767 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6768 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6770 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6772 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6773 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6776 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6780 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6783 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6784 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6785 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6788 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6789 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6791 tempcx = SiS_Pr->SiS_HT >> 1;
6792 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6794 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6795 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6798 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6799 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6801 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6803 tempbx = SiS_Pr->SiS_VDE;
6804 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6805 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6806 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6807 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6808 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6809 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6811 if(SiS_Pr->ChipType >= SIS_315H) {
6812 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6813 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6814 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6815 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6816 if(crt2crtc == 4) tempbx++;
6820 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6821 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6822 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6824 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6825 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6830 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6832 temp = (tempcx >> 8) & 0x0F;
6833 temp |= ((tempbx >> 2) & 0xC0);
6834 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6836 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6838 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6840 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6841 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6844 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6845 tempbx = SiS_Pr->SiS_VDE;
6846 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6847 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6851 temp = ((tempbx >> 3) & 0x60) | 0x18;
6852 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6853 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6855 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6856 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6861 if(!(modeflag & HalfDCLK)) {
6862 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6868 tempch = tempcl = 0x01;
6869 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6870 if(SiS_Pr->SiS_VGAHDE >= 960) {
6871 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6873 if(SiS_Pr->SiS_VGAHDE >= 1280) {
6876 } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6879 tempch = 25; /* OK */
6885 if(!(tempbx & 0x20)) {
6886 if(modeflag & HalfDCLK) tempcl <<= 1;
6887 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6888 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6889 tempax = longtemp / SiS_Pr->SiS_HDE;
6890 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6891 tempbx |= ((tempax >> 8) & 0x1F);
6892 tempcx = tempax >> 13;
6895 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6896 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6898 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6901 if(tempbx & 0x20) tempcx = 0;
6902 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6904 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6911 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6912 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6913 temp = (tempcx & 0x0300) >> 6;
6914 temp |= ((tempbx >> 8) & 0x03);
6915 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6917 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
6918 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6920 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
6922 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
6923 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
6925 SiS_SetTVSpecial(SiS_Pr, ModeNo);
6927 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
6929 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
6930 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
6935 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6936 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
6937 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
6938 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
6940 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
6943 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6944 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6945 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
6949 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
6951 /* From here: Part2 LCD setup */
6953 tempbx = SiS_Pr->SiS_HDE;
6954 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
6955 tempbx--; /* RHACTE = HDE - 1 */
6956 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
6957 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
6960 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
6961 if(SiS_Pr->SiS_ModeType == ModeEGA) {
6962 if(SiS_Pr->SiS_VGAHDE >= 1024) {
6964 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
6970 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
6972 tempbx = SiS_Pr->SiS_VDE - 1;
6973 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
6974 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
6976 tempcx = SiS_Pr->SiS_VT - 1;
6977 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
6978 temp = (tempcx >> 3) & 0xE0;
6979 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
6980 /* Enable dithering; only do this for 32bpp mode */
6981 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
6985 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
6987 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
6988 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
6990 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
6991 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
6994 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
6995 &CRT2Index, &resindex)) {
6997 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
6999 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7002 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7003 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7004 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7005 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7007 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7008 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7010 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7011 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7013 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7014 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7016 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7021 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7022 /* Clevo dual-link 1024x768 */
7023 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7024 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7026 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7027 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7028 tempbx = SiS_Pr->SiS_VDE - 1;
7029 tempcx = SiS_Pr->SiS_VT - 1;
7031 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7032 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7035 tempbx = SiS_Pr->PanelYRes;
7036 tempcx = SiS_Pr->SiS_VT;
7038 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7039 tempax = SiS_Pr->PanelYRes;
7040 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7041 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7042 tempax = tempcx = 0;
7044 tempax -= SiS_Pr->SiS_VDE;
7048 tempcx -= tempax; /* lcdvdes */
7049 tempbx -= tempax; /* lcdvdee */
7052 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7054 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7055 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7057 temp = (tempbx >> 5) & 0x38;
7058 temp |= ((tempcx >> 8) & 0x07);
7059 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7061 tempax = SiS_Pr->SiS_VDE;
7062 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7063 tempax = SiS_Pr->PanelYRes;
7065 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7066 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7067 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7068 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7072 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7073 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7074 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7075 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7076 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7077 if(tempax % 4) { tempax >>= 2; tempax++; }
7078 else { tempax >>= 2; }
7079 tempbx -= (tempax - 1);
7082 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7086 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7088 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7089 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7096 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7098 if(SiS_Pr->UseCustomMode) {
7099 tempbx = SiS_Pr->CVSyncStart;
7102 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7104 temp = (tempbx >> 4) & 0xF0;
7105 tempbx += (tempcx + 1);
7106 temp |= (tempbx & 0x0F);
7108 if(SiS_Pr->UseCustomMode) {
7110 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7113 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7116 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7120 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7121 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7122 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7123 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7124 /* Higher bridgeoffset shifts to the LEFT */
7127 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7128 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7129 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7130 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7133 temp += bridgeoffset;
7134 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7135 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7137 tempcx = SiS_Pr->SiS_HT;
7138 tempax = tempbx = SiS_Pr->SiS_HDE;
7139 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7140 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7141 tempax = SiS_Pr->PanelXRes;
7142 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7145 if(SiS_IsDualLink(SiS_Pr)) {
7151 tempbx += bridgeoffset;
7153 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7154 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7156 tempcx = (tempcx - tempax) >> 2;
7161 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7162 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7163 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7164 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7169 if(SiS_Pr->UseCustomMode) {
7170 tempbx = SiS_Pr->CHSyncStart;
7171 if(modeflag & HalfDCLK) tempbx <<= 1;
7172 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7173 tempbx += bridgeoffset;
7176 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7177 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7182 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7183 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7187 if(SiS_Pr->UseCustomMode) {
7188 tempbx = SiS_Pr->CHSyncEnd;
7189 if(modeflag & HalfDCLK) tempbx <<= 1;
7190 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7191 tempbx += bridgeoffset;
7194 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7196 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7199 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7202 } /* CRT2-LCD from table */
7206 /*********************************************/
7207 /* SET PART 3 REGISTER GROUP */
7208 /*********************************************/
7211 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7214 const unsigned char *tempdi;
7216 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7219 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7224 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7225 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7226 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7228 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7229 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7232 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7233 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7234 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7235 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7240 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7241 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7242 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7244 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7245 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7246 tempdi = SiS_HiTVGroup3_1;
7247 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7251 for(i=0; i<=0x3E; i++) {
7252 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7254 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7255 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7256 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7266 /*********************************************/
7267 /* SET PART 4 REGISTER GROUP */
7268 /*********************************************/
7273 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7275 unsigned short temp, temp1, temp2;
7277 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7278 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7279 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7280 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7281 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7282 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7283 temp = (unsigned short)((int)(temp) + shift);
7284 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7285 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7286 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7287 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7288 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7289 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7294 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7296 unsigned short temp, temp1, resinfo = 0;
7297 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7299 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7300 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7302 if(SiS_Pr->ChipType >= XGI_20) return;
7304 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7305 if(!(ROMAddr[0x61] & 0x04)) return;
7309 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7312 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7313 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7314 if(!(temp & 0x01)) {
7315 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7316 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7317 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7318 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7320 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7321 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7322 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7323 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7325 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7327 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7328 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7329 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7330 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7331 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7333 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7336 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7337 if(temp1 == 0x01) temp |= 0x01;
7338 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7339 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7340 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7342 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7347 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7348 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7349 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7350 if(resinfo == SIS_RI_1024x768) {
7351 SiS_ShiftXPos(SiS_Pr, 97);
7353 SiS_ShiftXPos(SiS_Pr, 111);
7355 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7356 SiS_ShiftXPos(SiS_Pr, 136);
7368 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7369 unsigned short RefreshRateTableIndex)
7371 unsigned short vclkindex, temp, reg1, reg2;
7373 if(SiS_Pr->UseCustomMode) {
7374 reg1 = SiS_Pr->CSR2B;
7375 reg2 = SiS_Pr->CSR2C;
7377 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7378 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7379 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7382 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7383 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7384 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7385 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7386 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7388 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7389 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7392 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7393 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7394 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7396 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7398 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7399 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7403 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7405 if(SiS_Pr->ChipType >= SIS_315H) {
7406 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7407 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7408 (SiS_IsVAMode(SiS_Pr))) {
7409 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7410 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7412 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7417 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7418 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7420 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7422 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7427 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7428 unsigned short RefreshRateTableIndex)
7430 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7431 unsigned int tempebx, tempeax, templong;
7433 if(ModeNo <= 0x13) {
7434 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7435 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7436 } else if(SiS_Pr->UseCustomMode) {
7437 modeflag = SiS_Pr->CModeFlag;
7440 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7441 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7444 if(SiS_Pr->ChipType >= SIS_315H) {
7445 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7446 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7447 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7452 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7453 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7454 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7458 if(SiS_Pr->ChipType >= SIS_315H) {
7459 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7460 SiS_SetDualLinkEtc(SiS_Pr);
7465 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7467 tempbx = SiS_Pr->SiS_RVBHCMAX;
7468 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7470 temp = (tempbx >> 1) & 0x80;
7472 tempcx = SiS_Pr->SiS_VGAHT - 1;
7473 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7475 temp |= ((tempcx >> 5) & 0x78);
7477 tempcx = SiS_Pr->SiS_VGAVT - 1;
7478 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7479 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7481 temp |= ((tempcx >> 8) & 0x07);
7482 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7484 tempbx = SiS_Pr->SiS_VGAHDE;
7485 if(modeflag & HalfDCLK) tempbx >>= 1;
7486 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7488 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7490 if(tempbx > 800) temp = 0x60;
7491 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7493 if(tempbx > 1024) temp = 0xC0;
7494 else if(tempbx >= 960) temp = 0xA0;
7495 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7497 if(tempbx >= 1280) temp = 0x40;
7498 else if(tempbx >= 1024) temp = 0x20;
7501 if(tempbx >= 1024) temp = 0xA0;
7504 temp |= SiS_Pr->Init_P4_0E;
7506 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7507 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7513 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7515 tempeax = SiS_Pr->SiS_VGAVDE;
7516 tempebx = SiS_Pr->SiS_VDE;
7517 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7518 if(!(temp & 0xE0)) tempebx >>=1;
7521 tempcx = SiS_Pr->SiS_RVBHRS;
7522 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7526 if(tempeax <= tempebx) {
7532 tempeax *= (256 * 1024);
7533 templong = tempeax % tempebx;
7535 if(templong) tempeax++;
7537 temp = (unsigned short)(tempeax & 0x000000FF);
7538 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7539 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7540 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7541 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7542 temp |= (tempcx & 0x4F);
7543 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7545 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7547 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7549 /* Calc Linebuffer max address and set/clear decimode */
7551 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7552 tempax = SiS_Pr->SiS_VGAHDE;
7553 if(modeflag & HalfDCLK) tempax >>= 1;
7554 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7556 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7560 if(tempax == 960) tempax *= 25; /* Correct */
7561 else if(tempax == 1024) tempax *= 25;
7567 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7568 if(resinfo == SIS_RI_1024x768 ||
7569 resinfo == SIS_RI_1024x576 ||
7570 resinfo == SIS_RI_1280x1024 ||
7571 resinfo == SIS_RI_1280x720) {
7572 /* Otherwise white line or garbage at right edge */
7573 tempax = (tempax & 0xff00) | 0x20;
7579 temp = ((tempax >> 4) & 0x30) | tempbx;
7580 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7581 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7583 temp = 0x0036; tempbx = 0xD0;
7584 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7585 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7587 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7588 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7590 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7591 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7597 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7599 tempbx = SiS_Pr->SiS_HT >> 1;
7600 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7602 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7603 temp = (tempbx >> 5) & 0x38;
7604 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7606 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7607 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7608 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7609 /* LCD-too-dark-error-source, see FinalizeLCD() */
7613 SiS_SetDualLinkEtc(SiS_Pr);
7617 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7620 /*********************************************/
7621 /* SET PART 5 REGISTER GROUP */
7622 /*********************************************/
7625 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7628 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7630 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7631 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7632 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7633 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7638 /*********************************************/
7639 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7640 /*********************************************/
7643 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7644 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7645 unsigned short *DisplayType)
7647 unsigned short modeflag = 0;
7648 bool checkhd = true;
7650 /* Pass 1:1 not supported here */
7652 if(ModeNo <= 0x13) {
7653 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7654 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7656 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7657 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7660 (*ResIndex) &= 0x3F;
7662 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7664 (*DisplayType) = 80;
7665 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7666 (*DisplayType) = 82;
7667 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7668 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7671 if((*DisplayType) != 84) {
7672 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7678 switch(SiS_Pr->SiS_LCDResInfo) {
7679 case Panel_320x240_1: (*DisplayType) = 50;
7682 case Panel_320x240_2: (*DisplayType) = 14;
7684 case Panel_320x240_3: (*DisplayType) = 18;
7686 case Panel_640x480: (*DisplayType) = 10;
7688 case Panel_1024x600: (*DisplayType) = 26;
7690 default: return true;
7694 if(modeflag & HalfDCLK) (*DisplayType)++;
7697 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7698 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7707 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7708 unsigned short RefreshRateTableIndex)
7710 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7711 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7712 static const unsigned short CRIdx[] = {
7713 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7714 0x07, 0x10, 0x11, 0x15, 0x16
7717 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7718 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7719 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7720 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7723 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7724 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7725 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7727 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7728 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7731 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7733 if(SiS_Pr->ChipType < SIS_315H) {
7734 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7737 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7738 &ResIndex, &DisplayType))) {
7742 switch(DisplayType) {
7743 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7744 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7745 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7746 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7747 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7748 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7749 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7750 #if 0 /* Works better with calculated numbers */
7751 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7752 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7753 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7754 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7756 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7757 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7758 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7759 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7760 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7765 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7767 for(i = 0; i <= 10; i++) {
7768 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7769 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7772 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7773 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7774 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7777 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7778 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7780 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7781 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7783 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7784 if(modeflag & DoubleScanMode) tempah |= 0x80;
7785 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7789 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7794 /*********************************************/
7796 /*********************************************/
7799 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7800 unsigned short RefreshRateTableIndex)
7802 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7803 unsigned short clkbase, vclkindex = 0;
7804 unsigned char sr2b, sr2c;
7806 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7807 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7808 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7809 RefreshRateTableIndex--;
7811 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7812 RefreshRateTableIndex);
7813 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7815 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7816 RefreshRateTableIndex);
7819 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7820 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7822 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7823 if(SiS_Pr->SiS_UseROM) {
7824 if(ROMAddr[0x220] & 0x01) {
7825 sr2b = ROMAddr[0x227];
7826 sr2c = ROMAddr[0x228];
7832 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7833 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7838 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7839 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7840 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7841 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7842 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7843 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7844 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7845 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7846 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7849 /*********************************************/
7850 /* SET UP CHRONTEL CHIPS */
7851 /*********************************************/
7854 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7855 unsigned short RefreshRateTableIndex)
7857 unsigned short TVType, resindex;
7858 const struct SiS_CHTVRegData *CHTVRegData = NULL;
7861 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7863 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7868 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7869 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7871 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7872 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7874 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7876 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7877 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7879 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7884 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7885 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7886 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
7887 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7888 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7889 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7890 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7891 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7892 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7893 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7897 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7901 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7903 /* We don't support modes >800x600 */
7904 if (resindex > 5) return;
7906 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7907 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7908 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
7910 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7911 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
7914 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
7915 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
7916 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
7917 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
7918 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
7920 /* Set minimum flicker filter for Luma channel (SR1-0=00),
7921 minimum text enhancement (S3-2=10),
7922 maximum flicker filter for Chroma channel (S5-4=10)
7923 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
7925 SiS_SetCH700x(SiS_Pr,0x01,0x28);
7927 /* Set video bandwidth
7928 High bandwidth Luma composite video filter(S0=1)
7929 low bandwidth Luma S-video filter (S2-1=00)
7930 disable peak filter in S-video channel (S3=0)
7931 high bandwidth Chroma Filter (S5-4=11)
7934 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
7936 /* Register 0x3D does not exist in non-macrovision register map
7937 (Maybe this is a macrovision register?)
7940 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
7943 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
7944 all other bits a read-only. Macrovision?
7946 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
7948 /* Register 0x11 only contains 3 writable bits (S0-S2) for
7949 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
7951 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
7955 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
7957 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
7958 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
7959 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
7960 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7961 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
7962 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
7963 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
7964 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
7965 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
7966 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
7967 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
7968 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
7969 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
7970 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
7971 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
7972 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
7975 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
7976 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7977 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7978 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
7980 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
7981 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
7982 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
7983 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
7984 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
7985 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
7986 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
7987 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
7988 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
7989 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
7990 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
7991 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7992 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7995 } else { /* ---- PAL ---- */
7996 /* We don't play around with FSCI in PAL mode */
7997 if(resindex == 0x04) {
7998 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7999 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8001 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8002 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8010 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8014 unsigned short temp;
8016 /* We don't support modes >1024x768 */
8017 if (resindex > 6) return;
8019 temp = CHTVRegData[resindex].Reg[0];
8020 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8021 SiS_SetCH701x(SiS_Pr,0x00,temp);
8023 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8024 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8025 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8026 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8027 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8028 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8030 temp = CHTVRegData[resindex].Reg[7];
8031 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8032 SiS_SetCH701x(SiS_Pr,0x07,temp);
8034 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8035 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8036 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8037 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8038 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8039 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8040 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8041 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8043 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8044 /* D1 should be set for PAL, PAL-N and NTSC-J,
8045 but I won't do that for PAL unless somebody
8046 tells me to do so. Since the BIOS uses
8047 non-default CIV values and blacklevels,
8048 this might be compensated anyway.
8050 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8051 SiS_SetCH701x(SiS_Pr,0x21,temp);
8063 #ifdef SIS315H /* ----------- 315 series only ---------- */
8066 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8068 unsigned short temp;
8070 /* Enable Chrontel 7019 LCD panel backlight */
8071 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8072 if(SiS_Pr->ChipType == SIS_740) {
8073 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8075 temp = SiS_GetCH701x(SiS_Pr,0x66);
8077 SiS_SetCH701x(SiS_Pr,0x66,temp);
8083 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8085 unsigned short temp;
8087 /* Disable Chrontel 7019 LCD panel backlight */
8088 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8089 temp = SiS_GetCH701x(SiS_Pr,0x66);
8091 SiS_SetCH701x(SiS_Pr,0x66,temp);
8096 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8098 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8099 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8100 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8101 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8102 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8103 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8104 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8105 const unsigned char *tableptr = NULL;
8108 /* Set up Power up/down timing */
8110 if(SiS_Pr->ChipType == SIS_740) {
8111 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8112 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8113 else tableptr = table1024_740;
8114 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8115 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8116 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8117 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8118 else tableptr = table1400_740;
8121 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8122 tableptr = table1024_650;
8123 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8124 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8125 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8126 tableptr = table1400_650;
8130 for(i=0; i<5; i++) {
8131 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8136 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8138 const unsigned char *tableptr = NULL;
8139 unsigned short tempbh;
8141 static const unsigned char regtable[] = {
8142 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8143 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8145 static const unsigned char table1024_740[] = {
8146 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8147 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8149 static const unsigned char table1280_740[] = {
8150 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8151 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8153 static const unsigned char table1400_740[] = {
8154 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8155 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8157 static const unsigned char table1600_740[] = {
8158 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8159 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8161 static const unsigned char table1024_650[] = {
8162 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8163 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8165 static const unsigned char table1280_650[] = {
8166 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8167 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8169 static const unsigned char table1400_650[] = {
8170 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8171 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8173 static const unsigned char table1600_650[] = {
8174 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8175 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8178 if(SiS_Pr->ChipType == SIS_740) {
8179 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8180 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8181 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8182 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8185 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8186 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8187 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8188 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8192 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8193 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8194 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8195 if(tempbh == 0xc8) {
8196 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8197 } else if(tempbh == 0xdb) {
8198 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8199 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8200 } else if(tempbh == 0xde) {
8201 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8205 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8208 for(i = 0; i < tempbh; i++) {
8209 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8211 SiS_ChrontelPowerSequencing(SiS_Pr);
8212 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8214 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8216 if(SiS_Pr->ChipType == SIS_740) {
8217 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8219 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8220 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8221 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8223 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8224 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8226 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8231 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8233 unsigned char temp, temp1;
8235 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8236 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8237 temp = SiS_GetCH701x(SiS_Pr,0x47);
8238 temp &= 0x7f; /* Use external VSYNC */
8239 SiS_SetCH701x(SiS_Pr,0x47,temp);
8240 SiS_LongDelay(SiS_Pr, 3);
8241 temp = SiS_GetCH701x(SiS_Pr,0x47);
8242 temp |= 0x80; /* Use internal VSYNC */
8243 SiS_SetCH701x(SiS_Pr,0x47,temp);
8244 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8248 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8250 unsigned short temp;
8252 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8253 if(SiS_Pr->ChipType == SIS_740) {
8254 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8255 temp |= 0x04; /* Invert XCLK phase */
8256 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8258 if(SiS_IsYPbPr(SiS_Pr)) {
8259 temp = SiS_GetCH701x(SiS_Pr,0x01);
8261 temp |= 0x80; /* Enable YPrPb (HDTV) */
8262 SiS_SetCH701x(SiS_Pr,0x01,temp);
8264 if(SiS_IsChScart(SiS_Pr)) {
8265 temp = SiS_GetCH701x(SiS_Pr,0x01);
8267 temp |= 0xc0; /* Enable SCART + CVBS */
8268 SiS_SetCH701x(SiS_Pr,0x01,temp);
8270 if(SiS_Pr->ChipType == SIS_740) {
8271 SiS_ChrontelResetVSync(SiS_Pr);
8272 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8274 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8275 temp = SiS_GetCH701x(SiS_Pr,0x49);
8276 if(SiS_IsYPbPr(SiS_Pr)) {
8277 temp = SiS_GetCH701x(SiS_Pr,0x73);
8279 SiS_SetCH701x(SiS_Pr,0x73,temp);
8281 temp = SiS_GetCH701x(SiS_Pr,0x47);
8283 SiS_SetCH701x(SiS_Pr,0x47,temp);
8284 SiS_LongDelay(SiS_Pr, 2);
8285 temp = SiS_GetCH701x(SiS_Pr,0x47);
8287 SiS_SetCH701x(SiS_Pr,0x47,temp);
8293 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8295 unsigned short temp;
8297 /* Complete power down of LVDS */
8298 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8299 if(SiS_Pr->ChipType == SIS_740) {
8300 SiS_LongDelay(SiS_Pr, 1);
8301 SiS_GenericDelay(SiS_Pr, 5887);
8302 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8303 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8305 SiS_LongDelay(SiS_Pr, 2);
8306 temp = SiS_GetCH701x(SiS_Pr,0x76);
8308 SiS_SetCH701x(SiS_Pr,0x76,temp);
8309 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8315 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8317 unsigned short temp;
8319 if(SiS_Pr->ChipType == SIS_740) {
8321 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8325 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8326 temp = SiS_GetCH701x(SiS_Pr,0x49);
8327 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8330 /* Reset Chrontel 7019 datapath */
8331 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8332 SiS_LongDelay(SiS_Pr, 1);
8333 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8335 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8336 SiS_ChrontelResetVSync(SiS_Pr);
8337 SiS_SetCH701x(SiS_Pr,0x49,temp);
8342 /* Clear/set/clear GPIO */
8343 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8345 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8346 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8348 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8349 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8351 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8352 temp = SiS_GetCH701x(SiS_Pr,0x61);
8354 SiS_SetCH701xForLCD(SiS_Pr);
8359 /* Reset Chrontel 7019 datapath */
8360 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8361 SiS_LongDelay(SiS_Pr, 1);
8362 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8367 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8369 unsigned short temp;
8371 if(SiS_Pr->ChipType == SIS_740) {
8373 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8374 SiS_ChrontelResetVSync(SiS_Pr);
8379 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8380 temp = SiS_GetCH701x(SiS_Pr,0x49);
8382 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8383 temp = SiS_GetCH701x(SiS_Pr,0x47);
8385 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8386 SiS_LongDelay(SiS_Pr, 3);
8387 temp = SiS_GetCH701x(SiS_Pr,0x47);
8389 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8396 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8398 unsigned short temp,temp1;
8400 if(SiS_Pr->ChipType == SIS_740) {
8402 temp = SiS_GetCH701x(SiS_Pr,0x61);
8405 SiS_SetCH701x(SiS_Pr,0x61,temp);
8407 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8408 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8409 SiS_LongDelay(SiS_Pr, 1);
8410 SiS_GenericDelay(SiS_Pr, 5887);
8415 temp = SiS_GetCH701x(SiS_Pr,0x61);
8418 SiS_SetCH701x(SiS_Pr,0x61,temp);
8421 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8422 temp = SiS_GetCH701x(SiS_Pr,0x66);
8424 SiS_SetCH701x(SiS_Pr,0x66,temp);
8426 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8427 SiS_GenericDelay(SiS_Pr, 1023);
8429 SiS_GenericDelay(SiS_Pr, 767);
8433 SiS_GenericDelay(SiS_Pr, 767);
8435 temp = SiS_GetCH701x(SiS_Pr,0x76);
8437 SiS_SetCH701x(SiS_Pr,0x76,temp);
8438 temp = SiS_GetCH701x(SiS_Pr,0x66);
8440 SiS_SetCH701x(SiS_Pr,0x66,temp);
8441 SiS_LongDelay(SiS_Pr, 1);
8447 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8449 unsigned short temp;
8451 SiS_LongDelay(SiS_Pr, 1);
8454 temp = SiS_GetCH701x(SiS_Pr,0x66);
8455 temp &= 0x04; /* PLL stable? -> bail out */
8456 if(temp == 0x04) break;
8458 if(SiS_Pr->ChipType == SIS_740) {
8459 /* Power down LVDS output, PLL normal operation */
8460 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8463 SiS_SetCH701xForLCD(SiS_Pr);
8465 temp = SiS_GetCH701x(SiS_Pr,0x76);
8466 temp &= 0xfb; /* Reset PLL */
8467 SiS_SetCH701x(SiS_Pr,0x76,temp);
8468 SiS_LongDelay(SiS_Pr, 2);
8469 temp = SiS_GetCH701x(SiS_Pr,0x76);
8470 temp |= 0x04; /* PLL normal operation */
8471 SiS_SetCH701x(SiS_Pr,0x76,temp);
8472 if(SiS_Pr->ChipType == SIS_740) {
8473 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8475 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8477 SiS_LongDelay(SiS_Pr, 2);
8480 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8484 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8486 unsigned short temp;
8488 temp = SiS_GetCH701x(SiS_Pr,0x03);
8489 temp |= 0x80; /* Set datapath 1 to TV */
8490 temp &= 0xbf; /* Set datapath 2 to LVDS */
8491 SiS_SetCH701x(SiS_Pr,0x03,temp);
8493 if(SiS_Pr->ChipType == SIS_740) {
8495 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8496 temp &= 0xfb; /* Normal XCLK phase */
8497 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8499 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8501 temp = SiS_GetCH701x(SiS_Pr,0x64);
8502 temp |= 0x40; /* ? Bit not defined */
8503 SiS_SetCH701x(SiS_Pr,0x64,temp);
8505 temp = SiS_GetCH701x(SiS_Pr,0x03);
8506 temp &= 0x3f; /* D1 input to both LVDS and TV */
8507 SiS_SetCH701x(SiS_Pr,0x03,temp);
8509 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8510 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8511 SiS_LongDelay(SiS_Pr, 1);
8512 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8513 SiS_ChrontelResetDB(SiS_Pr);
8514 SiS_ChrontelDoSomething2(SiS_Pr);
8515 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8517 temp = SiS_GetCH701x(SiS_Pr,0x66);
8519 SiS_ChrontelResetDB(SiS_Pr);
8520 SiS_ChrontelDoSomething2(SiS_Pr);
8521 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8527 SiS_ChrontelResetDB(SiS_Pr);
8528 SiS_ChrontelDoSomething2(SiS_Pr);
8529 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8530 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8531 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8536 #endif /* 315 series */
8538 /*********************************************/
8539 /* MAIN: SET CRT2 REGISTER GROUP */
8540 /*********************************************/
8543 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8546 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8548 unsigned short ModeIdIndex, RefreshRateTableIndex;
8550 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8552 if(!SiS_Pr->UseCustomMode) {
8553 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8558 /* Used for shifting CR33 */
8559 SiS_Pr->SiS_SelectCRT2Rate = 4;
8561 SiS_UnLockCRT2(SiS_Pr);
8563 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8565 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8567 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8568 SiS_DisableBridge(SiS_Pr);
8569 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8570 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8572 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8575 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8576 SiS_LockCRT2(SiS_Pr);
8577 SiS_DisplayOn(SiS_Pr);
8581 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8583 /* Set up Panel Link for LVDS and LCDA */
8584 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8585 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8586 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8587 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8588 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8591 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8592 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8595 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8597 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8599 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8601 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8603 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8604 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8606 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8608 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8610 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8612 /* For 301BDH (Panel link initialization): */
8613 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8615 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8616 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8617 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8620 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8626 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8628 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8630 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8632 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8633 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8634 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8635 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8637 SiS_SetCH701xForLCD(SiS_Pr);
8641 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8642 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8650 if(SiS_Pr->ChipType < SIS_315H) {
8651 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8652 if(SiS_Pr->SiS_UseOEM) {
8653 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8654 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8655 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8658 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8661 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8662 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8663 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8664 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8666 SiS_DisplayOn(SiS_Pr);
8673 if(SiS_Pr->ChipType >= SIS_315H) {
8674 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8675 if(SiS_Pr->ChipType < SIS_661) {
8676 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8677 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8679 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8681 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8686 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8687 SiS_EnableBridge(SiS_Pr);
8690 SiS_DisplayOn(SiS_Pr);
8692 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8693 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8694 /* Disable LCD panel when using TV */
8695 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8697 /* Disable TV when using LCD */
8698 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8702 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8703 SiS_LockCRT2(SiS_Pr);
8710 /*********************************************/
8711 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8712 /*********************************************/
8715 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8717 /* Switch on LCD backlight on SiS30xLV */
8718 SiS_DDC2Delay(SiS_Pr,0xff00);
8719 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8720 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8721 SiS_WaitVBRetrace(SiS_Pr);
8723 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8724 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8729 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8731 /* Switch off LCD backlight on SiS30xLV */
8732 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8733 SiS_DDC2Delay(SiS_Pr,0xff00);
8736 /*********************************************/
8737 /* DDC RELATED FUNCTIONS */
8738 /*********************************************/
8741 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8743 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8744 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8745 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8746 SiS_Pr->SiS_DDC_NData &= 0x0f;
8747 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8752 static unsigned char *
8753 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8756 unsigned short tempah,temp;
8757 unsigned char *mydataptr;
8759 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8760 mydataptr = dataptr;
8762 if(!num) return mydataptr;
8764 SiS_SetStop(SiS_Pr);
8765 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8767 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8768 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8769 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8770 if(temp) continue; /* (ERROR: no ack) */
8771 tempah = *mydataptr++;
8772 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8773 if(temp) continue; /* (ERROR: no ack) */
8774 for(j=0; j<num; j++) {
8775 tempah = *mydataptr++;
8776 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8780 if(SiS_SetStop(SiS_Pr)) continue;
8787 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8789 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8790 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8791 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8792 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8793 SiS_SetupDDCN(SiS_Pr);
8795 SiS_SetSwitchDDC2(SiS_Pr);
8798 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8799 if(!dataptr) return false;
8805 /* The Chrontel 700x is connected to the 630/730 via
8806 * the 630/730's DDC/I2C port.
8808 * On 630(S)T chipset, the index changed from 0x11 to
8809 * 0x0a, possibly for working around the DDC problems
8813 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8815 unsigned short temp, i;
8817 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8819 SiS_SetStop(SiS_Pr);
8820 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8822 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8823 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8824 if(temp) continue; /* (ERROR: no ack) */
8825 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
8826 if(temp) continue; /* (ERROR: no ack) */
8827 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
8828 if(temp) continue; /* (ERROR: no ack) */
8829 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
8830 SiS_Pr->SiS_ChrontelInit = 1;
8836 /* Write to Chrontel 700x */
8838 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8840 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8842 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8844 if(!(SiS_Pr->SiS_ChrontelInit)) {
8845 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8846 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8847 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8848 SiS_SetupDDCN(SiS_Pr);
8851 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
8852 (!(SiS_Pr->SiS_ChrontelInit)) ) {
8853 SiS_Pr->SiS_DDC_Index = 0x0a;
8854 SiS_Pr->SiS_DDC_Data = 0x80;
8855 SiS_Pr->SiS_DDC_Clk = 0x40;
8856 SiS_SetupDDCN(SiS_Pr);
8858 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
8862 /* Write to Chrontel 701x */
8863 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
8865 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8867 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8868 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8869 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8870 SiS_SetupDDCN(SiS_Pr);
8871 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8872 SiS_SetChReg(SiS_Pr, reg, val, 0);
8875 #ifdef SIS_LINUX_KERNEL
8879 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8881 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8882 SiS_SetCH700x(SiS_Pr, reg, val);
8884 SiS_SetCH701x(SiS_Pr, reg, val);
8887 static unsigned short
8888 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
8890 unsigned short tempah, temp, i;
8892 for(i=0; i<20; i++) { /* Do 20 attempts to read */
8894 SiS_SetStop(SiS_Pr);
8895 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8897 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8898 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8899 if(temp) continue; /* (ERROR: no ack) */
8900 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
8901 if(temp) continue; /* (ERROR: no ack) */
8902 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
8903 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
8904 if(temp) continue; /* (ERROR: no ack) */
8905 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
8906 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
8907 SiS_Pr->SiS_ChrontelInit = 1;
8913 /* Read from Chrontel 700x */
8914 /* Parameter is [Register no (S7-S0)] */
8916 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8918 unsigned short result;
8920 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8922 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8924 if(!(SiS_Pr->SiS_ChrontelInit)) {
8925 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8926 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8927 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8928 SiS_SetupDDCN(SiS_Pr);
8931 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8933 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
8934 (!SiS_Pr->SiS_ChrontelInit) ) {
8936 SiS_Pr->SiS_DDC_Index = 0x0a;
8937 SiS_Pr->SiS_DDC_Data = 0x80;
8938 SiS_Pr->SiS_DDC_Clk = 0x40;
8939 SiS_SetupDDCN(SiS_Pr);
8941 result = SiS_GetChReg(SiS_Pr,0x80);
8946 /* Read from Chrontel 701x */
8947 /* Parameter is [Register no (S7-S0)] */
8949 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8951 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8952 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8953 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8954 SiS_SetupDDCN(SiS_Pr);
8955 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8957 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8959 return SiS_GetChReg(SiS_Pr,0);
8962 /* Read from Chrontel 70xx */
8963 /* Parameter is [Register no (S7-S0)] */
8964 #ifdef SIS_LINUX_KERNEL
8968 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8970 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8971 return SiS_GetCH700x(SiS_Pr, tempbx);
8973 return SiS_GetCH701x(SiS_Pr, tempbx);
8977 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
8978 unsigned char myor, unsigned short myand)
8980 unsigned short tempbl;
8982 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
8983 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
8986 /* Our own DDC functions */
8989 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
8990 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
8991 unsigned int VBFlags2)
8993 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
8994 unsigned char flag, cr32;
8995 unsigned short temp = 0, myadaptnum = adaptnum;
8998 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
8999 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9002 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9004 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9006 SiS_Pr->SiS_DDC_SecAddr = 0;
9007 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9008 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9009 SiS_Pr->SiS_DDC_Index = 0x11;
9012 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9015 if(VBFlags2 & VB2_SISBRIDGE) {
9016 if(myadaptnum == 0) {
9017 if(!(cr32 & 0x20)) {
9019 if(!(cr32 & 0x10)) {
9021 if(!(cr32 & 0x08)) {
9030 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9032 if(myadaptnum != 0) {
9034 if(VBFlags2 & VB2_SISBRIDGE) {
9035 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9036 SiS_Pr->SiS_DDC_Index = 0x0f;
9040 if(!(VBFlags2 & VB2_301)) {
9041 if((cr32 & 0x80) && (checkcr32)) {
9042 if(myadaptnum >= 1) {
9043 if(!(cr32 & 0x08)) {
9045 if(!(cr32 & 0x10)) return 0xFFFF;
9051 temp = 4 - (myadaptnum * 2);
9054 } else { /* 315/330 series */
9056 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9058 if(VBFlags2 & VB2_SISBRIDGE) {
9059 if(myadaptnum == 2) {
9064 if(myadaptnum == 1) {
9066 if(VBFlags2 & VB2_SISBRIDGE) {
9067 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9068 SiS_Pr->SiS_DDC_Index = 0x0f;
9072 if((cr32 & 0x80) && (checkcr32)) {
9073 if(myadaptnum >= 1) {
9074 if(!(cr32 & 0x08)) {
9076 if(!(cr32 & 0x10)) return 0xFFFF;
9082 if(myadaptnum == 1) {
9084 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9090 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9091 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9093 SiS_SetupDDCN(SiS_Pr);
9098 static unsigned short
9099 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9101 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9102 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9105 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9111 static unsigned short
9112 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9114 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9115 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9121 static unsigned short
9122 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9124 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9125 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9130 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9132 SiS_SetSCLKLow(SiS_Pr);
9134 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9135 SiS_Pr->SiS_DDC_Index,
9136 SiS_Pr->SiS_DDC_NData,
9137 SiS_Pr->SiS_DDC_Data);
9139 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9140 SiS_Pr->SiS_DDC_Index,
9141 SiS_Pr->SiS_DDC_NData,
9144 SiS_SetSCLKHigh(SiS_Pr);
9147 static unsigned short
9148 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9150 unsigned char mask, value;
9151 unsigned short temp, ret=0;
9152 bool failed = false;
9154 SiS_SetSwitchDDC2(SiS_Pr);
9155 if(SiS_PrepareDDC(SiS_Pr)) {
9156 SiS_SetStop(SiS_Pr);
9161 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9162 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9163 SiS_SendACK(SiS_Pr, 0);
9173 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9174 SiS_SendACK(SiS_Pr, 1);
9176 if(temp == value) ret = 0;
9179 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9180 if(temp == 0x30) ret = 0;
9184 SiS_SetStop(SiS_Pr);
9190 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9192 unsigned short flag;
9195 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9196 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9197 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9198 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9199 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9200 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9201 if(!(flag & 0x1a)) flag = 0;
9207 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9209 unsigned short flag, length, i;
9210 unsigned char chksum,gotcha;
9212 if(DDCdatatype > 4) return 0xFFFF;
9215 SiS_SetSwitchDDC2(SiS_Pr);
9216 if(!(SiS_PrepareDDC(SiS_Pr))) {
9218 if(DDCdatatype != 1) length = 255;
9221 for(i=0; i<length; i++) {
9222 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9223 chksum += buffer[i];
9224 gotcha |= buffer[i];
9225 SiS_SendACK(SiS_Pr, 0);
9227 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9228 chksum += buffer[i];
9229 SiS_SendACK(SiS_Pr, 1);
9230 if(gotcha) flag = (unsigned short)chksum;
9235 SiS_SetStop(SiS_Pr);
9239 /* Our private DDC functions
9241 It complies somewhat with the corresponding VESA function
9242 in arguments and return values.
9244 Since this is probably called before the mode is changed,
9245 we use our pre-detected pSiS-values instead of SiS_Pr as
9246 regards chipset and video bridge type.
9249 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9250 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9251 LCDA is CRT1, but DDC is read from CRT2 port.
9252 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9253 buffer: ptr to 256 data bytes which will be filled with read data.
9255 Returns 0xFFFF if error, otherwise
9256 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9257 if DDCdatatype = 0: Returns supported DDC modes
9261 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9262 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9263 unsigned int VBFlags2)
9265 unsigned char sr1f, cr17=1;
9266 unsigned short result;
9274 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9277 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9280 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9281 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9282 if(VGAEngine == SIS_300_VGA) {
9283 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9285 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9286 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9287 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9290 if((sr1f) || (!cr17)) {
9291 SiS_WaitRetrace1(SiS_Pr);
9292 SiS_WaitRetrace1(SiS_Pr);
9293 SiS_WaitRetrace1(SiS_Pr);
9294 SiS_WaitRetrace1(SiS_Pr);
9297 if(DDCdatatype == 0) {
9298 result = SiS_ProbeDDC(SiS_Pr);
9300 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9301 if((!result) && (DDCdatatype == 1)) {
9302 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9303 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9304 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9305 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9306 (buffer[0x12] == 1)) {
9307 if(!SiS_Pr->DDCPortMixup) {
9309 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9311 if(buffer[0x14] & 0x80) result = 0xFFFE;
9317 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9318 if(VGAEngine == SIS_300_VGA) {
9319 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9324 /* Generic I2C functions for Chrontel & DDC --------- */
9327 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9329 SiS_SetSCLKHigh(SiS_Pr);
9330 SiS_WaitRetrace1(SiS_Pr);
9332 SiS_SetSCLKLow(SiS_Pr);
9333 SiS_WaitRetrace1(SiS_Pr);
9337 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9339 SiS_WaitRetrace1(SiS_Pr);
9340 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9343 /* Set I2C start condition */
9344 /* This is done by a SD high-to-low transition while SC is high */
9345 static unsigned short
9346 SiS_SetStart(struct SiS_Private *SiS_Pr)
9348 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9349 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9350 SiS_Pr->SiS_DDC_Index,
9351 SiS_Pr->SiS_DDC_NData,
9352 SiS_Pr->SiS_DDC_Data); /* SD->high */
9353 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9354 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9355 SiS_Pr->SiS_DDC_Index,
9356 SiS_Pr->SiS_DDC_NData,
9357 0x00); /* SD->low = start condition */
9358 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9362 /* Set I2C stop condition */
9363 /* This is done by a SD low-to-high transition while SC is high */
9364 static unsigned short
9365 SiS_SetStop(struct SiS_Private *SiS_Pr)
9367 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9368 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9369 SiS_Pr->SiS_DDC_Index,
9370 SiS_Pr->SiS_DDC_NData,
9371 0x00); /* SD->low */
9372 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9373 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9374 SiS_Pr->SiS_DDC_Index,
9375 SiS_Pr->SiS_DDC_NData,
9376 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9377 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9381 /* Write 8 bits of data */
9382 static unsigned short
9383 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9385 unsigned short i,flag,temp;
9388 for(i = 0; i < 8; i++) {
9389 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9391 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9392 SiS_Pr->SiS_DDC_Index,
9393 SiS_Pr->SiS_DDC_NData,
9394 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9396 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9397 SiS_Pr->SiS_DDC_Index,
9398 SiS_Pr->SiS_DDC_NData,
9399 0x00); /* Write bit (0) to SD */
9401 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9404 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9408 static unsigned short
9409 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9411 unsigned short i, temp, getdata;
9414 for(i = 0; i < 8; i++) {
9416 SiS_SetSCLKLow(SiS_Pr);
9417 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9418 SiS_Pr->SiS_DDC_Index,
9419 SiS_Pr->SiS_DDC_NData,
9420 SiS_Pr->SiS_DDC_Data);
9421 SiS_SetSCLKHigh(SiS_Pr);
9422 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9423 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9428 static unsigned short
9429 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9431 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9432 SiS_Pr->SiS_DDC_Index,
9433 SiS_Pr->SiS_DDC_NClk,
9434 0x00); /* SetSCLKLow() */
9435 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9439 static unsigned short
9440 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9442 unsigned short temp, watchdog=1000;
9444 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9445 SiS_Pr->SiS_DDC_Index,
9446 SiS_Pr->SiS_DDC_NClk,
9447 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9449 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9450 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9454 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9458 /* Check I2C acknowledge */
9459 /* Returns 0 if ack ok, non-0 if ack not ok */
9460 static unsigned short
9461 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9463 unsigned short tempah;
9465 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9466 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9467 SiS_Pr->SiS_DDC_Index,
9468 SiS_Pr->SiS_DDC_NData,
9469 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9470 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9471 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9472 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9473 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9477 /* End of I2C functions ----------------------- */
9480 /* =============== SiS 315/330 O.E.M. ================= */
9484 static unsigned short
9485 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9487 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9488 unsigned short romptr;
9490 if(SiS_Pr->ChipType < SIS_330) {
9491 romptr = SISGETROMW(0x128);
9492 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9493 romptr = SISGETROMW(0x12a);
9495 romptr = SISGETROMW(0x1a8);
9496 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9497 romptr = SISGETROMW(0x1aa);
9502 static unsigned short
9503 GetLCDromptr(struct SiS_Private *SiS_Pr)
9505 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9506 unsigned short romptr;
9508 if(SiS_Pr->ChipType < SIS_330) {
9509 romptr = SISGETROMW(0x120);
9510 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9511 romptr = SISGETROMW(0x122);
9513 romptr = SISGETROMW(0x1a0);
9514 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9515 romptr = SISGETROMW(0x1a2);
9520 static unsigned short
9521 GetTVromptr(struct SiS_Private *SiS_Pr)
9523 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9524 unsigned short romptr;
9526 if(SiS_Pr->ChipType < SIS_330) {
9527 romptr = SISGETROMW(0x114);
9528 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9529 romptr = SISGETROMW(0x11a);
9531 romptr = SISGETROMW(0x194);
9532 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9533 romptr = SISGETROMW(0x19a);
9538 static unsigned short
9539 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9541 unsigned short index;
9543 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9544 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9545 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9548 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9549 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9555 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9556 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9557 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9558 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9559 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9561 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9565 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9566 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9570 static unsigned short
9571 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9573 unsigned short index;
9575 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9576 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9577 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9581 static unsigned short
9582 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9584 unsigned short index;
9587 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9588 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9590 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9594 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9595 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9603 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9605 unsigned short index = 0, temp = 0;
9607 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9608 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9609 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9610 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9611 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9613 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9614 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9617 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9618 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9619 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9625 return (unsigned int)(index | (temp << 16));
9629 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9631 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9636 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9638 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9643 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9647 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9648 if(SiS_Pr->SiS_ROMNew) {
9649 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9650 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9651 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9652 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9654 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9655 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9656 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9657 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9660 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9666 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9668 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9669 unsigned short delay=0,index,myindex,temp,romptr=0;
9670 bool dochiptest = true;
9672 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9673 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9675 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9678 /* Find delay (from ROM, internal tables, PCI subsystem) */
9680 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9682 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9683 romptr = GetRAMDACromptr(SiS_Pr);
9685 if(romptr) delay = ROMAddr[romptr];
9688 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9691 } else if(IS_SIS740) {
9693 } else if(SiS_Pr->ChipType < SIS_330) {
9698 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9703 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9705 bool gotitfrompci = false;
9707 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9709 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9710 if(SiS_Pr->PDC != -1) {
9711 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9712 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9716 if(SiS_Pr->PDCA != -1) {
9717 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9718 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9725 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9726 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9728 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9731 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9734 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9736 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9739 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9740 if(IS_SIS740) delay = 0x01;
9743 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9748 /* This is a piece of typical SiS crap: They code the OEM LCD
9749 * delay into the code, at no defined place in the BIOS.
9750 * We now have to start doing a PCI subsystem check here.
9753 switch(SiS_Pr->SiS_CustomT) {
9754 case CUT_COMPAQ1280:
9755 case CUT_COMPAQ12802:
9756 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9757 gotitfrompci = true;
9763 case CUT_CLEVO14002:
9764 gotitfrompci = true;
9769 case CUT_CLEVO10242:
9770 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9771 gotitfrompci = true;
9774 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9780 /* Could we find it through the PCI ID? If no, use ROM or table */
9784 index = GetLCDPtrIndexBIOS(SiS_Pr);
9785 myindex = GetLCDPtrIndex(SiS_Pr);
9787 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9789 if(SiS_IsNotM650orLater(SiS_Pr)) {
9791 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9792 /* Always use the second pointer on 650; some BIOSes */
9793 /* still carry old 301 data at the first location */
9794 /* romptr = SISGETROMW(0x120); */
9795 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9796 romptr = SISGETROMW(0x122);
9798 delay = ROMAddr[(romptr + index)];
9800 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9805 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
9806 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
9807 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
9811 } else if(SiS_Pr->SiS_UseROM &&
9812 (!(SiS_Pr->SiS_ROMNew)) &&
9813 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
9814 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
9815 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
9816 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
9817 ((romptr = GetLCDromptr(SiS_Pr)))) {
9819 /* Data for 1280x1024 wrong in 301B BIOS */
9820 /* Data for 1600x1200 wrong in 301C BIOS */
9821 delay = ROMAddr[(romptr + index)];
9823 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9825 if(IS_SIS740) delay = 0x03;
9830 delay = SiS310_LCDDelayCompensation_301[myindex];
9831 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9832 if(IS_SIS740) delay = 0x01;
9833 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
9834 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9835 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9836 if(IS_SIS740) delay = 0x01; /* ? */
9838 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
9839 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9840 if(IS_SIS740) delay = 0x01;
9841 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
9846 } /* got it from PCI */
9848 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9849 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
9853 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
9855 index = GetTVPtrIndex(SiS_Pr);
9857 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9859 if(SiS_IsNotM650orLater(SiS_Pr)) {
9861 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9862 /* Always use the second pointer on 650; some BIOSes */
9863 /* still carry old 301 data at the first location */
9864 /* romptr = SISGETROMW(0x114); */
9865 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9866 romptr = SISGETROMW(0x11a);
9868 delay = ROMAddr[romptr + index];
9872 delay = SiS310_TVDelayCompensation_301B[index];
9878 switch(SiS_Pr->SiS_CustomT) {
9879 case CUT_COMPAQ1280:
9880 case CUT_COMPAQ12802:
9882 case CUT_CLEVO14002:
9887 case CUT_CLEVO10242:
9892 delay = SiS310_TVDelayCompensation_651301LV[index];
9893 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
9894 delay = SiS310_TVDelayCompensation_651302LV[index];
9899 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9901 romptr = GetTVromptr(SiS_Pr);
9903 delay = ROMAddr[romptr + index];
9905 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9907 delay = SiS310_TVDelayCompensation_LVDS[index];
9911 delay = SiS310_TVDelayCompensation_301[index];
9912 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9914 delay = SiS310_TVDelayCompensation_740301B[index];
9915 /* LV: use 301 data? BIOS bug? */
9917 delay = SiS310_TVDelayCompensation_301B[index];
9918 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
9924 if(SiS_LCDAEnabled(SiS_Pr)) {
9933 if(SiS_Pr->SiS_VBType & VB_SISVB) {
9935 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
9937 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
9938 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
9941 } else if(temp == 6) {
9944 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
9947 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9951 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9957 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9958 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9960 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
9962 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
9964 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9973 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
9975 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9976 unsigned short index,temp,temp1,romptr=0;
9978 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
9981 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
9983 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
9985 temp = GetTVPtrIndex(SiS_Pr);
9986 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9989 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
9990 if(SiS_Pr->ChipType >= SIS_661) {
9991 temp1 = GetOEMTVPtr661(SiS_Pr);
9993 romptr = SISGETROMW(0x260);
9994 if(SiS_Pr->ChipType >= SIS_760) {
9995 romptr = SISGETROMW(0x360);
9997 } else if(SiS_Pr->ChipType >= SIS_330) {
9998 romptr = SISGETROMW(0x192);
10000 romptr = SISGETROMW(0x112);
10006 temp = ROMAddr[romptr + temp1 + index];
10008 temp = SiS310_TVAntiFlick1[temp][index];
10012 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10016 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10018 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10019 unsigned short index,temp,temp1,romptr=0;
10021 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10024 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10026 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10028 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10029 if(SiS_Pr->ChipType >= SIS_661) {
10030 romptr = SISGETROMW(0x26c);
10031 if(SiS_Pr->ChipType >= SIS_760) {
10032 romptr = SISGETROMW(0x36c);
10034 temp1 = GetOEMTVPtr661(SiS_Pr);
10036 } else if(SiS_Pr->ChipType >= SIS_330) {
10037 romptr = SISGETROMW(0x1a4);
10039 romptr = SISGETROMW(0x124);
10045 temp = ROMAddr[romptr + temp1 + index];
10047 temp = SiS310_TVEdge1[temp][index];
10050 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10054 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10056 unsigned short index, temp, i, j;
10058 if(ModeNo <= 0x13) {
10059 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10061 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10064 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10066 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10067 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10068 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10069 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10071 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10072 for(i=0x35, j=0; i<=0x38; i++, j++) {
10073 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10075 for(i=0x48; i<=0x4A; i++, j++) {
10076 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10079 for(i=0x35, j=0; i<=0x38; i++, j++) {
10080 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10086 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10088 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10089 unsigned short index,temp,i,j,resinfo,romptr=0;
10090 unsigned int lindex;
10092 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10094 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10095 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10097 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10098 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10100 for(j=0, i=0x31; i<=0x34; i++, j++) {
10101 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10106 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10107 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10110 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10112 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10115 temp = GetTVPtrIndex(SiS_Pr);
10116 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10117 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10119 if(SiS_Pr->SiS_UseROM) {
10120 romptr = SISGETROMW(0x116);
10121 if(SiS_Pr->ChipType >= SIS_330) {
10122 romptr = SISGETROMW(0x196);
10124 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10125 romptr = SISGETROMW(0x11c);
10126 if(SiS_Pr->ChipType >= SIS_330) {
10127 romptr = SISGETROMW(0x19c);
10129 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10130 romptr = SISGETROMW(0x116);
10131 if(SiS_Pr->ChipType >= SIS_330) {
10132 romptr = SISGETROMW(0x196);
10138 romptr += (temp << 2);
10139 for(j=0, i=0x31; i<=0x34; i++, j++) {
10140 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10144 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10145 for(j=0, i=0x31; i<=0x34; i++, j++) {
10146 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10147 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10148 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10149 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10151 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10155 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10156 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10157 if((resinfo == SIS_RI_640x480) ||
10158 (resinfo == SIS_RI_800x600)) {
10159 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10160 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10161 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10162 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10163 } else if(resinfo == SIS_RI_1024x768) {
10164 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10165 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10166 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10167 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10174 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10175 unsigned short ModeIdIndex, unsigned short RTI)
10177 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10178 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10180 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10183 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10184 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10186 if(SiS_Pr->SiS_ROMNew) {
10187 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10188 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10189 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10191 if(SiS_Pr->UseCustomMode) {
10192 index = SiS_Pr->CSRClock;
10193 } else if(ModeNo > 0x13) {
10194 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10195 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10197 if(index < 25) index = 25;
10198 index = ((index / 25) - 1) << 1;
10199 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10202 romptr = SISGETROMW(0x104);
10203 delay = ROMAddr[romptr + index];
10204 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10205 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10206 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10208 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10209 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10215 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10217 if(SiS_Pr->UseCustomMode) delay = 0x04;
10218 else if(ModeNo <= 0x13) delay = 0x04;
10219 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10220 delay |= (delay << 8);
10222 if(SiS_Pr->ChipType >= XGI_20) {
10225 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10228 if(SiS_Pr->SiS_XGIROM) {
10229 index = GetTVPtrIndex(SiS_Pr);
10230 if((romptr = SISGETROMW(0x35e))) {
10231 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10232 delay |= (delay << 8);
10236 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10237 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10243 } else if(SiS_Pr->ChipType >= SIS_340) {
10246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10249 /* TODO (eventually) */
10251 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10255 index = GetOEMTVPtr661(SiS_Pr);
10256 if(SiS_Pr->SiS_ROMNew) {
10257 romptr = SISGETROMW(0x106);
10258 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10259 delay = ROMAddr[romptr + index];
10262 if(index > 3) delay = 0;
10265 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10267 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10269 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10270 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10272 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10274 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10275 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10276 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10280 /* TMDS: Set our own, since BIOS has no idea */
10281 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10282 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10283 switch(SiS_Pr->SiS_LCDResInfo) {
10284 case Panel_1024x768: delay = 0x0008; break;
10285 case Panel_1280x720: delay = 0x0004; break;
10286 case Panel_1280x768:
10287 case Panel_1280x768_2:delay = 0x0004; break;
10288 case Panel_1280x800:
10289 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10290 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10291 case Panel_1280x1024: delay = 0x1e04; break;
10292 case Panel_1400x1050: delay = 0x0004; break;
10293 case Panel_1600x1200: delay = 0x0400; break;
10294 case Panel_1680x1050: delay = 0x0e04; break;
10296 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10298 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10300 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10302 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10310 /* Override by detected or user-set values */
10311 /* (but only if, for some reason, we can't read value from BIOS) */
10312 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10313 delay = SiS_Pr->PDC & 0x1f;
10315 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10316 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10323 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10325 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10326 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10328 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10329 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10334 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10336 unsigned short infoflag;
10337 unsigned char temp;
10339 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10341 if(ModeNo <= 0x13) {
10342 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10343 } else if(SiS_Pr->UseCustomMode) {
10344 infoflag = SiS_Pr->CInfoFlag;
10346 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10349 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10350 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10355 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10356 temp = (infoflag >> 6) | 0x0c;
10357 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10359 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10361 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10364 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10366 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10368 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10369 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10371 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10378 SetPanelParms661(struct SiS_Private *SiS_Pr)
10380 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10381 unsigned short romptr, temp1, temp2;
10383 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10384 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10387 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10388 if(SiS_Pr->LVDSHL != -1) {
10389 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10393 if(SiS_Pr->SiS_ROMNew) {
10395 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10396 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10397 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10399 if(SiS_Pr->LVDSHL != -1) {
10403 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10405 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10406 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10407 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10415 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10417 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10418 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10419 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10420 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10421 SetPanelParms661(SiS_Pr);
10424 SetDelayComp(SiS_Pr,ModeNo);
10427 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10428 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10429 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10430 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10431 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10432 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10438 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10439 unsigned short ModeIdIndex, unsigned short RRTI)
10441 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10443 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10445 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10446 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10447 SetPanelParms661(SiS_Pr);
10450 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10451 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10452 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10453 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10454 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10455 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10462 * This finalizes some CRT2 registers for the very panel used.
10463 * If we have a backup if these registers, we use it; otherwise
10464 * we set the register according to most BIOSes. However, this
10465 * function looks quite different in every BIOS, so you better
10466 * pray that we have a backup...
10469 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10471 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10472 unsigned short resinfo,modeflag;
10474 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10475 if(SiS_Pr->SiS_ROMNew) return;
10477 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10478 if(SiS_Pr->LVDSHL != -1) {
10479 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10483 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10484 if(SiS_Pr->UseCustomMode) return;
10486 switch(SiS_Pr->SiS_CustomT) {
10487 case CUT_COMPAQ1280:
10488 case CUT_COMPAQ12802:
10489 case CUT_CLEVO1400:
10490 case CUT_CLEVO14002:
10494 if(ModeNo <= 0x13) {
10495 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10496 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10498 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10499 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10503 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10504 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10505 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10507 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10512 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10513 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10514 /* Maybe all panels? */
10515 if(SiS_Pr->LVDSHL == -1) {
10516 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10522 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10523 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10524 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10525 if(SiS_Pr->LVDSHL == -1) {
10526 /* Maybe all panels? */
10527 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10529 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10530 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10532 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10533 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10534 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10535 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10543 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10544 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10545 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10546 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10548 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10550 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10552 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10553 if(SiS_Pr->LVDSHL == -1) {
10554 /* Maybe ACER only? */
10555 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10558 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10559 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10560 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10561 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10562 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10563 if(tempch == 0x03) {
10564 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10565 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10566 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10567 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10569 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10570 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10571 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10572 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10573 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10574 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10575 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10576 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10577 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10578 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10579 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10580 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10581 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10582 if(ModeNo <= 0x13) {
10583 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10584 if((resinfo == 0) || (resinfo == 2)) return;
10585 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10586 if((resinfo == 1) || (resinfo == 3)) return;
10588 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10589 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10590 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10592 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10594 temp = tempbx & 0xff;
10595 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10596 temp = (tempbx >> 8) & 0x03;
10597 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10600 } else if(ModeNo <= 0x13) {
10602 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10603 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10604 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10605 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10607 if(!(modeflag & HalfDCLK)) {
10608 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10609 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10610 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10611 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10612 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10613 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10614 if(ModeNo == 0x12) {
10617 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10618 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10619 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10620 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10621 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10622 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10625 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10626 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10629 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10637 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10641 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10642 tempbx = (tempbh << 8) | tempbl;
10643 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10644 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10645 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10648 if(tempbx > 770) tempbx = 770;
10649 if(SiS_Pr->SiS_VGAVDE < 600) {
10650 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10651 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10652 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10658 temp = tempbx & 0xff;
10659 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10660 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10661 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10668 /* ================= SiS 300 O.E.M. ================== */
10673 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10674 unsigned short RefTabIndex)
10676 unsigned short crt2crtc=0, modeflag, myindex=0;
10677 unsigned char temp;
10680 if(ModeNo <= 0x13) {
10681 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10682 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10684 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10685 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10690 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10691 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10694 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10695 if(modeflag & HalfDCLK) myindex = 1;
10697 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10698 for(i=0; i<7; i++) {
10699 if(barco_p1[myindex][crt2crtc][i][0]) {
10700 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10701 barco_p1[myindex][crt2crtc][i][0],
10702 barco_p1[myindex][crt2crtc][i][2],
10703 barco_p1[myindex][crt2crtc][i][1]);
10707 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10709 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10711 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10716 static unsigned short
10717 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10719 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10720 unsigned short tempbx=0,romptr=0;
10721 static const unsigned char customtable300[] = {
10722 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10723 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10725 static const unsigned char customtable630[] = {
10726 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10727 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10730 if(SiS_Pr->ChipType == SIS_300) {
10732 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10733 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10735 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10736 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10737 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10739 if(SiS_Pr->SiS_UseROM) {
10740 if(ROMAddr[0x235] & 0x80) {
10741 tempbx = SiS_Pr->SiS_LCDTypeInfo;
10743 romptr = SISGETROMW(0x255);
10744 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10745 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10746 if(tempbx == 0xFF) return 0xFFFF;
10749 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10756 if(SiS_Pr->SiS_UseROM) {
10757 romptr = SISGETROMW(0x255);
10758 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10759 else tempbx = 0xff;
10761 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10763 if(tempbx == 0xFF) return 0xFFFF;
10765 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10766 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10769 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10770 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10771 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10779 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10781 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10782 unsigned short index,temp,romptr=0;
10784 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10786 if(SiS_Pr->SiS_UseROM) {
10787 if(!(ROMAddr[0x237] & 0x01)) return;
10788 if(!(ROMAddr[0x237] & 0x02)) return;
10789 romptr = SISGETROMW(0x24b);
10792 /* The Panel Compensation Delay should be set according to tables
10793 * here. Unfortunately, various BIOS versions don't care about
10794 * a uniform way using eg. ROM byte 0x220, but use different
10795 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10796 * Thus we don't set this if the user selected a custom pdc or if
10797 * we otherwise detected a valid pdc.
10799 if(SiS_Pr->PDC != -1) return;
10801 temp = GetOEMLCDPtr(SiS_Pr, 0);
10803 if(SiS_Pr->UseCustomMode)
10806 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
10808 if(SiS_Pr->ChipType != SIS_300) {
10810 romptr += (temp * 2);
10811 romptr = SISGETROMW(romptr);
10813 temp = ROMAddr[romptr];
10815 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10816 temp = SiS300_OEMLCDDelay2[temp][index];
10818 temp = SiS300_OEMLCDDelay3[temp][index];
10822 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
10824 romptr += (temp * 2);
10825 romptr = SISGETROMW(romptr);
10827 temp = ROMAddr[romptr];
10829 temp = SiS300_OEMLCDDelay5[temp][index];
10832 if(SiS_Pr->SiS_UseROM) {
10833 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
10835 romptr += (temp * 2);
10836 romptr = SISGETROMW(romptr);
10838 temp = ROMAddr[romptr];
10840 temp = SiS300_OEMLCDDelay4[temp][index];
10843 temp = SiS300_OEMLCDDelay4[temp][index];
10848 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
10852 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10854 #if 0 /* Unfinished; Data table missing */
10855 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10856 unsigned short index,temp;
10858 if((SiS_Pr->SiS_UseROM) {
10859 if(!(ROMAddr[0x237] & 0x01)) return;
10860 if(!(ROMAddr[0x237] & 0x04)) return;
10861 /* No rom pointer in BIOS header! */
10864 temp = GetOEMLCDPtr(SiS_Pr, 1);
10865 if(temp == 0xFFFF) return;
10867 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
10868 for(i=0x14, j=0; i<=0x17; i++, j++) {
10869 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
10871 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
10873 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
10874 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
10875 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
10876 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
10877 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
10878 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
10883 static unsigned short
10884 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
10886 unsigned short index;
10889 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
10890 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10891 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
10892 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
10893 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10895 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
10896 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10902 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10904 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10905 unsigned short index,temp,romptr=0;
10907 if(SiS_Pr->SiS_UseROM) {
10908 if(!(ROMAddr[0x238] & 0x01)) return;
10909 if(!(ROMAddr[0x238] & 0x02)) return;
10910 romptr = SISGETROMW(0x241);
10913 temp = GetOEMTVPtr(SiS_Pr);
10915 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
10918 romptr += (temp * 2);
10919 romptr = SISGETROMW(romptr);
10921 temp = ROMAddr[romptr];
10923 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10924 temp = SiS300_OEMTVDelay301[temp][index];
10926 temp = SiS300_OEMTVDelayLVDS[temp][index];
10930 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
10934 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10936 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10937 unsigned short index,temp,romptr=0;
10939 if(SiS_Pr->SiS_UseROM) {
10940 if(!(ROMAddr[0x238] & 0x01)) return;
10941 if(!(ROMAddr[0x238] & 0x04)) return;
10942 romptr = SISGETROMW(0x243);
10945 temp = GetOEMTVPtr(SiS_Pr);
10947 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
10950 romptr += (temp * 2);
10951 romptr = SISGETROMW(romptr);
10953 temp = ROMAddr[romptr];
10955 temp = SiS300_OEMTVFlicker[temp][index];
10958 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
10962 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10964 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10965 unsigned short index,i,j,temp,romptr=0;
10967 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
10969 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
10971 if(SiS_Pr->SiS_UseROM) {
10972 if(!(ROMAddr[0x238] & 0x01)) return;
10973 if(!(ROMAddr[0x238] & 0x08)) return;
10974 romptr = SISGETROMW(0x245);
10977 temp = GetOEMTVPtr(SiS_Pr);
10979 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
10981 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10982 for(i=0x31, j=0; i<=0x34; i++, j++) {
10983 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
10987 romptr += (temp * 2);
10988 romptr = SISGETROMW(romptr);
10989 romptr += (index * 4);
10990 for(i=0x31, j=0; i<=0x34; i++, j++) {
10991 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10994 for(i=0x31, j=0; i<=0x34; i++, j++) {
10995 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11002 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11004 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11005 unsigned short index,temp,i,j,romptr=0;
11007 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11009 if(SiS_Pr->SiS_UseROM) {
11010 if(!(ROMAddr[0x238] & 0x01)) return;
11011 if(!(ROMAddr[0x238] & 0x10)) return;
11012 romptr = SISGETROMW(0x247);
11015 temp = GetOEMTVPtr(SiS_Pr);
11017 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11018 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11019 /* NTSCJ uses NTSC filters */
11021 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11023 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11024 for(i=0x35, j=0; i<=0x38; i++, j++) {
11025 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11027 for(i=0x48; i<=0x4A; i++, j++) {
11028 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11031 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11032 romptr += (temp * 2);
11033 romptr = SISGETROMW(romptr);
11034 romptr += (index * 4);
11035 for(i=0x35, j=0; i<=0x38; i++, j++) {
11036 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11039 for(i=0x35, j=0; i<=0x38; i++, j++) {
11040 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11046 static unsigned short
11047 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11049 unsigned short ModeIdIndex;
11050 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11052 if(*ModeNo <= 5) *ModeNo |= 1;
11054 for(ModeIdIndex=0; ; ModeIdIndex++) {
11055 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11056 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11059 if(*ModeNo != 0x07) {
11060 if(*ModeNo > 0x03) return ModeIdIndex;
11061 if(VGAINFO & 0x80) return ModeIdIndex;
11065 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11066 /* else 350 lines */
11067 return ModeIdIndex;
11071 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11072 unsigned short RefTableIndex)
11074 unsigned short OEMModeIdIndex = 0;
11076 if(!SiS_Pr->UseCustomMode) {
11077 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11078 if(!(OEMModeIdIndex)) return;
11081 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11082 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11083 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11084 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11087 if(SiS_Pr->UseCustomMode) return;
11088 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11089 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11090 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11091 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11092 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11093 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);