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 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
92 /*********************************************/
93 /* HELPER: Lock/Unlock CRT2 */
94 /*********************************************/
97 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
99 if(SiS_Pr->ChipType == XGI_20)
101 else if(SiS_Pr->ChipType >= SIS_315H)
102 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
104 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
109 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
111 if(SiS_Pr->ChipType == XGI_20)
113 else if(SiS_Pr->ChipType >= SIS_315H)
114 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
116 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
119 /*********************************************/
120 /* HELPER: Write SR11 */
121 /*********************************************/
124 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
126 if(SiS_Pr->ChipType >= SIS_661) {
130 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
133 /*********************************************/
134 /* HELPER: Get Pointer to LCD structure */
135 /*********************************************/
138 static unsigned char *
139 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
141 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
142 unsigned char *myptr = NULL;
143 unsigned short romindex = 0, reg = 0, idx = 0;
145 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
146 * due to the variaty of panels the BIOS doesn't know about.
147 * Exception: If the BIOS has better knowledge (such as in case
148 * of machines with a 301C and a panel that does not support DDC)
149 * use the BIOS data as well.
152 if((SiS_Pr->SiS_ROMNew) &&
153 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
155 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
158 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
161 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
163 romindex = SISGETROMW(0x100);
166 myptr = &ROMAddr[romindex];
172 static unsigned short
173 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
175 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
176 unsigned short romptr = 0;
178 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
179 * due to the variaty of panels the BIOS doesn't know about.
180 * Exception: If the BIOS has better knowledge (such as in case
181 * of machines with a 301C and a panel that does not support DDC)
182 * use the BIOS data as well.
185 if((SiS_Pr->SiS_ROMNew) &&
186 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
187 romptr = SISGETROMW(0x102);
188 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
195 /*********************************************/
196 /* Adjust Rate for CRT2 */
197 /*********************************************/
200 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
201 unsigned short RRTI, unsigned short *i)
203 unsigned short checkmask=0, modeid, infoflag;
205 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
207 if(SiS_Pr->SiS_VBType & VB_SISVB) {
209 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
211 checkmask |= SupportRAMDAC2;
212 if(SiS_Pr->ChipType >= SIS_315H) {
213 checkmask |= SupportRAMDAC2_135;
214 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
215 checkmask |= SupportRAMDAC2_162;
216 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
217 checkmask |= SupportRAMDAC2_202;
222 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
224 checkmask |= SupportLCD;
225 if(SiS_Pr->ChipType >= SIS_315H) {
226 if(SiS_Pr->SiS_VBType & VB_SISVB) {
227 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
228 if(modeid == 0x2e) checkmask |= Support64048060Hz;
233 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
235 checkmask |= SupportHiVision;
237 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
239 checkmask |= SupportTV;
240 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
241 checkmask |= SupportTV1024;
242 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
243 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
244 checkmask |= SupportYPbPr750p;
253 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
254 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
255 checkmask |= SupportCHTV;
259 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
260 checkmask |= SupportLCD;
265 /* Look backwards in table for matching CRT2 mode */
266 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
267 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
268 if(infoflag & checkmask) return true;
272 /* Look through the whole mode-section of the table from the beginning
273 * for a matching CRT2 mode if no mode was found yet.
275 for((*i) = 0; ; (*i)++) {
276 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
277 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
278 if(infoflag & checkmask) return true;
283 /*********************************************/
285 /*********************************************/
288 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
290 unsigned short RRTI,i,backup_i;
291 unsigned short modeflag,index,temp,backupindex;
292 static const unsigned short LCDRefreshIndex[] = {
293 0x00, 0x00, 0x01, 0x01,
294 0x01, 0x01, 0x01, 0x01,
295 0x01, 0x01, 0x01, 0x01,
296 0x01, 0x01, 0x01, 0x01,
297 0x00, 0x00, 0x00, 0x00
300 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
301 if(ModeNo == 0xfe) return 0;
304 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
306 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
309 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
310 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
311 if(modeflag & HalfDCLK) return 0;
315 if(ModeNo < 0x14) return 0xFFFF;
317 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
320 if(index > 0) index--;
322 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
323 if(SiS_Pr->SiS_VBType & VB_SISVB) {
324 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
325 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
326 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
328 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
329 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
330 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
331 if(index > temp) index = temp;
335 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
336 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
337 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
342 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
343 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
345 if(SiS_Pr->ChipType >= SIS_315H) {
346 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
347 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
348 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
349 if(backupindex <= 1) RRTI++;
356 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
357 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
358 temp &= ModeTypeMask;
359 if(temp < SiS_Pr->SiS_ModeType) break;
362 } while(index != 0xFFFF);
364 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
365 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
366 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
367 if(temp & InterlaceMode) i++;
373 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
375 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
383 /*********************************************/
384 /* STORE CRT2 INFO in CR34 */
385 /*********************************************/
388 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
390 unsigned short temp1, temp2;
392 /* Store CRT1 ModeNo in CR34 */
393 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
394 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
395 temp2 = ~(SetInSlaveMode >> 8);
396 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
399 /*********************************************/
400 /* HELPER: GET SOME DATA FROM BIOS ROM */
401 /*********************************************/
405 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
407 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
408 unsigned short temp,temp1;
410 if(SiS_Pr->SiS_UseROM) {
411 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
412 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
413 temp1 = SISGETROMW(0x23b);
414 if(temp1 & temp) return true;
421 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
423 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
424 unsigned short temp,temp1;
426 if(SiS_Pr->SiS_UseROM) {
427 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
428 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
429 temp1 = SISGETROMW(0x23d);
430 if(temp1 & temp) return true;
437 /*********************************************/
438 /* HELPER: DELAY FUNCTIONS */
439 /*********************************************/
442 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
444 while (delaytime-- > 0)
445 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
448 #if defined(SIS300) || defined(SIS315H)
450 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
452 SiS_DDC2Delay(SiS_Pr, delay * 36);
458 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
461 SiS_GenericDelay(SiS_Pr, 6623);
466 #if defined(SIS300) || defined(SIS315H)
468 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
471 SiS_GenericDelay(SiS_Pr, 66);
477 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
479 #if defined(SIS300) || defined(SIS315H)
480 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
481 unsigned short PanelID, DelayIndex, Delay=0;
484 if(SiS_Pr->ChipType < SIS_315H) {
488 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
489 if(SiS_Pr->SiS_VBType & VB_SISVB) {
490 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
491 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
493 DelayIndex = PanelID >> 4;
494 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
497 if(DelayTime >= 2) DelayTime -= 2;
498 if(!(DelayTime & 0x01)) {
499 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
501 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
503 if(SiS_Pr->SiS_UseROM) {
504 if(ROMAddr[0x220] & 0x40) {
505 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
506 else Delay = (unsigned short)ROMAddr[0x226];
510 SiS_ShortDelay(SiS_Pr, Delay);
518 if((SiS_Pr->ChipType >= SIS_661) ||
519 (SiS_Pr->ChipType <= SIS_315PRO) ||
520 (SiS_Pr->ChipType == SIS_330) ||
521 (SiS_Pr->SiS_ROMNew)) {
523 if(!(DelayTime & 0x01)) {
524 SiS_DDC2Delay(SiS_Pr, 0x1000);
526 SiS_DDC2Delay(SiS_Pr, 0x4000);
529 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
530 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
531 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
533 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
534 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
535 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
536 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
538 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
539 DelayIndex = PanelID & 0x0f;
541 DelayIndex = PanelID >> 4;
543 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
546 if(DelayTime >= 2) DelayTime -= 2;
547 if(!(DelayTime & 0x01)) {
548 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
550 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
552 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
553 if(ROMAddr[0x13c] & 0x40) {
554 if(!(DelayTime & 0x01)) {
555 Delay = (unsigned short)ROMAddr[0x17e];
557 Delay = (unsigned short)ROMAddr[0x17f];
562 SiS_ShortDelay(SiS_Pr, Delay);
565 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
567 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
568 if(!(DelayTime & 0x01)) {
569 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
571 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
574 SiS_DDC2Delay(SiS_Pr, Delay);
585 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
588 for(i = 0; i < DelayLoop; i++) {
589 SiS_PanelDelay(SiS_Pr, DelayTime);
594 /*********************************************/
595 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
596 /*********************************************/
599 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
601 unsigned short watchdog;
603 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
604 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
607 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
609 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
612 #if defined(SIS300) || defined(SIS315H)
614 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
616 unsigned short watchdog;
619 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
621 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
626 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
628 if(SiS_Pr->ChipType < SIS_315H) {
630 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
631 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
633 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
634 SiS_WaitRetrace1(SiS_Pr);
636 SiS_WaitRetrace2(SiS_Pr, 0x25);
641 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
642 SiS_WaitRetrace1(SiS_Pr);
644 SiS_WaitRetrace2(SiS_Pr, 0x30);
651 SiS_VBWait(struct SiS_Private *SiS_Pr)
653 unsigned short tempal,temp,i,j;
656 for(i = 0; i < 3; i++) {
657 for(j = 0; j < 100; j++) {
658 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
660 if((tempal & 0x08)) continue;
663 if(!(tempal & 0x08)) continue;
672 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
674 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
677 SiS_WaitRetrace1(SiS_Pr);
681 /*********************************************/
683 /*********************************************/
687 SiS_Is301B(struct SiS_Private *SiS_Pr)
689 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
695 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
697 if(SiS_Pr->ChipType == SIS_730) {
698 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
700 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
705 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
708 if(SiS_Pr->ChipType >= SIS_315H) {
709 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
710 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
718 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
723 if(SiS_Pr->ChipType >= SIS_315H) {
724 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
725 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
733 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
735 if(SiS_IsVAMode(SiS_Pr)) return true;
736 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
742 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
745 if(SiS_Pr->ChipType >= SIS_315H) {
746 if((SiS_CRT2IsLCD(SiS_Pr)) ||
747 (SiS_IsVAMode(SiS_Pr))) {
748 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
757 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
759 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
760 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
761 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
769 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
771 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
778 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
780 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
781 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
789 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
793 if(SiS_Pr->ChipType == SIS_650) {
794 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
795 /* Check for revision != A0 only */
796 if((flag == 0xe0) || (flag == 0xc0) ||
797 (flag == 0xb0) || (flag == 0x90)) return false;
798 } else if(SiS_Pr->ChipType >= SIS_661) return false;
805 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
807 if(SiS_Pr->ChipType >= SIS_315H) {
809 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
817 SiS_IsChScart(struct SiS_Private *SiS_Pr)
819 if(SiS_Pr->ChipType >= SIS_315H) {
821 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
829 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
833 if(SiS_Pr->ChipType >= SIS_315H) {
834 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
835 if(flag & SetCRT2ToTV) return true;
836 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
837 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
838 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
840 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
841 if(flag & SetCRT2ToTV) return true;
849 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
853 if(SiS_Pr->ChipType >= SIS_315H) {
854 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
855 if(flag & SetCRT2ToLCD) return true;
856 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
857 if(flag & SetToLCDA) return true;
859 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
860 if(flag & SetCRT2ToLCD) return true;
867 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
871 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
873 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
874 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
875 if((flag == 1) || (flag == 2)) return true;
881 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
885 if(SiS_HaveBridge(SiS_Pr)) {
886 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
887 if(SiS_Pr->ChipType < SIS_315H) {
889 if((flag == 0x80) || (flag == 0x20)) return true;
892 if((flag == 0x40) || (flag == 0x10)) return true;
899 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
901 unsigned short flag1;
903 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
904 if(flag1 & (SetInSlaveMode >> 8)) return true;
908 /*********************************************/
909 /* GET VIDEO BRIDGE CONFIG INFO */
910 /*********************************************/
912 /* Setup general purpose IO for Chrontel communication */
915 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
917 unsigned int acpibase;
920 if(!(SiS_Pr->SiS_ChSW)) return;
922 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
924 if(!acpibase) return;
925 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
927 SiS_SetRegShort((acpibase + 0x3c), temp);
928 temp = SiS_GetRegShort((acpibase + 0x3c));
929 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
931 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
932 SiS_SetRegShort((acpibase + 0x3a), temp);
933 temp = SiS_GetRegShort((acpibase + 0x3a));
938 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
939 unsigned short ModeIdIndex, int checkcrt2mode)
941 unsigned short tempax, tempbx, temp;
942 unsigned short modeflag, resinfo = 0;
944 SiS_Pr->SiS_SetFlag = 0;
946 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
948 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
950 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
951 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
956 if(SiS_HaveBridge(SiS_Pr)) {
958 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
960 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
961 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
965 if(SiS_Pr->ChipType >= SIS_315H) {
966 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
968 /* Mode 0x03 is never in driver mode */
969 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
971 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
972 /* Reset LCDA setting if not driver mode */
973 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
976 if(SiS_Pr->SiS_UseLCDA) {
977 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
978 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
979 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
984 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
985 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
986 tempbx |= SetCRT2ToLCDA;
990 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
991 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
992 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
993 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
994 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
995 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
996 tempbx |= SetCRT2ToYPbPr525750;
1001 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1002 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1003 if(temp & SetToLCDA) {
1004 tempbx |= SetCRT2ToLCDA;
1006 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1007 if(temp & EnableCHYPbPr) {
1008 tempbx |= SetCRT2ToCHYPbPr;
1014 #endif /* SIS315H */
1016 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1017 tempbx &= ~(SetCRT2ToRAMDAC);
1020 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1021 temp = SetCRT2ToSVIDEO |
1028 SetCRT2ToYPbPr525750;
1030 if(SiS_Pr->ChipType >= SIS_315H) {
1031 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1032 temp = SetCRT2ToAVIDEO |
1039 temp = SetCRT2ToLCDA |
1043 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1044 temp = SetCRT2ToTV | SetCRT2ToLCD;
1046 temp = SetCRT2ToLCD;
1051 if(!(tempbx & temp)) {
1052 tempax = DisableCRT2Display;
1056 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1058 unsigned short clearmask = ( DriverMode |
1059 DisableCRT2Display |
1067 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1068 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1069 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1070 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1071 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1072 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1076 if(SiS_Pr->ChipType >= SIS_315H) {
1077 if(tempbx & SetCRT2ToLCDA) {
1078 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1081 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1082 if(tempbx & SetCRT2ToTV) {
1083 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1086 if(tempbx & SetCRT2ToLCD) {
1087 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1089 if(SiS_Pr->ChipType >= SIS_315H) {
1090 if(tempbx & SetCRT2ToLCDA) {
1091 tempbx |= SetCRT2ToLCD;
1097 if(tempax & DisableCRT2Display) {
1098 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1099 tempbx = SetSimuScanMode | DisableCRT2Display;
1103 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1105 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1106 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1107 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1108 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1109 modeflag &= (~CRT2Mode);
1113 if(!(tempbx & SetSimuScanMode)) {
1114 if(tempbx & SwitchCRT2) {
1115 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1116 if(resinfo != SIS_RI_1600x1200) {
1117 tempbx |= SetSimuScanMode;
1121 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1122 if(!(tempbx & DriverMode)) {
1123 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1124 tempbx |= SetSimuScanMode;
1131 if(!(tempbx & DisableCRT2Display)) {
1132 if(tempbx & DriverMode) {
1133 if(tempbx & SetSimuScanMode) {
1134 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1135 if(resinfo != SIS_RI_1600x1200) {
1136 tempbx |= SetInSlaveMode;
1141 tempbx |= SetInSlaveMode;
1147 SiS_Pr->SiS_VBInfo = tempbx;
1150 if(SiS_Pr->ChipType == SIS_630) {
1151 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1156 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1157 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1161 /*********************************************/
1162 /* DETERMINE YPbPr MODE */
1163 /*********************************************/
1166 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1171 /* Note: This variable is only used on 30xLV systems.
1172 * CR38 has a different meaning on LVDS/CH7019 systems.
1173 * On 661 and later, these bits moved to CR35.
1175 * On 301, 301B, only HiVision 1080i is supported.
1176 * On 30xLV, 301C, only YPbPr 1080i is supported.
1179 SiS_Pr->SiS_YPbPr = 0;
1180 if(SiS_Pr->ChipType >= SIS_661) return;
1182 if(SiS_Pr->SiS_VBType) {
1183 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1184 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1188 if(SiS_Pr->ChipType >= SIS_315H) {
1189 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1190 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1192 switch((temp >> 4)) {
1193 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1194 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1195 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1196 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1204 /*********************************************/
1205 /* DETERMINE TVMode flag */
1206 /*********************************************/
1209 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1211 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1212 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1213 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1215 SiS_Pr->SiS_TVMode = 0;
1217 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1218 if(SiS_Pr->UseCustomMode) return;
1221 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1224 if(SiS_Pr->ChipType < SIS_661) {
1226 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1228 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1230 if((SiS_Pr->ChipType == SIS_630) ||
1231 (SiS_Pr->ChipType == SIS_730)) {
1234 } else if(SiS_Pr->ChipType >= SIS_315H) {
1236 if(SiS_Pr->ChipType < XGI_20) {
1238 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1242 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1243 OutputSelect = ROMAddr[romindex];
1244 if(!(OutputSelect & EnablePALMN)) {
1245 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1248 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1249 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1250 if(temp1 & EnablePALM) { /* 0x40 */
1251 SiS_Pr->SiS_TVMode |= TVSetPALM;
1252 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1253 } else if(temp1 & EnablePALN) { /* 0x80 */
1254 SiS_Pr->SiS_TVMode |= TVSetPALN;
1257 if(temp1 & EnableNTSCJ) { /* 0x40 */
1258 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1262 /* Translate HiVision/YPbPr to our new flags */
1263 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1264 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1265 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1266 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1267 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1268 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1269 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1270 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1271 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1272 SiS_Pr->SiS_TVMode |= TVSetPAL;
1275 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1276 if(SiS_Pr->SiS_CHOverScan) {
1277 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1278 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1279 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1280 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1282 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1283 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1284 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1285 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1288 if(SiS_Pr->SiS_CHSOverScan) {
1289 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1292 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1293 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1294 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1295 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1296 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1298 if(temp & EnableNTSCJ) {
1299 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1305 } else { /* 661 and later */
1307 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1309 SiS_Pr->SiS_TVMode |= TVSetPAL;
1311 SiS_Pr->SiS_TVMode |= TVSetPALN;
1312 } else if(temp1 & 0x04) {
1313 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1314 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1316 SiS_Pr->SiS_TVMode |= TVSetPALM;
1320 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1323 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1324 if(SiS_Pr->SiS_CHOverScan) {
1325 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1326 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1330 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1331 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1333 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1334 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1335 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1336 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1337 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1339 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1340 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1341 SiS_Pr->SiS_TVMode |= TVAspect169;
1343 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1345 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1346 SiS_Pr->SiS_TVMode |= TVAspect169;
1348 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1351 SiS_Pr->SiS_TVMode |= TVAspect43;
1358 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1360 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1362 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1363 SiS_Pr->SiS_TVMode |= TVSetPAL;
1364 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1365 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1366 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1367 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1371 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1372 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1373 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1377 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1378 if(resinfo == SIS_RI_1024x768) {
1379 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1380 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1381 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1382 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1387 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1388 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1389 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1390 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1391 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1392 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1393 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1394 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1395 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1401 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1404 /*********************************************/
1406 /*********************************************/
1408 static unsigned short
1409 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1411 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1412 /* Translate my LCDResInfo to BIOS value */
1414 case Panel_1280x768_2: temp = Panel_1280x768; break;
1415 case Panel_1280x800_2: temp = Panel_1280x800; break;
1416 case Panel_1280x854: temp = Panel661_1280x854; break;
1422 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1425 unsigned char *ROMAddr;
1426 unsigned short temp;
1428 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1429 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1430 SiS_Pr->SiS_NeedRomModeData = true;
1431 SiS_Pr->PanelHT = temp;
1433 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1434 SiS_Pr->SiS_NeedRomModeData = true;
1435 SiS_Pr->PanelVT = temp;
1437 SiS_Pr->PanelHRS = SISGETROMW(10);
1438 SiS_Pr->PanelHRE = SISGETROMW(12);
1439 SiS_Pr->PanelVRS = SISGETROMW(14);
1440 SiS_Pr->PanelVRE = SISGETROMW(16);
1441 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1442 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1443 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1444 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1445 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1446 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1447 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1454 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1455 const unsigned char *nonscalingmodes)
1458 while(nonscalingmodes[i] != 0xff) {
1459 if(nonscalingmodes[i++] == resinfo) {
1460 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1461 (SiS_Pr->UsePanelScaler == -1)) {
1462 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1470 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1472 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1473 bool panelcanscale = false;
1475 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1476 static const unsigned char SiS300SeriesLCDRes[] =
1477 { 0, 1, 2, 3, 7, 4, 5, 8,
1478 0, 0, 10, 0, 0, 0, 0, 15 };
1481 unsigned char *myptr = NULL;
1484 SiS_Pr->SiS_LCDResInfo = 0;
1485 SiS_Pr->SiS_LCDTypeInfo = 0;
1486 SiS_Pr->SiS_LCDInfo = 0;
1487 SiS_Pr->PanelHRS = 999; /* HSync start */
1488 SiS_Pr->PanelHRE = 999; /* HSync end */
1489 SiS_Pr->PanelVRS = 999; /* VSync start */
1490 SiS_Pr->PanelVRE = 999; /* VSync end */
1491 SiS_Pr->SiS_NeedRomModeData = false;
1493 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1494 SiS_Pr->Alternate1600x1200 = false;
1496 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1498 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1500 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1501 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1502 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1503 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1506 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1508 /* For broken BIOSes: Assume 1024x768 */
1509 if(temp == 0) temp = 0x02;
1511 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1512 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1513 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1514 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1516 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1520 if(SiS_Pr->ChipType < SIS_315H) {
1521 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1522 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1523 if(temp < 0x0f) temp &= 0x07;
1525 /* Translate 300 series LCDRes to 315 series for unified usage */
1526 temp = SiS300SeriesLCDRes[temp];
1530 /* Translate to our internal types */
1532 if(SiS_Pr->ChipType == SIS_550) {
1533 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1534 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1535 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1536 } else if(SiS_Pr->ChipType >= SIS_661) {
1537 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1541 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1542 if(temp == Panel310_1280x768) {
1543 temp = Panel_1280x768_2;
1545 if(SiS_Pr->SiS_ROMNew) {
1546 if(temp == Panel661_1280x800) {
1547 temp = Panel_1280x800_2;
1552 SiS_Pr->SiS_LCDResInfo = temp;
1555 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1556 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1557 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1558 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1559 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1560 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1561 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1566 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1567 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1568 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1570 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1571 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1574 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1575 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1576 /* Need temp below! */
1578 /* These must/can't scale no matter what */
1579 switch(SiS_Pr->SiS_LCDResInfo) {
1580 case Panel_320x240_1:
1581 case Panel_320x240_2:
1582 case Panel_320x240_3:
1583 case Panel_1280x960:
1584 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1587 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1590 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1592 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1593 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1595 /* Dual link, Pass 1:1 BIOS default, etc. */
1597 if(SiS_Pr->ChipType >= SIS_661) {
1598 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1599 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1601 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1602 if(SiS_Pr->SiS_ROMNew) {
1603 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1604 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1605 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1608 } else if(SiS_Pr->ChipType >= SIS_315H) {
1609 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1610 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1612 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1613 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1614 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1615 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1616 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1617 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1619 } else if(!(SiS_Pr->SiS_ROMNew)) {
1620 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1621 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1622 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1623 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1625 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1626 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1627 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1628 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1629 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1637 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1638 /* Always center screen on LVDS (if scaling is disabled) */
1639 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1640 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1641 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1642 /* Always center screen on SiS LVDS (if scaling is disabled) */
1643 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1645 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1646 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1647 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1651 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1652 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1654 switch(SiS_Pr->SiS_LCDResInfo) {
1655 case Panel_320x240_1:
1656 case Panel_320x240_2:
1657 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1658 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1659 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1660 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1662 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1663 SiS_Pr->PanelVRE = 3;
1664 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1665 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1667 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1668 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1669 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1670 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1671 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1672 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1674 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1675 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1676 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1677 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1678 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1679 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1681 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1682 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1683 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1684 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1685 if(SiS_Pr->ChipType < SIS_315H) {
1686 SiS_Pr->PanelHRS = 23;
1687 SiS_Pr->PanelVRE = 5;
1689 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1690 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1691 SiS_GetLCDInfoBIOS(SiS_Pr);
1693 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1694 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1695 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1696 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1697 if(SiS_Pr->ChipType < SIS_315H) {
1698 SiS_Pr->PanelHRS = 23;
1699 SiS_Pr->PanelVRE = 5;
1701 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1702 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1704 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1706 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1707 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1708 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1709 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1710 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1711 /* Data above for TMDS (projector); get from BIOS for LVDS */
1712 SiS_GetLCDInfoBIOS(SiS_Pr);
1714 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1715 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1716 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1717 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1718 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1720 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1721 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1722 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1723 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1724 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1727 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1728 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1729 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1730 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1731 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1732 SiS_GetLCDInfoBIOS(SiS_Pr);
1734 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1735 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1736 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1737 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1738 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1739 SiS_GetLCDInfoBIOS(SiS_Pr);
1741 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1742 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1743 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1744 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1745 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1746 SiS_GetLCDInfoBIOS(SiS_Pr);
1748 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1749 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1750 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1751 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1752 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1753 SiS_GetLCDInfoBIOS(SiS_Pr);
1755 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1756 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1757 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1758 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1759 if(resinfo == SIS_RI_1280x1024) {
1760 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1761 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1764 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1765 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1766 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1767 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1768 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1769 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1770 SiS_GetLCDInfoBIOS(SiS_Pr);
1772 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1773 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1774 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1775 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1776 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1777 SiS_GetLCDInfoBIOS(SiS_Pr);
1779 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1780 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1781 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1782 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1783 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1784 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1785 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1786 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1787 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1788 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1789 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1790 SiS_Pr->Alternate1600x1200 = true;
1792 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1793 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1794 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1795 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1797 SiS_GetLCDInfoBIOS(SiS_Pr);
1799 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1800 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1801 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1802 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1803 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1804 SiS_GetLCDInfoBIOS(SiS_Pr);
1806 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1807 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1809 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1810 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1812 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1813 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1815 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1816 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1817 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1818 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1819 if(SiS_Pr->CP_PreferredIndex != -1) {
1820 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1821 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1822 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1823 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1824 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1825 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1826 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1827 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1828 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1829 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1830 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1831 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1832 if(SiS_Pr->CP_PrefClock) {
1834 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1835 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1836 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1837 else idx = VCLK_CUSTOM_315;
1838 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1839 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1840 SiS_Pr->SiS_VCLKData[idx].SR2B =
1841 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1842 SiS_Pr->SiS_VCLKData[idx].SR2C =
1843 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1847 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1848 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1853 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1854 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1855 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1856 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1857 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1858 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1859 SiS_Pr->PanelHRS = 999;
1860 SiS_Pr->PanelHRE = 999;
1863 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1864 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1865 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1866 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1867 SiS_Pr->PanelVRS = 999;
1868 SiS_Pr->PanelVRE = 999;
1871 /* DontExpand overrule */
1872 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1874 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1875 /* No scaling for this mode on any panel (LCD=CRT2)*/
1876 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1879 switch(SiS_Pr->SiS_LCDResInfo) {
1882 case Panel_1152x864:
1883 case Panel_1280x768: /* TMDS only */
1884 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1887 case Panel_800x600: {
1888 static const unsigned char nonscalingmodes[] = {
1889 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1891 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1894 case Panel_1024x768: {
1895 static const unsigned char nonscalingmodes[] = {
1896 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1897 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1900 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1903 case Panel_1280x720: {
1904 static const unsigned char nonscalingmodes[] = {
1905 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1906 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1909 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1910 if(SiS_Pr->PanelHT == 1650) {
1911 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1915 case Panel_1280x768_2: { /* LVDS only */
1916 static const unsigned char nonscalingmodes[] = {
1917 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1918 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1919 SIS_RI_1152x768,0xff
1921 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1923 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1924 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1930 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1931 static const unsigned char nonscalingmodes[] = {
1932 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1933 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1934 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1936 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1939 case Panel_1280x800_2: { /* SiS LVDS */
1940 static const unsigned char nonscalingmodes[] = {
1941 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1942 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1943 SIS_RI_1152x768,0xff
1945 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1947 case SIS_RI_1280x720:
1948 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1949 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1955 case Panel_1280x854: { /* SiS LVDS */
1956 static const unsigned char nonscalingmodes[] = {
1957 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1958 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1959 SIS_RI_1152x768,0xff
1961 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1963 case SIS_RI_1280x720:
1964 case SIS_RI_1280x768:
1965 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
1966 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1972 case Panel_1280x960: {
1973 static const unsigned char nonscalingmodes[] = {
1974 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1975 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1976 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1977 SIS_RI_1280x854,0xff
1979 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1982 case Panel_1280x1024: {
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,SIS_RI_1280x960,0xff
1989 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1992 case Panel_1400x1050: {
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_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
1997 SIS_RI_1280x960,0xff
1999 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2001 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2002 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2005 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2010 case Panel_1600x1200: {
2011 static const unsigned char nonscalingmodes[] = {
2012 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2013 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2014 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2015 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2017 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2020 case Panel_1680x1050: {
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_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2025 SIS_RI_1360x1024,0xff
2027 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2034 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2035 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2036 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2040 if(SiS_Pr->ChipType < SIS_315H) {
2041 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2042 if(SiS_Pr->SiS_UseROM) {
2043 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2044 if(!(ROMAddr[0x235] & 0x02)) {
2045 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2049 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2050 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2051 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2059 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2060 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2063 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2064 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2067 switch(SiS_Pr->SiS_LCDResInfo) {
2069 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2071 case Panel_1280x800:
2072 /* Don't pass 1:1 by default (TMDS special) */
2073 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2075 case Panel_1280x960:
2076 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2079 if((!SiS_Pr->CP_PrefClock) ||
2080 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2081 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2086 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2087 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2090 /* (In)validate LCDPass11 flag */
2091 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2092 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2096 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2098 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2099 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2100 if(ModeNo == 0x12) {
2101 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2102 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2104 } else if(ModeNo > 0x13) {
2105 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2106 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2107 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2108 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2116 if(modeflag & HalfDCLK) {
2117 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2118 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2119 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2120 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2121 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2122 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2123 } else if(ModeNo > 0x13) {
2124 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2125 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2126 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2127 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2135 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2136 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2137 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2140 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2144 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2145 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2149 /*********************************************/
2151 /*********************************************/
2154 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2155 unsigned short RefreshRateTableIndex)
2157 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2158 unsigned short modeflag, resinfo, tempbx;
2159 const unsigned char *CHTVVCLKPtr = NULL;
2161 if(ModeNo <= 0x13) {
2162 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2163 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2164 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2165 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2166 VCLKIndexGENCRT = VCLKIndexGEN;
2168 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2169 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2170 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2171 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2172 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2173 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2176 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2178 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2181 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2183 if(SiS_Pr->ChipType < SIS_315H) {
2184 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2185 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2186 VCLKIndex = VCLKIndexGEN;
2189 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2190 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2192 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2193 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2194 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2195 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2196 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2197 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2198 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2199 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2200 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2201 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2202 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2203 default: VCLKIndex = VCLKIndexGEN;
2206 if(ModeNo <= 0x13) {
2207 if(SiS_Pr->ChipType <= SIS_315PRO) {
2208 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2210 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2213 if(SiS_Pr->ChipType <= SIS_315PRO) {
2214 if(VCLKIndex == 0) VCLKIndex = 0x41;
2215 if(VCLKIndex == 1) VCLKIndex = 0x43;
2216 if(VCLKIndex == 4) VCLKIndex = 0x44;
2221 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2223 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2224 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2225 else VCLKIndex = HiTVVCLK;
2226 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2227 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2228 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2229 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2230 else VCLKIndex = TVVCLK;
2232 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2233 else VCLKIndex += TVCLKBASE_315;
2237 VCLKIndex = VCLKIndexGENCRT;
2238 if(SiS_Pr->ChipType < SIS_315H) {
2240 if( (SiS_Pr->ChipType == SIS_630) &&
2241 (SiS_Pr->ChipRevision >= 0x30)) {
2242 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2244 /* Better VGA2 clock for 1280x1024@75 */
2245 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2250 } else { /* If not programming CRT2 */
2252 VCLKIndex = VCLKIndexGENCRT;
2253 if(SiS_Pr->ChipType < SIS_315H) {
2255 if( (SiS_Pr->ChipType != SIS_630) &&
2256 (SiS_Pr->ChipType != SIS_300) ) {
2257 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2265 VCLKIndex = CRT2Index;
2267 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2269 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2273 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2274 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2276 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2277 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2279 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2281 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2282 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2284 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2288 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2289 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2290 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2291 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2292 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2293 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2294 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2295 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2296 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2297 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2299 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2301 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2303 if(SiS_Pr->ChipType < SIS_315H) {
2304 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2306 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2310 /* Special Timing: Barco iQ Pro R series */
2311 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2313 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2314 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2315 if(SiS_Pr->ChipType < SIS_315H) {
2316 VCLKIndex = VCLK34_300;
2317 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2319 VCLKIndex = VCLK34_315;
2320 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2327 VCLKIndex = VCLKIndexGENCRT;
2328 if(SiS_Pr->ChipType < SIS_315H) {
2330 if( (SiS_Pr->ChipType == SIS_630) &&
2331 (SiS_Pr->ChipRevision >= 0x30) ) {
2332 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2338 } else { /* if not programming CRT2 */
2340 VCLKIndex = VCLKIndexGENCRT;
2341 if(SiS_Pr->ChipType < SIS_315H) {
2343 if( (SiS_Pr->ChipType != SIS_630) &&
2344 (SiS_Pr->ChipType != SIS_300) ) {
2345 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2348 if(SiS_Pr->ChipType == SIS_730) {
2349 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2350 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2363 /*********************************************/
2364 /* SET CRT2 MODE TYPE REGISTERS */
2365 /*********************************************/
2368 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2370 unsigned short i, j, modeflag, tempah=0;
2372 #if defined(SIS300) || defined(SIS315H)
2373 unsigned short tempbl;
2376 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2377 unsigned short tempah2, tempbl2;
2380 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2382 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2384 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2385 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2389 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2390 if(SiS_Pr->ChipType >= SIS_315H) {
2391 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2394 tempcl = SiS_Pr->SiS_ModeType;
2396 if(SiS_Pr->ChipType < SIS_315H) {
2398 #ifdef SIS300 /* ---- 300 series ---- */
2400 /* For 301BDH: (with LCD via LVDS) */
2401 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2402 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2405 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2409 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2415 tempah = ((0x10 >> tempcl) | 0x80);
2417 } else tempah = 0x80;
2419 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2425 #ifdef SIS315H /* ------- 315/330 series ------ */
2430 tempah = (0x08 >> tempcl);
2431 if (tempah == 0) tempah = 1;
2434 } else tempah = 0x40;
2436 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2438 #endif /* SIS315H */
2442 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2444 if(SiS_Pr->ChipType < SIS_315H) {
2445 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2448 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2449 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2450 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2452 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2454 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2460 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2463 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2466 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2468 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2473 if(SiS_Pr->ChipType < SIS_315H) {
2475 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2477 tempah = (tempah << 5) & 0xFF;
2478 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2479 tempah = (tempah >> 5) & 0xFF;
2483 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2484 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2485 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2490 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2495 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2496 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2499 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2500 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2501 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2507 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2510 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2511 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2514 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2516 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2517 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2522 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2526 if(SiS_Pr->ChipType >= SIS_315H) {
2529 /* LVDS can only be slave in 8bpp modes */
2531 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2532 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2537 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2539 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2541 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2543 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2550 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2555 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2557 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2566 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2568 if(SiS_Pr->ChipType >= SIS_315H) {
2571 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2573 /* The following is nearly unpreditable and varies from machine
2574 * to machine. Especially the 301DH seems to be a real trouble
2575 * maker. Some BIOSes simply set the registers (like in the
2576 * NoLCD-if-statements here), some set them according to the
2577 * LCDA stuff. It is very likely that some machines are not
2578 * treated correctly in the following, very case-orientated
2579 * code. What do I do then...?
2582 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2585 tempah = 0x04; /* For all bridges */
2587 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2589 if(SiS_IsDualEdge(SiS_Pr)) {
2593 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2596 /* The following two are responsible for eventually wrong colors
2597 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2598 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2599 * in a 650 box (Jake). What is the criteria?
2600 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2601 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2602 * chipset than the bridge revision.
2605 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2608 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2609 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2613 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2614 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2615 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2616 /* Fixes "TV-blue-bug" on 315+301 */
2617 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2618 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2619 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2620 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2621 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2622 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2623 tempah = 0x30; tempah2 = 0xc0;
2624 tempbl = 0xcf; tempbl2 = 0x3f;
2625 if(SiS_Pr->SiS_TVBlue == 0) {
2626 tempah = tempah2 = 0x00;
2627 } else if(SiS_Pr->SiS_TVBlue == -1) {
2628 /* Set on 651/M650, clear on 315/650 */
2629 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2630 tempah = tempah2 = 0x00;
2633 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2634 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2636 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2637 tempbl = 0xcf; tempbl2 = 0x3f;
2638 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2639 tempah = tempah2 = 0x00;
2640 if(SiS_IsDualEdge(SiS_Pr)) {
2641 tempbl = tempbl2 = 0xff;
2644 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2645 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2650 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2651 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2655 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2657 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2659 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2662 #endif /* SIS315H */
2664 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2667 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2669 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2670 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2671 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2672 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2674 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2680 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2681 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2682 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2683 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2690 if(SiS_Pr->ChipType >= SIS_315H) {
2692 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2696 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2698 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2700 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2702 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2703 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2706 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2708 } else if(SiS_Pr->ChipType == SIS_550) {
2710 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2711 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2722 /*********************************************/
2723 /* GET RESOLUTION DATA */
2724 /*********************************************/
2727 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2730 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2732 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2736 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2738 unsigned short xres, yres, modeflag=0, resindex;
2740 if(SiS_Pr->UseCustomMode) {
2741 xres = SiS_Pr->CHDisplay;
2742 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2743 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2744 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2745 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2749 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2751 if(ModeNo <= 0x13) {
2752 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2753 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2755 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2756 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2757 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2760 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2762 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2763 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2764 if(yres == 350) yres = 400;
2766 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2767 if(ModeNo == 0x12) yres = 400;
2771 if(modeflag & HalfDCLK) xres <<= 1;
2772 if(modeflag & DoubleScanMode) yres <<= 1;
2776 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2778 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2779 switch(SiS_Pr->SiS_LCDResInfo) {
2780 case Panel_1024x768:
2781 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2782 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2783 if(yres == 350) yres = 357;
2784 if(yres == 400) yres = 420;
2785 if(yres == 480) yres = 525;
2789 case Panel_1280x1024:
2790 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2791 /* BIOS bug - does this regardless of scaling */
2792 if(yres == 400) yres = 405;
2794 if(yres == 350) yres = 360;
2795 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2796 if(yres == 360) yres = 375;
2799 case Panel_1600x1200:
2800 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2801 if(yres == 1024) yres = 1056;
2809 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2810 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2811 if(xres == 720) xres = 640;
2813 } else if(xres == 720) xres = 640;
2815 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2817 if(SiS_Pr->ChipType >= SIS_315H) {
2818 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2820 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2822 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2826 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2827 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2830 /*********************************************/
2831 /* GET CRT2 TIMING DATA */
2832 /*********************************************/
2835 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2836 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2837 unsigned short *ResIndex)
2839 unsigned short tempbx=0, tempal=0, resinfo=0;
2841 if(ModeNo <= 0x13) {
2842 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2844 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2845 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2848 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2850 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2852 tempbx = SiS_Pr->SiS_LCDResInfo;
2853 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2856 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2857 if (resinfo == SIS_RI_1280x800) tempal = 9;
2858 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2859 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2860 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2861 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2862 if (resinfo == SIS_RI_1280x768) tempal = 9;
2865 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2866 /* Pass 1:1 only (center-screen handled outside) */
2867 /* This is never called for the panel's native resolution */
2868 /* since Pass1:1 will not be set in this case */
2870 if(ModeNo >= 0x13) {
2871 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2876 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2877 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2878 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2880 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2888 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2889 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2891 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2893 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2895 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2896 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2897 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2899 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2901 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2903 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2911 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2913 case SIS_RI_720x480:
2915 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
2917 case SIS_RI_720x576:
2918 case SIS_RI_768x576:
2919 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2921 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2922 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
2925 case SIS_RI_800x480:
2928 case SIS_RI_512x384:
2929 case SIS_RI_1024x768:
2931 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2932 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
2935 case SIS_RI_1280x720:
2936 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2937 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
2944 *CRT2Index = tempbx;
2947 } else { /* LVDS, 301B-DH (if running on LCD) */
2950 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2953 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2955 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2956 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2958 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
2959 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
2962 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
2967 switch(SiS_Pr->SiS_LCDResInfo) {
2968 case Panel_640x480: tempbx = 12; break;
2969 case Panel_320x240_1: tempbx = 10; break;
2970 case Panel_320x240_2:
2971 case Panel_320x240_3: tempbx = 14; break;
2972 case Panel_800x600: tempbx = 16; break;
2973 case Panel_1024x600: tempbx = 18; break;
2974 case Panel_1152x768:
2975 case Panel_1024x768: tempbx = 20; break;
2976 case Panel_1280x768: tempbx = 22; break;
2977 case Panel_1280x1024: tempbx = 24; break;
2978 case Panel_1400x1050: tempbx = 26; break;
2979 case Panel_1600x1200: tempbx = 28; break;
2981 case Panel_Barco1366: tempbx = 80; break;
2985 switch(SiS_Pr->SiS_LCDResInfo) {
2986 case Panel_320x240_1:
2987 case Panel_320x240_2:
2988 case Panel_320x240_3:
2992 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2995 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
2998 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3000 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3001 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3003 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3009 (*CRT2Index) = tempbx;
3010 (*ResIndex) = tempal & 0x1F;
3015 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3016 unsigned short RefreshRateTableIndex)
3018 unsigned short tempax=0, tempbx=0, index, dotclock;
3019 unsigned short temp1=0, modeflag=0, tempcx=0;
3021 SiS_Pr->SiS_RVBHCMAX = 1;
3022 SiS_Pr->SiS_RVBHCFACT = 1;
3024 if(ModeNo <= 0x13) {
3026 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3027 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3029 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3030 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3031 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3033 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3037 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3038 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3040 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3041 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3043 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3044 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3048 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3054 if(temp1 & 0x01) tempbx |= 0x0100;
3055 if(temp1 & 0x20) tempbx |= 0x0200;
3059 if(modeflag & HalfDCLK) tempax <<= 1;
3063 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3064 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3068 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3069 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3071 unsigned short ResIndex;
3073 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3074 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3075 if(SiS_Pr->UseCustomMode) {
3076 ResIndex = SiS_Pr->CHTotal;
3077 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3078 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3079 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3082 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3084 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3086 if(ResIndex == 0x09) {
3087 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3088 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3090 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3091 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3092 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3093 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3096 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3097 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3100 /* This handles custom modes and custom panels */
3101 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3102 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3103 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3104 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3105 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3106 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3111 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3112 unsigned short RefreshRateTableIndex)
3114 unsigned short CRT2Index, ResIndex, backup;
3115 const struct SiS_LVDSData *LVDSData = NULL;
3117 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3119 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3120 SiS_Pr->SiS_RVBHCMAX = 1;
3121 SiS_Pr->SiS_RVBHCFACT = 1;
3122 SiS_Pr->SiS_NewFlickerMode = 0;
3123 SiS_Pr->SiS_RVBHRS = 50;
3124 SiS_Pr->SiS_RY1COE = 0;
3125 SiS_Pr->SiS_RY2COE = 0;
3126 SiS_Pr->SiS_RY3COE = 0;
3127 SiS_Pr->SiS_RY4COE = 0;
3128 SiS_Pr->SiS_RVBHRS2 = 0;
3131 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3134 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3135 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3140 /* 301BDH needs LVDS Data */
3141 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3142 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3143 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3146 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3147 &CRT2Index, &ResIndex);
3149 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3152 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3153 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3154 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3155 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3156 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3157 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3159 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3160 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3161 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3162 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3163 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3165 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3166 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3167 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3168 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3169 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3170 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3171 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3172 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3173 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3177 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3178 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3179 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3180 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3182 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3185 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3186 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3187 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3188 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3189 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3190 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3191 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3193 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3194 if(ResIndex < 0x08) {
3195 SiS_Pr->SiS_HDE = 1280;
3196 SiS_Pr->SiS_VDE = 1024;
3206 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3207 unsigned short RefreshRateTableIndex)
3209 unsigned char *ROMAddr = NULL;
3210 unsigned short tempax, tempbx, modeflag, romptr=0;
3211 unsigned short resinfo, CRT2Index, ResIndex;
3212 const struct SiS_LCDData *LCDPtr = NULL;
3213 const struct SiS_TVData *TVPtr = NULL;
3218 if(ModeNo <= 0x13) {
3219 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3220 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3221 } else if(SiS_Pr->UseCustomMode) {
3222 modeflag = SiS_Pr->CModeFlag;
3225 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3226 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3228 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3229 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3230 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3231 (resinfo661 >= 0) &&
3232 (SiS_Pr->SiS_NeedRomModeData) ) {
3233 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3234 if((romptr = (SISGETROMW(21)))) {
3235 romptr += (resinfo661 * 10);
3236 ROMAddr = SiS_Pr->VirtualRomBase;
3243 SiS_Pr->SiS_NewFlickerMode = 0;
3244 SiS_Pr->SiS_RVBHRS = 50;
3245 SiS_Pr->SiS_RY1COE = 0;
3246 SiS_Pr->SiS_RY2COE = 0;
3247 SiS_Pr->SiS_RY3COE = 0;
3248 SiS_Pr->SiS_RY4COE = 0;
3249 SiS_Pr->SiS_RVBHRS2 = 0;
3251 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3253 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3255 if(SiS_Pr->UseCustomMode) {
3257 SiS_Pr->SiS_RVBHCMAX = 1;
3258 SiS_Pr->SiS_RVBHCFACT = 1;
3259 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3260 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3262 tempax = SiS_Pr->CHTotal;
3263 if(modeflag & HalfDCLK) tempax <<= 1;
3264 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3265 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3269 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3273 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3275 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3276 &CRT2Index,&ResIndex);
3279 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3280 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3281 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3282 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3283 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3284 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3285 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3286 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3287 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3288 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3289 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3290 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3291 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3292 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3295 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3296 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3297 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3298 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3299 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3300 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3301 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3302 if(modeflag & HalfDCLK) {
3303 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3304 if(SiS_Pr->SiS_RVBHRS2) {
3305 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3306 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3307 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3308 else SiS_Pr->SiS_RVBHRS2 += tempax;
3311 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3313 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3315 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3317 if((resinfo == SIS_RI_960x600) ||
3318 (resinfo == SIS_RI_1024x768) ||
3319 (resinfo == SIS_RI_1280x1024) ||
3320 (resinfo == SIS_RI_1280x720)) {
3321 SiS_Pr->SiS_NewFlickerMode = 0x40;
3324 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3326 SiS_Pr->SiS_HT = ExtHiTVHT;
3327 SiS_Pr->SiS_VT = ExtHiTVVT;
3328 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3329 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3330 SiS_Pr->SiS_HT = StHiTVHT;
3331 SiS_Pr->SiS_VT = StHiTVVT;
3335 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3337 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3338 SiS_Pr->SiS_HT = 1650;
3339 SiS_Pr->SiS_VT = 750;
3340 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3341 SiS_Pr->SiS_HT = NTSCHT;
3342 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3343 SiS_Pr->SiS_VT = NTSCVT;
3345 SiS_Pr->SiS_HT = NTSCHT;
3346 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3347 SiS_Pr->SiS_VT = NTSCVT;
3352 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3353 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3354 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3355 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3357 if(modeflag & HalfDCLK) {
3358 SiS_Pr->SiS_RY1COE = 0x00;
3359 SiS_Pr->SiS_RY2COE = 0xf4;
3360 SiS_Pr->SiS_RY3COE = 0x10;
3361 SiS_Pr->SiS_RY4COE = 0x38;
3364 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3365 SiS_Pr->SiS_HT = NTSCHT;
3366 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3367 SiS_Pr->SiS_VT = NTSCVT;
3369 SiS_Pr->SiS_HT = PALHT;
3370 SiS_Pr->SiS_VT = PALVT;
3375 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3377 SiS_Pr->SiS_RVBHCMAX = 1;
3378 SiS_Pr->SiS_RVBHCFACT = 1;
3380 if(SiS_Pr->UseCustomMode) {
3382 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3383 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3385 tempax = SiS_Pr->CHTotal;
3386 if(modeflag & HalfDCLK) tempax <<= 1;
3387 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3388 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3394 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3396 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3397 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3398 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3399 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3402 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3405 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3406 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3407 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3408 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3409 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3410 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3411 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3412 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3413 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3414 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3415 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3416 else SiS_Pr->SiS_RVBHRS2 += tempax;
3418 if(SiS_Pr->SiS_VGAHT) gotit = true;
3420 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3421 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3422 SiS_Pr->SiS_RVBHCMAX = 1;
3423 SiS_Pr->SiS_RVBHCFACT = 1;
3424 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3425 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3426 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3427 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3428 SiS_Pr->SiS_RVBHRS2 = 0;
3437 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3438 &CRT2Index,&ResIndex);
3441 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3442 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3443 case Panel_1280x720 :
3444 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3445 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3446 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3447 case Panel_1280x800 :
3448 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3449 case Panel_1280x800_2 :
3450 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3451 case Panel_1280x854 :
3452 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3453 case Panel_1280x960 :
3454 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3455 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3456 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3457 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3458 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3459 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3460 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3461 case Panel_1680x1050 :
3462 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3463 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3465 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3466 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3468 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3471 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3472 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3473 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3474 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3475 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3476 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3480 tempax = SiS_Pr->PanelXRes;
3481 tempbx = SiS_Pr->PanelYRes;
3483 switch(SiS_Pr->SiS_LCDResInfo) {
3484 case Panel_1024x768:
3485 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3486 if(SiS_Pr->ChipType < SIS_315H) {
3487 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3488 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3491 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3492 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3493 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3494 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3495 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3496 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3499 case Panel_1280x960:
3500 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3501 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3502 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3504 case Panel_1280x1024:
3505 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3506 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3507 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3509 case Panel_1600x1200:
3510 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3511 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3512 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3517 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3518 tempax = SiS_Pr->SiS_VGAHDE;
3519 tempbx = SiS_Pr->SiS_VGAVDE;
3522 SiS_Pr->SiS_HDE = tempax;
3523 SiS_Pr->SiS_VDE = tempbx;
3529 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3530 unsigned short RefreshRateTableIndex)
3533 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3535 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3536 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3538 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3539 /* Need LVDS Data for LCD on 301B-DH */
3540 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3542 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3548 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3553 /*********************************************/
3554 /* GET LVDS DES (SKEW) DATA */
3555 /*********************************************/
3557 static const struct SiS_LVDSDes *
3558 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3560 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3563 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3565 if(SiS_Pr->ChipType < SIS_315H) {
3566 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3567 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3568 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3569 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3570 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3572 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3573 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3574 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3575 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3586 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3587 unsigned short RefreshRateTableIndex)
3589 unsigned short modeflag, ResIndex;
3590 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3592 SiS_Pr->SiS_LCDHDES = 0;
3593 SiS_Pr->SiS_LCDVDES = 0;
3595 /* Some special cases */
3596 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3599 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3600 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3601 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3602 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3608 /* 640x480 on LVDS */
3609 if(SiS_Pr->ChipType < SIS_315H) {
3610 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3611 SiS_Pr->SiS_LCDHDES = 8;
3612 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3613 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3614 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3621 if( (SiS_Pr->UseCustomMode) ||
3622 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3623 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3624 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3625 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3629 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3630 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3632 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3635 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3636 /* non-pass 1:1 only, see above */
3637 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3638 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3640 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3641 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3644 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3645 switch(SiS_Pr->SiS_CustomT) {
3646 case CUT_UNIWILL1024:
3647 case CUT_UNIWILL10242:
3649 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3650 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3654 switch(SiS_Pr->SiS_LCDResInfo) {
3655 case Panel_1280x1024:
3656 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3657 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3660 case Panel_1280x800: /* Verified for Averatec 6240 */
3661 case Panel_1280x800_2: /* Verified for Asus A4L */
3662 case Panel_1280x854: /* Not verified yet FIXME */
3663 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3671 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3673 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3674 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3677 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3679 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3680 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3682 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3684 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3685 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3687 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3688 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3690 if(SiS_Pr->ChipType < SIS_315H) {
3691 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3693 switch(SiS_Pr->SiS_LCDResInfo) {
3695 case Panel_1024x768:
3696 case Panel_1280x1024:
3697 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3699 case Panel_1400x1050:
3700 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3708 if(SiS_Pr->ChipType < SIS_315H) {
3710 switch(SiS_Pr->SiS_LCDResInfo) {
3712 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3713 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3715 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3716 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3717 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3718 else SiS_Pr->SiS_LCDVDES -= 4;
3721 case Panel_1024x768:
3722 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3723 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3725 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3726 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3727 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3730 case Panel_1024x600:
3732 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3733 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3734 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3736 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3741 switch(SiS_Pr->SiS_LCDTypeInfo) {
3743 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3745 case 3: /* 640x480 only? */
3746 SiS_Pr->SiS_LCDHDES = 8;
3747 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3748 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3749 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3755 switch(SiS_Pr->SiS_LCDResInfo) {
3756 case Panel_1024x768:
3757 case Panel_1280x1024:
3758 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3759 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3762 case Panel_320x240_1:
3763 case Panel_320x240_2:
3764 case Panel_320x240_3:
3765 SiS_Pr->SiS_LCDVDES = 524;
3772 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3773 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3774 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3775 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3776 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3777 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3778 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3779 if(SiS_Pr->ChipType < SIS_315H) {
3780 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3783 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3784 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3785 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3786 if(!(modeflag & HalfDCLK)) {
3787 SiS_Pr->SiS_LCDHDES = 320;
3788 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3789 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3800 /*********************************************/
3801 /* DISABLE VIDEO BRIDGE */
3802 /*********************************************/
3806 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3810 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3811 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3812 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3813 unsigned short temp;
3815 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3817 (SiS_Pr->SiS_PWDOffset) ) {
3818 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3819 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3820 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3821 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3822 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3824 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3828 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3835 /* NEVER use any variables (VBInfo), this will be called
3836 * from outside the context of modeswitch!
3837 * MUST call getVBType before calling this
3840 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3843 unsigned short tempah, pushax=0, modenum;
3845 unsigned short temp=0;
3847 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3849 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3851 if(SiS_Pr->ChipType < SIS_315H) {
3853 #ifdef SIS300 /* 300 series */
3855 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3856 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3857 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3859 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3861 SiS_PanelDelay(SiS_Pr, 3);
3863 if(SiS_Is301B(SiS_Pr)) {
3864 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3865 SiS_ShortDelay(SiS_Pr,1);
3867 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3868 SiS_DisplayOff(SiS_Pr);
3869 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3870 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3871 SiS_UnLockCRT2(SiS_Pr);
3872 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3873 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3874 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3876 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3877 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3878 SiS_PanelDelay(SiS_Pr, 2);
3879 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3880 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3882 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3890 #ifdef SIS315H /* 315 series */
3893 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3894 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
3896 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3898 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3901 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3902 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3903 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3908 didpwd = SiS_HandlePWD(SiS_Pr);
3910 if( (modenum <= 0x13) ||
3911 (SiS_IsVAMode(SiS_Pr)) ||
3912 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3914 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3915 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3917 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3922 SiS_DDC2Delay(SiS_Pr,0xff00);
3923 SiS_DDC2Delay(SiS_Pr,0xe000);
3924 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3925 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3927 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3929 SiS_PanelDelay(SiS_Pr, 3);
3934 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
3935 /* if(SiS_Pr->ChipType < SIS_340) {*/
3937 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
3938 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3942 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3943 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3947 if(SiS_IsDualEdge(SiS_Pr)) {
3949 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
3951 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3953 if((SiS_IsVAMode(SiS_Pr)) ||
3954 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3956 SiS_DisplayOff(SiS_Pr);
3957 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3958 SiS_PanelDelay(SiS_Pr, 2);
3960 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3961 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3965 if((!(SiS_IsVAMode(SiS_Pr))) ||
3966 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3968 if(!(SiS_IsDualEdge(SiS_Pr))) {
3969 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3970 SiS_DisplayOff(SiS_Pr);
3972 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3974 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3975 SiS_PanelDelay(SiS_Pr, 2);
3978 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3979 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3980 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3981 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3982 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3986 if(SiS_IsNotM650orLater(SiS_Pr)) {
3987 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3990 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3992 if( (!(SiS_IsVAMode(SiS_Pr))) &&
3993 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
3994 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3996 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
3998 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4000 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4004 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4005 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4006 if(SiS_IsVAorLCD(SiS_Pr)) {
4007 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4014 #endif /* SIS315H */
4018 } else { /* ============ For 301 ================ */
4020 if(SiS_Pr->ChipType < SIS_315H) {
4022 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4023 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4024 SiS_PanelDelay(SiS_Pr, 3);
4029 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4030 SiS_DisplayOff(SiS_Pr);
4032 if(SiS_Pr->ChipType >= SIS_315H) {
4033 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4036 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4038 if(SiS_Pr->ChipType >= SIS_315H) {
4039 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4040 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4041 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4042 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4045 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4046 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4047 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4048 SiS_PanelDelay(SiS_Pr, 2);
4049 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4056 } else { /* ============ For LVDS =============*/
4058 if(SiS_Pr->ChipType < SIS_315H) {
4060 #ifdef SIS300 /* 300 series */
4062 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4063 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4066 if(SiS_Pr->ChipType == SIS_730) {
4067 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4068 SiS_WaitVBRetrace(SiS_Pr);
4070 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4071 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4072 SiS_PanelDelay(SiS_Pr, 3);
4075 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4076 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4077 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4078 SiS_WaitVBRetrace(SiS_Pr);
4079 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4080 SiS_DisplayOff(SiS_Pr);
4082 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4083 SiS_PanelDelay(SiS_Pr, 3);
4089 SiS_DisplayOff(SiS_Pr);
4091 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4093 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4094 SiS_UnLockCRT2(SiS_Pr);
4095 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4096 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4098 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4099 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4100 SiS_PanelDelay(SiS_Pr, 2);
4101 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4108 #ifdef SIS315H /* 315 series */
4110 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4111 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4112 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4116 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4118 if(SiS_Pr->ChipType == SIS_740) {
4119 temp = SiS_GetCH701x(SiS_Pr,0x61);
4121 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4122 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4125 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4126 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4127 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4131 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4132 (SiS_IsVAMode(SiS_Pr)) ) {
4133 SiS_Chrontel701xBLOff(SiS_Pr);
4134 SiS_Chrontel701xOff(SiS_Pr);
4137 if(SiS_Pr->ChipType != SIS_740) {
4138 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4139 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4140 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4146 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4147 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4148 SiS_PanelDelay(SiS_Pr, 3);
4151 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4152 (!(SiS_IsDualEdge(SiS_Pr))) ||
4153 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4154 SiS_DisplayOff(SiS_Pr);
4157 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4158 (!(SiS_IsDualEdge(SiS_Pr))) ||
4159 (!(SiS_IsVAMode(SiS_Pr))) ) {
4160 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4163 if(SiS_Pr->ChipType == SIS_740) {
4164 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4167 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4169 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4170 (!(SiS_IsDualEdge(SiS_Pr))) ||
4171 (!(SiS_IsVAMode(SiS_Pr))) ) {
4172 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4175 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4176 if(SiS_CRT2IsLCD(SiS_Pr)) {
4177 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4178 if(SiS_Pr->ChipType == SIS_550) {
4179 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4180 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4184 if(SiS_Pr->ChipType == SIS_740) {
4185 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4186 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4188 } else if(SiS_IsVAMode(SiS_Pr)) {
4189 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4193 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4194 if(SiS_IsDualEdge(SiS_Pr)) {
4195 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4197 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4201 SiS_UnLockCRT2(SiS_Pr);
4203 if(SiS_Pr->ChipType == SIS_550) {
4204 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4205 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4206 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4207 (!(SiS_IsDualEdge(SiS_Pr))) ||
4208 (!(SiS_IsVAMode(SiS_Pr))) ) {
4209 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4212 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4213 if(SiS_CRT2IsLCD(SiS_Pr)) {
4214 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4215 SiS_PanelDelay(SiS_Pr, 2);
4216 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4221 #endif /* SIS315H */
4229 /*********************************************/
4230 /* ENABLE VIDEO BRIDGE */
4231 /*********************************************/
4233 /* NEVER use any variables (VBInfo), this will be called
4234 * from outside the context of a mode switch!
4235 * MUST call getVBType before calling this
4239 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4241 unsigned short temp=0, tempah;
4243 unsigned short temp1, pushax=0;
4244 bool delaylong = false;
4247 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4249 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4251 if(SiS_Pr->ChipType < SIS_315H) {
4253 #ifdef SIS300 /* 300 series */
4255 if(SiS_CRT2IsLCD(SiS_Pr)) {
4256 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4257 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4258 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4259 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4261 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4262 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4263 SiS_PanelDelay(SiS_Pr, 0);
4268 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4269 (SiS_CRT2IsLCD(SiS_Pr))) {
4271 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4272 SiS_DisplayOn(SiS_Pr);
4273 SiS_UnLockCRT2(SiS_Pr);
4274 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4275 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4276 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4278 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4280 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4281 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4282 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4283 SiS_PanelDelay(SiS_Pr, 1);
4285 SiS_WaitVBRetrace(SiS_Pr);
4286 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4292 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4293 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4294 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4295 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4297 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4298 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4299 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4300 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4301 SiS_DisplayOn(SiS_Pr);
4302 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4303 if(SiS_CRT2IsLCD(SiS_Pr)) {
4304 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4305 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4306 SiS_PanelDelay(SiS_Pr, 1);
4308 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4320 #ifdef SIS315H /* 315 series */
4323 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4325 /* unsigned short emidelay=0; */
4328 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4329 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4331 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4332 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4337 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4338 /*if(SiS_Pr->ChipType < SIS_340) { */
4340 if(SiS_LCDAEnabled(SiS_Pr)) {
4341 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4344 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4348 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4350 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4351 SiS_DisplayOff(SiS_Pr);
4352 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4354 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4357 didpwd = SiS_HandlePWD(SiS_Pr);
4359 if(SiS_IsVAorLCD(SiS_Pr)) {
4361 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4362 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4363 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4364 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4365 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4366 SiS_GenericDelay(SiS_Pr, 17664);
4370 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4371 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4372 SiS_GenericDelay(SiS_Pr, 17664);
4377 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4378 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4384 if(!(SiS_IsVAMode(SiS_Pr))) {
4386 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4387 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4388 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4389 if(!(tempah & SetCRT2ToRAMDAC)) {
4390 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4393 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4395 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4397 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4398 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4400 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4401 SiS_PanelDelay(SiS_Pr, 2);
4406 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4410 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4411 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4413 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4414 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4415 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4416 /* Enable "LVDS PLL power on" (even on 301C) */
4417 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4418 /* Enable "LVDS Driver Power on" (even on 301C) */
4419 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4424 if(SiS_IsDualEdge(SiS_Pr)) {
4426 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4428 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4430 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4432 SiS_PanelDelay(SiS_Pr, 2);
4434 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4435 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4437 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4439 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4440 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4441 SiS_GenericDelay(SiS_Pr, 2048);
4444 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4446 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4448 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4450 if(SiS_Pr->SiS_ROMNew) {
4451 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4452 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4454 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4456 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4457 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4458 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4459 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4460 /* emidelay = SISGETROMW((romptr + 0x22)); */
4461 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4466 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4467 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4468 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4469 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4470 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4471 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4472 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4473 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4474 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4476 if(SiS_Pr->HaveEMI) {
4477 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4478 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4483 /* EMI_30 is read at driver start; however, the BIOS sets this
4484 * (if it is used) only if the LCD is in use. In case we caught
4485 * the machine while on TV output, this bit is not set and we
4486 * don't know if it should be set - hence our detection is wrong.
4487 * Work-around this here:
4490 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4491 switch((cr36 & 0x0f)) {
4494 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4495 if(!SiS_Pr->HaveEMI) {
4496 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4497 if((cr36 & 0xf0) == 0x30) {
4498 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4502 case 3: /* 1280x1024 */
4503 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4504 if(!SiS_Pr->HaveEMI) {
4505 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4506 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4507 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4511 case 9: /* 1400x1050 */
4513 if(!SiS_Pr->HaveEMI) {
4514 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4515 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4516 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4520 case 11: /* 1600x1200 - unknown */
4522 if(!SiS_Pr->HaveEMI) {
4523 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4528 /* BIOS values don't work so well sometimes */
4529 if(!SiS_Pr->OverruleEMI) {
4531 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4532 if((cr36 & 0x0f) == 0x09) {
4533 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4538 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4539 if((cr36 & 0x0f) == 0x03) {
4540 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4545 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4546 if((cr36 & 0x0f) == 0x02) {
4547 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4548 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4549 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4550 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4556 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4557 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4558 SiS_GenericDelay(SiS_Pr, 2048);
4560 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4561 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4562 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4563 #endif /* SET_EMI */
4565 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4568 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4569 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4571 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4572 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4574 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4577 SiS_WaitVBRetrace(SiS_Pr);
4578 SiS_WaitVBRetrace(SiS_Pr);
4579 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4580 SiS_GenericDelay(SiS_Pr, 1280);
4582 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4583 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4590 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4591 if(SiS_IsVAorLCD(SiS_Pr)) {
4592 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4594 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4596 SiS_WaitVBRetrace(SiS_Pr);
4597 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4598 SiS_GenericDelay(SiS_Pr, 2048);
4599 SiS_WaitVBRetrace(SiS_Pr);
4602 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4604 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4609 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4610 SiS_DisplayOn(SiS_Pr);
4611 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4615 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4616 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4619 #endif /* SIS315H */
4623 } else { /* ============ For 301 ================ */
4625 if(SiS_Pr->ChipType < SIS_315H) {
4626 if(SiS_CRT2IsLCD(SiS_Pr)) {
4627 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4628 SiS_PanelDelay(SiS_Pr, 0);
4632 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4633 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4634 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4635 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4637 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4639 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4641 if(SiS_Pr->ChipType >= SIS_315H) {
4642 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4643 if(!(temp & 0x80)) {
4644 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4648 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4650 SiS_VBLongWait(SiS_Pr);
4651 SiS_DisplayOn(SiS_Pr);
4652 if(SiS_Pr->ChipType >= SIS_315H) {
4653 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4655 SiS_VBLongWait(SiS_Pr);
4657 if(SiS_Pr->ChipType < SIS_315H) {
4658 if(SiS_CRT2IsLCD(SiS_Pr)) {
4659 SiS_PanelDelay(SiS_Pr, 1);
4660 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4666 } else { /* =================== For LVDS ================== */
4668 if(SiS_Pr->ChipType < SIS_315H) {
4670 #ifdef SIS300 /* 300 series */
4672 if(SiS_CRT2IsLCD(SiS_Pr)) {
4673 if(SiS_Pr->ChipType == SIS_730) {
4674 SiS_PanelDelay(SiS_Pr, 1);
4675 SiS_PanelDelay(SiS_Pr, 1);
4676 SiS_PanelDelay(SiS_Pr, 1);
4678 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4679 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4680 SiS_PanelDelay(SiS_Pr, 0);
4684 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4685 SiS_DisplayOn(SiS_Pr);
4686 SiS_UnLockCRT2(SiS_Pr);
4687 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4688 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4689 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4691 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4694 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4695 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4696 SiS_WaitVBRetrace(SiS_Pr);
4697 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4701 if(SiS_CRT2IsLCD(SiS_Pr)) {
4702 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4703 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4704 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4705 SiS_PanelDelay(SiS_Pr, 1);
4706 SiS_PanelDelay(SiS_Pr, 1);
4708 SiS_WaitVBRetrace(SiS_Pr);
4709 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4718 #ifdef SIS315H /* 315 series */
4720 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4721 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4722 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4726 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4727 if(SiS_CRT2IsLCD(SiS_Pr)) {
4728 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4729 SiS_PanelDelay(SiS_Pr, 0);
4733 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4734 SiS_UnLockCRT2(SiS_Pr);
4736 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4738 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4739 temp = SiS_GetCH701x(SiS_Pr,0x66);
4741 SiS_Chrontel701xBLOff(SiS_Pr);
4744 if(SiS_Pr->ChipType != SIS_550) {
4745 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4748 if(SiS_Pr->ChipType == SIS_740) {
4749 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4750 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4751 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4756 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4757 if(!(temp1 & 0x80)) {
4758 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4761 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4763 SiS_Chrontel701xBLOn(SiS_Pr);
4767 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4768 if(SiS_CRT2IsLCD(SiS_Pr)) {
4769 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4770 if(SiS_Pr->ChipType == SIS_550) {
4771 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4772 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4775 } else if(SiS_IsVAMode(SiS_Pr)) {
4776 if(SiS_Pr->ChipType != SIS_740) {
4777 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4781 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4782 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4785 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4786 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4787 SiS_Chrontel701xOn(SiS_Pr);
4789 if( (SiS_IsVAMode(SiS_Pr)) ||
4790 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4791 SiS_ChrontelDoSomething1(SiS_Pr);
4795 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4796 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4797 if( (SiS_IsVAMode(SiS_Pr)) ||
4798 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4799 SiS_Chrontel701xBLOn(SiS_Pr);
4800 SiS_ChrontelInitTVVSync(SiS_Pr);
4803 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4804 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4805 if(SiS_CRT2IsLCD(SiS_Pr)) {
4806 SiS_PanelDelay(SiS_Pr, 1);
4807 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4812 #endif /* SIS315H */
4820 /*********************************************/
4821 /* SET PART 1 REGISTER GROUP */
4822 /*********************************************/
4824 /* Set CRT2 OFFSET / PITCH */
4826 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4827 unsigned short RRTI)
4829 unsigned short offset;
4832 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4834 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4836 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4839 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4840 if(offset & 0x07) temp++;
4841 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4844 /* Set CRT2 sync and PanelLink mode */
4846 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4848 unsigned short tempah=0, tempbl, infoflag;
4852 if(SiS_Pr->UseCustomMode) {
4853 infoflag = SiS_Pr->CInfoFlag;
4855 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4858 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4860 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4862 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4863 tempah = SiS_Pr->SiS_LCDInfo;
4864 } else tempah = infoflag >> 8;
4867 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4868 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4869 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4870 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4873 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4874 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4875 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4876 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4877 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4880 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4881 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4885 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4886 if(SiS_Pr->ChipType >= SIS_315H) {
4889 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4890 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4892 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4895 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4898 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4900 if(SiS_Pr->ChipType < SIS_315H) {
4902 #ifdef SIS300 /* ---- 300 series --- */
4904 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4906 tempah = infoflag >> 8;
4908 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4909 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4910 tempah = SiS_Pr->SiS_LCDInfo;
4911 tempbl = (tempah >> 6) & 0x03;
4916 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4918 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4919 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4920 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4923 } else { /* 630 - 301 */
4925 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4926 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4927 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4935 #ifdef SIS315H /* ------- 315 series ------ */
4937 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
4940 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4941 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4942 tempah = infoflag >> 8;
4943 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4944 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4946 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4947 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4948 tempah = infoflag >> 8;
4951 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4952 tempbl = (tempah >> 6) & 0x03;
4954 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4958 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4959 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4960 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4961 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4962 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4963 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4967 } else { /* 315 - TMDS */
4969 tempah = tempbl = infoflag >> 8;
4970 if(!SiS_Pr->UseCustomMode) {
4972 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4973 if(ModeNo <= 0x13) {
4974 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4977 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4978 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4979 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4980 tempah = SiS_Pr->SiS_LCDInfo;
4981 tempbl = (tempah >> 6) & 0x03;
4988 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4989 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4990 /* Imitate BIOS bug */
4991 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4993 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4996 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4998 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4999 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5000 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5001 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5007 #endif /* SIS315H */
5012 /* Set CRT2 FIFO on 300/540/630/730 */
5015 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5017 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5018 unsigned short temp, index, modeidindex, refreshratetableindex;
5019 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5020 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5021 unsigned int data, pci50, pciA0;
5022 static const unsigned char colortharray[] = {
5026 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5028 if(!SiS_Pr->CRT1UsesCustomMode) {
5030 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5031 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5032 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5033 SiS_Pr->SiS_SelectCRT2Rate = 0;
5034 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5036 if(CRT1ModeNo >= 0x13) {
5038 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5039 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5041 /* Get colordepth */
5042 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5043 if(!colorth) colorth++;
5051 VCLK = SiS_Pr->CSRClock_CRT1;
5053 /* Get color depth */
5054 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5058 if(CRT1ModeNo >= 0x13) {
5060 if(SiS_Pr->ChipType == SIS_300) {
5061 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5063 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5066 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5068 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5072 data2 = temp - ((colorth * VCLK) / MCLK);
5074 temp = (28 * 16) % data2;
5075 data2 = (28 * 16) / data2;
5078 if(SiS_Pr->ChipType == SIS_300) {
5080 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5081 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5085 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5086 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5088 if(SiS_Pr->ChipType == SIS_730) {
5090 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5091 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5093 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5094 index = 0; /* -- do it like the BIOS anyway... */
5101 index = (pci50 >> 1) & 0x07;
5103 if(pci50 & 0x01) index += 6;
5104 if(!(pciA0 & 0x01)) index += 24;
5106 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5110 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5111 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5115 data += data2; /* CRT1 Request Period */
5117 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5118 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5120 if(!SiS_Pr->UseCustomMode) {
5122 CRT2ModeNo = ModeNo;
5123 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5125 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5128 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5129 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5131 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5132 if(SiS_Pr->SiS_UseROM) {
5133 if(ROMAddr[0x220] & 0x01) {
5134 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5143 VCLK = SiS_Pr->CSRClock;
5147 /* Get colordepth */
5148 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5149 if(!colorth) colorth++;
5151 data = data * VCLK * colorth;
5152 temp = data % (MCLK << 4);
5153 data = data / (MCLK << 4);
5156 if(data < 6) data = 6;
5157 else if(data > 0x14) data = 0x14;
5159 if(SiS_Pr->ChipType == SIS_300) {
5161 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5165 if(( (SiS_Pr->ChipType == SIS_630) ||
5166 (SiS_Pr->ChipType == SIS_730) ) &&
5167 (SiS_Pr->ChipRevision >= 0x30))
5170 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5172 if((SiS_Pr->ChipType == SIS_630) &&
5173 (SiS_Pr->ChipRevision >= 0x30)) {
5174 if(data > 0x13) data = 0x13;
5176 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5178 } else { /* If mode <= 0x13, we just restore everything */
5180 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5181 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5187 /* Set CRT2 FIFO on 315/330 series */
5190 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5192 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5193 if( (SiS_Pr->ChipType == SIS_760) &&
5194 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5195 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5196 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5197 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5198 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5199 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5200 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5201 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5202 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5203 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5205 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5211 static unsigned short
5212 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5214 unsigned int tempax,tempbx;
5216 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5217 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5218 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5219 return (unsigned short)tempax;
5222 /* Set Part 1 / SiS bridge slave mode */
5224 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5225 unsigned short RefreshRateTableIndex)
5227 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5228 static const unsigned short CRTranslation[] = {
5229 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5230 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5231 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5232 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5233 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5234 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5237 if(ModeNo <= 0x13) {
5238 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5239 } else if(SiS_Pr->UseCustomMode) {
5240 modeflag = SiS_Pr->CModeFlag;
5241 xres = SiS_Pr->CHDisplay;
5243 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5244 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5247 /* The following is only done if bridge is in slave mode: */
5249 if(SiS_Pr->ChipType >= SIS_315H) {
5250 if(xres >= 1600) { /* BIOS: == 1600 */
5251 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5255 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5257 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5258 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5260 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5261 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5262 SiS_Pr->CHBlankStart += 16;
5265 SiS_Pr->CHBlankEnd = 32;
5266 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5267 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5270 temp = SiS_Pr->SiS_VGAHT - 96;
5271 if(!(modeflag & HalfDCLK)) temp -= 32;
5272 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5273 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5274 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5278 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5280 SiS_Pr->CHSyncStart = temp;
5282 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5284 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5286 VGAVDE = SiS_Pr->SiS_VGAVDE;
5287 if (VGAVDE == 357) VGAVDE = 350;
5288 else if(VGAVDE == 360) VGAVDE = 350;
5289 else if(VGAVDE == 375) VGAVDE = 350;
5290 else if(VGAVDE == 405) VGAVDE = 400;
5291 else if(VGAVDE == 420) VGAVDE = 400;
5292 else if(VGAVDE == 525) VGAVDE = 480;
5293 else if(VGAVDE == 1056) VGAVDE = 1024;
5294 SiS_Pr->CVDisplay = VGAVDE;
5296 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5298 SiS_Pr->CVBlankEnd = 1;
5299 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5301 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5302 SiS_Pr->CVSyncStart = VGAVDE + temp;
5305 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5307 SiS_CalcCRRegisters(SiS_Pr, 0);
5308 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5310 for(i = 0; i <= 7; i++) {
5311 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5313 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5314 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5316 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5317 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5319 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5320 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5323 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5324 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5326 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5327 if(modeflag & DoubleScanMode) temp |= 0x80;
5328 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5331 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5332 if(modeflag & HalfDCLK) temp |= 0x08;
5333 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5335 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5336 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5339 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5340 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5342 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5344 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5345 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5349 * This is used for LVDS, LCDA and Chrontel TV output
5350 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5353 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5354 unsigned short RefreshRateTableIndex)
5356 unsigned short modeflag, resinfo = 0;
5357 unsigned short push2, tempax, tempbx, tempcx, temp;
5358 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5359 bool islvds = false, issis = false, chkdclkfirst = false;
5361 unsigned short crt2crtc = 0;
5364 unsigned short pushcx;
5367 if(ModeNo <= 0x13) {
5368 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5369 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5371 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5373 } else if(SiS_Pr->UseCustomMode) {
5374 modeflag = SiS_Pr->CModeFlag;
5376 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5377 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5379 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5383 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5384 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5388 /* is really sis if sis bridge, but not 301B-DH */
5389 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5393 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5394 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5395 chkdclkfirst = true;
5400 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5402 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5403 } else if(IS_SIS740) {
5405 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5406 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5407 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5408 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5412 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5413 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5414 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5415 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5416 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5417 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5418 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5419 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5429 tempax = SiS_Pr->SiS_LCDHDES;
5431 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5432 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5433 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5434 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5441 temp = (tempax & 0x0007);
5442 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5443 temp = (tempax >> 3) & 0x00FF;
5444 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5446 tempbx = SiS_Pr->SiS_HDE;
5447 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5448 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5449 tempbx = SiS_Pr->PanelXRes;
5451 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5452 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5453 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5459 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5462 if(temp & 0x07) temp += 8;
5464 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5466 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5468 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5469 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5470 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5475 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5477 temp = (tempcx >> 3) & 0x00FF;
5478 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5479 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5480 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5484 case 0x0d: temp = 0x56; break;
5485 case 0x10: temp = 0x60; break;
5486 case 0x13: temp = 0x5f; break;
5496 case 0x5e: temp = 0x54; break;
5501 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5503 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5505 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5507 if(SiS_Pr->PanelHRE != 999) {
5508 temp = tempcx + SiS_Pr->PanelHRE;
5509 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5518 temp |= ((tempcx & 0x07) << 5);
5519 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5523 tempax = SiS_Pr->SiS_VGAVDE;
5524 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5525 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5526 tempax = SiS_Pr->PanelYRes;
5530 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5531 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5535 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5536 if(SiS_Pr->ChipType < SIS_315H) {
5537 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5538 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5539 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5543 if(islvds) tempcx >>= 1;
5546 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5547 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5548 (SiS_Pr->PanelVRS != 999) ) {
5549 tempcx = SiS_Pr->PanelVRS;
5554 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5555 else if(issis) tempbx++;
5558 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5560 temp = tempbx & 0x00FF;
5561 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5562 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5563 if(ModeNo == 0x10) temp = 0xa9;
5566 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5571 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5572 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5573 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5578 temp = tempcx & 0x000F;
5579 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5581 temp = ((tempbx >> 8) & 0x07) << 3;
5582 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5583 if(SiS_Pr->SiS_HDE != 640) {
5584 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5586 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5587 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5589 if((SiS_Pr->ChipType >= SIS_315H) ||
5590 (SiS_Pr->ChipRevision >= 0x30)) {
5592 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5593 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5595 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5596 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5597 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5598 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5600 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5604 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5606 tempbx = push2; /* BPLVDEE */
5608 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5610 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5611 switch(SiS_Pr->SiS_LCDResInfo) {
5613 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5614 tempcx = SiS_Pr->SiS_VGAVDE;
5617 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5618 if(resinfo == SIS_RI_800x600) tempcx++;
5621 case Panel_1024x600:
5622 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5623 if(resinfo == SIS_RI_1024x600) tempcx++;
5624 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5625 if(resinfo == SIS_RI_800x600) tempcx++;
5629 case Panel_1024x768:
5630 if(SiS_Pr->ChipType < SIS_315H) {
5631 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5632 if(resinfo == SIS_RI_1024x768) tempcx++;
5639 temp = ((tempbx >> 8) & 0x07) << 3;
5640 temp |= ((tempcx >> 8) & 0x07);
5641 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5642 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5643 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5645 /* Vertical scaling */
5647 if(SiS_Pr->ChipType < SIS_315H) {
5649 #ifdef SIS300 /* 300 series */
5650 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5651 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5652 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5655 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5657 temp = (unsigned short)(tempeax & 0x00FF);
5658 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5664 #ifdef SIS315H /* 315 series */
5665 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5666 tempebx = SiS_Pr->SiS_VDE;
5667 temp = (tempeax % tempebx);
5668 tempeax = tempeax / tempebx;
5670 tempvcfact = tempeax;
5672 temp = (unsigned short)(tempeax & 0x00FF);
5673 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5674 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5675 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5676 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5677 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5678 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5680 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5681 temp = (unsigned short)(tempeax & 0x00FF);
5682 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5683 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5684 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5685 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5686 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5688 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5689 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5695 /* Horizontal scaling */
5697 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5699 if(modeflag & HalfDCLK) tempeax >>= 1;
5701 tempebx = tempeax << 16;
5702 if(SiS_Pr->SiS_HDE == tempeax) {
5705 tempecx = tempebx / SiS_Pr->SiS_HDE;
5706 if(SiS_Pr->ChipType >= SIS_315H) {
5707 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5711 if(SiS_Pr->ChipType >= SIS_315H) {
5712 tempeax = (tempebx / tempecx) - 1;
5714 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5716 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5717 temp = (unsigned short)(tempecx & 0x00FF);
5718 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5720 if(SiS_Pr->ChipType >= SIS_315H) {
5721 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5722 tempbx = (unsigned short)(tempeax & 0xFFFF);
5724 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5725 tempbx = tempvcfact & 0x3f;
5726 if(tempbx == 0) tempbx = 64;
5728 tempbx = (unsigned short)(tempeax & 0xFFFF);
5730 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5731 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5732 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5733 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5736 temp = ((tempbx >> 8) & 0x07) << 3;
5737 temp = temp | ((tempecx >> 8) & 0x07);
5738 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5739 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5741 tempecx >>= 16; /* BPLHCFACT */
5743 if(modeflag & HalfDCLK) tempecx >>= 1;
5745 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5746 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5747 temp = (unsigned short)(tempecx & 0x00FF);
5748 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5751 if(SiS_Pr->ChipType >= SIS_315H) {
5752 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5753 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5754 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5758 if(SiS_Pr->ChipType == SIS_740) {
5759 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5761 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5769 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5770 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5771 unsigned char *trumpdata;
5772 int i, j = crt2crtc;
5773 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5774 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5775 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5777 if(SiS_Pr->SiS_UseROM) {
5778 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5780 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5781 trumpdata = &SiS300_TrumpionData[j][0];
5784 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5785 for(i=0; i<5; i++) {
5786 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5788 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5789 if(ModeNo == 0x13) {
5790 for(i=0; i<4; i++) {
5791 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5793 } else if(ModeNo == 0x10) {
5794 for(i=0; i<4; i++) {
5795 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5796 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5800 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5805 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5806 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5807 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5808 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5809 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5810 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5811 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5812 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5813 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5814 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5815 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5816 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5818 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5819 temp = (tempax >> 8) << 3;
5820 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5821 tempax += 32; /* Blpe = lBlps+32 */
5822 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5823 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
5824 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5826 tempax = SiS_Pr->SiS_VDE;
5827 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5828 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5829 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5831 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5832 temp = (tempax >> 8) << 3;
5833 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5835 tempeax = SiS_Pr->SiS_HDE;
5836 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5837 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5838 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5839 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5840 temp = tempeax & 0x7f;
5843 temp = tempeax & 0x3f;
5844 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5845 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5846 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5847 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5848 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5850 tempax = SiS_Pr->SiS_HDE;
5851 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5852 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5853 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5854 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5856 temp = tempax & 0x00FF;
5857 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5858 temp = ((tempax & 0xFF00) >> 8) << 3;
5859 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5861 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5862 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5863 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5864 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5865 tempeax = tempax * pushcx;
5866 temp = tempeax & 0xFF;
5867 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5868 temp = (tempeax & 0xFF00) >> 8;
5869 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5870 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5871 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5872 temp = ((tempeax & 0x01000000) >> 24) << 7;
5873 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
5875 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5876 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5878 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5879 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5881 if(SiS_Pr->SiS_IF_DEF_FSTN) {
5882 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5883 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5885 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5887 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5888 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5889 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5890 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5891 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5893 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5894 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5895 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5896 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5897 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5898 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
5899 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
5900 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
5901 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
5904 #endif /* SIS315H */
5909 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5910 unsigned short RefreshRateTableIndex)
5912 #if defined(SIS300) || defined(SIS315H)
5913 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5915 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
5916 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
5918 unsigned short tempbl=0;
5921 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5922 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5926 if(ModeNo <= 0x13) {
5927 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5928 } else if(SiS_Pr->UseCustomMode) {
5929 modeflag = SiS_Pr->CModeFlag;
5931 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
5932 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5933 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5936 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5938 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
5939 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
5940 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
5942 if(SiS_Pr->ChipType < SIS_315H ) {
5944 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
5948 SiS_SetCRT2FIFO_310(SiS_Pr);
5952 /* 1. Horizontal setup */
5954 if(SiS_Pr->ChipType < SIS_315H ) {
5956 #ifdef SIS300 /* ------------- 300 series --------------*/
5958 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
5959 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
5961 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
5962 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
5964 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
5965 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
5967 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
5968 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
5969 tempbx = pushbx + tempcx;
5979 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
5981 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
5982 if(modeflag & HalfDCLK) {
5983 if(SiS_Pr->SiS_VBType & VB_SISVB) {
5986 tempax = SiS_Pr->SiS_VGAHDE >> 1;
5987 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
5988 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5989 tempcx = SiS_Pr->SiS_HT - tempax;
5994 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
5995 temp = (tempcx >> 4) & 0xF0;
5996 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
5998 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
5999 tempbx = SiS_Pr->SiS_VGAHDE;
6002 if(modeflag & HalfDCLK) {
6008 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6017 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6018 if(SiS_Pr->ChipType >= SIS_661) {
6019 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6020 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6021 if(resinfo == SIS_RI_1280x1024) {
6022 tempcx = (tempcx & 0xff00) | 0x30;
6023 } else if(resinfo == SIS_RI_1600x1200) {
6024 tempcx = (tempcx & 0xff00) | 0xff;
6030 #endif /* SIS315H */
6032 } /* 315/330 series */
6034 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6036 if(SiS_Pr->UseCustomMode) {
6037 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6038 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6039 tempax = SiS_Pr->SiS_VGAHT;
6040 if(modeflag & HalfDCLK) tempax >>= 1;
6042 if(tempcx > tempax) tempcx = tempax;
6045 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6046 unsigned char cr4, cr14, cr5, cr15;
6047 if(SiS_Pr->UseCustomMode) {
6048 cr4 = SiS_Pr->CCRT1CRTC[4];
6049 cr14 = SiS_Pr->CCRT1CRTC[14];
6050 cr5 = SiS_Pr->CCRT1CRTC[5];
6051 cr15 = SiS_Pr->CCRT1CRTC[15];
6053 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6054 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6055 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6056 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6058 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6059 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6061 tempcx |= (tempbx & 0xFF00);
6062 tempbx += bridgeadd;
6063 tempcx += bridgeadd;
6064 tempax = SiS_Pr->SiS_VGAHT;
6065 if(modeflag & HalfDCLK) tempax >>= 1;
6067 if(tempcx > tempax) tempcx = tempax;
6070 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6072 tempcx = 1044; /* HWCursor bug! */
6077 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6079 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6081 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6082 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6084 /* 2. Vertical setup */
6086 tempcx = SiS_Pr->SiS_VGAVT - 1;
6087 temp = tempcx & 0x00FF;
6089 if(SiS_Pr->ChipType < SIS_661) {
6090 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6091 if(SiS_Pr->ChipType < SIS_315H) {
6092 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6093 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6100 } else if(SiS_Pr->ChipType >= SIS_315H) {
6104 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6106 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6107 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6109 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6110 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6112 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6119 if(tempcx < 4) tempcx = 4;
6124 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6125 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6128 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6129 if(SiS_Pr->UseCustomMode) {
6130 tempbx = SiS_Pr->CVSyncStart;
6131 tempcx = SiS_Pr->CVSyncEnd;
6133 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6134 unsigned char cr8, cr7, cr13;
6135 if(SiS_Pr->UseCustomMode) {
6136 cr8 = SiS_Pr->CCRT1CRTC[8];
6137 cr7 = SiS_Pr->CCRT1CRTC[7];
6138 cr13 = SiS_Pr->CCRT1CRTC[13];
6139 tempcx = SiS_Pr->CCRT1CRTC[9];
6141 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6142 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6143 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6144 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6147 if(cr7 & 0x04) tempbx |= 0x0100;
6148 if(cr7 & 0x80) tempbx |= 0x0200;
6149 if(cr13 & 0x08) tempbx |= 0x0400;
6152 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6154 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6155 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6157 /* 3. Panel delay compensation */
6159 if(SiS_Pr->ChipType < SIS_315H) {
6161 #ifdef SIS300 /* ---------- 300 series -------------- */
6163 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6165 if(SiS_Pr->ChipType == SIS_300) {
6167 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6168 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6170 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6171 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6173 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6174 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6175 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6176 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6177 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6180 if(SiS_Pr->SiS_UseROM) {
6181 if(ROMAddr[0x220] & 0x80) {
6182 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6183 temp = ROMAddr[0x221];
6184 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6185 temp = ROMAddr[0x222];
6186 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6187 temp = ROMAddr[0x223];
6189 temp = ROMAddr[0x224];
6192 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6193 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6198 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6199 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6201 if(SiS_Pr->SiS_UseROM) {
6202 if(ROMAddr[0x220] & 0x80) {
6203 temp = ROMAddr[0x220];
6206 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6207 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6213 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6219 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6221 if(SiS_Pr->ChipType < SIS_661) {
6223 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6225 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6228 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6230 if(SiS_Pr->ChipType == SIS_650) {
6231 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6232 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6236 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6239 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6240 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6244 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6250 if(modeflag & DoubleScanMode) tempax |= 0x80;
6251 if(modeflag & HalfDCLK) tempax |= 0x40;
6252 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6254 #endif /* SIS315H */
6260 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6261 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6262 /* For 301BDH with LCD, we set up the Panel Link */
6263 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6264 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6265 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6268 if(SiS_Pr->ChipType < SIS_315H) {
6269 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6271 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6272 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6273 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6276 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6282 /*********************************************/
6283 /* SET PART 2 REGISTER GROUP */
6284 /*********************************************/
6287 static unsigned char *
6288 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6290 const unsigned char *tableptr = NULL;
6291 unsigned short a, b, p = 0;
6293 a = SiS_Pr->SiS_VGAHDE;
6294 b = SiS_Pr->SiS_HDE;
6296 a = SiS_Pr->SiS_VGAVDE;
6297 b = SiS_Pr->SiS_VDE;
6301 tableptr = SiS_Part2CLVX_1;
6303 tableptr = SiS_Part2CLVX_2;
6305 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6306 tableptr = SiS_Part2CLVX_4;
6308 tableptr = SiS_Part2CLVX_3;
6310 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6311 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6312 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6313 else tableptr = SiS_Part2CLVX_5;
6314 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6315 tableptr = SiS_Part2CLVX_6;
6318 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6320 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6321 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6324 return ((unsigned char *)&tableptr[p]);
6328 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6329 unsigned short RefreshRateTableIndex)
6331 unsigned char *tableptr;
6335 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6337 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6338 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6339 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6341 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6342 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6343 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6344 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6348 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6349 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6353 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6354 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6355 unsigned short *ResIndex)
6358 if(SiS_Pr->ChipType < SIS_315H) return false;
6361 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6363 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6365 (*ResIndex) &= 0x3f;
6368 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6369 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6374 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6375 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6376 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6379 return (((*CRT2Index) != 0));
6385 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6387 unsigned short tempcx;
6388 static const unsigned char atable[] = {
6389 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6390 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6393 if(!SiS_Pr->UseCustomMode) {
6394 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6395 (SiS_Pr->ChipType == SIS_730) ) &&
6396 (SiS_Pr->ChipRevision > 2) ) &&
6397 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6398 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6399 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6400 if(ModeNo == 0x13) {
6401 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6402 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6403 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6404 } else if((crt2crtc & 0x3F) == 4) {
6405 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6406 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6407 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6408 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6409 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6413 if(SiS_Pr->ChipType < SIS_315H) {
6414 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6417 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6418 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6424 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6427 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6428 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6430 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6434 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6435 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6441 /* For ECS A907. Highly preliminary. */
6443 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6444 unsigned short ModeNo)
6446 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6447 unsigned short crt2crtc, resindex;
6450 if(SiS_Pr->ChipType != SIS_300) return;
6451 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6452 if(SiS_Pr->UseCustomMode) return;
6454 if(ModeNo <= 0x13) {
6455 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6457 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6460 resindex = crt2crtc & 0x3F;
6461 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6462 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6464 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6466 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6470 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6471 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6472 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6473 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6475 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6476 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6478 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6479 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6481 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6482 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6487 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6489 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6490 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6491 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6493 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6494 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6495 const unsigned char specialtv[] = {
6496 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6497 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6498 0x58,0xe4,0x73,0xda,0x13
6501 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6502 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6505 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6506 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6507 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6508 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6510 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6511 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6516 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6517 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6518 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6519 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6521 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6522 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6528 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6530 unsigned short temp;
6532 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6533 if(SiS_Pr->SiS_VGAVDE == 525) {
6535 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6537 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6539 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6540 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6541 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6543 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6545 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6547 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6551 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6552 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6553 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6554 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6555 /* Not always for LV, see SetGrp2 */
6558 if(ModeNo <= 0x13) temp = 3;
6559 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6562 /* 651+301C, for 1280x768 - do I really need that? */
6563 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6564 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6565 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6566 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6567 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6568 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6569 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6570 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6571 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6572 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6573 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6574 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6575 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6576 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6577 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6578 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6587 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6588 unsigned short RefreshRateTableIndex)
6590 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6591 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6592 unsigned int longtemp, PhaseIndex;
6594 const unsigned char *TimingPoint;
6596 unsigned short resindex, CRT2Index;
6597 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6599 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6602 if(ModeNo <= 0x13) {
6603 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6604 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6605 } else if(SiS_Pr->UseCustomMode) {
6606 modeflag = SiS_Pr->CModeFlag;
6609 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6610 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6614 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6615 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6616 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6617 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6619 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6621 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6623 PhaseIndex = 0x01; /* SiS_PALPhase */
6624 TimingPoint = SiS_Pr->SiS_PALTiming;
6627 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6628 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6629 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6633 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6635 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6636 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6637 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6638 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6639 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6643 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6646 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6647 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6649 TimingPoint = &SiS_YPbPrTable[i][0];
6651 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6653 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6655 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6659 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6660 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6661 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6665 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6666 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6667 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6670 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6671 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6672 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6673 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6674 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6676 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6680 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6681 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6684 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6685 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6687 for(i = 0x39; i <= 0x45; i++, j++) {
6688 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6691 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6692 if(SiS_Pr->SiS_ModeType != ModeText) {
6693 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6697 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6699 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6700 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6701 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6702 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6704 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6705 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
6706 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6707 else tempax = 440; /* NTSC, YPbPr 525 */
6709 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6710 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6711 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6713 tempax -= SiS_Pr->SiS_VDE;
6715 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6720 temp = tempax + (unsigned short)TimingPoint[0];
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6723 temp = tempax + (unsigned short)TimingPoint[1];
6724 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6726 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6727 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6728 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6729 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6731 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6732 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6738 tempcx = SiS_Pr->SiS_HT;
6739 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6741 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6742 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6743 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6745 tempcx = SiS_Pr->SiS_HT >> 1;
6746 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6748 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6749 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6751 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6753 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6754 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6757 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6761 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6764 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6765 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6766 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6769 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6770 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6772 tempcx = SiS_Pr->SiS_HT >> 1;
6773 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6775 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6776 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6779 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6780 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6782 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6784 tempbx = SiS_Pr->SiS_VDE;
6785 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6786 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6787 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6788 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6789 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6790 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6792 if(SiS_Pr->ChipType >= SIS_315H) {
6793 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6794 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6795 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6796 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6797 if(crt2crtc == 4) tempbx++;
6801 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6802 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6803 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6805 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6806 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6811 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6813 temp = (tempcx >> 8) & 0x0F;
6814 temp |= ((tempbx >> 2) & 0xC0);
6815 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6817 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6819 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6821 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6822 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6825 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6826 tempbx = SiS_Pr->SiS_VDE;
6827 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6828 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6832 temp = ((tempbx >> 3) & 0x60) | 0x18;
6833 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6834 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6836 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6837 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6842 if(!(modeflag & HalfDCLK)) {
6843 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6849 tempch = tempcl = 0x01;
6850 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6851 if(SiS_Pr->SiS_VGAHDE >= 960) {
6852 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6854 if(SiS_Pr->SiS_VGAHDE >= 1280) {
6857 } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6860 tempch = 25; /* OK */
6866 if(!(tempbx & 0x20)) {
6867 if(modeflag & HalfDCLK) tempcl <<= 1;
6868 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6869 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6870 tempax = longtemp / SiS_Pr->SiS_HDE;
6871 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6872 tempbx |= ((tempax >> 8) & 0x1F);
6873 tempcx = tempax >> 13;
6876 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6877 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6879 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6882 if(tempbx & 0x20) tempcx = 0;
6883 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6885 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6892 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6893 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6894 temp = (tempcx & 0x0300) >> 6;
6895 temp |= ((tempbx >> 8) & 0x03);
6896 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6898 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
6899 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6901 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
6903 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
6904 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
6906 SiS_SetTVSpecial(SiS_Pr, ModeNo);
6908 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
6910 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
6911 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
6916 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6917 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
6918 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
6919 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
6921 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
6924 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6925 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6926 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
6930 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
6932 /* From here: Part2 LCD setup */
6934 tempbx = SiS_Pr->SiS_HDE;
6935 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
6936 tempbx--; /* RHACTE = HDE - 1 */
6937 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
6938 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
6941 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
6942 if(SiS_Pr->SiS_ModeType == ModeEGA) {
6943 if(SiS_Pr->SiS_VGAHDE >= 1024) {
6945 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
6951 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
6953 tempbx = SiS_Pr->SiS_VDE - 1;
6954 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
6955 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
6957 tempcx = SiS_Pr->SiS_VT - 1;
6958 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
6959 temp = (tempcx >> 3) & 0xE0;
6960 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
6961 /* Enable dithering; only do this for 32bpp mode */
6962 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
6966 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
6968 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
6969 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
6971 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
6972 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
6975 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
6976 &CRT2Index, &resindex)) {
6978 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
6980 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
6983 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6984 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6985 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6986 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6988 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6989 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6991 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6992 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6994 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6995 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6997 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7002 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7003 /* Clevo dual-link 1024x768 */
7004 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7005 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7007 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7008 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7009 tempbx = SiS_Pr->SiS_VDE - 1;
7010 tempcx = SiS_Pr->SiS_VT - 1;
7012 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7013 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7016 tempbx = SiS_Pr->PanelYRes;
7017 tempcx = SiS_Pr->SiS_VT;
7019 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7020 tempax = SiS_Pr->PanelYRes;
7021 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7022 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7023 tempax = tempcx = 0;
7025 tempax -= SiS_Pr->SiS_VDE;
7029 tempcx -= tempax; /* lcdvdes */
7030 tempbx -= tempax; /* lcdvdee */
7033 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7035 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7036 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7038 temp = (tempbx >> 5) & 0x38;
7039 temp |= ((tempcx >> 8) & 0x07);
7040 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7042 tempax = SiS_Pr->SiS_VDE;
7043 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7044 tempax = SiS_Pr->PanelYRes;
7046 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7047 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7048 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7049 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7053 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7054 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7055 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7056 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7057 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7058 if(tempax % 4) { tempax >>= 2; tempax++; }
7059 else { tempax >>= 2; }
7060 tempbx -= (tempax - 1);
7063 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7067 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7069 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7070 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7077 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7079 if(SiS_Pr->UseCustomMode) {
7080 tempbx = SiS_Pr->CVSyncStart;
7083 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7085 temp = (tempbx >> 4) & 0xF0;
7086 tempbx += (tempcx + 1);
7087 temp |= (tempbx & 0x0F);
7089 if(SiS_Pr->UseCustomMode) {
7091 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7094 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7097 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7101 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7102 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7103 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7104 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7105 /* Higher bridgeoffset shifts to the LEFT */
7108 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7109 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7110 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7111 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7114 temp += bridgeoffset;
7115 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7116 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7118 tempcx = SiS_Pr->SiS_HT;
7119 tempax = tempbx = SiS_Pr->SiS_HDE;
7120 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7121 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7122 tempax = SiS_Pr->PanelXRes;
7123 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7126 if(SiS_IsDualLink(SiS_Pr)) {
7132 tempbx += bridgeoffset;
7134 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7135 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7137 tempcx = (tempcx - tempax) >> 2;
7142 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7143 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7144 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7145 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7150 if(SiS_Pr->UseCustomMode) {
7151 tempbx = SiS_Pr->CHSyncStart;
7152 if(modeflag & HalfDCLK) tempbx <<= 1;
7153 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7154 tempbx += bridgeoffset;
7157 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7158 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7163 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7164 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7168 if(SiS_Pr->UseCustomMode) {
7169 tempbx = SiS_Pr->CHSyncEnd;
7170 if(modeflag & HalfDCLK) tempbx <<= 1;
7171 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7172 tempbx += bridgeoffset;
7175 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7177 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7180 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7183 } /* CRT2-LCD from table */
7187 /*********************************************/
7188 /* SET PART 3 REGISTER GROUP */
7189 /*********************************************/
7192 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7195 const unsigned char *tempdi;
7197 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7200 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7205 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7206 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7207 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7209 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7210 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7213 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7214 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7215 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7216 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7220 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7221 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7222 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7223 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7225 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7226 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7227 tempdi = SiS_HiTVGroup3_1;
7228 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7232 for(i=0; i<=0x3E; i++) {
7233 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7235 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7236 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7237 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7247 /*********************************************/
7248 /* SET PART 4 REGISTER GROUP */
7249 /*********************************************/
7254 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7256 unsigned short temp, temp1, temp2;
7258 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7259 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7260 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7261 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7262 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7263 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7264 temp = (unsigned short)((int)(temp) + shift);
7265 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7266 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7267 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7268 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7269 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7270 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7275 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7277 unsigned short temp, temp1, resinfo = 0;
7278 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7280 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7281 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7283 if(SiS_Pr->ChipType >= XGI_20) return;
7285 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7286 if(!(ROMAddr[0x61] & 0x04)) return;
7290 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7293 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7294 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7295 if(!(temp & 0x01)) {
7296 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7297 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7298 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7299 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7301 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7302 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7303 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7304 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7306 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7308 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7309 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7310 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7311 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7312 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7314 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7317 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7318 if(temp1 == 0x01) temp |= 0x01;
7319 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7320 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7321 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7323 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7328 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7329 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7330 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7331 if(resinfo == SIS_RI_1024x768) {
7332 SiS_ShiftXPos(SiS_Pr, 97);
7334 SiS_ShiftXPos(SiS_Pr, 111);
7336 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7337 SiS_ShiftXPos(SiS_Pr, 136);
7349 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7350 unsigned short RefreshRateTableIndex)
7352 unsigned short vclkindex, temp, reg1, reg2;
7354 if(SiS_Pr->UseCustomMode) {
7355 reg1 = SiS_Pr->CSR2B;
7356 reg2 = SiS_Pr->CSR2C;
7358 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7359 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7360 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7363 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7364 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7365 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7366 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7367 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7369 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7370 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7373 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7374 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7375 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7377 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7379 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7380 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7384 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7386 if(SiS_Pr->ChipType >= SIS_315H) {
7387 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7388 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7389 (SiS_IsVAMode(SiS_Pr))) {
7390 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7391 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7393 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7398 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7399 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7401 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7403 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7408 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7409 unsigned short RefreshRateTableIndex)
7411 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7412 unsigned int tempebx, tempeax, templong;
7414 if(ModeNo <= 0x13) {
7415 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7416 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7417 } else if(SiS_Pr->UseCustomMode) {
7418 modeflag = SiS_Pr->CModeFlag;
7421 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7422 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7425 if(SiS_Pr->ChipType >= SIS_315H) {
7426 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7427 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7428 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7433 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7434 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7435 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7439 if(SiS_Pr->ChipType >= SIS_315H) {
7440 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7441 SiS_SetDualLinkEtc(SiS_Pr);
7446 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7448 tempbx = SiS_Pr->SiS_RVBHCMAX;
7449 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7451 temp = (tempbx >> 1) & 0x80;
7453 tempcx = SiS_Pr->SiS_VGAHT - 1;
7454 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7456 temp |= ((tempcx >> 5) & 0x78);
7458 tempcx = SiS_Pr->SiS_VGAVT - 1;
7459 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7460 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7462 temp |= ((tempcx >> 8) & 0x07);
7463 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7465 tempbx = SiS_Pr->SiS_VGAHDE;
7466 if(modeflag & HalfDCLK) tempbx >>= 1;
7467 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7469 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7471 if(tempbx > 800) temp = 0x60;
7472 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7474 if(tempbx > 1024) temp = 0xC0;
7475 else if(tempbx >= 960) temp = 0xA0;
7476 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7478 if(tempbx >= 1280) temp = 0x40;
7479 else if(tempbx >= 1024) temp = 0x20;
7482 if(tempbx >= 1024) temp = 0xA0;
7485 temp |= SiS_Pr->Init_P4_0E;
7487 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7488 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7494 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7496 tempeax = SiS_Pr->SiS_VGAVDE;
7497 tempebx = SiS_Pr->SiS_VDE;
7498 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7499 if(!(temp & 0xE0)) tempebx >>=1;
7502 tempcx = SiS_Pr->SiS_RVBHRS;
7503 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7507 if(tempeax <= tempebx) {
7513 tempeax *= (256 * 1024);
7514 templong = tempeax % tempebx;
7516 if(templong) tempeax++;
7518 temp = (unsigned short)(tempeax & 0x000000FF);
7519 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7520 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7521 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7522 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7523 temp |= (tempcx & 0x4F);
7524 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7526 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7528 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7530 /* Calc Linebuffer max address and set/clear decimode */
7532 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7533 tempax = SiS_Pr->SiS_VGAHDE;
7534 if(modeflag & HalfDCLK) tempax >>= 1;
7535 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7537 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7541 if(tempax == 960) tempax *= 25; /* Correct */
7542 else if(tempax == 1024) tempax *= 25;
7548 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7549 if(resinfo == SIS_RI_1024x768 ||
7550 resinfo == SIS_RI_1024x576 ||
7551 resinfo == SIS_RI_1280x1024 ||
7552 resinfo == SIS_RI_1280x720) {
7553 /* Otherwise white line or garbage at right edge */
7554 tempax = (tempax & 0xff00) | 0x20;
7560 temp = ((tempax >> 4) & 0x30) | tempbx;
7561 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7562 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7564 temp = 0x0036; tempbx = 0xD0;
7565 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7566 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7568 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7569 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7571 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7572 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7578 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7580 tempbx = SiS_Pr->SiS_HT >> 1;
7581 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7583 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7584 temp = (tempbx >> 5) & 0x38;
7585 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7587 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7588 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7589 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7590 /* LCD-too-dark-error-source, see FinalizeLCD() */
7594 SiS_SetDualLinkEtc(SiS_Pr);
7598 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7601 /*********************************************/
7602 /* SET PART 5 REGISTER GROUP */
7603 /*********************************************/
7606 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7609 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7611 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7612 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7613 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7614 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7619 /*********************************************/
7620 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7621 /*********************************************/
7624 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7625 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7626 unsigned short *DisplayType)
7628 unsigned short modeflag = 0;
7629 bool checkhd = true;
7631 /* Pass 1:1 not supported here */
7633 if(ModeNo <= 0x13) {
7634 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7635 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7637 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7638 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7641 (*ResIndex) &= 0x3F;
7643 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7645 (*DisplayType) = 80;
7646 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7647 (*DisplayType) = 82;
7648 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7649 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7652 if((*DisplayType) != 84) {
7653 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7659 switch(SiS_Pr->SiS_LCDResInfo) {
7660 case Panel_320x240_1: (*DisplayType) = 50;
7663 case Panel_320x240_2: (*DisplayType) = 14;
7665 case Panel_320x240_3: (*DisplayType) = 18;
7667 case Panel_640x480: (*DisplayType) = 10;
7669 case Panel_1024x600: (*DisplayType) = 26;
7671 default: return true;
7675 if(modeflag & HalfDCLK) (*DisplayType)++;
7678 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7679 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7688 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7689 unsigned short RefreshRateTableIndex)
7691 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7692 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7693 static const unsigned short CRIdx[] = {
7694 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7695 0x07, 0x10, 0x11, 0x15, 0x16
7698 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7699 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7700 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7701 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7704 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7705 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7706 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7708 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7709 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7712 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7714 if(SiS_Pr->ChipType < SIS_315H) {
7715 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7718 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7719 &ResIndex, &DisplayType))) {
7723 switch(DisplayType) {
7724 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7725 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7726 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7727 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7728 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7729 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7730 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7731 #if 0 /* Works better with calculated numbers */
7732 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7733 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7734 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7735 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7737 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7738 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7739 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7740 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7741 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7746 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7748 for(i = 0; i <= 10; i++) {
7749 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7750 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7753 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7754 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7755 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7758 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7759 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7761 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7762 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7764 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7765 if(modeflag & DoubleScanMode) tempah |= 0x80;
7766 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7770 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7775 /*********************************************/
7777 /*********************************************/
7780 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7781 unsigned short RefreshRateTableIndex)
7783 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7784 unsigned short clkbase, vclkindex = 0;
7785 unsigned char sr2b, sr2c;
7787 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7788 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7789 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7790 RefreshRateTableIndex--;
7792 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7793 RefreshRateTableIndex);
7794 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7796 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7797 RefreshRateTableIndex);
7800 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7801 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7803 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7804 if(SiS_Pr->SiS_UseROM) {
7805 if(ROMAddr[0x220] & 0x01) {
7806 sr2b = ROMAddr[0x227];
7807 sr2c = ROMAddr[0x228];
7813 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7814 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7819 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7820 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7821 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7822 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7823 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7824 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7825 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7826 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7827 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7830 /*********************************************/
7831 /* SET UP CHRONTEL CHIPS */
7832 /*********************************************/
7835 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7836 unsigned short RefreshRateTableIndex)
7838 unsigned short TVType, resindex;
7839 const struct SiS_CHTVRegData *CHTVRegData = NULL;
7842 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7844 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7849 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7850 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7852 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7853 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7855 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7857 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7858 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7860 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7865 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7866 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7867 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
7868 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7869 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7870 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7871 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7872 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7873 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7874 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7878 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7882 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7884 /* We don't support modes >800x600 */
7885 if (resindex > 5) return;
7887 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7888 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7889 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
7891 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7892 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
7895 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
7896 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
7897 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
7898 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
7899 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
7901 /* Set minimum flicker filter for Luma channel (SR1-0=00),
7902 minimum text enhancement (S3-2=10),
7903 maximum flicker filter for Chroma channel (S5-4=10)
7904 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
7906 SiS_SetCH700x(SiS_Pr,0x01,0x28);
7908 /* Set video bandwidth
7909 High bandwidth Luma composite video filter(S0=1)
7910 low bandwidth Luma S-video filter (S2-1=00)
7911 disable peak filter in S-video channel (S3=0)
7912 high bandwidth Chroma Filter (S5-4=11)
7915 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
7917 /* Register 0x3D does not exist in non-macrovision register map
7918 (Maybe this is a macrovision register?)
7921 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
7924 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
7925 all other bits a read-only. Macrovision?
7927 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
7929 /* Register 0x11 only contains 3 writable bits (S0-S2) for
7930 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
7932 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
7936 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
7938 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
7939 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
7940 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
7941 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7942 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
7943 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
7944 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
7945 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
7946 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
7947 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
7948 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
7949 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
7950 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
7951 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
7952 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
7953 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
7956 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
7957 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7958 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7959 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
7961 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
7962 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
7963 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
7964 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
7965 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
7966 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
7967 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
7968 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
7969 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
7970 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
7971 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
7972 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7973 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7976 } else { /* ---- PAL ---- */
7977 /* We don't play around with FSCI in PAL mode */
7978 if(resindex == 0x04) {
7979 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7980 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
7982 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7983 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
7991 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
7995 unsigned short temp;
7997 /* We don't support modes >1024x768 */
7998 if (resindex > 6) return;
8000 temp = CHTVRegData[resindex].Reg[0];
8001 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8002 SiS_SetCH701x(SiS_Pr,0x00,temp);
8004 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8005 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8006 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8007 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8008 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8009 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8011 temp = CHTVRegData[resindex].Reg[7];
8012 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8013 SiS_SetCH701x(SiS_Pr,0x07,temp);
8015 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8016 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8017 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8018 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8019 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8020 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8021 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8022 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8024 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8025 /* D1 should be set for PAL, PAL-N and NTSC-J,
8026 but I won't do that for PAL unless somebody
8027 tells me to do so. Since the BIOS uses
8028 non-default CIV values and blacklevels,
8029 this might be compensated anyway.
8031 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8032 SiS_SetCH701x(SiS_Pr,0x21,temp);
8044 #ifdef SIS315H /* ----------- 315 series only ---------- */
8047 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8049 unsigned short temp;
8051 /* Enable Chrontel 7019 LCD panel backlight */
8052 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8053 if(SiS_Pr->ChipType == SIS_740) {
8054 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8056 temp = SiS_GetCH701x(SiS_Pr,0x66);
8058 SiS_SetCH701x(SiS_Pr,0x66,temp);
8064 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8066 unsigned short temp;
8068 /* Disable Chrontel 7019 LCD panel backlight */
8069 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8070 temp = SiS_GetCH701x(SiS_Pr,0x66);
8072 SiS_SetCH701x(SiS_Pr,0x66,temp);
8077 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8079 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8080 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8081 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8082 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8083 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8084 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8085 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8086 const unsigned char *tableptr = NULL;
8089 /* Set up Power up/down timing */
8091 if(SiS_Pr->ChipType == SIS_740) {
8092 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8093 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8094 else tableptr = table1024_740;
8095 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8096 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8097 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8098 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8099 else tableptr = table1400_740;
8102 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8103 tableptr = table1024_650;
8104 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8105 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8106 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8107 tableptr = table1400_650;
8111 for(i=0; i<5; i++) {
8112 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8117 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8119 const unsigned char *tableptr = NULL;
8120 unsigned short tempbh;
8122 static const unsigned char regtable[] = {
8123 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8124 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8126 static const unsigned char table1024_740[] = {
8127 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8128 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8130 static const unsigned char table1280_740[] = {
8131 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8132 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8134 static const unsigned char table1400_740[] = {
8135 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8136 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8138 static const unsigned char table1600_740[] = {
8139 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8140 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8142 static const unsigned char table1024_650[] = {
8143 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8144 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8146 static const unsigned char table1280_650[] = {
8147 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8148 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8150 static const unsigned char table1400_650[] = {
8151 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8152 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8154 static const unsigned char table1600_650[] = {
8155 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8156 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8159 if(SiS_Pr->ChipType == SIS_740) {
8160 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8161 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8162 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8163 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8166 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8167 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8168 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8169 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8173 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8174 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8175 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8176 if(tempbh == 0xc8) {
8177 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8178 } else if(tempbh == 0xdb) {
8179 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8180 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8181 } else if(tempbh == 0xde) {
8182 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8186 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8189 for(i = 0; i < tempbh; i++) {
8190 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8192 SiS_ChrontelPowerSequencing(SiS_Pr);
8193 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8195 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8197 if(SiS_Pr->ChipType == SIS_740) {
8198 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8200 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8201 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8202 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8204 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8205 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8207 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8212 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8214 unsigned char temp, temp1;
8216 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8217 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8218 temp = SiS_GetCH701x(SiS_Pr,0x47);
8219 temp &= 0x7f; /* Use external VSYNC */
8220 SiS_SetCH701x(SiS_Pr,0x47,temp);
8221 SiS_LongDelay(SiS_Pr, 3);
8222 temp = SiS_GetCH701x(SiS_Pr,0x47);
8223 temp |= 0x80; /* Use internal VSYNC */
8224 SiS_SetCH701x(SiS_Pr,0x47,temp);
8225 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8229 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8231 unsigned short temp;
8233 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8234 if(SiS_Pr->ChipType == SIS_740) {
8235 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8236 temp |= 0x04; /* Invert XCLK phase */
8237 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8239 if(SiS_IsYPbPr(SiS_Pr)) {
8240 temp = SiS_GetCH701x(SiS_Pr,0x01);
8242 temp |= 0x80; /* Enable YPrPb (HDTV) */
8243 SiS_SetCH701x(SiS_Pr,0x01,temp);
8245 if(SiS_IsChScart(SiS_Pr)) {
8246 temp = SiS_GetCH701x(SiS_Pr,0x01);
8248 temp |= 0xc0; /* Enable SCART + CVBS */
8249 SiS_SetCH701x(SiS_Pr,0x01,temp);
8251 if(SiS_Pr->ChipType == SIS_740) {
8252 SiS_ChrontelResetVSync(SiS_Pr);
8253 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8255 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8256 temp = SiS_GetCH701x(SiS_Pr,0x49);
8257 if(SiS_IsYPbPr(SiS_Pr)) {
8258 temp = SiS_GetCH701x(SiS_Pr,0x73);
8260 SiS_SetCH701x(SiS_Pr,0x73,temp);
8262 temp = SiS_GetCH701x(SiS_Pr,0x47);
8264 SiS_SetCH701x(SiS_Pr,0x47,temp);
8265 SiS_LongDelay(SiS_Pr, 2);
8266 temp = SiS_GetCH701x(SiS_Pr,0x47);
8268 SiS_SetCH701x(SiS_Pr,0x47,temp);
8274 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8276 unsigned short temp;
8278 /* Complete power down of LVDS */
8279 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8280 if(SiS_Pr->ChipType == SIS_740) {
8281 SiS_LongDelay(SiS_Pr, 1);
8282 SiS_GenericDelay(SiS_Pr, 5887);
8283 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8284 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8286 SiS_LongDelay(SiS_Pr, 2);
8287 temp = SiS_GetCH701x(SiS_Pr,0x76);
8289 SiS_SetCH701x(SiS_Pr,0x76,temp);
8290 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8296 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8298 unsigned short temp;
8300 if(SiS_Pr->ChipType == SIS_740) {
8302 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8306 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8307 temp = SiS_GetCH701x(SiS_Pr,0x49);
8308 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8311 /* Reset Chrontel 7019 datapath */
8312 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8313 SiS_LongDelay(SiS_Pr, 1);
8314 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8316 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8317 SiS_ChrontelResetVSync(SiS_Pr);
8318 SiS_SetCH701x(SiS_Pr,0x49,temp);
8323 /* Clear/set/clear GPIO */
8324 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8326 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8327 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8329 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8330 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8332 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8333 temp = SiS_GetCH701x(SiS_Pr,0x61);
8335 SiS_SetCH701xForLCD(SiS_Pr);
8340 /* Reset Chrontel 7019 datapath */
8341 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8342 SiS_LongDelay(SiS_Pr, 1);
8343 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8348 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8350 unsigned short temp;
8352 if(SiS_Pr->ChipType == SIS_740) {
8354 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8355 SiS_ChrontelResetVSync(SiS_Pr);
8360 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8361 temp = SiS_GetCH701x(SiS_Pr,0x49);
8363 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8364 temp = SiS_GetCH701x(SiS_Pr,0x47);
8366 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8367 SiS_LongDelay(SiS_Pr, 3);
8368 temp = SiS_GetCH701x(SiS_Pr,0x47);
8370 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8377 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8379 unsigned short temp,temp1;
8381 if(SiS_Pr->ChipType == SIS_740) {
8383 temp = SiS_GetCH701x(SiS_Pr,0x61);
8386 SiS_SetCH701x(SiS_Pr,0x61,temp);
8388 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8389 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8390 SiS_LongDelay(SiS_Pr, 1);
8391 SiS_GenericDelay(SiS_Pr, 5887);
8396 temp = SiS_GetCH701x(SiS_Pr,0x61);
8399 SiS_SetCH701x(SiS_Pr,0x61,temp);
8402 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8403 temp = SiS_GetCH701x(SiS_Pr,0x66);
8405 SiS_SetCH701x(SiS_Pr,0x66,temp);
8407 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8408 SiS_GenericDelay(SiS_Pr, 1023);
8410 SiS_GenericDelay(SiS_Pr, 767);
8414 SiS_GenericDelay(SiS_Pr, 767);
8416 temp = SiS_GetCH701x(SiS_Pr,0x76);
8418 SiS_SetCH701x(SiS_Pr,0x76,temp);
8419 temp = SiS_GetCH701x(SiS_Pr,0x66);
8421 SiS_SetCH701x(SiS_Pr,0x66,temp);
8422 SiS_LongDelay(SiS_Pr, 1);
8428 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8430 unsigned short temp;
8432 SiS_LongDelay(SiS_Pr, 1);
8435 temp = SiS_GetCH701x(SiS_Pr,0x66);
8436 temp &= 0x04; /* PLL stable? -> bail out */
8437 if(temp == 0x04) break;
8439 if(SiS_Pr->ChipType == SIS_740) {
8440 /* Power down LVDS output, PLL normal operation */
8441 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8444 SiS_SetCH701xForLCD(SiS_Pr);
8446 temp = SiS_GetCH701x(SiS_Pr,0x76);
8447 temp &= 0xfb; /* Reset PLL */
8448 SiS_SetCH701x(SiS_Pr,0x76,temp);
8449 SiS_LongDelay(SiS_Pr, 2);
8450 temp = SiS_GetCH701x(SiS_Pr,0x76);
8451 temp |= 0x04; /* PLL normal operation */
8452 SiS_SetCH701x(SiS_Pr,0x76,temp);
8453 if(SiS_Pr->ChipType == SIS_740) {
8454 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8456 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8458 SiS_LongDelay(SiS_Pr, 2);
8461 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8465 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8467 unsigned short temp;
8469 temp = SiS_GetCH701x(SiS_Pr,0x03);
8470 temp |= 0x80; /* Set datapath 1 to TV */
8471 temp &= 0xbf; /* Set datapath 2 to LVDS */
8472 SiS_SetCH701x(SiS_Pr,0x03,temp);
8474 if(SiS_Pr->ChipType == SIS_740) {
8476 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8477 temp &= 0xfb; /* Normal XCLK phase */
8478 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8480 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8482 temp = SiS_GetCH701x(SiS_Pr,0x64);
8483 temp |= 0x40; /* ? Bit not defined */
8484 SiS_SetCH701x(SiS_Pr,0x64,temp);
8486 temp = SiS_GetCH701x(SiS_Pr,0x03);
8487 temp &= 0x3f; /* D1 input to both LVDS and TV */
8488 SiS_SetCH701x(SiS_Pr,0x03,temp);
8490 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8491 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8492 SiS_LongDelay(SiS_Pr, 1);
8493 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8494 SiS_ChrontelResetDB(SiS_Pr);
8495 SiS_ChrontelDoSomething2(SiS_Pr);
8496 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8498 temp = SiS_GetCH701x(SiS_Pr,0x66);
8500 SiS_ChrontelResetDB(SiS_Pr);
8501 SiS_ChrontelDoSomething2(SiS_Pr);
8502 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8508 SiS_ChrontelResetDB(SiS_Pr);
8509 SiS_ChrontelDoSomething2(SiS_Pr);
8510 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8511 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8512 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8517 #endif /* 315 series */
8519 /*********************************************/
8520 /* MAIN: SET CRT2 REGISTER GROUP */
8521 /*********************************************/
8524 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8527 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8529 unsigned short ModeIdIndex, RefreshRateTableIndex;
8531 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8533 if(!SiS_Pr->UseCustomMode) {
8534 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8539 /* Used for shifting CR33 */
8540 SiS_Pr->SiS_SelectCRT2Rate = 4;
8542 SiS_UnLockCRT2(SiS_Pr);
8544 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8546 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8548 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8549 SiS_DisableBridge(SiS_Pr);
8550 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8551 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8553 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8556 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8557 SiS_LockCRT2(SiS_Pr);
8558 SiS_DisplayOn(SiS_Pr);
8562 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8564 /* Set up Panel Link for LVDS and LCDA */
8565 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8566 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8567 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8568 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8569 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8572 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8573 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8576 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8578 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8580 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8582 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8584 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8585 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8587 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8589 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8591 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8593 /* For 301BDH (Panel link initialization): */
8594 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8596 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8597 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8598 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8601 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8607 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8609 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8611 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8613 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8614 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8615 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8616 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8618 SiS_SetCH701xForLCD(SiS_Pr);
8622 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8623 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8631 if(SiS_Pr->ChipType < SIS_315H) {
8632 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8633 if(SiS_Pr->SiS_UseOEM) {
8634 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8635 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8636 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8639 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8642 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8643 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8644 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8645 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8647 SiS_DisplayOn(SiS_Pr);
8654 if(SiS_Pr->ChipType >= SIS_315H) {
8655 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8656 if(SiS_Pr->ChipType < SIS_661) {
8657 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8658 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8660 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8662 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8667 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8668 SiS_EnableBridge(SiS_Pr);
8671 SiS_DisplayOn(SiS_Pr);
8673 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8674 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8675 /* Disable LCD panel when using TV */
8676 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8678 /* Disable TV when using LCD */
8679 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8683 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8684 SiS_LockCRT2(SiS_Pr);
8691 /*********************************************/
8692 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8693 /*********************************************/
8696 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8698 /* Switch on LCD backlight on SiS30xLV */
8699 SiS_DDC2Delay(SiS_Pr,0xff00);
8700 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8701 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8702 SiS_WaitVBRetrace(SiS_Pr);
8704 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8705 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8710 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8712 /* Switch off LCD backlight on SiS30xLV */
8713 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8714 SiS_DDC2Delay(SiS_Pr,0xff00);
8717 /*********************************************/
8718 /* DDC RELATED FUNCTIONS */
8719 /*********************************************/
8722 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8724 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8725 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8726 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8727 SiS_Pr->SiS_DDC_NData &= 0x0f;
8728 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8733 static unsigned char *
8734 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8737 unsigned short tempah,temp;
8738 unsigned char *mydataptr;
8740 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8741 mydataptr = dataptr;
8743 if(!num) return mydataptr;
8745 SiS_SetStop(SiS_Pr);
8746 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8748 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8749 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8750 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8751 if(temp) continue; /* (ERROR: no ack) */
8752 tempah = *mydataptr++;
8753 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8754 if(temp) continue; /* (ERROR: no ack) */
8755 for(j=0; j<num; j++) {
8756 tempah = *mydataptr++;
8757 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8761 if(SiS_SetStop(SiS_Pr)) continue;
8768 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8770 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8771 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8772 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8773 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8774 SiS_SetupDDCN(SiS_Pr);
8776 SiS_SetSwitchDDC2(SiS_Pr);
8779 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8780 if(!dataptr) return false;
8786 /* The Chrontel 700x is connected to the 630/730 via
8787 * the 630/730's DDC/I2C port.
8789 * On 630(S)T chipset, the index changed from 0x11 to
8790 * 0x0a, possibly for working around the DDC problems
8794 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8796 unsigned short temp, i;
8798 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8800 SiS_SetStop(SiS_Pr);
8801 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8803 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8804 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8805 if(temp) continue; /* (ERROR: no ack) */
8806 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
8807 if(temp) continue; /* (ERROR: no ack) */
8808 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
8809 if(temp) continue; /* (ERROR: no ack) */
8810 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
8811 SiS_Pr->SiS_ChrontelInit = 1;
8817 /* Write to Chrontel 700x */
8819 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8821 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8823 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8825 if(!(SiS_Pr->SiS_ChrontelInit)) {
8826 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8827 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8828 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8829 SiS_SetupDDCN(SiS_Pr);
8832 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
8833 (!(SiS_Pr->SiS_ChrontelInit)) ) {
8834 SiS_Pr->SiS_DDC_Index = 0x0a;
8835 SiS_Pr->SiS_DDC_Data = 0x80;
8836 SiS_Pr->SiS_DDC_Clk = 0x40;
8837 SiS_SetupDDCN(SiS_Pr);
8839 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
8843 /* Write to Chrontel 701x */
8844 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
8846 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8848 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8849 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8850 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8851 SiS_SetupDDCN(SiS_Pr);
8852 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8853 SiS_SetChReg(SiS_Pr, reg, val, 0);
8858 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8860 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8861 SiS_SetCH700x(SiS_Pr, reg, val);
8863 SiS_SetCH701x(SiS_Pr, reg, val);
8866 static unsigned short
8867 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
8869 unsigned short tempah, temp, i;
8871 for(i=0; i<20; i++) { /* Do 20 attempts to read */
8873 SiS_SetStop(SiS_Pr);
8874 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8876 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8877 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8878 if(temp) continue; /* (ERROR: no ack) */
8879 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
8880 if(temp) continue; /* (ERROR: no ack) */
8881 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
8882 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
8883 if(temp) continue; /* (ERROR: no ack) */
8884 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
8885 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
8886 SiS_Pr->SiS_ChrontelInit = 1;
8892 /* Read from Chrontel 700x */
8893 /* Parameter is [Register no (S7-S0)] */
8895 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8897 unsigned short result;
8899 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8901 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8903 if(!(SiS_Pr->SiS_ChrontelInit)) {
8904 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8905 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8906 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8907 SiS_SetupDDCN(SiS_Pr);
8910 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8912 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
8913 (!SiS_Pr->SiS_ChrontelInit) ) {
8915 SiS_Pr->SiS_DDC_Index = 0x0a;
8916 SiS_Pr->SiS_DDC_Data = 0x80;
8917 SiS_Pr->SiS_DDC_Clk = 0x40;
8918 SiS_SetupDDCN(SiS_Pr);
8920 result = SiS_GetChReg(SiS_Pr,0x80);
8925 /* Read from Chrontel 701x */
8926 /* Parameter is [Register no (S7-S0)] */
8928 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8930 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8931 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8932 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8933 SiS_SetupDDCN(SiS_Pr);
8934 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8936 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8938 return SiS_GetChReg(SiS_Pr,0);
8941 /* Read from Chrontel 70xx */
8942 /* Parameter is [Register no (S7-S0)] */
8945 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8947 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8948 return SiS_GetCH700x(SiS_Pr, tempbx);
8950 return SiS_GetCH701x(SiS_Pr, tempbx);
8954 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
8955 unsigned char myor, unsigned short myand)
8957 unsigned short tempbl;
8959 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
8960 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
8963 /* Our own DDC functions */
8966 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
8967 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
8968 unsigned int VBFlags2)
8970 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
8971 unsigned char flag, cr32;
8972 unsigned short temp = 0, myadaptnum = adaptnum;
8975 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
8976 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
8979 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
8981 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
8983 SiS_Pr->SiS_DDC_SecAddr = 0;
8984 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
8985 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
8986 SiS_Pr->SiS_DDC_Index = 0x11;
8989 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
8992 if(VBFlags2 & VB2_SISBRIDGE) {
8993 if(myadaptnum == 0) {
8994 if(!(cr32 & 0x20)) {
8996 if(!(cr32 & 0x10)) {
8998 if(!(cr32 & 0x08)) {
9007 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9009 if(myadaptnum != 0) {
9011 if(VBFlags2 & VB2_SISBRIDGE) {
9012 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9013 SiS_Pr->SiS_DDC_Index = 0x0f;
9017 if(!(VBFlags2 & VB2_301)) {
9018 if((cr32 & 0x80) && (checkcr32)) {
9019 if(myadaptnum >= 1) {
9020 if(!(cr32 & 0x08)) {
9022 if(!(cr32 & 0x10)) return 0xFFFF;
9028 temp = 4 - (myadaptnum * 2);
9031 } else { /* 315/330 series */
9033 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9035 if(VBFlags2 & VB2_SISBRIDGE) {
9036 if(myadaptnum == 2) {
9041 if(myadaptnum == 1) {
9043 if(VBFlags2 & VB2_SISBRIDGE) {
9044 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9045 SiS_Pr->SiS_DDC_Index = 0x0f;
9049 if((cr32 & 0x80) && (checkcr32)) {
9050 if(myadaptnum >= 1) {
9051 if(!(cr32 & 0x08)) {
9053 if(!(cr32 & 0x10)) return 0xFFFF;
9059 if(myadaptnum == 1) {
9061 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9067 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9068 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9070 SiS_SetupDDCN(SiS_Pr);
9075 static unsigned short
9076 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9078 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9079 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9082 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9088 static unsigned short
9089 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9091 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9092 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9098 static unsigned short
9099 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9101 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9102 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9107 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9109 SiS_SetSCLKLow(SiS_Pr);
9111 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9112 SiS_Pr->SiS_DDC_Index,
9113 SiS_Pr->SiS_DDC_NData,
9114 SiS_Pr->SiS_DDC_Data);
9116 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9117 SiS_Pr->SiS_DDC_Index,
9118 SiS_Pr->SiS_DDC_NData,
9121 SiS_SetSCLKHigh(SiS_Pr);
9124 static unsigned short
9125 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9127 unsigned char mask, value;
9128 unsigned short temp, ret=0;
9129 bool failed = false;
9131 SiS_SetSwitchDDC2(SiS_Pr);
9132 if(SiS_PrepareDDC(SiS_Pr)) {
9133 SiS_SetStop(SiS_Pr);
9138 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9139 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9140 SiS_SendACK(SiS_Pr, 0);
9150 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9151 SiS_SendACK(SiS_Pr, 1);
9153 if(temp == value) ret = 0;
9156 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9157 if(temp == 0x30) ret = 0;
9161 SiS_SetStop(SiS_Pr);
9167 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9169 unsigned short flag;
9172 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9173 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9174 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9175 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9176 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9177 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9178 if(!(flag & 0x1a)) flag = 0;
9184 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9186 unsigned short flag, length, i;
9187 unsigned char chksum,gotcha;
9189 if(DDCdatatype > 4) return 0xFFFF;
9192 SiS_SetSwitchDDC2(SiS_Pr);
9193 if(!(SiS_PrepareDDC(SiS_Pr))) {
9195 if(DDCdatatype != 1) length = 255;
9198 for(i=0; i<length; i++) {
9199 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9200 chksum += buffer[i];
9201 gotcha |= buffer[i];
9202 SiS_SendACK(SiS_Pr, 0);
9204 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9205 chksum += buffer[i];
9206 SiS_SendACK(SiS_Pr, 1);
9207 if(gotcha) flag = (unsigned short)chksum;
9212 SiS_SetStop(SiS_Pr);
9216 /* Our private DDC functions
9218 It complies somewhat with the corresponding VESA function
9219 in arguments and return values.
9221 Since this is probably called before the mode is changed,
9222 we use our pre-detected pSiS-values instead of SiS_Pr as
9223 regards chipset and video bridge type.
9226 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9227 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9228 LCDA is CRT1, but DDC is read from CRT2 port.
9229 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9230 buffer: ptr to 256 data bytes which will be filled with read data.
9232 Returns 0xFFFF if error, otherwise
9233 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9234 if DDCdatatype = 0: Returns supported DDC modes
9238 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9239 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9240 unsigned int VBFlags2)
9242 unsigned char sr1f, cr17=1;
9243 unsigned short result;
9251 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9254 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9257 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9258 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9259 if(VGAEngine == SIS_300_VGA) {
9260 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9262 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9263 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9264 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9267 if((sr1f) || (!cr17)) {
9268 SiS_WaitRetrace1(SiS_Pr);
9269 SiS_WaitRetrace1(SiS_Pr);
9270 SiS_WaitRetrace1(SiS_Pr);
9271 SiS_WaitRetrace1(SiS_Pr);
9274 if(DDCdatatype == 0) {
9275 result = SiS_ProbeDDC(SiS_Pr);
9277 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9278 if((!result) && (DDCdatatype == 1)) {
9279 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9280 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9281 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9282 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9283 (buffer[0x12] == 1)) {
9284 if(!SiS_Pr->DDCPortMixup) {
9286 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9288 if(buffer[0x14] & 0x80) result = 0xFFFE;
9294 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9295 if(VGAEngine == SIS_300_VGA) {
9296 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9301 /* Generic I2C functions for Chrontel & DDC --------- */
9304 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9306 SiS_SetSCLKHigh(SiS_Pr);
9307 SiS_WaitRetrace1(SiS_Pr);
9309 SiS_SetSCLKLow(SiS_Pr);
9310 SiS_WaitRetrace1(SiS_Pr);
9314 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9316 SiS_WaitRetrace1(SiS_Pr);
9317 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9320 /* Set I2C start condition */
9321 /* This is done by a SD high-to-low transition while SC is high */
9322 static unsigned short
9323 SiS_SetStart(struct SiS_Private *SiS_Pr)
9325 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9326 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9327 SiS_Pr->SiS_DDC_Index,
9328 SiS_Pr->SiS_DDC_NData,
9329 SiS_Pr->SiS_DDC_Data); /* SD->high */
9330 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9331 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9332 SiS_Pr->SiS_DDC_Index,
9333 SiS_Pr->SiS_DDC_NData,
9334 0x00); /* SD->low = start condition */
9335 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9339 /* Set I2C stop condition */
9340 /* This is done by a SD low-to-high transition while SC is high */
9341 static unsigned short
9342 SiS_SetStop(struct SiS_Private *SiS_Pr)
9344 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9345 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9346 SiS_Pr->SiS_DDC_Index,
9347 SiS_Pr->SiS_DDC_NData,
9348 0x00); /* SD->low */
9349 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9350 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9351 SiS_Pr->SiS_DDC_Index,
9352 SiS_Pr->SiS_DDC_NData,
9353 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9354 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9358 /* Write 8 bits of data */
9359 static unsigned short
9360 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9362 unsigned short i,flag,temp;
9365 for(i = 0; i < 8; i++) {
9366 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9368 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9369 SiS_Pr->SiS_DDC_Index,
9370 SiS_Pr->SiS_DDC_NData,
9371 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9373 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9374 SiS_Pr->SiS_DDC_Index,
9375 SiS_Pr->SiS_DDC_NData,
9376 0x00); /* Write bit (0) to SD */
9378 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9381 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9385 static unsigned short
9386 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9388 unsigned short i, temp, getdata;
9391 for(i = 0; i < 8; i++) {
9393 SiS_SetSCLKLow(SiS_Pr);
9394 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9395 SiS_Pr->SiS_DDC_Index,
9396 SiS_Pr->SiS_DDC_NData,
9397 SiS_Pr->SiS_DDC_Data);
9398 SiS_SetSCLKHigh(SiS_Pr);
9399 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9400 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9405 static unsigned short
9406 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9408 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9409 SiS_Pr->SiS_DDC_Index,
9410 SiS_Pr->SiS_DDC_NClk,
9411 0x00); /* SetSCLKLow() */
9412 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9416 static unsigned short
9417 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9419 unsigned short temp, watchdog=1000;
9421 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9422 SiS_Pr->SiS_DDC_Index,
9423 SiS_Pr->SiS_DDC_NClk,
9424 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9426 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9427 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9431 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9435 /* Check I2C acknowledge */
9436 /* Returns 0 if ack ok, non-0 if ack not ok */
9437 static unsigned short
9438 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9440 unsigned short tempah;
9442 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9443 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9444 SiS_Pr->SiS_DDC_Index,
9445 SiS_Pr->SiS_DDC_NData,
9446 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9447 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9448 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9449 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9450 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9454 /* End of I2C functions ----------------------- */
9457 /* =============== SiS 315/330 O.E.M. ================= */
9461 static unsigned short
9462 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9464 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9465 unsigned short romptr;
9467 if(SiS_Pr->ChipType < SIS_330) {
9468 romptr = SISGETROMW(0x128);
9469 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9470 romptr = SISGETROMW(0x12a);
9472 romptr = SISGETROMW(0x1a8);
9473 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9474 romptr = SISGETROMW(0x1aa);
9479 static unsigned short
9480 GetLCDromptr(struct SiS_Private *SiS_Pr)
9482 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9483 unsigned short romptr;
9485 if(SiS_Pr->ChipType < SIS_330) {
9486 romptr = SISGETROMW(0x120);
9487 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9488 romptr = SISGETROMW(0x122);
9490 romptr = SISGETROMW(0x1a0);
9491 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9492 romptr = SISGETROMW(0x1a2);
9497 static unsigned short
9498 GetTVromptr(struct SiS_Private *SiS_Pr)
9500 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9501 unsigned short romptr;
9503 if(SiS_Pr->ChipType < SIS_330) {
9504 romptr = SISGETROMW(0x114);
9505 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9506 romptr = SISGETROMW(0x11a);
9508 romptr = SISGETROMW(0x194);
9509 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9510 romptr = SISGETROMW(0x19a);
9515 static unsigned short
9516 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9518 unsigned short index;
9520 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9521 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9522 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9525 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9526 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9532 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9533 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9534 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9535 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9536 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9538 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9542 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9543 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9547 static unsigned short
9548 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9550 unsigned short index;
9552 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9553 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9554 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9558 static unsigned short
9559 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9561 unsigned short index;
9564 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9565 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9567 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9571 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9572 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9580 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9582 unsigned short index = 0, temp = 0;
9584 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9585 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9586 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9587 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9588 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9590 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9591 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9594 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9595 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9596 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9602 return (unsigned int)(index | (temp << 16));
9606 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9608 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9613 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9615 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9620 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9624 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9625 if(SiS_Pr->SiS_ROMNew) {
9626 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9627 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9628 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9629 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9631 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9632 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9633 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9634 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9637 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9643 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9645 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9646 unsigned short delay=0,index,myindex,temp,romptr=0;
9647 bool dochiptest = true;
9649 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9650 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9652 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9655 /* Find delay (from ROM, internal tables, PCI subsystem) */
9657 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9659 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9660 romptr = GetRAMDACromptr(SiS_Pr);
9662 if(romptr) delay = ROMAddr[romptr];
9665 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9668 } else if(IS_SIS740) {
9670 } else if(SiS_Pr->ChipType < SIS_330) {
9675 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9680 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9682 bool gotitfrompci = false;
9684 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9686 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9687 if(SiS_Pr->PDC != -1) {
9688 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9689 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9693 if(SiS_Pr->PDCA != -1) {
9694 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9695 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9702 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9703 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9705 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9708 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9711 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9713 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9716 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9717 if(IS_SIS740) delay = 0x01;
9720 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9725 /* This is a piece of typical SiS crap: They code the OEM LCD
9726 * delay into the code, at no defined place in the BIOS.
9727 * We now have to start doing a PCI subsystem check here.
9730 switch(SiS_Pr->SiS_CustomT) {
9731 case CUT_COMPAQ1280:
9732 case CUT_COMPAQ12802:
9733 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9734 gotitfrompci = true;
9740 case CUT_CLEVO14002:
9741 gotitfrompci = true;
9746 case CUT_CLEVO10242:
9747 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9748 gotitfrompci = true;
9751 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9757 /* Could we find it through the PCI ID? If no, use ROM or table */
9761 index = GetLCDPtrIndexBIOS(SiS_Pr);
9762 myindex = GetLCDPtrIndex(SiS_Pr);
9764 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9766 if(SiS_IsNotM650orLater(SiS_Pr)) {
9768 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9769 /* Always use the second pointer on 650; some BIOSes */
9770 /* still carry old 301 data at the first location */
9771 /* romptr = SISGETROMW(0x120); */
9772 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9773 romptr = SISGETROMW(0x122);
9775 delay = ROMAddr[(romptr + index)];
9777 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9782 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
9783 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
9784 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
9788 } else if(SiS_Pr->SiS_UseROM &&
9789 (!(SiS_Pr->SiS_ROMNew)) &&
9790 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
9791 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
9792 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
9793 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
9794 ((romptr = GetLCDromptr(SiS_Pr)))) {
9796 /* Data for 1280x1024 wrong in 301B BIOS */
9797 /* Data for 1600x1200 wrong in 301C BIOS */
9798 delay = ROMAddr[(romptr + index)];
9800 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9802 if(IS_SIS740) delay = 0x03;
9807 delay = SiS310_LCDDelayCompensation_301[myindex];
9808 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9809 if(IS_SIS740) delay = 0x01;
9810 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
9811 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9812 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9813 if(IS_SIS740) delay = 0x01; /* ? */
9815 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
9816 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9817 if(IS_SIS740) delay = 0x01;
9818 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
9823 } /* got it from PCI */
9825 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9826 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
9830 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
9832 index = GetTVPtrIndex(SiS_Pr);
9834 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9836 if(SiS_IsNotM650orLater(SiS_Pr)) {
9838 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9839 /* Always use the second pointer on 650; some BIOSes */
9840 /* still carry old 301 data at the first location */
9841 /* romptr = SISGETROMW(0x114); */
9842 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9843 romptr = SISGETROMW(0x11a);
9845 delay = ROMAddr[romptr + index];
9849 delay = SiS310_TVDelayCompensation_301B[index];
9855 switch(SiS_Pr->SiS_CustomT) {
9856 case CUT_COMPAQ1280:
9857 case CUT_COMPAQ12802:
9859 case CUT_CLEVO14002:
9864 case CUT_CLEVO10242:
9869 delay = SiS310_TVDelayCompensation_651301LV[index];
9870 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
9871 delay = SiS310_TVDelayCompensation_651302LV[index];
9876 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9878 romptr = GetTVromptr(SiS_Pr);
9880 delay = ROMAddr[romptr + index];
9882 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9884 delay = SiS310_TVDelayCompensation_LVDS[index];
9888 delay = SiS310_TVDelayCompensation_301[index];
9889 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9891 delay = SiS310_TVDelayCompensation_740301B[index];
9892 /* LV: use 301 data? BIOS bug? */
9894 delay = SiS310_TVDelayCompensation_301B[index];
9895 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
9901 if(SiS_LCDAEnabled(SiS_Pr)) {
9910 if(SiS_Pr->SiS_VBType & VB_SISVB) {
9912 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
9914 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
9915 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
9918 } else if(temp == 6) {
9921 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
9924 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9928 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9935 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9937 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
9939 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
9941 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9950 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
9952 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9953 unsigned short index,temp,temp1,romptr=0;
9955 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
9958 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
9960 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
9962 temp = GetTVPtrIndex(SiS_Pr);
9963 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9966 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
9967 if(SiS_Pr->ChipType >= SIS_661) {
9968 temp1 = GetOEMTVPtr661(SiS_Pr);
9970 romptr = SISGETROMW(0x260);
9971 if(SiS_Pr->ChipType >= SIS_760) {
9972 romptr = SISGETROMW(0x360);
9974 } else if(SiS_Pr->ChipType >= SIS_330) {
9975 romptr = SISGETROMW(0x192);
9977 romptr = SISGETROMW(0x112);
9983 temp = ROMAddr[romptr + temp1 + index];
9985 temp = SiS310_TVAntiFlick1[temp][index];
9989 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
9993 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
9995 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9996 unsigned short index,temp,temp1,romptr=0;
9998 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10001 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10003 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10005 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10006 if(SiS_Pr->ChipType >= SIS_661) {
10007 romptr = SISGETROMW(0x26c);
10008 if(SiS_Pr->ChipType >= SIS_760) {
10009 romptr = SISGETROMW(0x36c);
10011 temp1 = GetOEMTVPtr661(SiS_Pr);
10013 } else if(SiS_Pr->ChipType >= SIS_330) {
10014 romptr = SISGETROMW(0x1a4);
10016 romptr = SISGETROMW(0x124);
10022 temp = ROMAddr[romptr + temp1 + index];
10024 temp = SiS310_TVEdge1[temp][index];
10027 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10031 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10033 unsigned short index, temp, i, j;
10035 if(ModeNo <= 0x13) {
10036 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10038 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10041 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10043 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10044 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10045 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10046 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10048 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10049 for(i=0x35, j=0; i<=0x38; i++, j++) {
10050 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10052 for(i=0x48; i<=0x4A; i++, j++) {
10053 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10056 for(i=0x35, j=0; i<=0x38; i++, j++) {
10057 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10063 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10065 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10066 unsigned short index,temp,i,j,resinfo,romptr=0;
10067 unsigned int lindex;
10069 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10071 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10072 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10074 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10075 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10077 for(j=0, i=0x31; i<=0x34; i++, j++) {
10078 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10083 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10084 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10087 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10089 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10092 temp = GetTVPtrIndex(SiS_Pr);
10093 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10094 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10096 if(SiS_Pr->SiS_UseROM) {
10097 romptr = SISGETROMW(0x116);
10098 if(SiS_Pr->ChipType >= SIS_330) {
10099 romptr = SISGETROMW(0x196);
10101 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10102 romptr = SISGETROMW(0x11c);
10103 if(SiS_Pr->ChipType >= SIS_330) {
10104 romptr = SISGETROMW(0x19c);
10106 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10107 romptr = SISGETROMW(0x116);
10108 if(SiS_Pr->ChipType >= SIS_330) {
10109 romptr = SISGETROMW(0x196);
10115 romptr += (temp << 2);
10116 for(j=0, i=0x31; i<=0x34; i++, j++) {
10117 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10121 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10122 for(j=0, i=0x31; i<=0x34; i++, j++) {
10123 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10124 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10125 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10126 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10128 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10132 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10133 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10134 if((resinfo == SIS_RI_640x480) ||
10135 (resinfo == SIS_RI_800x600)) {
10136 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10137 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10138 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10139 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10140 } else if(resinfo == SIS_RI_1024x768) {
10141 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10142 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10143 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10144 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10151 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10152 unsigned short ModeIdIndex, unsigned short RTI)
10154 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10155 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10157 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10160 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10161 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10163 if(SiS_Pr->SiS_ROMNew) {
10164 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10165 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10166 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10168 if(SiS_Pr->UseCustomMode) {
10169 index = SiS_Pr->CSRClock;
10170 } else if(ModeNo > 0x13) {
10171 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10172 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10174 if(index < 25) index = 25;
10175 index = ((index / 25) - 1) << 1;
10176 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10179 romptr = SISGETROMW(0x104);
10180 delay = ROMAddr[romptr + index];
10181 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10182 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10183 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10185 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10186 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10192 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10194 if(SiS_Pr->UseCustomMode) delay = 0x04;
10195 else if(ModeNo <= 0x13) delay = 0x04;
10196 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10197 delay |= (delay << 8);
10199 if(SiS_Pr->ChipType >= XGI_20) {
10202 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10205 if(SiS_Pr->SiS_XGIROM) {
10206 index = GetTVPtrIndex(SiS_Pr);
10207 if((romptr = SISGETROMW(0x35e))) {
10208 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10209 delay |= (delay << 8);
10213 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10214 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10220 } else if(SiS_Pr->ChipType >= SIS_340) {
10223 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10226 /* TODO (eventually) */
10228 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10232 index = GetOEMTVPtr661(SiS_Pr);
10233 if(SiS_Pr->SiS_ROMNew) {
10234 romptr = SISGETROMW(0x106);
10235 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10236 delay = ROMAddr[romptr + index];
10239 if(index > 3) delay = 0;
10242 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10244 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10246 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10247 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10249 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10251 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10252 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10253 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10257 /* TMDS: Set our own, since BIOS has no idea */
10258 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10259 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10260 switch(SiS_Pr->SiS_LCDResInfo) {
10261 case Panel_1024x768: delay = 0x0008; break;
10262 case Panel_1280x720: delay = 0x0004; break;
10263 case Panel_1280x768:
10264 case Panel_1280x768_2:delay = 0x0004; break;
10265 case Panel_1280x800:
10266 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10267 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10268 case Panel_1280x1024: delay = 0x1e04; break;
10269 case Panel_1400x1050: delay = 0x0004; break;
10270 case Panel_1600x1200: delay = 0x0400; break;
10271 case Panel_1680x1050: delay = 0x0e04; break;
10273 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10275 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10277 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10279 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10287 /* Override by detected or user-set values */
10288 /* (but only if, for some reason, we can't read value from BIOS) */
10289 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10290 delay = SiS_Pr->PDC & 0x1f;
10292 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10293 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10300 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10302 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10303 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10305 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10306 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10311 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10313 unsigned short infoflag;
10314 unsigned char temp;
10316 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10318 if(ModeNo <= 0x13) {
10319 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10320 } else if(SiS_Pr->UseCustomMode) {
10321 infoflag = SiS_Pr->CInfoFlag;
10323 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10326 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10327 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10332 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10333 temp = (infoflag >> 6) | 0x0c;
10334 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10336 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10338 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10341 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10343 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10345 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10346 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10348 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10355 SetPanelParms661(struct SiS_Private *SiS_Pr)
10357 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10358 unsigned short romptr, temp1, temp2;
10360 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10361 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10364 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10365 if(SiS_Pr->LVDSHL != -1) {
10366 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10370 if(SiS_Pr->SiS_ROMNew) {
10372 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10373 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10374 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10376 if(SiS_Pr->LVDSHL != -1) {
10380 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10382 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10383 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10384 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10392 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10394 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10395 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10396 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10397 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10398 SetPanelParms661(SiS_Pr);
10401 SetDelayComp(SiS_Pr,ModeNo);
10404 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10405 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10406 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10407 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10408 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10409 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10415 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10416 unsigned short ModeIdIndex, unsigned short RRTI)
10418 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10420 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10422 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10423 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10424 SetPanelParms661(SiS_Pr);
10427 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10428 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10429 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10430 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10431 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10432 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10439 * This finalizes some CRT2 registers for the very panel used.
10440 * If we have a backup if these registers, we use it; otherwise
10441 * we set the register according to most BIOSes. However, this
10442 * function looks quite different in every BIOS, so you better
10443 * pray that we have a backup...
10446 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10448 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10449 unsigned short resinfo,modeflag;
10451 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10452 if(SiS_Pr->SiS_ROMNew) return;
10454 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10455 if(SiS_Pr->LVDSHL != -1) {
10456 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10460 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10461 if(SiS_Pr->UseCustomMode) return;
10463 switch(SiS_Pr->SiS_CustomT) {
10464 case CUT_COMPAQ1280:
10465 case CUT_COMPAQ12802:
10466 case CUT_CLEVO1400:
10467 case CUT_CLEVO14002:
10471 if(ModeNo <= 0x13) {
10472 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10473 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10475 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10476 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10480 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10481 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10482 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10484 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10489 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10490 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10491 /* Maybe all panels? */
10492 if(SiS_Pr->LVDSHL == -1) {
10493 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10499 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10500 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10501 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10502 if(SiS_Pr->LVDSHL == -1) {
10503 /* Maybe all panels? */
10504 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10506 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10507 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10509 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10510 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10511 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10512 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10520 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10521 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10522 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10523 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10525 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10527 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10529 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10530 if(SiS_Pr->LVDSHL == -1) {
10531 /* Maybe ACER only? */
10532 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10535 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10536 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10537 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10538 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10539 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10540 if(tempch == 0x03) {
10541 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10542 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10543 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10544 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10546 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10547 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10548 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10549 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10550 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10551 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10552 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10553 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10554 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10555 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10556 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10557 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10558 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10559 if(ModeNo <= 0x13) {
10560 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10561 if((resinfo == 0) || (resinfo == 2)) return;
10562 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10563 if((resinfo == 1) || (resinfo == 3)) return;
10565 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10566 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10567 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10569 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10571 temp = tempbx & 0xff;
10572 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10573 temp = (tempbx >> 8) & 0x03;
10574 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10577 } else if(ModeNo <= 0x13) {
10579 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10580 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10581 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10582 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10584 if(!(modeflag & HalfDCLK)) {
10585 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10586 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10587 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10588 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10589 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10590 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10591 if(ModeNo == 0x12) {
10594 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10595 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10596 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10597 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10598 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10599 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10602 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10603 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10606 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10614 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10618 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10619 tempbx = (tempbh << 8) | tempbl;
10620 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10621 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10622 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10625 if(tempbx > 770) tempbx = 770;
10626 if(SiS_Pr->SiS_VGAVDE < 600) {
10627 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10628 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10629 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10635 temp = tempbx & 0xff;
10636 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10637 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10638 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10645 /* ================= SiS 300 O.E.M. ================== */
10650 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10651 unsigned short RefTabIndex)
10653 unsigned short crt2crtc=0, modeflag, myindex=0;
10654 unsigned char temp;
10657 if(ModeNo <= 0x13) {
10658 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10659 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10661 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10662 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10667 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10668 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10671 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10672 if(modeflag & HalfDCLK) myindex = 1;
10674 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10675 for(i=0; i<7; i++) {
10676 if(barco_p1[myindex][crt2crtc][i][0]) {
10677 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10678 barco_p1[myindex][crt2crtc][i][0],
10679 barco_p1[myindex][crt2crtc][i][2],
10680 barco_p1[myindex][crt2crtc][i][1]);
10684 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10686 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10688 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10693 static unsigned short
10694 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10696 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10697 unsigned short tempbx=0,romptr=0;
10698 static const unsigned char customtable300[] = {
10699 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10700 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10702 static const unsigned char customtable630[] = {
10703 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10704 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10707 if(SiS_Pr->ChipType == SIS_300) {
10709 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10710 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10712 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10713 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10714 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10716 if(SiS_Pr->SiS_UseROM) {
10717 if(ROMAddr[0x235] & 0x80) {
10718 tempbx = SiS_Pr->SiS_LCDTypeInfo;
10720 romptr = SISGETROMW(0x255);
10721 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10722 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10723 if(tempbx == 0xFF) return 0xFFFF;
10726 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10733 if(SiS_Pr->SiS_UseROM) {
10734 romptr = SISGETROMW(0x255);
10735 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10736 else tempbx = 0xff;
10738 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10740 if(tempbx == 0xFF) return 0xFFFF;
10742 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10743 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10746 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10747 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10748 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10756 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10758 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10759 unsigned short index,temp,romptr=0;
10761 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10763 if(SiS_Pr->SiS_UseROM) {
10764 if(!(ROMAddr[0x237] & 0x01)) return;
10765 if(!(ROMAddr[0x237] & 0x02)) return;
10766 romptr = SISGETROMW(0x24b);
10769 /* The Panel Compensation Delay should be set according to tables
10770 * here. Unfortunately, various BIOS versions don't care about
10771 * a uniform way using eg. ROM byte 0x220, but use different
10772 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10773 * Thus we don't set this if the user selected a custom pdc or if
10774 * we otherwise detected a valid pdc.
10776 if(SiS_Pr->PDC != -1) return;
10778 temp = GetOEMLCDPtr(SiS_Pr, 0);
10780 if(SiS_Pr->UseCustomMode)
10783 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
10785 if(SiS_Pr->ChipType != SIS_300) {
10787 romptr += (temp * 2);
10788 romptr = SISGETROMW(romptr);
10790 temp = ROMAddr[romptr];
10792 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10793 temp = SiS300_OEMLCDDelay2[temp][index];
10795 temp = SiS300_OEMLCDDelay3[temp][index];
10799 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
10801 romptr += (temp * 2);
10802 romptr = SISGETROMW(romptr);
10804 temp = ROMAddr[romptr];
10806 temp = SiS300_OEMLCDDelay5[temp][index];
10809 if(SiS_Pr->SiS_UseROM) {
10810 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
10812 romptr += (temp * 2);
10813 romptr = SISGETROMW(romptr);
10815 temp = ROMAddr[romptr];
10817 temp = SiS300_OEMLCDDelay4[temp][index];
10820 temp = SiS300_OEMLCDDelay4[temp][index];
10825 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
10829 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10831 #if 0 /* Unfinished; Data table missing */
10832 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10833 unsigned short index,temp;
10835 if((SiS_Pr->SiS_UseROM) {
10836 if(!(ROMAddr[0x237] & 0x01)) return;
10837 if(!(ROMAddr[0x237] & 0x04)) return;
10838 /* No rom pointer in BIOS header! */
10841 temp = GetOEMLCDPtr(SiS_Pr, 1);
10842 if(temp == 0xFFFF) return;
10844 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
10845 for(i=0x14, j=0; i<=0x17; i++, j++) {
10846 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
10848 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
10850 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
10851 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
10852 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
10853 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
10854 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
10855 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
10860 static unsigned short
10861 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
10863 unsigned short index;
10866 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
10867 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10868 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
10869 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
10870 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10872 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
10873 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10879 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10881 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10882 unsigned short index,temp,romptr=0;
10884 if(SiS_Pr->SiS_UseROM) {
10885 if(!(ROMAddr[0x238] & 0x01)) return;
10886 if(!(ROMAddr[0x238] & 0x02)) return;
10887 romptr = SISGETROMW(0x241);
10890 temp = GetOEMTVPtr(SiS_Pr);
10892 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
10895 romptr += (temp * 2);
10896 romptr = SISGETROMW(romptr);
10898 temp = ROMAddr[romptr];
10900 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10901 temp = SiS300_OEMTVDelay301[temp][index];
10903 temp = SiS300_OEMTVDelayLVDS[temp][index];
10907 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
10911 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10913 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10914 unsigned short index,temp,romptr=0;
10916 if(SiS_Pr->SiS_UseROM) {
10917 if(!(ROMAddr[0x238] & 0x01)) return;
10918 if(!(ROMAddr[0x238] & 0x04)) return;
10919 romptr = SISGETROMW(0x243);
10922 temp = GetOEMTVPtr(SiS_Pr);
10924 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
10927 romptr += (temp * 2);
10928 romptr = SISGETROMW(romptr);
10930 temp = ROMAddr[romptr];
10932 temp = SiS300_OEMTVFlicker[temp][index];
10935 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
10939 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10941 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10942 unsigned short index,i,j,temp,romptr=0;
10944 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
10946 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
10948 if(SiS_Pr->SiS_UseROM) {
10949 if(!(ROMAddr[0x238] & 0x01)) return;
10950 if(!(ROMAddr[0x238] & 0x08)) return;
10951 romptr = SISGETROMW(0x245);
10954 temp = GetOEMTVPtr(SiS_Pr);
10956 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
10958 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10959 for(i=0x31, j=0; i<=0x34; i++, j++) {
10960 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
10964 romptr += (temp * 2);
10965 romptr = SISGETROMW(romptr);
10966 romptr += (index * 4);
10967 for(i=0x31, j=0; i<=0x34; i++, j++) {
10968 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10971 for(i=0x31, j=0; i<=0x34; i++, j++) {
10972 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
10979 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10981 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10982 unsigned short index,temp,i,j,romptr=0;
10984 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
10986 if(SiS_Pr->SiS_UseROM) {
10987 if(!(ROMAddr[0x238] & 0x01)) return;
10988 if(!(ROMAddr[0x238] & 0x10)) return;
10989 romptr = SISGETROMW(0x247);
10992 temp = GetOEMTVPtr(SiS_Pr);
10994 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
10995 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
10996 /* NTSCJ uses NTSC filters */
10998 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11000 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11001 for(i=0x35, j=0; i<=0x38; i++, j++) {
11002 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11004 for(i=0x48; i<=0x4A; i++, j++) {
11005 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11008 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11009 romptr += (temp * 2);
11010 romptr = SISGETROMW(romptr);
11011 romptr += (index * 4);
11012 for(i=0x35, j=0; i<=0x38; i++, j++) {
11013 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11016 for(i=0x35, j=0; i<=0x38; i++, j++) {
11017 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11023 static unsigned short
11024 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11026 unsigned short ModeIdIndex;
11027 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11029 if(*ModeNo <= 5) *ModeNo |= 1;
11031 for(ModeIdIndex=0; ; ModeIdIndex++) {
11032 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11033 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11036 if(*ModeNo != 0x07) {
11037 if(*ModeNo > 0x03) return ModeIdIndex;
11038 if(VGAINFO & 0x80) return ModeIdIndex;
11042 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11043 /* else 350 lines */
11044 return ModeIdIndex;
11048 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11049 unsigned short RefTableIndex)
11051 unsigned short OEMModeIdIndex = 0;
11053 if(!SiS_Pr->UseCustomMode) {
11054 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11055 if(!(OEMModeIdIndex)) return;
11058 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11059 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11060 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11061 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11064 if(SiS_Pr->UseCustomMode) return;
11065 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11066 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11067 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11068 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11069 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11070 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);