4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730,
6 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
12 * If distributed as part of the Linux kernel, the following license terms
15 * * This program is free software; you can redistribute it and/or modify
16 * * it under the terms of the GNU General Public License as published by
17 * * the Free Software Foundation; either version 2 of the named License,
18 * * or any later version.
20 * * This program is distributed in the hope that it will be useful,
21 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * * GNU General Public License for more details.
25 * * You should have received a copy of the GNU General Public License
26 * * along with this program; if not, write to the Free Software
27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
29 * Otherwise, the following license terms apply:
31 * * Redistribution and use in source and binary forms, with or without
32 * * modification, are permitted provided that the following conditions
34 * * 1) Redistributions of source code must retain the above copyright
35 * * notice, this list of conditions and the following disclaimer.
36 * * 2) Redistributions in binary form must reproduce the above copyright
37 * * notice, this list of conditions and the following disclaimer in the
38 * * documentation and/or other materials provided with the distribution.
39 * * 3) The name of the author may not be used to endorse or promote products
40 * * derived from this software without specific prior written permission.
42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 * Author: Thomas Winischhofer <thomas@winischhofer.net>
55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
65 #define SET_EMI /* 302LV/ELV: Set EMI values */
69 #define SET_PWD /* 301/302LV: Set PWD */
72 #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
73 #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
74 #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
86 #define SiS_I2CDELAY 1000
87 #define SiS_I2CDELAYSHORT 150
89 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
90 #ifdef SIS_LINUX_KERNEL
91 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
94 /*********************************************/
95 /* HELPER: Lock/Unlock CRT2 */
96 /*********************************************/
99 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
101 if(SiS_Pr->ChipType == XGI_20)
103 else if(SiS_Pr->ChipType >= SIS_315H)
104 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
106 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
109 #ifdef SIS_LINUX_KERNEL
113 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
115 if(SiS_Pr->ChipType == XGI_20)
117 else if(SiS_Pr->ChipType >= SIS_315H)
118 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
120 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
123 /*********************************************/
124 /* HELPER: Write SR11 */
125 /*********************************************/
128 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
130 if(SiS_Pr->ChipType >= SIS_661) {
134 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
137 /*********************************************/
138 /* HELPER: Get Pointer to LCD structure */
139 /*********************************************/
142 static unsigned char *
143 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
145 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
146 unsigned char *myptr = NULL;
147 unsigned short romindex = 0, reg = 0, idx = 0;
149 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
150 * due to the variaty of panels the BIOS doesn't know about.
151 * Exception: If the BIOS has better knowledge (such as in case
152 * of machines with a 301C and a panel that does not support DDC)
153 * use the BIOS data as well.
156 if((SiS_Pr->SiS_ROMNew) &&
157 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
159 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
162 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
165 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
167 romindex = SISGETROMW(0x100);
170 myptr = &ROMAddr[romindex];
176 static unsigned short
177 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
179 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
180 unsigned short romptr = 0;
182 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
183 * due to the variaty of panels the BIOS doesn't know about.
184 * Exception: If the BIOS has better knowledge (such as in case
185 * of machines with a 301C and a panel that does not support DDC)
186 * use the BIOS data as well.
189 if((SiS_Pr->SiS_ROMNew) &&
190 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
191 romptr = SISGETROMW(0x102);
192 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
199 /*********************************************/
200 /* Adjust Rate for CRT2 */
201 /*********************************************/
204 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
205 unsigned short RRTI, unsigned short *i)
207 unsigned short checkmask=0, modeid, infoflag;
209 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
211 if(SiS_Pr->SiS_VBType & VB_SISVB) {
213 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
215 checkmask |= SupportRAMDAC2;
216 if(SiS_Pr->ChipType >= SIS_315H) {
217 checkmask |= SupportRAMDAC2_135;
218 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
219 checkmask |= SupportRAMDAC2_162;
220 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
221 checkmask |= SupportRAMDAC2_202;
226 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
228 checkmask |= SupportLCD;
229 if(SiS_Pr->ChipType >= SIS_315H) {
230 if(SiS_Pr->SiS_VBType & VB_SISVB) {
231 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
232 if(modeid == 0x2e) checkmask |= Support64048060Hz;
237 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
239 checkmask |= SupportHiVision;
241 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
243 checkmask |= SupportTV;
244 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
245 checkmask |= SupportTV1024;
246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
247 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
248 checkmask |= SupportYPbPr750p;
257 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
258 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
259 checkmask |= SupportCHTV;
263 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
264 checkmask |= SupportLCD;
269 /* Look backwards in table for matching CRT2 mode */
270 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
271 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
272 if(infoflag & checkmask) return TRUE;
276 /* Look through the whole mode-section of the table from the beginning
277 * for a matching CRT2 mode if no mode was found yet.
279 for((*i) = 0; ; (*i)++) {
280 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
281 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
282 if(infoflag & checkmask) return TRUE;
287 /*********************************************/
289 /*********************************************/
292 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
294 unsigned short RRTI,i,backup_i;
295 unsigned short modeflag,index,temp,backupindex;
296 static const unsigned short LCDRefreshIndex[] = {
297 0x00, 0x00, 0x01, 0x01,
298 0x01, 0x01, 0x01, 0x01,
299 0x01, 0x01, 0x01, 0x01,
300 0x01, 0x01, 0x01, 0x01,
301 0x00, 0x00, 0x00, 0x00
304 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
305 if(ModeNo == 0xfe) return 0;
308 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
310 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
313 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
314 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
315 if(modeflag & HalfDCLK) return 0;
319 if(ModeNo < 0x14) return 0xFFFF;
321 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
324 if(index > 0) index--;
326 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
327 if(SiS_Pr->SiS_VBType & VB_SISVB) {
328 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
329 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
330 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
332 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
333 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
334 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
335 if(index > temp) index = temp;
339 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
340 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
341 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
346 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
347 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
349 if(SiS_Pr->ChipType >= SIS_315H) {
350 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
351 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
352 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
353 if(backupindex <= 1) RRTI++;
360 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
361 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
362 temp &= ModeTypeMask;
363 if(temp < SiS_Pr->SiS_ModeType) break;
366 } while(index != 0xFFFF);
368 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
369 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
370 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
371 if(temp & InterlaceMode) i++;
377 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
379 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
387 /*********************************************/
388 /* STORE CRT2 INFO in CR34 */
389 /*********************************************/
392 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
394 unsigned short temp1, temp2;
396 /* Store CRT1 ModeNo in CR34 */
397 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
398 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
399 temp2 = ~(SetInSlaveMode >> 8);
400 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
403 /*********************************************/
404 /* HELPER: GET SOME DATA FROM BIOS ROM */
405 /*********************************************/
409 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
411 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
412 unsigned short temp,temp1;
414 if(SiS_Pr->SiS_UseROM) {
415 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
416 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
417 temp1 = SISGETROMW(0x23b);
418 if(temp1 & temp) return TRUE;
425 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
427 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
428 unsigned short temp,temp1;
430 if(SiS_Pr->SiS_UseROM) {
431 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
432 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
433 temp1 = SISGETROMW(0x23d);
434 if(temp1 & temp) return TRUE;
441 /*********************************************/
442 /* HELPER: DELAY FUNCTIONS */
443 /*********************************************/
446 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
448 while (delaytime-- > 0)
449 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
452 #if defined(SIS300) || defined(SIS315H)
454 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
456 SiS_DDC2Delay(SiS_Pr, delay * 36);
462 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
465 SiS_GenericDelay(SiS_Pr, 6623);
470 #if defined(SIS300) || defined(SIS315H)
472 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
475 SiS_GenericDelay(SiS_Pr, 66);
481 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
483 #if defined(SIS300) || defined(SIS315H)
484 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
485 unsigned short PanelID, DelayIndex, Delay=0;
488 if(SiS_Pr->ChipType < SIS_315H) {
492 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
493 if(SiS_Pr->SiS_VBType & VB_SISVB) {
494 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
495 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
497 DelayIndex = PanelID >> 4;
498 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
501 if(DelayTime >= 2) DelayTime -= 2;
502 if(!(DelayTime & 0x01)) {
503 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
505 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
507 if(SiS_Pr->SiS_UseROM) {
508 if(ROMAddr[0x220] & 0x40) {
509 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
510 else Delay = (unsigned short)ROMAddr[0x226];
514 SiS_ShortDelay(SiS_Pr, Delay);
522 if((SiS_Pr->ChipType >= SIS_661) ||
523 (SiS_Pr->ChipType <= SIS_315PRO) ||
524 (SiS_Pr->ChipType == SIS_330) ||
525 (SiS_Pr->SiS_ROMNew)) {
527 if(!(DelayTime & 0x01)) {
528 SiS_DDC2Delay(SiS_Pr, 0x1000);
530 SiS_DDC2Delay(SiS_Pr, 0x4000);
533 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
534 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
535 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
537 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
538 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
539 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
540 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
542 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
543 DelayIndex = PanelID & 0x0f;
545 DelayIndex = PanelID >> 4;
547 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
550 if(DelayTime >= 2) DelayTime -= 2;
551 if(!(DelayTime & 0x01)) {
552 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
554 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
556 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
557 if(ROMAddr[0x13c] & 0x40) {
558 if(!(DelayTime & 0x01)) {
559 Delay = (unsigned short)ROMAddr[0x17e];
561 Delay = (unsigned short)ROMAddr[0x17f];
566 SiS_ShortDelay(SiS_Pr, Delay);
569 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
571 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
572 if(!(DelayTime & 0x01)) {
573 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
575 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
578 SiS_DDC2Delay(SiS_Pr, Delay);
589 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
592 for(i = 0; i < DelayLoop; i++) {
593 SiS_PanelDelay(SiS_Pr, DelayTime);
598 /*********************************************/
599 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
600 /*********************************************/
603 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
605 unsigned short watchdog;
607 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
608 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
611 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
613 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
616 #if defined(SIS300) || defined(SIS315H)
618 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
620 unsigned short watchdog;
623 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
625 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
630 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
632 if(SiS_Pr->ChipType < SIS_315H) {
634 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
635 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
637 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
638 SiS_WaitRetrace1(SiS_Pr);
640 SiS_WaitRetrace2(SiS_Pr, 0x25);
645 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
646 SiS_WaitRetrace1(SiS_Pr);
648 SiS_WaitRetrace2(SiS_Pr, 0x30);
655 SiS_VBWait(struct SiS_Private *SiS_Pr)
657 unsigned short tempal,temp,i,j;
660 for(i = 0; i < 3; i++) {
661 for(j = 0; j < 100; j++) {
662 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
664 if((tempal & 0x08)) continue;
667 if(!(tempal & 0x08)) continue;
676 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
678 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
681 SiS_WaitRetrace1(SiS_Pr);
685 /*********************************************/
687 /*********************************************/
691 SiS_Is301B(struct SiS_Private *SiS_Pr)
693 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
699 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
701 if(SiS_Pr->ChipType == SIS_730) {
702 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return TRUE;
704 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return TRUE;
709 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
712 if(SiS_Pr->ChipType >= SIS_315H) {
713 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
714 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return TRUE;
722 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
727 if(SiS_Pr->ChipType >= SIS_315H) {
728 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
729 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
737 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
739 if(SiS_IsVAMode(SiS_Pr)) return TRUE;
740 if(SiS_CRT2IsLCD(SiS_Pr)) return TRUE;
746 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
749 if(SiS_Pr->ChipType >= SIS_315H) {
750 if((SiS_CRT2IsLCD(SiS_Pr)) ||
751 (SiS_IsVAMode(SiS_Pr))) {
752 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
761 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
763 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
764 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
765 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
773 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
775 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
782 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
784 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
785 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
793 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
797 if(SiS_Pr->ChipType == SIS_650) {
798 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
799 /* Check for revision != A0 only */
800 if((flag == 0xe0) || (flag == 0xc0) ||
801 (flag == 0xb0) || (flag == 0x90)) return FALSE;
802 } else if(SiS_Pr->ChipType >= SIS_661) return FALSE;
809 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
811 if(SiS_Pr->ChipType >= SIS_315H) {
813 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return TRUE;
821 SiS_IsChScart(struct SiS_Private *SiS_Pr)
823 if(SiS_Pr->ChipType >= SIS_315H) {
825 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return TRUE;
833 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
837 if(SiS_Pr->ChipType >= SIS_315H) {
838 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
839 if(flag & SetCRT2ToTV) return TRUE;
840 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
841 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
842 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
844 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
845 if(flag & SetCRT2ToTV) return TRUE;
853 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
857 if(SiS_Pr->ChipType >= SIS_315H) {
858 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
859 if(flag & SetCRT2ToLCD) return TRUE;
860 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
861 if(flag & SetToLCDA) return TRUE;
863 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
864 if(flag & SetCRT2ToLCD) return TRUE;
871 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
875 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
877 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
878 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
879 if((flag == 1) || (flag == 2)) return TRUE;
885 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
889 if(SiS_HaveBridge(SiS_Pr)) {
890 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
891 if(SiS_Pr->ChipType < SIS_315H) {
893 if((flag == 0x80) || (flag == 0x20)) return TRUE;
896 if((flag == 0x40) || (flag == 0x10)) return TRUE;
903 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
905 unsigned short flag1;
907 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
908 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
912 /*********************************************/
913 /* GET VIDEO BRIDGE CONFIG INFO */
914 /*********************************************/
916 /* Setup general purpose IO for Chrontel communication */
919 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
921 unsigned int acpibase;
924 if(!(SiS_Pr->SiS_ChSW)) return;
926 #ifdef SIS_LINUX_KERNEL
927 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
929 acpibase = pciReadLong(0x00000800, 0x74);
932 if(!acpibase) return;
933 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
935 SiS_SetRegShort((acpibase + 0x3c), temp);
936 temp = SiS_GetRegShort((acpibase + 0x3c));
937 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
939 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
940 SiS_SetRegShort((acpibase + 0x3a), temp);
941 temp = SiS_GetRegShort((acpibase + 0x3a));
946 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
947 unsigned short ModeIdIndex, int checkcrt2mode)
949 unsigned short tempax, tempbx, temp;
950 unsigned short modeflag, resinfo = 0;
952 SiS_Pr->SiS_SetFlag = 0;
954 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
956 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
958 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
959 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
964 if(SiS_HaveBridge(SiS_Pr)) {
966 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
968 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
969 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
973 if(SiS_Pr->ChipType >= SIS_315H) {
974 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
976 /* Mode 0x03 is never in driver mode */
977 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
979 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
980 /* Reset LCDA setting if not driver mode */
981 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
984 if(SiS_Pr->SiS_UseLCDA) {
985 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
986 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
987 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
992 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
993 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
994 tempbx |= SetCRT2ToLCDA;
998 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
999 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1000 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1001 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1002 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1003 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1004 tempbx |= SetCRT2ToYPbPr525750;
1009 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1010 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1011 if(temp & SetToLCDA) {
1012 tempbx |= SetCRT2ToLCDA;
1014 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1015 if(temp & EnableCHYPbPr) {
1016 tempbx |= SetCRT2ToCHYPbPr;
1022 #endif /* SIS315H */
1024 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1025 tempbx &= ~(SetCRT2ToRAMDAC);
1028 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1029 temp = SetCRT2ToSVIDEO |
1036 SetCRT2ToYPbPr525750;
1038 if(SiS_Pr->ChipType >= SIS_315H) {
1039 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1040 temp = SetCRT2ToAVIDEO |
1047 temp = SetCRT2ToLCDA |
1051 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1052 temp = SetCRT2ToTV | SetCRT2ToLCD;
1054 temp = SetCRT2ToLCD;
1059 if(!(tempbx & temp)) {
1060 tempax = DisableCRT2Display;
1064 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1066 unsigned short clearmask = ( DriverMode |
1067 DisableCRT2Display |
1075 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1076 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1077 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1078 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1079 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1080 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1084 if(SiS_Pr->ChipType >= SIS_315H) {
1085 if(tempbx & SetCRT2ToLCDA) {
1086 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1089 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1090 if(tempbx & SetCRT2ToTV) {
1091 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1094 if(tempbx & SetCRT2ToLCD) {
1095 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1097 if(SiS_Pr->ChipType >= SIS_315H) {
1098 if(tempbx & SetCRT2ToLCDA) {
1099 tempbx |= SetCRT2ToLCD;
1105 if(tempax & DisableCRT2Display) {
1106 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1107 tempbx = SetSimuScanMode | DisableCRT2Display;
1111 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1113 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1114 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1115 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1116 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1117 modeflag &= (~CRT2Mode);
1121 if(!(tempbx & SetSimuScanMode)) {
1122 if(tempbx & SwitchCRT2) {
1123 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1124 if(resinfo != SIS_RI_1600x1200) {
1125 tempbx |= SetSimuScanMode;
1129 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1130 if(!(tempbx & DriverMode)) {
1131 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1132 tempbx |= SetSimuScanMode;
1139 if(!(tempbx & DisableCRT2Display)) {
1140 if(tempbx & DriverMode) {
1141 if(tempbx & SetSimuScanMode) {
1142 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1143 if(resinfo != SIS_RI_1600x1200) {
1144 tempbx |= SetInSlaveMode;
1149 tempbx |= SetInSlaveMode;
1155 SiS_Pr->SiS_VBInfo = tempbx;
1158 if(SiS_Pr->ChipType == SIS_630) {
1159 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1163 #ifdef SIS_LINUX_KERNEL
1165 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1166 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1169 #ifdef SIS_XORG_XF86
1171 xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1172 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1177 /*********************************************/
1178 /* DETERMINE YPbPr MODE */
1179 /*********************************************/
1182 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1187 /* Note: This variable is only used on 30xLV systems.
1188 * CR38 has a different meaning on LVDS/CH7019 systems.
1189 * On 661 and later, these bits moved to CR35.
1191 * On 301, 301B, only HiVision 1080i is supported.
1192 * On 30xLV, 301C, only YPbPr 1080i is supported.
1195 SiS_Pr->SiS_YPbPr = 0;
1196 if(SiS_Pr->ChipType >= SIS_661) return;
1198 if(SiS_Pr->SiS_VBType) {
1199 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1200 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1204 if(SiS_Pr->ChipType >= SIS_315H) {
1205 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1206 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1208 switch((temp >> 4)) {
1209 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1210 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1211 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1212 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1220 /*********************************************/
1221 /* DETERMINE TVMode flag */
1222 /*********************************************/
1225 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1227 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1228 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1229 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1231 SiS_Pr->SiS_TVMode = 0;
1233 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1234 if(SiS_Pr->UseCustomMode) return;
1237 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1240 if(SiS_Pr->ChipType < SIS_661) {
1242 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1244 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1246 if((SiS_Pr->ChipType == SIS_630) ||
1247 (SiS_Pr->ChipType == SIS_730)) {
1250 } else if(SiS_Pr->ChipType >= SIS_315H) {
1252 if(SiS_Pr->ChipType < XGI_20) {
1254 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1258 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1259 OutputSelect = ROMAddr[romindex];
1260 if(!(OutputSelect & EnablePALMN)) {
1261 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1264 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1265 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1266 if(temp1 & EnablePALM) { /* 0x40 */
1267 SiS_Pr->SiS_TVMode |= TVSetPALM;
1268 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1269 } else if(temp1 & EnablePALN) { /* 0x80 */
1270 SiS_Pr->SiS_TVMode |= TVSetPALN;
1273 if(temp1 & EnableNTSCJ) { /* 0x40 */
1274 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1278 /* Translate HiVision/YPbPr to our new flags */
1279 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1280 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1281 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1282 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1283 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1284 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1285 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1286 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1287 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1288 SiS_Pr->SiS_TVMode |= TVSetPAL;
1291 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1292 if(SiS_Pr->SiS_CHOverScan) {
1293 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1294 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1295 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1296 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1298 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1299 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1300 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1301 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1304 if(SiS_Pr->SiS_CHSOverScan) {
1305 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1308 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1309 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1310 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1311 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1312 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1314 if(temp & EnableNTSCJ) {
1315 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1321 } else { /* 661 and later */
1323 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1325 SiS_Pr->SiS_TVMode |= TVSetPAL;
1327 SiS_Pr->SiS_TVMode |= TVSetPALN;
1328 } else if(temp1 & 0x04) {
1329 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1330 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1332 SiS_Pr->SiS_TVMode |= TVSetPALM;
1336 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1339 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1340 if(SiS_Pr->SiS_CHOverScan) {
1341 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1342 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1346 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1347 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1349 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1350 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1351 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1352 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1353 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1355 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1356 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1357 SiS_Pr->SiS_TVMode |= TVAspect169;
1359 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1361 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1362 SiS_Pr->SiS_TVMode |= TVAspect169;
1364 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1367 SiS_Pr->SiS_TVMode |= TVAspect43;
1374 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1376 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1378 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1379 SiS_Pr->SiS_TVMode |= TVSetPAL;
1380 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1381 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1382 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1383 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1387 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1388 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1389 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1393 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1394 if(resinfo == SIS_RI_1024x768) {
1395 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1396 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1397 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1398 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1403 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1404 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1405 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1406 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1407 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1408 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1409 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1410 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1411 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1417 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1419 #ifdef SIS_XORG_XF86
1421 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1426 /*********************************************/
1428 /*********************************************/
1430 static unsigned short
1431 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1433 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1434 /* Translate my LCDResInfo to BIOS value */
1436 case Panel_1280x768_2: temp = Panel_1280x768; break;
1437 case Panel_1280x800_2: temp = Panel_1280x800; break;
1438 case Panel_1280x854: temp = Panel661_1280x854; break;
1444 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1447 unsigned char *ROMAddr;
1448 unsigned short temp;
1450 #ifdef SIS_XORG_XF86
1452 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1453 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1454 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1455 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1456 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1457 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1458 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1462 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1463 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1464 SiS_Pr->SiS_NeedRomModeData = TRUE;
1465 SiS_Pr->PanelHT = temp;
1467 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1468 SiS_Pr->SiS_NeedRomModeData = TRUE;
1469 SiS_Pr->PanelVT = temp;
1471 SiS_Pr->PanelHRS = SISGETROMW(10);
1472 SiS_Pr->PanelHRE = SISGETROMW(12);
1473 SiS_Pr->PanelVRS = SISGETROMW(14);
1474 SiS_Pr->PanelVRE = SISGETROMW(16);
1475 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1476 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1477 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1478 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1479 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1480 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1481 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1483 #ifdef SIS_XORG_XF86
1485 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1486 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1487 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1488 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1489 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1490 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1491 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1500 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1501 const unsigned char *nonscalingmodes)
1504 while(nonscalingmodes[i] != 0xff) {
1505 if(nonscalingmodes[i++] == resinfo) {
1506 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1507 (SiS_Pr->UsePanelScaler == -1)) {
1508 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1516 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1518 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1519 BOOLEAN panelcanscale = FALSE;
1521 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1522 static const unsigned char SiS300SeriesLCDRes[] =
1523 { 0, 1, 2, 3, 7, 4, 5, 8,
1524 0, 0, 10, 0, 0, 0, 0, 15 };
1527 unsigned char *myptr = NULL;
1530 SiS_Pr->SiS_LCDResInfo = 0;
1531 SiS_Pr->SiS_LCDTypeInfo = 0;
1532 SiS_Pr->SiS_LCDInfo = 0;
1533 SiS_Pr->PanelHRS = 999; /* HSync start */
1534 SiS_Pr->PanelHRE = 999; /* HSync end */
1535 SiS_Pr->PanelVRS = 999; /* VSync start */
1536 SiS_Pr->PanelVRE = 999; /* VSync end */
1537 SiS_Pr->SiS_NeedRomModeData = FALSE;
1539 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1540 SiS_Pr->Alternate1600x1200 = FALSE;
1542 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1544 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1546 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1547 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1548 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1549 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1552 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1554 /* For broken BIOSes: Assume 1024x768 */
1555 if(temp == 0) temp = 0x02;
1557 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1558 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1559 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1560 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1562 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1566 if(SiS_Pr->ChipType < SIS_315H) {
1567 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1568 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1569 if(temp < 0x0f) temp &= 0x07;
1571 /* Translate 300 series LCDRes to 315 series for unified usage */
1572 temp = SiS300SeriesLCDRes[temp];
1576 /* Translate to our internal types */
1578 if(SiS_Pr->ChipType == SIS_550) {
1579 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1580 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1581 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1582 } else if(SiS_Pr->ChipType >= SIS_661) {
1583 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1587 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1588 if(temp == Panel310_1280x768) {
1589 temp = Panel_1280x768_2;
1591 if(SiS_Pr->SiS_ROMNew) {
1592 if(temp == Panel661_1280x800) {
1593 temp = Panel_1280x800_2;
1598 SiS_Pr->SiS_LCDResInfo = temp;
1601 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1602 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1603 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1604 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1605 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1606 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1607 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1612 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1613 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1614 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1616 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1617 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1620 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1621 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1622 /* Need temp below! */
1624 /* These must/can't scale no matter what */
1625 switch(SiS_Pr->SiS_LCDResInfo) {
1626 case Panel_320x240_1:
1627 case Panel_320x240_2:
1628 case Panel_320x240_3:
1629 case Panel_1280x960:
1630 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1633 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1636 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
1638 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1639 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1641 /* Dual link, Pass 1:1 BIOS default, etc. */
1643 if(SiS_Pr->ChipType >= SIS_661) {
1644 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1645 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1647 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1648 if(SiS_Pr->SiS_ROMNew) {
1649 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1650 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1651 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1654 } else if(SiS_Pr->ChipType >= SIS_315H) {
1655 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1656 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1658 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1659 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1660 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1661 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1662 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1663 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1665 } else if(!(SiS_Pr->SiS_ROMNew)) {
1666 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1667 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1668 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1669 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1671 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1672 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1673 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1674 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1675 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1683 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1684 /* Always center screen on LVDS (if scaling is disabled) */
1685 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1686 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1687 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1688 /* Always center screen on SiS LVDS (if scaling is disabled) */
1689 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1691 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1692 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1693 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1697 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1698 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1700 switch(SiS_Pr->SiS_LCDResInfo) {
1701 case Panel_320x240_1:
1702 case Panel_320x240_2:
1703 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1704 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1705 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1706 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1708 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1709 SiS_Pr->PanelVRE = 3;
1710 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1711 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1713 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1714 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1715 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1716 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1717 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1718 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1720 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1721 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1722 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1723 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1724 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1725 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1727 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1728 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1729 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1730 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1731 if(SiS_Pr->ChipType < SIS_315H) {
1732 SiS_Pr->PanelHRS = 23;
1733 SiS_Pr->PanelVRE = 5;
1735 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1736 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1737 SiS_GetLCDInfoBIOS(SiS_Pr);
1739 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1740 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1741 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1742 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1743 if(SiS_Pr->ChipType < SIS_315H) {
1744 SiS_Pr->PanelHRS = 23;
1745 SiS_Pr->PanelVRE = 5;
1747 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1748 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1750 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1752 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1753 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1754 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1755 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1756 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1757 /* Data above for TMDS (projector); get from BIOS for LVDS */
1758 SiS_GetLCDInfoBIOS(SiS_Pr);
1760 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1761 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1762 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1763 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1764 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1766 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1767 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1768 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1769 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1770 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1773 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1774 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1775 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1776 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1777 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1778 SiS_GetLCDInfoBIOS(SiS_Pr);
1780 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1781 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1782 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1783 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1784 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1785 SiS_GetLCDInfoBIOS(SiS_Pr);
1787 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1788 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1789 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1790 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1791 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1792 SiS_GetLCDInfoBIOS(SiS_Pr);
1794 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1795 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1796 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1797 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1798 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1799 SiS_GetLCDInfoBIOS(SiS_Pr);
1801 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1802 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1803 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1804 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1805 if(resinfo == SIS_RI_1280x1024) {
1806 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1807 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1810 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1811 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1812 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1813 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1814 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1815 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1816 SiS_GetLCDInfoBIOS(SiS_Pr);
1818 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1819 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1820 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1821 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1822 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1823 SiS_GetLCDInfoBIOS(SiS_Pr);
1825 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1826 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1827 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1828 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1829 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1830 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1831 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1832 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1833 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1834 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1835 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1836 SiS_Pr->Alternate1600x1200 = TRUE;
1838 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1839 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1840 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1841 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1843 SiS_GetLCDInfoBIOS(SiS_Pr);
1845 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1846 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1847 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1848 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1849 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1850 SiS_GetLCDInfoBIOS(SiS_Pr);
1852 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1853 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1855 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1856 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1858 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1859 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1861 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1862 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1863 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1864 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1865 if(SiS_Pr->CP_PreferredIndex != -1) {
1866 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1867 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1868 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1869 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1870 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1871 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1872 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1873 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1874 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1875 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1876 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1877 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1878 if(SiS_Pr->CP_PrefClock) {
1880 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1881 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1882 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1883 else idx = VCLK_CUSTOM_315;
1884 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1885 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1886 SiS_Pr->SiS_VCLKData[idx].SR2B =
1887 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1888 SiS_Pr->SiS_VCLKData[idx].SR2C =
1889 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1893 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1894 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1899 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1900 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1901 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1902 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1903 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1904 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1905 SiS_Pr->PanelHRS = 999;
1906 SiS_Pr->PanelHRE = 999;
1909 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1910 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1911 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1912 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1913 SiS_Pr->PanelVRS = 999;
1914 SiS_Pr->PanelVRE = 999;
1917 /* DontExpand overrule */
1918 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1920 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1921 /* No scaling for this mode on any panel (LCD=CRT2)*/
1922 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1925 switch(SiS_Pr->SiS_LCDResInfo) {
1928 case Panel_1152x864:
1929 case Panel_1280x768: /* TMDS only */
1930 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1933 case Panel_800x600: {
1934 static const unsigned char nonscalingmodes[] = {
1935 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1937 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1940 case Panel_1024x768: {
1941 static const unsigned char nonscalingmodes[] = {
1942 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1943 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1946 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1949 case Panel_1280x720: {
1950 static const unsigned char nonscalingmodes[] = {
1951 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1952 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1955 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1956 if(SiS_Pr->PanelHT == 1650) {
1957 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1961 case Panel_1280x768_2: { /* LVDS only */
1962 static const unsigned char nonscalingmodes[] = {
1963 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1964 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1965 SIS_RI_1152x768,0xff
1967 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1969 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1970 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1976 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1977 static const unsigned char nonscalingmodes[] = {
1978 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1979 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1980 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1982 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1985 case Panel_1280x800_2: { /* SiS LVDS */
1986 static const unsigned char nonscalingmodes[] = {
1987 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1988 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1989 SIS_RI_1152x768,0xff
1991 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1993 case SIS_RI_1280x720:
1994 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1995 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2001 case Panel_1280x854: { /* SiS LVDS */
2002 static const unsigned char nonscalingmodes[] = {
2003 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2004 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2005 SIS_RI_1152x768,0xff
2007 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2009 case SIS_RI_1280x720:
2010 case SIS_RI_1280x768:
2011 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2012 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2018 case Panel_1280x960: {
2019 static const unsigned char nonscalingmodes[] = {
2020 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2021 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2022 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2023 SIS_RI_1280x854,0xff
2025 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2028 case Panel_1280x1024: {
2029 static const unsigned char nonscalingmodes[] = {
2030 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2031 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2032 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2033 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2035 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2038 case Panel_1400x1050: {
2039 static const unsigned char nonscalingmodes[] = {
2040 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2041 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2042 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2043 SIS_RI_1280x960,0xff
2045 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2047 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2048 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2051 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2056 case Panel_1600x1200: {
2057 static const unsigned char nonscalingmodes[] = {
2058 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2059 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2060 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2061 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2063 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2066 case Panel_1680x1050: {
2067 static const unsigned char nonscalingmodes[] = {
2068 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2069 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2070 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2071 SIS_RI_1360x1024,0xff
2073 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2080 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2081 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2082 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2086 if(SiS_Pr->ChipType < SIS_315H) {
2087 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2088 if(SiS_Pr->SiS_UseROM) {
2089 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2090 if(!(ROMAddr[0x235] & 0x02)) {
2091 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2095 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2096 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2097 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2105 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2106 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2109 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2110 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2113 switch(SiS_Pr->SiS_LCDResInfo) {
2115 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2117 case Panel_1280x800:
2118 /* Don't pass 1:1 by default (TMDS special) */
2119 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2121 case Panel_1280x960:
2122 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2125 if((!SiS_Pr->CP_PrefClock) ||
2126 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2127 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2132 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2133 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2136 /* (In)validate LCDPass11 flag */
2137 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2138 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2142 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2144 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2145 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2146 if(ModeNo == 0x12) {
2147 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2148 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2150 } else if(ModeNo > 0x13) {
2151 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2152 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2153 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2154 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2162 if(modeflag & HalfDCLK) {
2163 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2164 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2165 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2166 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2167 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2168 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2169 } else if(ModeNo > 0x13) {
2170 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2171 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2172 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2173 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2181 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2182 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2183 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2186 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2189 #ifdef SIS_LINUX_KERNEL
2191 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2192 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2195 #ifdef SIS_XORG_XF86
2196 xf86DrvMsgVerb(0, X_PROBED, 4,
2197 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2198 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2202 /*********************************************/
2204 /*********************************************/
2207 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2208 unsigned short RefreshRateTableIndex)
2210 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2211 unsigned short modeflag, resinfo, tempbx;
2212 const unsigned char *CHTVVCLKPtr = NULL;
2214 if(ModeNo <= 0x13) {
2215 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2216 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2217 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2218 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2219 VCLKIndexGENCRT = VCLKIndexGEN;
2221 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2222 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2223 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2224 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2225 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2226 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2229 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2231 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2234 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2236 if(SiS_Pr->ChipType < SIS_315H) {
2237 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2238 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2239 VCLKIndex = VCLKIndexGEN;
2242 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2243 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2245 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2246 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2247 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2248 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2249 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2250 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2251 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2252 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2253 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2254 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2255 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2256 default: VCLKIndex = VCLKIndexGEN;
2259 if(ModeNo <= 0x13) {
2260 if(SiS_Pr->ChipType <= SIS_315PRO) {
2261 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2263 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2266 if(SiS_Pr->ChipType <= SIS_315PRO) {
2267 if(VCLKIndex == 0) VCLKIndex = 0x41;
2268 if(VCLKIndex == 1) VCLKIndex = 0x43;
2269 if(VCLKIndex == 4) VCLKIndex = 0x44;
2274 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2276 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2277 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2278 else VCLKIndex = HiTVVCLK;
2279 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2280 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2281 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2282 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2283 else VCLKIndex = TVVCLK;
2285 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2286 else VCLKIndex += TVCLKBASE_315;
2290 VCLKIndex = VCLKIndexGENCRT;
2291 if(SiS_Pr->ChipType < SIS_315H) {
2293 if( (SiS_Pr->ChipType == SIS_630) &&
2294 (SiS_Pr->ChipRevision >= 0x30)) {
2295 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2297 /* Better VGA2 clock for 1280x1024@75 */
2298 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2303 } else { /* If not programming CRT2 */
2305 VCLKIndex = VCLKIndexGENCRT;
2306 if(SiS_Pr->ChipType < SIS_315H) {
2308 if( (SiS_Pr->ChipType != SIS_630) &&
2309 (SiS_Pr->ChipType != SIS_300) ) {
2310 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2318 VCLKIndex = CRT2Index;
2320 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2322 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2326 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2327 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2329 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2330 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2332 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2334 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2335 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2337 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2341 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2342 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2343 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2344 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2345 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2346 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2347 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2348 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2349 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2350 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2352 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2354 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2356 if(SiS_Pr->ChipType < SIS_315H) {
2357 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2359 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2363 /* Special Timing: Barco iQ Pro R series */
2364 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2366 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2367 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2368 if(SiS_Pr->ChipType < SIS_315H) {
2369 VCLKIndex = VCLK34_300;
2370 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2372 VCLKIndex = VCLK34_315;
2373 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2380 VCLKIndex = VCLKIndexGENCRT;
2381 if(SiS_Pr->ChipType < SIS_315H) {
2383 if( (SiS_Pr->ChipType == SIS_630) &&
2384 (SiS_Pr->ChipRevision >= 0x30) ) {
2385 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2391 } else { /* if not programming CRT2 */
2393 VCLKIndex = VCLKIndexGENCRT;
2394 if(SiS_Pr->ChipType < SIS_315H) {
2396 if( (SiS_Pr->ChipType != SIS_630) &&
2397 (SiS_Pr->ChipType != SIS_300) ) {
2398 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2401 if(SiS_Pr->ChipType == SIS_730) {
2402 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2403 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2413 #ifdef SIS_XORG_XF86
2415 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2422 /*********************************************/
2423 /* SET CRT2 MODE TYPE REGISTERS */
2424 /*********************************************/
2427 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2429 unsigned short i, j, modeflag, tempah=0;
2431 #if defined(SIS300) || defined(SIS315H)
2432 unsigned short tempbl;
2435 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2436 unsigned short tempah2, tempbl2;
2439 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2441 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2443 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2444 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2448 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2449 if(SiS_Pr->ChipType >= SIS_315H) {
2450 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2453 tempcl = SiS_Pr->SiS_ModeType;
2455 if(SiS_Pr->ChipType < SIS_315H) {
2457 #ifdef SIS300 /* ---- 300 series ---- */
2459 /* For 301BDH: (with LCD via LVDS) */
2460 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2461 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2464 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2468 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2474 tempah = ((0x10 >> tempcl) | 0x80);
2476 } else tempah = 0x80;
2478 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2484 #ifdef SIS315H /* ------- 315/330 series ------ */
2489 tempah = (0x08 >> tempcl);
2490 if (tempah == 0) tempah = 1;
2493 } else tempah = 0x40;
2495 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2497 #endif /* SIS315H */
2501 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2503 if(SiS_Pr->ChipType < SIS_315H) {
2504 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2507 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2508 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2509 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2511 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2513 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2519 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2522 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2525 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2527 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2532 if(SiS_Pr->ChipType < SIS_315H) {
2534 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2536 tempah = (tempah << 5) & 0xFF;
2537 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2538 tempah = (tempah >> 5) & 0xFF;
2542 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2543 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2544 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2549 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2554 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2555 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2558 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2559 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2560 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2566 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2569 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2570 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2573 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2575 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2576 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2581 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2585 if(SiS_Pr->ChipType >= SIS_315H) {
2588 /* LVDS can only be slave in 8bpp modes */
2590 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2591 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2596 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2598 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2600 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2602 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2609 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2614 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2616 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2625 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2627 if(SiS_Pr->ChipType >= SIS_315H) {
2630 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2632 /* The following is nearly unpreditable and varies from machine
2633 * to machine. Especially the 301DH seems to be a real trouble
2634 * maker. Some BIOSes simply set the registers (like in the
2635 * NoLCD-if-statements here), some set them according to the
2636 * LCDA stuff. It is very likely that some machines are not
2637 * treated correctly in the following, very case-orientated
2638 * code. What do I do then...?
2641 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2644 tempah = 0x04; /* For all bridges */
2646 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2648 if(SiS_IsDualEdge(SiS_Pr)) {
2652 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2655 /* The following two are responsible for eventually wrong colors
2656 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2657 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2658 * in a 650 box (Jake). What is the criteria?
2659 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2660 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2661 * chipset than the bridge revision.
2664 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2667 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2668 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2672 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2673 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2674 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2675 /* Fixes "TV-blue-bug" on 315+301 */
2676 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2677 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2678 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2679 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2680 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2681 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2682 tempah = 0x30; tempah2 = 0xc0;
2683 tempbl = 0xcf; tempbl2 = 0x3f;
2684 if(SiS_Pr->SiS_TVBlue == 0) {
2685 tempah = tempah2 = 0x00;
2686 } else if(SiS_Pr->SiS_TVBlue == -1) {
2687 /* Set on 651/M650, clear on 315/650 */
2688 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2689 tempah = tempah2 = 0x00;
2692 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2693 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2695 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2696 tempbl = 0xcf; tempbl2 = 0x3f;
2697 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2698 tempah = tempah2 = 0x00;
2699 if(SiS_IsDualEdge(SiS_Pr)) {
2700 tempbl = tempbl2 = 0xff;
2703 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2704 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2709 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2710 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2714 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2716 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2718 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2721 #endif /* SIS315H */
2723 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2726 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2728 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2729 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2730 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2731 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2733 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2739 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2740 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2741 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2742 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2749 if(SiS_Pr->ChipType >= SIS_315H) {
2751 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2755 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2757 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2759 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2761 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2762 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2765 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2767 } else if(SiS_Pr->ChipType == SIS_550) {
2769 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2770 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2781 /*********************************************/
2782 /* GET RESOLUTION DATA */
2783 /*********************************************/
2786 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2789 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2791 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2795 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2797 unsigned short xres, yres, modeflag=0, resindex;
2799 if(SiS_Pr->UseCustomMode) {
2800 xres = SiS_Pr->CHDisplay;
2801 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2802 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2803 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2804 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2808 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2810 if(ModeNo <= 0x13) {
2811 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2812 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2814 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2815 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2816 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2819 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2821 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2822 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2823 if(yres == 350) yres = 400;
2825 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2826 if(ModeNo == 0x12) yres = 400;
2830 if(modeflag & HalfDCLK) xres <<= 1;
2831 if(modeflag & DoubleScanMode) yres <<= 1;
2835 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2837 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2838 switch(SiS_Pr->SiS_LCDResInfo) {
2839 case Panel_1024x768:
2840 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2841 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2842 if(yres == 350) yres = 357;
2843 if(yres == 400) yres = 420;
2844 if(yres == 480) yres = 525;
2848 case Panel_1280x1024:
2849 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2850 /* BIOS bug - does this regardless of scaling */
2851 if(yres == 400) yres = 405;
2853 if(yres == 350) yres = 360;
2854 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2855 if(yres == 360) yres = 375;
2858 case Panel_1600x1200:
2859 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2860 if(yres == 1024) yres = 1056;
2868 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2869 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2870 if(xres == 720) xres = 640;
2872 } else if(xres == 720) xres = 640;
2874 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2876 if(SiS_Pr->ChipType >= SIS_315H) {
2877 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2879 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2881 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2885 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2886 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2889 /*********************************************/
2890 /* GET CRT2 TIMING DATA */
2891 /*********************************************/
2894 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2895 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2896 unsigned short *ResIndex)
2898 unsigned short tempbx=0, tempal=0, resinfo=0;
2900 if(ModeNo <= 0x13) {
2901 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2903 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2904 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2907 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2909 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2911 tempbx = SiS_Pr->SiS_LCDResInfo;
2912 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2915 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2916 if (resinfo == SIS_RI_1280x800) tempal = 9;
2917 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2918 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2919 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2920 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2921 if (resinfo == SIS_RI_1280x768) tempal = 9;
2924 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2925 /* Pass 1:1 only (center-screen handled outside) */
2926 /* This is never called for the panel's native resolution */
2927 /* since Pass1:1 will not be set in this case */
2929 if(ModeNo >= 0x13) {
2930 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2935 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2936 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2937 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2939 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2947 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2948 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2950 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2952 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2954 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2955 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2956 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2958 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2960 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2962 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2970 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2972 case SIS_RI_720x480:
2974 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
2976 case SIS_RI_720x576:
2977 case SIS_RI_768x576:
2978 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2980 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2981 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
2984 case SIS_RI_800x480:
2987 case SIS_RI_512x384:
2988 case SIS_RI_1024x768:
2990 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2991 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
2994 case SIS_RI_1280x720:
2995 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2996 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
3003 *CRT2Index = tempbx;
3006 } else { /* LVDS, 301B-DH (if running on LCD) */
3009 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3012 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3014 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3015 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3017 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3018 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3021 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3026 switch(SiS_Pr->SiS_LCDResInfo) {
3027 case Panel_640x480: tempbx = 12; break;
3028 case Panel_320x240_1: tempbx = 10; break;
3029 case Panel_320x240_2:
3030 case Panel_320x240_3: tempbx = 14; break;
3031 case Panel_800x600: tempbx = 16; break;
3032 case Panel_1024x600: tempbx = 18; break;
3033 case Panel_1152x768:
3034 case Panel_1024x768: tempbx = 20; break;
3035 case Panel_1280x768: tempbx = 22; break;
3036 case Panel_1280x1024: tempbx = 24; break;
3037 case Panel_1400x1050: tempbx = 26; break;
3038 case Panel_1600x1200: tempbx = 28; break;
3040 case Panel_Barco1366: tempbx = 80; break;
3044 switch(SiS_Pr->SiS_LCDResInfo) {
3045 case Panel_320x240_1:
3046 case Panel_320x240_2:
3047 case Panel_320x240_3:
3051 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3054 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3057 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3059 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3060 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3062 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3068 (*CRT2Index) = tempbx;
3069 (*ResIndex) = tempal & 0x1F;
3074 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3075 unsigned short RefreshRateTableIndex)
3077 unsigned short tempax=0, tempbx=0, index, dotclock;
3078 unsigned short temp1=0, modeflag=0, tempcx=0;
3080 SiS_Pr->SiS_RVBHCMAX = 1;
3081 SiS_Pr->SiS_RVBHCFACT = 1;
3083 if(ModeNo <= 0x13) {
3085 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3086 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3088 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3089 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3090 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3092 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3096 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3097 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3099 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3100 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3102 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3103 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3107 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3113 if(temp1 & 0x01) tempbx |= 0x0100;
3114 if(temp1 & 0x20) tempbx |= 0x0200;
3118 if(modeflag & HalfDCLK) tempax <<= 1;
3122 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3123 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3127 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3128 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3130 unsigned short ResIndex;
3132 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3133 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3134 if(SiS_Pr->UseCustomMode) {
3135 ResIndex = SiS_Pr->CHTotal;
3136 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3137 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3138 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3141 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3143 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3145 if(ResIndex == 0x09) {
3146 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3147 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3149 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3150 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3151 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3152 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3155 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3156 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3159 /* This handles custom modes and custom panels */
3160 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3161 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3162 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3163 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3164 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3165 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3170 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3171 unsigned short RefreshRateTableIndex)
3173 unsigned short CRT2Index, ResIndex, backup;
3174 const struct SiS_LVDSData *LVDSData = NULL;
3176 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3178 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3179 SiS_Pr->SiS_RVBHCMAX = 1;
3180 SiS_Pr->SiS_RVBHCFACT = 1;
3181 SiS_Pr->SiS_NewFlickerMode = 0;
3182 SiS_Pr->SiS_RVBHRS = 50;
3183 SiS_Pr->SiS_RY1COE = 0;
3184 SiS_Pr->SiS_RY2COE = 0;
3185 SiS_Pr->SiS_RY3COE = 0;
3186 SiS_Pr->SiS_RY4COE = 0;
3187 SiS_Pr->SiS_RVBHRS2 = 0;
3190 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3193 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3194 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3199 /* 301BDH needs LVDS Data */
3200 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3201 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3202 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3205 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3206 &CRT2Index, &ResIndex);
3208 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3211 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3212 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3213 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3214 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3215 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3216 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3218 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3219 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3220 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3221 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3222 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3224 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3225 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3226 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3227 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3228 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3229 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3230 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3231 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3232 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3236 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3237 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3238 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3239 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3241 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3244 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3245 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3246 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3247 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3248 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3249 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3250 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3252 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3253 if(ResIndex < 0x08) {
3254 SiS_Pr->SiS_HDE = 1280;
3255 SiS_Pr->SiS_VDE = 1024;
3265 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3266 unsigned short RefreshRateTableIndex)
3268 unsigned char *ROMAddr = NULL;
3269 unsigned short tempax, tempbx, modeflag, romptr=0;
3270 unsigned short resinfo, CRT2Index, ResIndex;
3271 const struct SiS_LCDData *LCDPtr = NULL;
3272 const struct SiS_TVData *TVPtr = NULL;
3277 if(ModeNo <= 0x13) {
3278 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3279 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3280 } else if(SiS_Pr->UseCustomMode) {
3281 modeflag = SiS_Pr->CModeFlag;
3284 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3285 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3287 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3288 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3289 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3290 (resinfo661 >= 0) &&
3291 (SiS_Pr->SiS_NeedRomModeData) ) {
3292 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3293 if((romptr = (SISGETROMW(21)))) {
3294 romptr += (resinfo661 * 10);
3295 ROMAddr = SiS_Pr->VirtualRomBase;
3302 SiS_Pr->SiS_NewFlickerMode = 0;
3303 SiS_Pr->SiS_RVBHRS = 50;
3304 SiS_Pr->SiS_RY1COE = 0;
3305 SiS_Pr->SiS_RY2COE = 0;
3306 SiS_Pr->SiS_RY3COE = 0;
3307 SiS_Pr->SiS_RY4COE = 0;
3308 SiS_Pr->SiS_RVBHRS2 = 0;
3310 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3312 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3314 if(SiS_Pr->UseCustomMode) {
3316 SiS_Pr->SiS_RVBHCMAX = 1;
3317 SiS_Pr->SiS_RVBHCFACT = 1;
3318 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3319 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3321 tempax = SiS_Pr->CHTotal;
3322 if(modeflag & HalfDCLK) tempax <<= 1;
3323 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3324 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3328 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3332 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3334 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3335 &CRT2Index,&ResIndex);
3338 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3339 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3340 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3341 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3342 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3343 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3344 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3345 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3346 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3347 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3348 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3349 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3350 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3351 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3354 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3355 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3356 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3357 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3358 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3359 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3360 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3361 if(modeflag & HalfDCLK) {
3362 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3363 if(SiS_Pr->SiS_RVBHRS2) {
3364 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3365 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3366 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3367 else SiS_Pr->SiS_RVBHRS2 += tempax;
3370 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3372 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3374 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3376 if((resinfo == SIS_RI_960x600) ||
3377 (resinfo == SIS_RI_1024x768) ||
3378 (resinfo == SIS_RI_1280x1024) ||
3379 (resinfo == SIS_RI_1280x720)) {
3380 SiS_Pr->SiS_NewFlickerMode = 0x40;
3383 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3385 SiS_Pr->SiS_HT = ExtHiTVHT;
3386 SiS_Pr->SiS_VT = ExtHiTVVT;
3387 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3388 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3389 SiS_Pr->SiS_HT = StHiTVHT;
3390 SiS_Pr->SiS_VT = StHiTVVT;
3394 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3396 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3397 SiS_Pr->SiS_HT = 1650;
3398 SiS_Pr->SiS_VT = 750;
3399 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3400 SiS_Pr->SiS_HT = NTSCHT;
3401 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3402 SiS_Pr->SiS_VT = NTSCVT;
3404 SiS_Pr->SiS_HT = NTSCHT;
3405 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3406 SiS_Pr->SiS_VT = NTSCVT;
3411 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3412 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3413 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3414 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3416 if(modeflag & HalfDCLK) {
3417 SiS_Pr->SiS_RY1COE = 0x00;
3418 SiS_Pr->SiS_RY2COE = 0xf4;
3419 SiS_Pr->SiS_RY3COE = 0x10;
3420 SiS_Pr->SiS_RY4COE = 0x38;
3423 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3424 SiS_Pr->SiS_HT = NTSCHT;
3425 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3426 SiS_Pr->SiS_VT = NTSCVT;
3428 SiS_Pr->SiS_HT = PALHT;
3429 SiS_Pr->SiS_VT = PALVT;
3434 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3436 SiS_Pr->SiS_RVBHCMAX = 1;
3437 SiS_Pr->SiS_RVBHCFACT = 1;
3439 if(SiS_Pr->UseCustomMode) {
3441 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3442 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3444 tempax = SiS_Pr->CHTotal;
3445 if(modeflag & HalfDCLK) tempax <<= 1;
3446 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3447 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3451 BOOLEAN gotit = FALSE;
3453 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3455 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3456 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3457 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3458 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3461 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3464 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3465 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3466 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3467 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3468 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3469 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3470 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3471 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3472 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3473 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3474 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3475 else SiS_Pr->SiS_RVBHRS2 += tempax;
3477 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3479 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3480 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3481 SiS_Pr->SiS_RVBHCMAX = 1;
3482 SiS_Pr->SiS_RVBHCFACT = 1;
3483 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3484 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3485 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3486 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3487 SiS_Pr->SiS_RVBHRS2 = 0;
3496 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3497 &CRT2Index,&ResIndex);
3500 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3501 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3502 case Panel_1280x720 :
3503 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3504 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3505 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3506 case Panel_1280x800 :
3507 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3508 case Panel_1280x800_2 :
3509 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3510 case Panel_1280x854 :
3511 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3512 case Panel_1280x960 :
3513 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3514 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3515 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3516 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3517 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3518 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3519 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3520 case Panel_1680x1050 :
3521 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3522 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3524 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3525 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3527 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3530 #ifdef SIS_XORG_XF86
3532 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3536 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3537 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3538 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3539 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3540 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3541 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3545 tempax = SiS_Pr->PanelXRes;
3546 tempbx = SiS_Pr->PanelYRes;
3548 switch(SiS_Pr->SiS_LCDResInfo) {
3549 case Panel_1024x768:
3550 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3551 if(SiS_Pr->ChipType < SIS_315H) {
3552 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3553 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3556 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3557 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3558 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3559 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3560 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3561 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3564 case Panel_1280x960:
3565 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3566 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3567 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3569 case Panel_1280x1024:
3570 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3571 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3572 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3574 case Panel_1600x1200:
3575 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3576 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3577 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3582 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3583 tempax = SiS_Pr->SiS_VGAHDE;
3584 tempbx = SiS_Pr->SiS_VGAVDE;
3587 SiS_Pr->SiS_HDE = tempax;
3588 SiS_Pr->SiS_VDE = tempbx;
3594 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3595 unsigned short RefreshRateTableIndex)
3598 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3600 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3601 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3603 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3604 /* Need LVDS Data for LCD on 301B-DH */
3605 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3607 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3613 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3618 /*********************************************/
3619 /* GET LVDS DES (SKEW) DATA */
3620 /*********************************************/
3622 static const struct SiS_LVDSDes *
3623 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3625 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3628 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3630 if(SiS_Pr->ChipType < SIS_315H) {
3631 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3632 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3633 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3634 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3635 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3637 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3638 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3639 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3640 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3651 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3652 unsigned short RefreshRateTableIndex)
3654 unsigned short modeflag, ResIndex;
3655 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3657 SiS_Pr->SiS_LCDHDES = 0;
3658 SiS_Pr->SiS_LCDVDES = 0;
3660 /* Some special cases */
3661 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3664 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3665 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3666 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3667 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3673 /* 640x480 on LVDS */
3674 if(SiS_Pr->ChipType < SIS_315H) {
3675 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3676 SiS_Pr->SiS_LCDHDES = 8;
3677 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3678 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3679 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3686 if( (SiS_Pr->UseCustomMode) ||
3687 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3688 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3689 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3690 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3694 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3695 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3697 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3700 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3701 /* non-pass 1:1 only, see above */
3702 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3703 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3705 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3706 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3709 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3710 switch(SiS_Pr->SiS_CustomT) {
3711 case CUT_UNIWILL1024:
3712 case CUT_UNIWILL10242:
3714 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3715 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3719 switch(SiS_Pr->SiS_LCDResInfo) {
3720 case Panel_1280x1024:
3721 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3722 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3725 case Panel_1280x800: /* Verified for Averatec 6240 */
3726 case Panel_1280x800_2: /* Verified for Asus A4L */
3727 case Panel_1280x854: /* Not verified yet FIXME */
3728 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3736 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3738 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3739 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3742 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3744 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3745 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3747 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3749 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3750 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3752 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3753 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3755 if(SiS_Pr->ChipType < SIS_315H) {
3756 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3758 switch(SiS_Pr->SiS_LCDResInfo) {
3760 case Panel_1024x768:
3761 case Panel_1280x1024:
3762 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3764 case Panel_1400x1050:
3765 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3773 if(SiS_Pr->ChipType < SIS_315H) {
3775 switch(SiS_Pr->SiS_LCDResInfo) {
3777 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3778 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3780 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3781 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3782 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3783 else SiS_Pr->SiS_LCDVDES -= 4;
3786 case Panel_1024x768:
3787 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3788 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3790 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3791 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3792 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3795 case Panel_1024x600:
3797 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3798 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3799 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3801 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3806 switch(SiS_Pr->SiS_LCDTypeInfo) {
3808 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3810 case 3: /* 640x480 only? */
3811 SiS_Pr->SiS_LCDHDES = 8;
3812 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3813 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3814 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3820 switch(SiS_Pr->SiS_LCDResInfo) {
3821 case Panel_1024x768:
3822 case Panel_1280x1024:
3823 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3824 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3827 case Panel_320x240_1:
3828 case Panel_320x240_2:
3829 case Panel_320x240_3:
3830 SiS_Pr->SiS_LCDVDES = 524;
3837 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3838 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3839 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3840 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3841 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3842 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3843 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3844 if(SiS_Pr->ChipType < SIS_315H) {
3845 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3848 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3849 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3850 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3851 if(!(modeflag & HalfDCLK)) {
3852 SiS_Pr->SiS_LCDHDES = 320;
3853 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3854 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3865 /*********************************************/
3866 /* DISABLE VIDEO BRIDGE */
3867 /*********************************************/
3871 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3875 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3876 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3877 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3878 unsigned short temp;
3880 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3882 (SiS_Pr->SiS_PWDOffset) ) {
3883 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3884 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3885 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3886 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3887 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3889 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3893 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3894 #ifdef SIS_XORG_XF86
3896 xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
3905 /* NEVER use any variables (VBInfo), this will be called
3906 * from outside the context of modeswitch!
3907 * MUST call getVBType before calling this
3910 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3913 unsigned short tempah, pushax=0, modenum;
3915 unsigned short temp=0;
3917 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3919 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3921 if(SiS_Pr->ChipType < SIS_315H) {
3923 #ifdef SIS300 /* 300 series */
3925 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3926 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3927 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3929 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3931 SiS_PanelDelay(SiS_Pr, 3);
3933 if(SiS_Is301B(SiS_Pr)) {
3934 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3935 SiS_ShortDelay(SiS_Pr,1);
3937 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3938 SiS_DisplayOff(SiS_Pr);
3939 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3940 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3941 SiS_UnLockCRT2(SiS_Pr);
3942 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3943 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3944 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3946 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3947 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3948 SiS_PanelDelay(SiS_Pr, 2);
3949 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3950 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3952 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3960 #ifdef SIS315H /* 315 series */
3963 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3964 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3966 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3968 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3971 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3972 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3973 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3978 didpwd = SiS_HandlePWD(SiS_Pr);
3980 if( (modenum <= 0x13) ||
3981 (SiS_IsVAMode(SiS_Pr)) ||
3982 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3984 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3985 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3987 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3992 SiS_DDC2Delay(SiS_Pr,0xff00);
3993 SiS_DDC2Delay(SiS_Pr,0xe000);
3994 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3995 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3997 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3999 SiS_PanelDelay(SiS_Pr, 3);
4004 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4005 /* if(SiS_Pr->ChipType < SIS_340) {*/
4007 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4008 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4012 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4013 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4017 if(SiS_IsDualEdge(SiS_Pr)) {
4019 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4021 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4023 if((SiS_IsVAMode(SiS_Pr)) ||
4024 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4026 SiS_DisplayOff(SiS_Pr);
4027 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4028 SiS_PanelDelay(SiS_Pr, 2);
4030 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4031 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4035 if((!(SiS_IsVAMode(SiS_Pr))) ||
4036 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4038 if(!(SiS_IsDualEdge(SiS_Pr))) {
4039 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4040 SiS_DisplayOff(SiS_Pr);
4042 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4044 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4045 SiS_PanelDelay(SiS_Pr, 2);
4048 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4049 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4050 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4051 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4052 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4056 if(SiS_IsNotM650orLater(SiS_Pr)) {
4057 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4060 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4062 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4063 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4064 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4066 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4068 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4070 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4074 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4075 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4076 if(SiS_IsVAorLCD(SiS_Pr)) {
4077 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4084 #endif /* SIS315H */
4088 } else { /* ============ For 301 ================ */
4090 if(SiS_Pr->ChipType < SIS_315H) {
4092 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4093 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4094 SiS_PanelDelay(SiS_Pr, 3);
4099 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4100 SiS_DisplayOff(SiS_Pr);
4102 if(SiS_Pr->ChipType >= SIS_315H) {
4103 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4106 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4108 if(SiS_Pr->ChipType >= SIS_315H) {
4109 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4110 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4111 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4112 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4115 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4116 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4117 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4118 SiS_PanelDelay(SiS_Pr, 2);
4119 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4126 } else { /* ============ For LVDS =============*/
4128 if(SiS_Pr->ChipType < SIS_315H) {
4130 #ifdef SIS300 /* 300 series */
4132 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4133 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4136 if(SiS_Pr->ChipType == SIS_730) {
4137 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4138 SiS_WaitVBRetrace(SiS_Pr);
4140 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4141 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4142 SiS_PanelDelay(SiS_Pr, 3);
4145 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4146 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4147 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4148 SiS_WaitVBRetrace(SiS_Pr);
4149 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4150 SiS_DisplayOff(SiS_Pr);
4152 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4153 SiS_PanelDelay(SiS_Pr, 3);
4159 SiS_DisplayOff(SiS_Pr);
4161 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4163 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4164 SiS_UnLockCRT2(SiS_Pr);
4165 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4166 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4168 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4169 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4170 SiS_PanelDelay(SiS_Pr, 2);
4171 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4178 #ifdef SIS315H /* 315 series */
4180 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4181 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4182 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4186 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4188 if(SiS_Pr->ChipType == SIS_740) {
4189 temp = SiS_GetCH701x(SiS_Pr,0x61);
4191 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4192 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4195 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4196 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4197 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4201 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4202 (SiS_IsVAMode(SiS_Pr)) ) {
4203 SiS_Chrontel701xBLOff(SiS_Pr);
4204 SiS_Chrontel701xOff(SiS_Pr);
4207 if(SiS_Pr->ChipType != SIS_740) {
4208 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4209 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4210 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4216 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4217 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4218 SiS_PanelDelay(SiS_Pr, 3);
4221 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4222 (!(SiS_IsDualEdge(SiS_Pr))) ||
4223 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4224 SiS_DisplayOff(SiS_Pr);
4227 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4228 (!(SiS_IsDualEdge(SiS_Pr))) ||
4229 (!(SiS_IsVAMode(SiS_Pr))) ) {
4230 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4233 if(SiS_Pr->ChipType == SIS_740) {
4234 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4237 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4239 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4240 (!(SiS_IsDualEdge(SiS_Pr))) ||
4241 (!(SiS_IsVAMode(SiS_Pr))) ) {
4242 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4245 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4246 if(SiS_CRT2IsLCD(SiS_Pr)) {
4247 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4248 if(SiS_Pr->ChipType == SIS_550) {
4249 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4250 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4254 if(SiS_Pr->ChipType == SIS_740) {
4255 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4256 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4258 } else if(SiS_IsVAMode(SiS_Pr)) {
4259 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4263 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4264 if(SiS_IsDualEdge(SiS_Pr)) {
4265 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4267 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4271 SiS_UnLockCRT2(SiS_Pr);
4273 if(SiS_Pr->ChipType == SIS_550) {
4274 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4275 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4276 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4277 (!(SiS_IsDualEdge(SiS_Pr))) ||
4278 (!(SiS_IsVAMode(SiS_Pr))) ) {
4279 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4282 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4283 if(SiS_CRT2IsLCD(SiS_Pr)) {
4284 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4285 SiS_PanelDelay(SiS_Pr, 2);
4286 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4291 #endif /* SIS315H */
4299 /*********************************************/
4300 /* ENABLE VIDEO BRIDGE */
4301 /*********************************************/
4303 /* NEVER use any variables (VBInfo), this will be called
4304 * from outside the context of a mode switch!
4305 * MUST call getVBType before calling this
4307 #ifdef SIS_LINUX_KERNEL
4311 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4313 unsigned short temp=0, tempah;
4315 unsigned short temp1, pushax=0;
4316 BOOLEAN delaylong = FALSE;
4319 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4321 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4323 if(SiS_Pr->ChipType < SIS_315H) {
4325 #ifdef SIS300 /* 300 series */
4327 if(SiS_CRT2IsLCD(SiS_Pr)) {
4328 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4329 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4330 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4331 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4333 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4334 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4335 SiS_PanelDelay(SiS_Pr, 0);
4340 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4341 (SiS_CRT2IsLCD(SiS_Pr))) {
4343 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4344 SiS_DisplayOn(SiS_Pr);
4345 SiS_UnLockCRT2(SiS_Pr);
4346 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4347 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4348 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4350 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4352 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4353 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4354 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4355 SiS_PanelDelay(SiS_Pr, 1);
4357 SiS_WaitVBRetrace(SiS_Pr);
4358 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4364 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4365 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4366 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4367 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4369 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4370 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4371 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4372 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4373 SiS_DisplayOn(SiS_Pr);
4374 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4375 if(SiS_CRT2IsLCD(SiS_Pr)) {
4376 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4377 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4378 SiS_PanelDelay(SiS_Pr, 1);
4380 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4392 #ifdef SIS315H /* 315 series */
4395 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4397 /* unsigned short emidelay=0; */
4400 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4401 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4403 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4404 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4409 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4410 /*if(SiS_Pr->ChipType < SIS_340) { */
4412 if(SiS_LCDAEnabled(SiS_Pr)) {
4413 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4416 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4420 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4422 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4423 SiS_DisplayOff(SiS_Pr);
4424 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4426 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4429 didpwd = SiS_HandlePWD(SiS_Pr);
4431 if(SiS_IsVAorLCD(SiS_Pr)) {
4433 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4434 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4435 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4436 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4437 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4438 SiS_GenericDelay(SiS_Pr, 17664);
4442 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4443 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4444 SiS_GenericDelay(SiS_Pr, 17664);
4449 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4450 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4456 if(!(SiS_IsVAMode(SiS_Pr))) {
4458 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4459 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4460 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4461 if(!(tempah & SetCRT2ToRAMDAC)) {
4462 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4465 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4467 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4469 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4470 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4472 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4473 SiS_PanelDelay(SiS_Pr, 2);
4478 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4482 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4483 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4485 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4486 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4487 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4488 /* Enable "LVDS PLL power on" (even on 301C) */
4489 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4490 /* Enable "LVDS Driver Power on" (even on 301C) */
4491 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4496 if(SiS_IsDualEdge(SiS_Pr)) {
4498 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4500 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4502 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4504 SiS_PanelDelay(SiS_Pr, 2);
4506 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4507 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4509 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4511 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4512 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4513 SiS_GenericDelay(SiS_Pr, 2048);
4516 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4518 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4520 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4522 if(SiS_Pr->SiS_ROMNew) {
4523 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4524 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4526 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4528 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4529 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4530 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4531 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4532 /* emidelay = SISGETROMW((romptr + 0x22)); */
4533 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4538 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4539 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4540 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4541 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4542 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4543 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4544 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4545 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4546 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4548 if(SiS_Pr->HaveEMI) {
4549 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4550 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4555 /* EMI_30 is read at driver start; however, the BIOS sets this
4556 * (if it is used) only if the LCD is in use. In case we caught
4557 * the machine while on TV output, this bit is not set and we
4558 * don't know if it should be set - hence our detection is wrong.
4559 * Work-around this here:
4562 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4563 switch((cr36 & 0x0f)) {
4566 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4567 if(!SiS_Pr->HaveEMI) {
4568 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4569 if((cr36 & 0xf0) == 0x30) {
4570 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4574 case 3: /* 1280x1024 */
4575 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4576 if(!SiS_Pr->HaveEMI) {
4577 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4578 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4579 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4583 case 9: /* 1400x1050 */
4585 if(!SiS_Pr->HaveEMI) {
4586 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4587 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4588 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4592 case 11: /* 1600x1200 - unknown */
4594 if(!SiS_Pr->HaveEMI) {
4595 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4600 /* BIOS values don't work so well sometimes */
4601 if(!SiS_Pr->OverruleEMI) {
4603 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4604 if((cr36 & 0x0f) == 0x09) {
4605 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4610 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4611 if((cr36 & 0x0f) == 0x03) {
4612 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4617 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4618 if((cr36 & 0x0f) == 0x02) {
4619 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4620 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4621 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4622 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4628 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4629 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4630 SiS_GenericDelay(SiS_Pr, 2048);
4632 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4633 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4634 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4635 #endif /* SET_EMI */
4637 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4640 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4641 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4643 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4644 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4646 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4649 SiS_WaitVBRetrace(SiS_Pr);
4650 SiS_WaitVBRetrace(SiS_Pr);
4651 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4652 SiS_GenericDelay(SiS_Pr, 1280);
4654 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4655 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4662 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4663 if(SiS_IsVAorLCD(SiS_Pr)) {
4664 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4666 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4668 SiS_WaitVBRetrace(SiS_Pr);
4669 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4670 SiS_GenericDelay(SiS_Pr, 2048);
4671 SiS_WaitVBRetrace(SiS_Pr);
4674 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4676 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4681 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4682 SiS_DisplayOn(SiS_Pr);
4683 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4687 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4688 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4691 #endif /* SIS315H */
4695 } else { /* ============ For 301 ================ */
4697 if(SiS_Pr->ChipType < SIS_315H) {
4698 if(SiS_CRT2IsLCD(SiS_Pr)) {
4699 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4700 SiS_PanelDelay(SiS_Pr, 0);
4704 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4705 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4706 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4707 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4709 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4711 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4713 if(SiS_Pr->ChipType >= SIS_315H) {
4714 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4715 if(!(temp & 0x80)) {
4716 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4720 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4722 SiS_VBLongWait(SiS_Pr);
4723 SiS_DisplayOn(SiS_Pr);
4724 if(SiS_Pr->ChipType >= SIS_315H) {
4725 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4727 SiS_VBLongWait(SiS_Pr);
4729 if(SiS_Pr->ChipType < SIS_315H) {
4730 if(SiS_CRT2IsLCD(SiS_Pr)) {
4731 SiS_PanelDelay(SiS_Pr, 1);
4732 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4738 } else { /* =================== For LVDS ================== */
4740 if(SiS_Pr->ChipType < SIS_315H) {
4742 #ifdef SIS300 /* 300 series */
4744 if(SiS_CRT2IsLCD(SiS_Pr)) {
4745 if(SiS_Pr->ChipType == SIS_730) {
4746 SiS_PanelDelay(SiS_Pr, 1);
4747 SiS_PanelDelay(SiS_Pr, 1);
4748 SiS_PanelDelay(SiS_Pr, 1);
4750 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4751 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4752 SiS_PanelDelay(SiS_Pr, 0);
4756 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4757 SiS_DisplayOn(SiS_Pr);
4758 SiS_UnLockCRT2(SiS_Pr);
4759 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4760 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4761 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4763 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4766 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4767 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4768 SiS_WaitVBRetrace(SiS_Pr);
4769 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4773 if(SiS_CRT2IsLCD(SiS_Pr)) {
4774 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4775 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4776 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4777 SiS_PanelDelay(SiS_Pr, 1);
4778 SiS_PanelDelay(SiS_Pr, 1);
4780 SiS_WaitVBRetrace(SiS_Pr);
4781 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4790 #ifdef SIS315H /* 315 series */
4792 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4793 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4794 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4798 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4799 if(SiS_CRT2IsLCD(SiS_Pr)) {
4800 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4801 SiS_PanelDelay(SiS_Pr, 0);
4805 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4806 SiS_UnLockCRT2(SiS_Pr);
4808 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4810 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4811 temp = SiS_GetCH701x(SiS_Pr,0x66);
4813 SiS_Chrontel701xBLOff(SiS_Pr);
4816 if(SiS_Pr->ChipType != SIS_550) {
4817 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4820 if(SiS_Pr->ChipType == SIS_740) {
4821 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4822 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4823 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4828 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4829 if(!(temp1 & 0x80)) {
4830 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4833 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4835 SiS_Chrontel701xBLOn(SiS_Pr);
4839 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4840 if(SiS_CRT2IsLCD(SiS_Pr)) {
4841 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4842 if(SiS_Pr->ChipType == SIS_550) {
4843 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4844 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4847 } else if(SiS_IsVAMode(SiS_Pr)) {
4848 if(SiS_Pr->ChipType != SIS_740) {
4849 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4853 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4854 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4857 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4858 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4859 SiS_Chrontel701xOn(SiS_Pr);
4861 if( (SiS_IsVAMode(SiS_Pr)) ||
4862 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4863 SiS_ChrontelDoSomething1(SiS_Pr);
4867 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4868 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4869 if( (SiS_IsVAMode(SiS_Pr)) ||
4870 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4871 SiS_Chrontel701xBLOn(SiS_Pr);
4872 SiS_ChrontelInitTVVSync(SiS_Pr);
4875 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4876 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4877 if(SiS_CRT2IsLCD(SiS_Pr)) {
4878 SiS_PanelDelay(SiS_Pr, 1);
4879 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4884 #endif /* SIS315H */
4892 /*********************************************/
4893 /* SET PART 1 REGISTER GROUP */
4894 /*********************************************/
4896 /* Set CRT2 OFFSET / PITCH */
4898 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4899 unsigned short RRTI)
4901 unsigned short offset;
4904 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4906 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4909 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4911 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4912 if(offset & 0x07) temp++;
4913 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4916 /* Set CRT2 sync and PanelLink mode */
4918 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4920 unsigned short tempah=0, tempbl, infoflag;
4924 if(SiS_Pr->UseCustomMode) {
4925 infoflag = SiS_Pr->CInfoFlag;
4927 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4930 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4932 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4934 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4935 tempah = SiS_Pr->SiS_LCDInfo;
4936 } else tempah = infoflag >> 8;
4939 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4940 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4941 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4942 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4945 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4946 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4947 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4948 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4949 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4952 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4953 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4957 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4958 if(SiS_Pr->ChipType >= SIS_315H) {
4961 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4962 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4964 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4967 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4970 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4972 if(SiS_Pr->ChipType < SIS_315H) {
4974 #ifdef SIS300 /* ---- 300 series --- */
4976 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4978 tempah = infoflag >> 8;
4980 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4981 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4982 tempah = SiS_Pr->SiS_LCDInfo;
4983 tempbl = (tempah >> 6) & 0x03;
4988 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4990 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4991 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4992 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4995 } else { /* 630 - 301 */
4997 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4998 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4999 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5007 #ifdef SIS315H /* ------- 315 series ------ */
5009 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
5012 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5013 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5014 tempah = infoflag >> 8;
5015 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5016 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5018 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
5019 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5020 tempah = infoflag >> 8;
5023 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5024 tempbl = (tempah >> 6) & 0x03;
5026 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5030 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5031 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
5032 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5033 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5034 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5035 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5039 } else { /* 315 - TMDS */
5041 tempah = tempbl = infoflag >> 8;
5042 if(!SiS_Pr->UseCustomMode) {
5044 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5045 if(ModeNo <= 0x13) {
5046 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5049 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5050 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5051 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5052 tempah = SiS_Pr->SiS_LCDInfo;
5053 tempbl = (tempah >> 6) & 0x03;
5060 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5061 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5062 /* Imitate BIOS bug */
5063 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5065 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5068 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5070 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5071 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5072 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5073 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5079 #endif /* SIS315H */
5084 /* Set CRT2 FIFO on 300/540/630/730 */
5087 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5089 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5090 unsigned short temp, index, modeidindex, refreshratetableindex;
5091 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5092 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5093 unsigned int data, pci50, pciA0;
5094 static const unsigned char colortharray[] = {
5098 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5100 if(!SiS_Pr->CRT1UsesCustomMode) {
5102 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5103 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5104 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5105 SiS_Pr->SiS_SelectCRT2Rate = 0;
5106 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5108 if(CRT1ModeNo >= 0x13) {
5110 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5111 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5113 /* Get colordepth */
5114 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5115 if(!colorth) colorth++;
5123 VCLK = SiS_Pr->CSRClock_CRT1;
5125 /* Get color depth */
5126 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5130 if(CRT1ModeNo >= 0x13) {
5132 if(SiS_Pr->ChipType == SIS_300) {
5133 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5135 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5138 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5140 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5144 data2 = temp - ((colorth * VCLK) / MCLK);
5146 temp = (28 * 16) % data2;
5147 data2 = (28 * 16) / data2;
5150 if(SiS_Pr->ChipType == SIS_300) {
5152 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5153 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5157 #ifdef SIS_LINUX_KERNEL
5158 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5159 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5161 pci50 = pciReadLong(0x00000000, 0x50);
5162 pciA0 = pciReadLong(0x00000000, 0xA0);
5165 if(SiS_Pr->ChipType == SIS_730) {
5167 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5168 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5170 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5171 index = 0; /* -- do it like the BIOS anyway... */
5178 index = (pci50 >> 1) & 0x07;
5180 if(pci50 & 0x01) index += 6;
5181 if(!(pciA0 & 0x01)) index += 24;
5183 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5187 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5188 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5192 data += data2; /* CRT1 Request Period */
5194 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5195 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5197 if(!SiS_Pr->UseCustomMode) {
5199 CRT2ModeNo = ModeNo;
5200 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5202 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5205 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5206 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5208 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5209 if(SiS_Pr->SiS_UseROM) {
5210 if(ROMAddr[0x220] & 0x01) {
5211 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5220 VCLK = SiS_Pr->CSRClock;
5224 /* Get colordepth */
5225 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5226 if(!colorth) colorth++;
5228 data = data * VCLK * colorth;
5229 temp = data % (MCLK << 4);
5230 data = data / (MCLK << 4);
5233 if(data < 6) data = 6;
5234 else if(data > 0x14) data = 0x14;
5236 if(SiS_Pr->ChipType == SIS_300) {
5238 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5242 if(( (SiS_Pr->ChipType == SIS_630) ||
5243 (SiS_Pr->ChipType == SIS_730) ) &&
5244 (SiS_Pr->ChipRevision >= 0x30))
5247 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5249 if((SiS_Pr->ChipType == SIS_630) &&
5250 (SiS_Pr->ChipRevision >= 0x30)) {
5251 if(data > 0x13) data = 0x13;
5253 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5255 } else { /* If mode <= 0x13, we just restore everything */
5257 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5258 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5264 /* Set CRT2 FIFO on 315/330 series */
5267 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5269 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5270 if( (SiS_Pr->ChipType == SIS_760) &&
5271 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5272 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5273 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5274 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5275 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5276 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5277 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5278 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5279 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5280 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5282 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5288 static unsigned short
5289 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5291 unsigned int tempax,tempbx;
5293 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5294 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5295 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5296 return (unsigned short)tempax;
5299 /* Set Part 1 / SiS bridge slave mode */
5301 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5302 unsigned short RefreshRateTableIndex)
5304 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5305 static const unsigned short CRTranslation[] = {
5306 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5307 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5308 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5309 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5310 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5311 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5314 if(ModeNo <= 0x13) {
5315 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5316 } else if(SiS_Pr->UseCustomMode) {
5317 modeflag = SiS_Pr->CModeFlag;
5318 xres = SiS_Pr->CHDisplay;
5320 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5321 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5324 /* The following is only done if bridge is in slave mode: */
5326 if(SiS_Pr->ChipType >= SIS_315H) {
5327 if(xres >= 1600) { /* BIOS: == 1600 */
5328 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5332 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5334 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5335 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5337 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5338 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5339 SiS_Pr->CHBlankStart += 16;
5342 SiS_Pr->CHBlankEnd = 32;
5343 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5344 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5347 temp = SiS_Pr->SiS_VGAHT - 96;
5348 if(!(modeflag & HalfDCLK)) temp -= 32;
5349 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5350 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5351 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5355 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5357 SiS_Pr->CHSyncStart = temp;
5359 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5361 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5363 VGAVDE = SiS_Pr->SiS_VGAVDE;
5364 if (VGAVDE == 357) VGAVDE = 350;
5365 else if(VGAVDE == 360) VGAVDE = 350;
5366 else if(VGAVDE == 375) VGAVDE = 350;
5367 else if(VGAVDE == 405) VGAVDE = 400;
5368 else if(VGAVDE == 420) VGAVDE = 400;
5369 else if(VGAVDE == 525) VGAVDE = 480;
5370 else if(VGAVDE == 1056) VGAVDE = 1024;
5371 SiS_Pr->CVDisplay = VGAVDE;
5373 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5375 SiS_Pr->CVBlankEnd = 1;
5376 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5378 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5379 SiS_Pr->CVSyncStart = VGAVDE + temp;
5382 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5384 SiS_CalcCRRegisters(SiS_Pr, 0);
5385 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5387 for(i = 0; i <= 7; i++) {
5388 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5390 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5391 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5393 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5394 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5396 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5397 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5400 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5401 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5403 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5404 if(modeflag & DoubleScanMode) temp |= 0x80;
5405 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5408 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5409 if(modeflag & HalfDCLK) temp |= 0x08;
5410 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5412 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5413 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5416 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5417 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5419 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5421 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5422 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5424 #ifdef SIS_XORG_XF86
5426 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
5427 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
5428 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
5429 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
5431 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5432 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
5433 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
5434 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
5435 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
5436 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5437 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
5438 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
5439 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
5440 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
5441 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
5447 * This is used for LVDS, LCDA and Chrontel TV output
5448 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5451 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5452 unsigned short RefreshRateTableIndex)
5454 unsigned short modeflag, resinfo = 0;
5455 unsigned short push2, tempax, tempbx, tempcx, temp;
5456 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5457 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5459 unsigned short crt2crtc = 0;
5462 unsigned short pushcx;
5465 if(ModeNo <= 0x13) {
5466 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5467 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5469 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5471 } else if(SiS_Pr->UseCustomMode) {
5472 modeflag = SiS_Pr->CModeFlag;
5474 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5475 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5477 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5481 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5482 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5486 /* is really sis if sis bridge, but not 301B-DH */
5487 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5491 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5492 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5493 chkdclkfirst = TRUE;
5498 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5500 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5501 } else if(IS_SIS740) {
5503 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5504 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5505 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5506 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5510 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5511 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5512 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5513 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5514 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5515 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5516 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5517 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5527 tempax = SiS_Pr->SiS_LCDHDES;
5529 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5530 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5531 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5532 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5539 temp = (tempax & 0x0007);
5540 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5541 temp = (tempax >> 3) & 0x00FF;
5542 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5544 tempbx = SiS_Pr->SiS_HDE;
5545 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5546 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5547 tempbx = SiS_Pr->PanelXRes;
5549 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5550 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5551 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5557 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5560 if(temp & 0x07) temp += 8;
5562 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5564 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5566 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5567 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5568 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5573 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5575 temp = (tempcx >> 3) & 0x00FF;
5576 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5577 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5578 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5582 case 0x0d: temp = 0x56; break;
5583 case 0x10: temp = 0x60; break;
5584 case 0x13: temp = 0x5f; break;
5594 case 0x5e: temp = 0x54; break;
5599 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5601 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5603 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5605 if(SiS_Pr->PanelHRE != 999) {
5606 temp = tempcx + SiS_Pr->PanelHRE;
5607 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5616 temp |= ((tempcx & 0x07) << 5);
5617 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5621 tempax = SiS_Pr->SiS_VGAVDE;
5622 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5623 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5624 tempax = SiS_Pr->PanelYRes;
5628 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5629 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5633 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5634 if(SiS_Pr->ChipType < SIS_315H) {
5635 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5636 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5637 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5641 if(islvds) tempcx >>= 1;
5644 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5645 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5646 (SiS_Pr->PanelVRS != 999) ) {
5647 tempcx = SiS_Pr->PanelVRS;
5652 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5653 else if(issis) tempbx++;
5656 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5658 temp = tempbx & 0x00FF;
5659 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5660 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5661 if(ModeNo == 0x10) temp = 0xa9;
5664 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5669 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5670 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5671 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5676 temp = tempcx & 0x000F;
5677 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5679 temp = ((tempbx >> 8) & 0x07) << 3;
5680 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5681 if(SiS_Pr->SiS_HDE != 640) {
5682 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5684 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5685 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5687 if((SiS_Pr->ChipType >= SIS_315H) ||
5688 (SiS_Pr->ChipRevision >= 0x30)) {
5690 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5691 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5693 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5694 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5695 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5696 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5698 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5702 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5704 tempbx = push2; /* BPLVDEE */
5706 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5708 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5709 switch(SiS_Pr->SiS_LCDResInfo) {
5711 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5712 tempcx = SiS_Pr->SiS_VGAVDE;
5715 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5716 if(resinfo == SIS_RI_800x600) tempcx++;
5719 case Panel_1024x600:
5720 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5721 if(resinfo == SIS_RI_1024x600) tempcx++;
5722 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5723 if(resinfo == SIS_RI_800x600) tempcx++;
5727 case Panel_1024x768:
5728 if(SiS_Pr->ChipType < SIS_315H) {
5729 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5730 if(resinfo == SIS_RI_1024x768) tempcx++;
5737 temp = ((tempbx >> 8) & 0x07) << 3;
5738 temp |= ((tempcx >> 8) & 0x07);
5739 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5740 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5741 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5743 /* Vertical scaling */
5745 if(SiS_Pr->ChipType < SIS_315H) {
5747 #ifdef SIS300 /* 300 series */
5748 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5749 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5750 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5753 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5755 temp = (unsigned short)(tempeax & 0x00FF);
5756 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5762 #ifdef SIS315H /* 315 series */
5763 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5764 tempebx = SiS_Pr->SiS_VDE;
5765 temp = (tempeax % tempebx);
5766 tempeax = tempeax / tempebx;
5768 tempvcfact = tempeax;
5770 temp = (unsigned short)(tempeax & 0x00FF);
5771 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5772 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5773 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5774 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5775 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5776 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5778 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5779 temp = (unsigned short)(tempeax & 0x00FF);
5780 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5781 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5782 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5783 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5784 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5786 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5787 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5793 /* Horizontal scaling */
5795 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5797 if(modeflag & HalfDCLK) tempeax >>= 1;
5799 tempebx = tempeax << 16;
5800 if(SiS_Pr->SiS_HDE == tempeax) {
5803 tempecx = tempebx / SiS_Pr->SiS_HDE;
5804 if(SiS_Pr->ChipType >= SIS_315H) {
5805 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5809 if(SiS_Pr->ChipType >= SIS_315H) {
5810 tempeax = (tempebx / tempecx) - 1;
5812 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5814 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5815 temp = (unsigned short)(tempecx & 0x00FF);
5816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5818 if(SiS_Pr->ChipType >= SIS_315H) {
5819 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5820 tempbx = (unsigned short)(tempeax & 0xFFFF);
5822 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5823 tempbx = tempvcfact & 0x3f;
5824 if(tempbx == 0) tempbx = 64;
5826 tempbx = (unsigned short)(tempeax & 0xFFFF);
5828 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5829 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5830 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5831 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5834 temp = ((tempbx >> 8) & 0x07) << 3;
5835 temp = temp | ((tempecx >> 8) & 0x07);
5836 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5839 tempecx >>= 16; /* BPLHCFACT */
5841 if(modeflag & HalfDCLK) tempecx >>= 1;
5843 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5844 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5845 temp = (unsigned short)(tempecx & 0x00FF);
5846 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5849 if(SiS_Pr->ChipType >= SIS_315H) {
5850 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5851 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5852 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5856 if(SiS_Pr->ChipType == SIS_740) {
5857 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5867 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5868 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5869 unsigned char *trumpdata;
5870 int i, j = crt2crtc;
5871 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5872 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5873 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5875 if(SiS_Pr->SiS_UseROM) {
5876 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5878 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5879 trumpdata = &SiS300_TrumpionData[j][0];
5882 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5883 for(i=0; i<5; i++) {
5884 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5886 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5887 if(ModeNo == 0x13) {
5888 for(i=0; i<4; i++) {
5889 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5891 } else if(ModeNo == 0x10) {
5892 for(i=0; i<4; i++) {
5893 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5894 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5898 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5903 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5904 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5905 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5906 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5907 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5909 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5910 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5911 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5912 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5913 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5914 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5916 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5917 temp = (tempax >> 8) << 3;
5918 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5919 tempax += 32; /* Blpe = lBlps+32 */
5920 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5921 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
5922 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5924 tempax = SiS_Pr->SiS_VDE;
5925 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5926 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5927 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5929 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5930 temp = (tempax >> 8) << 3;
5931 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5933 tempeax = SiS_Pr->SiS_HDE;
5934 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5935 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5936 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5937 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5938 temp = tempeax & 0x7f;
5941 temp = tempeax & 0x3f;
5942 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5943 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5944 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5945 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5946 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5948 tempax = SiS_Pr->SiS_HDE;
5949 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5950 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5951 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5952 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5954 temp = tempax & 0x00FF;
5955 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5956 temp = ((tempax & 0xFF00) >> 8) << 3;
5957 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5959 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5960 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5961 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5962 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5963 tempeax = tempax * pushcx;
5964 temp = tempeax & 0xFF;
5965 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5966 temp = (tempeax & 0xFF00) >> 8;
5967 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5968 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5969 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5970 temp = ((tempeax & 0x01000000) >> 24) << 7;
5971 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
5973 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5974 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5975 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5976 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5977 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5979 if(SiS_Pr->SiS_IF_DEF_FSTN) {
5980 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5981 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5982 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5983 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5984 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5985 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5986 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5987 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5988 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5989 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5990 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5991 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5992 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5994 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5996 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
5997 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
5998 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
5999 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6002 #endif /* SIS315H */
6007 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6008 unsigned short RefreshRateTableIndex)
6010 #if defined(SIS300) || defined(SIS315H)
6011 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6013 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6014 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6016 unsigned short tempbl=0;
6019 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6020 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6024 if(ModeNo <= 0x13) {
6025 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6026 } else if(SiS_Pr->UseCustomMode) {
6027 modeflag = SiS_Pr->CModeFlag;
6029 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6030 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6031 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6034 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6036 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6037 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6038 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6040 if(SiS_Pr->ChipType < SIS_315H ) {
6042 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6046 SiS_SetCRT2FIFO_310(SiS_Pr);
6050 /* 1. Horizontal setup */
6052 if(SiS_Pr->ChipType < SIS_315H ) {
6054 #ifdef SIS300 /* ------------- 300 series --------------*/
6056 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6057 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6059 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6060 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6062 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6063 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6065 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6066 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6067 tempbx = pushbx + tempcx;
6077 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6079 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6080 if(modeflag & HalfDCLK) {
6081 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6084 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6085 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6086 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6087 tempcx = SiS_Pr->SiS_HT - tempax;
6092 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6093 temp = (tempcx >> 4) & 0xF0;
6094 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6096 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6097 tempbx = SiS_Pr->SiS_VGAHDE;
6100 if(modeflag & HalfDCLK) {
6106 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6115 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6116 if(SiS_Pr->ChipType >= SIS_661) {
6117 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6118 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6119 if(resinfo == SIS_RI_1280x1024) {
6120 tempcx = (tempcx & 0xff00) | 0x30;
6121 } else if(resinfo == SIS_RI_1600x1200) {
6122 tempcx = (tempcx & 0xff00) | 0xff;
6128 #endif /* SIS315H */
6130 } /* 315/330 series */
6132 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6134 if(SiS_Pr->UseCustomMode) {
6135 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6136 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6137 tempax = SiS_Pr->SiS_VGAHT;
6138 if(modeflag & HalfDCLK) tempax >>= 1;
6140 if(tempcx > tempax) tempcx = tempax;
6143 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6144 unsigned char cr4, cr14, cr5, cr15;
6145 if(SiS_Pr->UseCustomMode) {
6146 cr4 = SiS_Pr->CCRT1CRTC[4];
6147 cr14 = SiS_Pr->CCRT1CRTC[14];
6148 cr5 = SiS_Pr->CCRT1CRTC[5];
6149 cr15 = SiS_Pr->CCRT1CRTC[15];
6151 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6152 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6153 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6154 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6156 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6157 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6159 tempcx |= (tempbx & 0xFF00);
6160 tempbx += bridgeadd;
6161 tempcx += bridgeadd;
6162 tempax = SiS_Pr->SiS_VGAHT;
6163 if(modeflag & HalfDCLK) tempax >>= 1;
6165 if(tempcx > tempax) tempcx = tempax;
6168 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6170 tempcx = 1044; /* HWCursor bug! */
6175 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6177 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6179 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6180 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6182 /* 2. Vertical setup */
6184 tempcx = SiS_Pr->SiS_VGAVT - 1;
6185 temp = tempcx & 0x00FF;
6187 if(SiS_Pr->ChipType < SIS_661) {
6188 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6189 if(SiS_Pr->ChipType < SIS_315H) {
6190 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6191 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6198 } else if(SiS_Pr->ChipType >= SIS_315H) {
6202 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6204 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6207 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6210 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6217 if(tempcx < 4) tempcx = 4;
6222 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6223 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6226 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6227 if(SiS_Pr->UseCustomMode) {
6228 tempbx = SiS_Pr->CVSyncStart;
6229 tempcx = SiS_Pr->CVSyncEnd;
6231 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6232 unsigned char cr8, cr7, cr13;
6233 if(SiS_Pr->UseCustomMode) {
6234 cr8 = SiS_Pr->CCRT1CRTC[8];
6235 cr7 = SiS_Pr->CCRT1CRTC[7];
6236 cr13 = SiS_Pr->CCRT1CRTC[13];
6237 tempcx = SiS_Pr->CCRT1CRTC[9];
6239 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6240 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6241 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6242 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6245 if(cr7 & 0x04) tempbx |= 0x0100;
6246 if(cr7 & 0x80) tempbx |= 0x0200;
6247 if(cr13 & 0x08) tempbx |= 0x0400;
6250 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6252 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6253 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6255 /* 3. Panel delay compensation */
6257 if(SiS_Pr->ChipType < SIS_315H) {
6259 #ifdef SIS300 /* ---------- 300 series -------------- */
6261 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6263 if(SiS_Pr->ChipType == SIS_300) {
6265 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6266 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6268 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6269 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6271 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6272 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6273 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6274 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6275 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6278 if(SiS_Pr->SiS_UseROM) {
6279 if(ROMAddr[0x220] & 0x80) {
6280 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6281 temp = ROMAddr[0x221];
6282 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6283 temp = ROMAddr[0x222];
6284 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6285 temp = ROMAddr[0x223];
6287 temp = ROMAddr[0x224];
6290 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6291 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6296 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6297 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6299 if(SiS_Pr->SiS_UseROM) {
6300 if(ROMAddr[0x220] & 0x80) {
6301 temp = ROMAddr[0x220];
6304 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6305 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6311 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6317 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6319 if(SiS_Pr->ChipType < SIS_661) {
6321 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6323 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6326 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6328 if(SiS_Pr->ChipType == SIS_650) {
6329 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6330 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6334 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6337 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6338 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6342 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6348 if(modeflag & DoubleScanMode) tempax |= 0x80;
6349 if(modeflag & HalfDCLK) tempax |= 0x40;
6350 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6352 #endif /* SIS315H */
6358 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6359 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6360 /* For 301BDH with LCD, we set up the Panel Link */
6361 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6362 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6363 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6366 if(SiS_Pr->ChipType < SIS_315H) {
6367 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6369 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6370 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6371 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6374 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6380 /*********************************************/
6381 /* SET PART 2 REGISTER GROUP */
6382 /*********************************************/
6385 static unsigned char *
6386 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6388 const unsigned char *tableptr = NULL;
6389 unsigned short a, b, p = 0;
6391 a = SiS_Pr->SiS_VGAHDE;
6392 b = SiS_Pr->SiS_HDE;
6394 a = SiS_Pr->SiS_VGAVDE;
6395 b = SiS_Pr->SiS_VDE;
6399 tableptr = SiS_Part2CLVX_1;
6401 tableptr = SiS_Part2CLVX_2;
6403 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6404 tableptr = SiS_Part2CLVX_4;
6406 tableptr = SiS_Part2CLVX_3;
6408 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6409 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6410 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6411 else tableptr = SiS_Part2CLVX_5;
6412 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6413 tableptr = SiS_Part2CLVX_6;
6416 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6418 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6419 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6422 return ((unsigned char *)&tableptr[p]);
6426 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6427 unsigned short RefreshRateTableIndex)
6429 unsigned char *tableptr;
6433 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6435 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6436 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6437 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6439 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6440 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6441 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6442 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6446 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6447 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6451 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6452 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6453 unsigned short *ResIndex)
6456 if(SiS_Pr->ChipType < SIS_315H) return FALSE;
6459 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6461 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6463 (*ResIndex) &= 0x3f;
6466 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6467 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6472 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6473 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6474 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6477 return (((*CRT2Index) != 0));
6483 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6485 unsigned short tempcx;
6486 static const unsigned char atable[] = {
6487 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6488 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6491 if(!SiS_Pr->UseCustomMode) {
6492 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6493 (SiS_Pr->ChipType == SIS_730) ) &&
6494 (SiS_Pr->ChipRevision > 2) ) &&
6495 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6496 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6497 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6498 if(ModeNo == 0x13) {
6499 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6500 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6501 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6502 } else if((crt2crtc & 0x3F) == 4) {
6503 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6505 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6506 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6507 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6511 if(SiS_Pr->ChipType < SIS_315H) {
6512 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6515 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6516 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6522 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6525 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6526 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6528 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6532 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6533 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6539 /* For ECS A907. Highly preliminary. */
6541 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6542 unsigned short ModeNo)
6544 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6545 unsigned short crt2crtc, resindex;
6548 if(SiS_Pr->ChipType != SIS_300) return;
6549 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6550 if(SiS_Pr->UseCustomMode) return;
6552 if(ModeNo <= 0x13) {
6553 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6555 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6558 resindex = crt2crtc & 0x3F;
6559 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6560 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6562 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6564 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6568 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6569 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6570 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6571 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6573 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6574 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6576 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6577 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6579 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6580 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6585 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6587 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6588 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6589 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6591 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6592 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6593 const unsigned char specialtv[] = {
6594 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6595 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6596 0x58,0xe4,0x73,0xda,0x13
6599 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6600 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6602 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6603 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6604 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6605 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6606 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6608 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6609 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6614 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6615 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6616 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6617 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6619 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6620 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6626 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6628 unsigned short temp;
6630 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6631 if(SiS_Pr->SiS_VGAVDE == 525) {
6633 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6635 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6637 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6638 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6639 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6641 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6643 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6645 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6649 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6650 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6651 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6652 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6653 /* Not always for LV, see SetGrp2 */
6656 if(ModeNo <= 0x13) temp = 3;
6657 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6660 /* 651+301C, for 1280x768 - do I really need that? */
6661 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6662 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6663 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6664 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6665 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6666 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6667 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6668 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6669 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6670 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6671 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6672 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6673 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6674 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6675 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6676 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6685 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6686 unsigned short RefreshRateTableIndex)
6688 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6689 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6690 unsigned int longtemp, PhaseIndex;
6692 const unsigned char *TimingPoint;
6694 unsigned short resindex, CRT2Index;
6695 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6697 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6700 if(ModeNo <= 0x13) {
6701 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6702 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6703 } else if(SiS_Pr->UseCustomMode) {
6704 modeflag = SiS_Pr->CModeFlag;
6707 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6708 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6712 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6713 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6714 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6715 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6717 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6719 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6721 PhaseIndex = 0x01; /* SiS_PALPhase */
6722 TimingPoint = SiS_Pr->SiS_PALTiming;
6725 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6726 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6727 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6731 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6733 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6734 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6735 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6736 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6737 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6741 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6744 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6745 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6747 TimingPoint = &SiS_YPbPrTable[i][0];
6749 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6751 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6753 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6757 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6758 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6759 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6763 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6764 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6765 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6768 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6769 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6770 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6771 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6772 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6774 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6778 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6779 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6782 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6783 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6785 for(i = 0x39; i <= 0x45; i++, j++) {
6786 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6789 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6790 if(SiS_Pr->SiS_ModeType != ModeText) {
6791 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6795 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6797 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6798 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6799 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6800 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6802 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6803 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
6804 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6805 else tempax = 440; /* NTSC, YPbPr 525 */
6807 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6808 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6809 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6811 tempax -= SiS_Pr->SiS_VDE;
6813 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6818 temp = tempax + (unsigned short)TimingPoint[0];
6819 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6821 temp = tempax + (unsigned short)TimingPoint[1];
6822 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6824 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6825 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6829 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6830 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6836 tempcx = SiS_Pr->SiS_HT;
6837 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6839 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6840 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6841 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6843 tempcx = SiS_Pr->SiS_HT >> 1;
6844 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6846 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6847 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6849 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6851 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6852 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6855 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6859 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6862 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6863 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6864 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6867 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6868 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6870 tempcx = SiS_Pr->SiS_HT >> 1;
6871 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6873 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6874 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6877 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6878 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6880 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6882 tempbx = SiS_Pr->SiS_VDE;
6883 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6884 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6885 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6886 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6887 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6888 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6890 if(SiS_Pr->ChipType >= SIS_315H) {
6891 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6892 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6893 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6894 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6895 if(crt2crtc == 4) tempbx++;
6899 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6900 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6901 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6903 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6904 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6909 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6911 temp = (tempcx >> 8) & 0x0F;
6912 temp |= ((tempbx >> 2) & 0xC0);
6913 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6915 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6917 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6919 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6920 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6923 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6924 tempbx = SiS_Pr->SiS_VDE;
6925 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6926 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6930 temp = ((tempbx >> 3) & 0x60) | 0x18;
6931 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6932 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6934 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6935 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6940 if(!(modeflag & HalfDCLK)) {
6941 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6947 tempch = tempcl = 0x01;
6948 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6949 if(SiS_Pr->SiS_VGAHDE >= 960) {
6950 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6952 if(SiS_Pr->SiS_VGAHDE >= 1280) {
6955 } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6958 tempch = 25; /* OK */
6964 if(!(tempbx & 0x20)) {
6965 if(modeflag & HalfDCLK) tempcl <<= 1;
6966 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6967 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6968 tempax = longtemp / SiS_Pr->SiS_HDE;
6969 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6970 tempbx |= ((tempax >> 8) & 0x1F);
6971 tempcx = tempax >> 13;
6974 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6975 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6977 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6980 if(tempbx & 0x20) tempcx = 0;
6981 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6983 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6990 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6991 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6992 temp = (tempcx & 0x0300) >> 6;
6993 temp |= ((tempbx >> 8) & 0x03);
6994 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6996 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
6997 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6999 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7001 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7002 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7004 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7006 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7008 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7009 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7014 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7015 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7016 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7017 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7019 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7022 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7023 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7024 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7028 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7030 /* From here: Part2 LCD setup */
7032 tempbx = SiS_Pr->SiS_HDE;
7033 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7034 tempbx--; /* RHACTE = HDE - 1 */
7035 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7036 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7039 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7040 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7041 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7043 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7049 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7051 tempbx = SiS_Pr->SiS_VDE - 1;
7052 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7053 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7055 tempcx = SiS_Pr->SiS_VT - 1;
7056 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7057 temp = (tempcx >> 3) & 0xE0;
7058 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7059 /* Enable dithering; only do this for 32bpp mode */
7060 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7064 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7066 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7067 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7069 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7070 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7073 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7074 &CRT2Index, &resindex)) {
7076 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7078 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7081 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7082 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7083 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7084 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7086 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7087 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7089 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7090 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7092 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7093 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7095 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7100 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7101 /* Clevo dual-link 1024x768 */
7102 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7103 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7105 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7106 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7107 tempbx = SiS_Pr->SiS_VDE - 1;
7108 tempcx = SiS_Pr->SiS_VT - 1;
7110 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7111 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7114 tempbx = SiS_Pr->PanelYRes;
7115 tempcx = SiS_Pr->SiS_VT;
7117 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7118 tempax = SiS_Pr->PanelYRes;
7119 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7120 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7121 tempax = tempcx = 0;
7123 tempax -= SiS_Pr->SiS_VDE;
7127 tempcx -= tempax; /* lcdvdes */
7128 tempbx -= tempax; /* lcdvdee */
7131 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7133 #ifdef SIS_XORG_XF86
7135 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7139 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7140 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7142 temp = (tempbx >> 5) & 0x38;
7143 temp |= ((tempcx >> 8) & 0x07);
7144 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7146 tempax = SiS_Pr->SiS_VDE;
7147 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7148 tempax = SiS_Pr->PanelYRes;
7150 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7151 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7152 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7153 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7157 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7158 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7159 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7160 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7161 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7162 if(tempax % 4) { tempax >>= 2; tempax++; }
7163 else { tempax >>= 2; }
7164 tempbx -= (tempax - 1);
7167 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7171 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7173 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7174 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7181 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7183 if(SiS_Pr->UseCustomMode) {
7184 tempbx = SiS_Pr->CVSyncStart;
7187 #ifdef SIS_XORG_XF86
7189 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7193 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7195 temp = (tempbx >> 4) & 0xF0;
7196 tempbx += (tempcx + 1);
7197 temp |= (tempbx & 0x0F);
7199 if(SiS_Pr->UseCustomMode) {
7201 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7204 #ifdef SIS_XORG_XF86
7206 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7210 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7213 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7217 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7218 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7219 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7220 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7221 /* Higher bridgeoffset shifts to the LEFT */
7224 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7225 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7226 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7227 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7230 temp += bridgeoffset;
7231 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7232 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7234 tempcx = SiS_Pr->SiS_HT;
7235 tempax = tempbx = SiS_Pr->SiS_HDE;
7236 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7237 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7238 tempax = SiS_Pr->PanelXRes;
7239 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7242 if(SiS_IsDualLink(SiS_Pr)) {
7248 #ifdef SIS_XORG_XF86
7250 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7254 tempbx += bridgeoffset;
7256 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7257 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7259 tempcx = (tempcx - tempax) >> 2;
7264 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7265 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7266 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7267 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7272 if(SiS_Pr->UseCustomMode) {
7273 tempbx = SiS_Pr->CHSyncStart;
7274 if(modeflag & HalfDCLK) tempbx <<= 1;
7275 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7276 tempbx += bridgeoffset;
7279 #ifdef SIS_XORG_XF86
7281 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7285 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7286 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7291 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7292 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7296 if(SiS_Pr->UseCustomMode) {
7297 tempbx = SiS_Pr->CHSyncEnd;
7298 if(modeflag & HalfDCLK) tempbx <<= 1;
7299 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7300 tempbx += bridgeoffset;
7303 #ifdef SIS_XORG_XF86
7305 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7309 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7311 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7314 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7317 } /* CRT2-LCD from table */
7321 /*********************************************/
7322 /* SET PART 3 REGISTER GROUP */
7323 /*********************************************/
7326 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7329 const unsigned char *tempdi;
7331 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7334 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7339 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7340 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7341 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7343 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7344 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7347 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7348 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7349 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7350 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7354 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7355 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7356 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7357 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7359 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7360 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7361 tempdi = SiS_HiTVGroup3_1;
7362 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7366 for(i=0; i<=0x3E; i++) {
7367 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7369 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7370 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7371 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7381 /*********************************************/
7382 /* SET PART 4 REGISTER GROUP */
7383 /*********************************************/
7388 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7390 unsigned short temp, temp1, temp2;
7392 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7393 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7394 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7395 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7396 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7397 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7398 temp = (unsigned short)((int)(temp) + shift);
7399 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7400 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7401 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7402 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7403 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7404 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7409 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7411 unsigned short temp, temp1, resinfo = 0;
7412 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7414 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7415 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7417 if(SiS_Pr->ChipType >= XGI_20) return;
7419 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7420 if(!(ROMAddr[0x61] & 0x04)) return;
7424 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7427 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7428 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7429 if(!(temp & 0x01)) {
7430 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7431 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7432 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7433 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7435 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7436 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7437 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7438 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7440 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7442 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7443 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7444 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7445 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7446 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7448 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7451 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7452 if(temp1 == 0x01) temp |= 0x01;
7453 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7454 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7455 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7457 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7462 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7463 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7464 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7465 if(resinfo == SIS_RI_1024x768) {
7466 SiS_ShiftXPos(SiS_Pr, 97);
7468 SiS_ShiftXPos(SiS_Pr, 111);
7470 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7471 SiS_ShiftXPos(SiS_Pr, 136);
7483 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7484 unsigned short RefreshRateTableIndex)
7486 unsigned short vclkindex, temp, reg1, reg2;
7488 if(SiS_Pr->UseCustomMode) {
7489 reg1 = SiS_Pr->CSR2B;
7490 reg2 = SiS_Pr->CSR2C;
7492 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7493 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7494 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7497 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7498 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7499 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7500 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7501 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7503 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7504 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7507 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7508 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7509 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7511 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7513 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7514 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7518 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7520 if(SiS_Pr->ChipType >= SIS_315H) {
7521 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7522 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7523 (SiS_IsVAMode(SiS_Pr))) {
7524 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7525 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7527 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7532 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7533 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7535 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7537 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7542 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7543 unsigned short RefreshRateTableIndex)
7545 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7546 unsigned int tempebx, tempeax, templong;
7548 if(ModeNo <= 0x13) {
7549 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7550 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7551 } else if(SiS_Pr->UseCustomMode) {
7552 modeflag = SiS_Pr->CModeFlag;
7555 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7556 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7559 if(SiS_Pr->ChipType >= SIS_315H) {
7560 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7561 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7562 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7567 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7568 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7569 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7573 if(SiS_Pr->ChipType >= SIS_315H) {
7574 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7575 SiS_SetDualLinkEtc(SiS_Pr);
7580 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7582 tempbx = SiS_Pr->SiS_RVBHCMAX;
7583 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7585 temp = (tempbx >> 1) & 0x80;
7587 tempcx = SiS_Pr->SiS_VGAHT - 1;
7588 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7590 temp |= ((tempcx >> 5) & 0x78);
7592 tempcx = SiS_Pr->SiS_VGAVT - 1;
7593 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7594 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7596 temp |= ((tempcx >> 8) & 0x07);
7597 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7599 tempbx = SiS_Pr->SiS_VGAHDE;
7600 if(modeflag & HalfDCLK) tempbx >>= 1;
7601 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7603 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7605 if(tempbx > 800) temp = 0x60;
7606 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7608 if(tempbx > 1024) temp = 0xC0;
7609 else if(tempbx >= 960) temp = 0xA0;
7610 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7612 if(tempbx >= 1280) temp = 0x40;
7613 else if(tempbx >= 1024) temp = 0x20;
7616 if(tempbx >= 1024) temp = 0xA0;
7619 temp |= SiS_Pr->Init_P4_0E;
7621 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7622 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7628 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7630 tempeax = SiS_Pr->SiS_VGAVDE;
7631 tempebx = SiS_Pr->SiS_VDE;
7632 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7633 if(!(temp & 0xE0)) tempebx >>=1;
7636 tempcx = SiS_Pr->SiS_RVBHRS;
7637 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7641 if(tempeax <= tempebx) {
7647 tempeax *= (256 * 1024);
7648 templong = tempeax % tempebx;
7650 if(templong) tempeax++;
7652 temp = (unsigned short)(tempeax & 0x000000FF);
7653 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7654 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7655 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7656 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7657 temp |= (tempcx & 0x4F);
7658 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7660 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7662 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7664 /* Calc Linebuffer max address and set/clear decimode */
7666 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7667 tempax = SiS_Pr->SiS_VGAHDE;
7668 if(modeflag & HalfDCLK) tempax >>= 1;
7669 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7671 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7675 if(tempax == 960) tempax *= 25; /* Correct */
7676 else if(tempax == 1024) tempax *= 25;
7682 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7683 if(resinfo == SIS_RI_1024x768 ||
7684 resinfo == SIS_RI_1024x576 ||
7685 resinfo == SIS_RI_1280x1024 ||
7686 resinfo == SIS_RI_1280x720) {
7687 /* Otherwise white line or garbage at right edge */
7688 tempax = (tempax & 0xff00) | 0x20;
7694 temp = ((tempax >> 4) & 0x30) | tempbx;
7695 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7696 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7698 temp = 0x0036; tempbx = 0xD0;
7699 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7700 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7702 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7703 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7705 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7706 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7712 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7714 tempbx = SiS_Pr->SiS_HT >> 1;
7715 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7717 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7718 temp = (tempbx >> 5) & 0x38;
7719 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7721 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7722 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7723 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7724 /* LCD-too-dark-error-source, see FinalizeLCD() */
7728 SiS_SetDualLinkEtc(SiS_Pr);
7732 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7735 /*********************************************/
7736 /* SET PART 5 REGISTER GROUP */
7737 /*********************************************/
7740 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7743 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7745 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7746 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7747 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7748 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7753 /*********************************************/
7754 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7755 /*********************************************/
7758 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7759 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7760 unsigned short *DisplayType)
7762 unsigned short modeflag = 0;
7763 BOOLEAN checkhd = TRUE;
7765 /* Pass 1:1 not supported here */
7767 if(ModeNo <= 0x13) {
7768 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7769 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7771 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7772 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7775 (*ResIndex) &= 0x3F;
7777 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7779 (*DisplayType) = 80;
7780 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7781 (*DisplayType) = 82;
7782 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7783 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7786 if((*DisplayType) != 84) {
7787 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7793 switch(SiS_Pr->SiS_LCDResInfo) {
7794 case Panel_320x240_1: (*DisplayType) = 50;
7797 case Panel_320x240_2: (*DisplayType) = 14;
7799 case Panel_320x240_3: (*DisplayType) = 18;
7801 case Panel_640x480: (*DisplayType) = 10;
7803 case Panel_1024x600: (*DisplayType) = 26;
7805 default: return TRUE;
7809 if(modeflag & HalfDCLK) (*DisplayType)++;
7812 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7813 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7822 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7823 unsigned short RefreshRateTableIndex)
7825 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7826 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7827 static const unsigned short CRIdx[] = {
7828 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7829 0x07, 0x10, 0x11, 0x15, 0x16
7832 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7833 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7834 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7835 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7838 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7839 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7840 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7842 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7843 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7846 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7848 if(SiS_Pr->ChipType < SIS_315H) {
7849 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7852 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7853 &ResIndex, &DisplayType))) {
7857 switch(DisplayType) {
7858 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7859 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7860 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7861 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7862 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7863 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7864 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7865 #if 0 /* Works better with calculated numbers */
7866 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7867 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7868 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7869 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7871 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7872 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7873 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7874 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7875 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7880 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7882 for(i = 0; i <= 10; i++) {
7883 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7884 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7887 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7888 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7889 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7892 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7893 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7895 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7896 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7898 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7899 if(modeflag & DoubleScanMode) tempah |= 0x80;
7900 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7904 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7909 /*********************************************/
7911 /*********************************************/
7914 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7915 unsigned short RefreshRateTableIndex)
7917 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7918 unsigned short clkbase, vclkindex = 0;
7919 unsigned char sr2b, sr2c;
7921 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7922 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7923 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7924 RefreshRateTableIndex--;
7926 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7927 RefreshRateTableIndex);
7928 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7930 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7931 RefreshRateTableIndex);
7934 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7935 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7937 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7938 if(SiS_Pr->SiS_UseROM) {
7939 if(ROMAddr[0x220] & 0x01) {
7940 sr2b = ROMAddr[0x227];
7941 sr2c = ROMAddr[0x228];
7947 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7948 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7953 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7954 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7955 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7956 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7957 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7958 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7959 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7960 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7961 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7964 /*********************************************/
7965 /* SET UP CHRONTEL CHIPS */
7966 /*********************************************/
7969 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7970 unsigned short RefreshRateTableIndex)
7972 unsigned short TVType, resindex;
7973 const struct SiS_CHTVRegData *CHTVRegData = NULL;
7976 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7978 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7983 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7984 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7986 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7987 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7989 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7991 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7992 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7994 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7999 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8000 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8001 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8002 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8003 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8004 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8005 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8006 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8007 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8008 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8012 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8016 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8018 /* We don't support modes >800x600 */
8019 if (resindex > 5) return;
8021 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8022 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8023 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
8025 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8026 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
8029 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
8030 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
8031 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
8032 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
8033 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
8035 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8036 minimum text enhancement (S3-2=10),
8037 maximum flicker filter for Chroma channel (S5-4=10)
8038 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8040 SiS_SetCH700x(SiS_Pr,0x01,0x28);
8042 /* Set video bandwidth
8043 High bandwidth Luma composite video filter(S0=1)
8044 low bandwidth Luma S-video filter (S2-1=00)
8045 disable peak filter in S-video channel (S3=0)
8046 high bandwidth Chroma Filter (S5-4=11)
8049 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
8051 /* Register 0x3D does not exist in non-macrovision register map
8052 (Maybe this is a macrovision register?)
8055 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8058 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8059 all other bits a read-only. Macrovision?
8061 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8063 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8064 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8066 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8070 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8072 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8073 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8074 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8075 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8076 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
8077 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8078 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8079 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8080 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8081 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8082 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8083 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8084 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8085 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8086 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
8087 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
8090 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8091 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8092 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8093 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8095 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8096 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
8097 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
8098 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8099 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8100 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8101 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8102 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8103 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
8104 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
8105 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8106 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8107 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8110 } else { /* ---- PAL ---- */
8111 /* We don't play around with FSCI in PAL mode */
8112 if(resindex == 0x04) {
8113 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8114 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8116 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8117 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8125 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8129 unsigned short temp;
8131 /* We don't support modes >1024x768 */
8132 if (resindex > 6) return;
8134 temp = CHTVRegData[resindex].Reg[0];
8135 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8136 SiS_SetCH701x(SiS_Pr,0x00,temp);
8138 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8139 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8140 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8141 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8142 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8143 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8145 temp = CHTVRegData[resindex].Reg[7];
8146 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8147 SiS_SetCH701x(SiS_Pr,0x07,temp);
8149 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8150 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8151 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8152 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8153 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8154 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8155 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8156 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8158 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8159 /* D1 should be set for PAL, PAL-N and NTSC-J,
8160 but I won't do that for PAL unless somebody
8161 tells me to do so. Since the BIOS uses
8162 non-default CIV values and blacklevels,
8163 this might be compensated anyway.
8165 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8166 SiS_SetCH701x(SiS_Pr,0x21,temp);
8178 #ifdef SIS315H /* ----------- 315 series only ---------- */
8181 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8183 unsigned short temp;
8185 /* Enable Chrontel 7019 LCD panel backlight */
8186 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8187 if(SiS_Pr->ChipType == SIS_740) {
8188 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8190 temp = SiS_GetCH701x(SiS_Pr,0x66);
8192 SiS_SetCH701x(SiS_Pr,0x66,temp);
8198 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8200 unsigned short temp;
8202 /* Disable Chrontel 7019 LCD panel backlight */
8203 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8204 temp = SiS_GetCH701x(SiS_Pr,0x66);
8206 SiS_SetCH701x(SiS_Pr,0x66,temp);
8211 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8213 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8214 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8215 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8216 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8217 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8218 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8219 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8220 const unsigned char *tableptr = NULL;
8223 /* Set up Power up/down timing */
8225 if(SiS_Pr->ChipType == SIS_740) {
8226 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8227 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8228 else tableptr = table1024_740;
8229 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8230 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8231 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8232 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8233 else tableptr = table1400_740;
8236 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8237 tableptr = table1024_650;
8238 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8239 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8240 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8241 tableptr = table1400_650;
8245 for(i=0; i<5; i++) {
8246 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8251 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8253 const unsigned char *tableptr = NULL;
8254 unsigned short tempbh;
8256 static const unsigned char regtable[] = {
8257 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8258 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8260 static const unsigned char table1024_740[] = {
8261 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8262 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8264 static const unsigned char table1280_740[] = {
8265 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8266 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8268 static const unsigned char table1400_740[] = {
8269 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8270 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8272 static const unsigned char table1600_740[] = {
8273 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8274 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8276 static const unsigned char table1024_650[] = {
8277 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8278 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8280 static const unsigned char table1280_650[] = {
8281 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8282 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8284 static const unsigned char table1400_650[] = {
8285 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8286 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8288 static const unsigned char table1600_650[] = {
8289 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8290 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8293 if(SiS_Pr->ChipType == SIS_740) {
8294 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8295 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8296 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8297 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8300 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8301 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8302 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8303 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8307 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8308 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8309 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8310 if(tempbh == 0xc8) {
8311 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8312 } else if(tempbh == 0xdb) {
8313 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8314 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8315 } else if(tempbh == 0xde) {
8316 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8320 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8323 for(i = 0; i < tempbh; i++) {
8324 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8326 SiS_ChrontelPowerSequencing(SiS_Pr);
8327 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8329 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8331 if(SiS_Pr->ChipType == SIS_740) {
8332 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8334 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8335 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8336 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8338 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8339 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8341 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8346 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8348 unsigned char temp, temp1;
8350 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8351 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8352 temp = SiS_GetCH701x(SiS_Pr,0x47);
8353 temp &= 0x7f; /* Use external VSYNC */
8354 SiS_SetCH701x(SiS_Pr,0x47,temp);
8355 SiS_LongDelay(SiS_Pr, 3);
8356 temp = SiS_GetCH701x(SiS_Pr,0x47);
8357 temp |= 0x80; /* Use internal VSYNC */
8358 SiS_SetCH701x(SiS_Pr,0x47,temp);
8359 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8363 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8365 unsigned short temp;
8367 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8368 if(SiS_Pr->ChipType == SIS_740) {
8369 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8370 temp |= 0x04; /* Invert XCLK phase */
8371 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8373 if(SiS_IsYPbPr(SiS_Pr)) {
8374 temp = SiS_GetCH701x(SiS_Pr,0x01);
8376 temp |= 0x80; /* Enable YPrPb (HDTV) */
8377 SiS_SetCH701x(SiS_Pr,0x01,temp);
8379 if(SiS_IsChScart(SiS_Pr)) {
8380 temp = SiS_GetCH701x(SiS_Pr,0x01);
8382 temp |= 0xc0; /* Enable SCART + CVBS */
8383 SiS_SetCH701x(SiS_Pr,0x01,temp);
8385 if(SiS_Pr->ChipType == SIS_740) {
8386 SiS_ChrontelResetVSync(SiS_Pr);
8387 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8389 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8390 temp = SiS_GetCH701x(SiS_Pr,0x49);
8391 if(SiS_IsYPbPr(SiS_Pr)) {
8392 temp = SiS_GetCH701x(SiS_Pr,0x73);
8394 SiS_SetCH701x(SiS_Pr,0x73,temp);
8396 temp = SiS_GetCH701x(SiS_Pr,0x47);
8398 SiS_SetCH701x(SiS_Pr,0x47,temp);
8399 SiS_LongDelay(SiS_Pr, 2);
8400 temp = SiS_GetCH701x(SiS_Pr,0x47);
8402 SiS_SetCH701x(SiS_Pr,0x47,temp);
8408 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8410 unsigned short temp;
8412 /* Complete power down of LVDS */
8413 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8414 if(SiS_Pr->ChipType == SIS_740) {
8415 SiS_LongDelay(SiS_Pr, 1);
8416 SiS_GenericDelay(SiS_Pr, 5887);
8417 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8418 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8420 SiS_LongDelay(SiS_Pr, 2);
8421 temp = SiS_GetCH701x(SiS_Pr,0x76);
8423 SiS_SetCH701x(SiS_Pr,0x76,temp);
8424 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8430 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8432 unsigned short temp;
8434 if(SiS_Pr->ChipType == SIS_740) {
8436 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8440 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8441 temp = SiS_GetCH701x(SiS_Pr,0x49);
8442 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8445 /* Reset Chrontel 7019 datapath */
8446 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8447 SiS_LongDelay(SiS_Pr, 1);
8448 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8450 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8451 SiS_ChrontelResetVSync(SiS_Pr);
8452 SiS_SetCH701x(SiS_Pr,0x49,temp);
8457 /* Clear/set/clear GPIO */
8458 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8460 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8461 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8463 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8464 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8466 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8467 temp = SiS_GetCH701x(SiS_Pr,0x61);
8469 SiS_SetCH701xForLCD(SiS_Pr);
8474 /* Reset Chrontel 7019 datapath */
8475 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8476 SiS_LongDelay(SiS_Pr, 1);
8477 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8482 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8484 unsigned short temp;
8486 if(SiS_Pr->ChipType == SIS_740) {
8488 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8489 SiS_ChrontelResetVSync(SiS_Pr);
8494 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8495 temp = SiS_GetCH701x(SiS_Pr,0x49);
8497 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8498 temp = SiS_GetCH701x(SiS_Pr,0x47);
8500 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8501 SiS_LongDelay(SiS_Pr, 3);
8502 temp = SiS_GetCH701x(SiS_Pr,0x47);
8504 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8511 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8513 unsigned short temp,temp1;
8515 if(SiS_Pr->ChipType == SIS_740) {
8517 temp = SiS_GetCH701x(SiS_Pr,0x61);
8520 SiS_SetCH701x(SiS_Pr,0x61,temp);
8522 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8523 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8524 SiS_LongDelay(SiS_Pr, 1);
8525 SiS_GenericDelay(SiS_Pr, 5887);
8530 temp = SiS_GetCH701x(SiS_Pr,0x61);
8533 SiS_SetCH701x(SiS_Pr,0x61,temp);
8536 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8537 temp = SiS_GetCH701x(SiS_Pr,0x66);
8539 SiS_SetCH701x(SiS_Pr,0x66,temp);
8541 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8542 SiS_GenericDelay(SiS_Pr, 1023);
8544 SiS_GenericDelay(SiS_Pr, 767);
8548 SiS_GenericDelay(SiS_Pr, 767);
8550 temp = SiS_GetCH701x(SiS_Pr,0x76);
8552 SiS_SetCH701x(SiS_Pr,0x76,temp);
8553 temp = SiS_GetCH701x(SiS_Pr,0x66);
8555 SiS_SetCH701x(SiS_Pr,0x66,temp);
8556 SiS_LongDelay(SiS_Pr, 1);
8562 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8564 unsigned short temp;
8566 SiS_LongDelay(SiS_Pr, 1);
8569 temp = SiS_GetCH701x(SiS_Pr,0x66);
8570 temp &= 0x04; /* PLL stable? -> bail out */
8571 if(temp == 0x04) break;
8573 if(SiS_Pr->ChipType == SIS_740) {
8574 /* Power down LVDS output, PLL normal operation */
8575 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8578 SiS_SetCH701xForLCD(SiS_Pr);
8580 temp = SiS_GetCH701x(SiS_Pr,0x76);
8581 temp &= 0xfb; /* Reset PLL */
8582 SiS_SetCH701x(SiS_Pr,0x76,temp);
8583 SiS_LongDelay(SiS_Pr, 2);
8584 temp = SiS_GetCH701x(SiS_Pr,0x76);
8585 temp |= 0x04; /* PLL normal operation */
8586 SiS_SetCH701x(SiS_Pr,0x76,temp);
8587 if(SiS_Pr->ChipType == SIS_740) {
8588 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8590 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8592 SiS_LongDelay(SiS_Pr, 2);
8595 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8599 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8601 unsigned short temp;
8603 temp = SiS_GetCH701x(SiS_Pr,0x03);
8604 temp |= 0x80; /* Set datapath 1 to TV */
8605 temp &= 0xbf; /* Set datapath 2 to LVDS */
8606 SiS_SetCH701x(SiS_Pr,0x03,temp);
8608 if(SiS_Pr->ChipType == SIS_740) {
8610 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8611 temp &= 0xfb; /* Normal XCLK phase */
8612 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8614 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8616 temp = SiS_GetCH701x(SiS_Pr,0x64);
8617 temp |= 0x40; /* ? Bit not defined */
8618 SiS_SetCH701x(SiS_Pr,0x64,temp);
8620 temp = SiS_GetCH701x(SiS_Pr,0x03);
8621 temp &= 0x3f; /* D1 input to both LVDS and TV */
8622 SiS_SetCH701x(SiS_Pr,0x03,temp);
8624 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8625 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8626 SiS_LongDelay(SiS_Pr, 1);
8627 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8628 SiS_ChrontelResetDB(SiS_Pr);
8629 SiS_ChrontelDoSomething2(SiS_Pr);
8630 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8632 temp = SiS_GetCH701x(SiS_Pr,0x66);
8634 SiS_ChrontelResetDB(SiS_Pr);
8635 SiS_ChrontelDoSomething2(SiS_Pr);
8636 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8642 SiS_ChrontelResetDB(SiS_Pr);
8643 SiS_ChrontelDoSomething2(SiS_Pr);
8644 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8645 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8646 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8651 #endif /* 315 series */
8653 /*********************************************/
8654 /* MAIN: SET CRT2 REGISTER GROUP */
8655 /*********************************************/
8658 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8661 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8663 unsigned short ModeIdIndex, RefreshRateTableIndex;
8665 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8667 if(!SiS_Pr->UseCustomMode) {
8668 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8673 /* Used for shifting CR33 */
8674 SiS_Pr->SiS_SelectCRT2Rate = 4;
8676 SiS_UnLockCRT2(SiS_Pr);
8678 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8680 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8682 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8683 SiS_DisableBridge(SiS_Pr);
8684 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8685 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8687 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8690 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8691 SiS_LockCRT2(SiS_Pr);
8692 SiS_DisplayOn(SiS_Pr);
8696 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8698 /* Set up Panel Link for LVDS and LCDA */
8699 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8700 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8701 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8702 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8703 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8706 #ifdef SIS_XORG_XF86
8708 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8709 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8710 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8711 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8712 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8716 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8717 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8720 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8722 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8724 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8726 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8728 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8729 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8731 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8733 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8735 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8737 /* For 301BDH (Panel link initialization): */
8738 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8740 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8741 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8742 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8745 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8751 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8753 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8755 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8757 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8758 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8759 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8760 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8762 SiS_SetCH701xForLCD(SiS_Pr);
8766 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8767 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8775 if(SiS_Pr->ChipType < SIS_315H) {
8776 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8777 if(SiS_Pr->SiS_UseOEM) {
8778 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8779 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8780 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8783 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8786 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8787 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8788 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8789 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8791 SiS_DisplayOn(SiS_Pr);
8798 if(SiS_Pr->ChipType >= SIS_315H) {
8799 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8800 if(SiS_Pr->ChipType < SIS_661) {
8801 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8802 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8804 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8806 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8811 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8812 SiS_EnableBridge(SiS_Pr);
8815 SiS_DisplayOn(SiS_Pr);
8817 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8818 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8819 /* Disable LCD panel when using TV */
8820 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8822 /* Disable TV when using LCD */
8823 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8827 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8828 SiS_LockCRT2(SiS_Pr);
8835 /*********************************************/
8836 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8837 /*********************************************/
8840 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8842 /* Switch on LCD backlight on SiS30xLV */
8843 SiS_DDC2Delay(SiS_Pr,0xff00);
8844 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8845 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8846 SiS_WaitVBRetrace(SiS_Pr);
8848 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8849 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8854 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8856 /* Switch off LCD backlight on SiS30xLV */
8857 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8858 SiS_DDC2Delay(SiS_Pr,0xff00);
8861 /*********************************************/
8862 /* DDC RELATED FUNCTIONS */
8863 /*********************************************/
8866 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8868 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8869 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8870 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8871 SiS_Pr->SiS_DDC_NData &= 0x0f;
8872 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8877 static unsigned char *
8878 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8881 unsigned short tempah,temp;
8882 unsigned char *mydataptr;
8884 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8885 mydataptr = dataptr;
8887 if(!num) return mydataptr;
8889 SiS_SetStop(SiS_Pr);
8890 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8892 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8893 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8894 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8895 if(temp) continue; /* (ERROR: no ack) */
8896 tempah = *mydataptr++;
8897 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8898 if(temp) continue; /* (ERROR: no ack) */
8899 for(j=0; j<num; j++) {
8900 tempah = *mydataptr++;
8901 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8905 if(SiS_SetStop(SiS_Pr)) continue;
8912 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8914 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8915 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8916 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8917 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8918 SiS_SetupDDCN(SiS_Pr);
8920 SiS_SetSwitchDDC2(SiS_Pr);
8923 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8924 if(!dataptr) return FALSE;
8926 #ifdef SIS_XORG_XF86
8928 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
8935 /* The Chrontel 700x is connected to the 630/730 via
8936 * the 630/730's DDC/I2C port.
8938 * On 630(S)T chipset, the index changed from 0x11 to
8939 * 0x0a, possibly for working around the DDC problems
8943 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8945 unsigned short temp, i;
8947 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8949 SiS_SetStop(SiS_Pr);
8950 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8952 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8953 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8954 if(temp) continue; /* (ERROR: no ack) */
8955 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
8956 if(temp) continue; /* (ERROR: no ack) */
8957 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
8958 if(temp) continue; /* (ERROR: no ack) */
8959 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
8960 SiS_Pr->SiS_ChrontelInit = 1;
8966 /* Write to Chrontel 700x */
8968 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8970 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8972 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8974 if(!(SiS_Pr->SiS_ChrontelInit)) {
8975 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8976 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8977 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8978 SiS_SetupDDCN(SiS_Pr);
8981 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
8982 (!(SiS_Pr->SiS_ChrontelInit)) ) {
8983 SiS_Pr->SiS_DDC_Index = 0x0a;
8984 SiS_Pr->SiS_DDC_Data = 0x80;
8985 SiS_Pr->SiS_DDC_Clk = 0x40;
8986 SiS_SetupDDCN(SiS_Pr);
8988 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
8992 /* Write to Chrontel 701x */
8993 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
8995 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8997 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8998 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8999 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9000 SiS_SetupDDCN(SiS_Pr);
9001 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9002 SiS_SetChReg(SiS_Pr, reg, val, 0);
9005 #ifdef SIS_LINUX_KERNEL
9009 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9011 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9012 SiS_SetCH700x(SiS_Pr, reg, val);
9014 SiS_SetCH701x(SiS_Pr, reg, val);
9017 static unsigned short
9018 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9020 unsigned short tempah, temp, i;
9022 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9024 SiS_SetStop(SiS_Pr);
9025 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9027 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9028 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9029 if(temp) continue; /* (ERROR: no ack) */
9030 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
9031 if(temp) continue; /* (ERROR: no ack) */
9032 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9033 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9034 if(temp) continue; /* (ERROR: no ack) */
9035 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
9036 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9037 SiS_Pr->SiS_ChrontelInit = 1;
9043 /* Read from Chrontel 700x */
9044 /* Parameter is [Register no (S7-S0)] */
9046 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9048 unsigned short result;
9050 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9052 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9054 if(!(SiS_Pr->SiS_ChrontelInit)) {
9055 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9056 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9057 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9058 SiS_SetupDDCN(SiS_Pr);
9061 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9063 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9064 (!SiS_Pr->SiS_ChrontelInit) ) {
9066 SiS_Pr->SiS_DDC_Index = 0x0a;
9067 SiS_Pr->SiS_DDC_Data = 0x80;
9068 SiS_Pr->SiS_DDC_Clk = 0x40;
9069 SiS_SetupDDCN(SiS_Pr);
9071 result = SiS_GetChReg(SiS_Pr,0x80);
9076 /* Read from Chrontel 701x */
9077 /* Parameter is [Register no (S7-S0)] */
9079 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9081 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9082 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9083 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9084 SiS_SetupDDCN(SiS_Pr);
9085 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9087 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9089 return SiS_GetChReg(SiS_Pr,0);
9092 /* Read from Chrontel 70xx */
9093 /* Parameter is [Register no (S7-S0)] */
9094 #ifdef SIS_LINUX_KERNEL
9098 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9100 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9101 return SiS_GetCH700x(SiS_Pr, tempbx);
9103 return SiS_GetCH701x(SiS_Pr, tempbx);
9107 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9108 unsigned char myor, unsigned short myand)
9110 unsigned short tempbl;
9112 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9113 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9116 /* Our own DDC functions */
9117 #ifndef SIS_XORG_XF86
9121 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9122 unsigned short adaptnum, unsigned short DDCdatatype, BOOLEAN checkcr32,
9123 unsigned int VBFlags2)
9125 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9126 unsigned char flag, cr32;
9127 unsigned short temp = 0, myadaptnum = adaptnum;
9130 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9131 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9134 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9136 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9138 SiS_Pr->SiS_DDC_SecAddr = 0;
9139 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9140 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9141 SiS_Pr->SiS_DDC_Index = 0x11;
9144 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9147 if(VBFlags2 & VB2_SISBRIDGE) {
9148 if(myadaptnum == 0) {
9149 if(!(cr32 & 0x20)) {
9151 if(!(cr32 & 0x10)) {
9153 if(!(cr32 & 0x08)) {
9162 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9164 if(myadaptnum != 0) {
9166 if(VBFlags2 & VB2_SISBRIDGE) {
9167 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9168 SiS_Pr->SiS_DDC_Index = 0x0f;
9172 if(!(VBFlags2 & VB2_301)) {
9173 if((cr32 & 0x80) && (checkcr32)) {
9174 if(myadaptnum >= 1) {
9175 if(!(cr32 & 0x08)) {
9177 if(!(cr32 & 0x10)) return 0xFFFF;
9183 temp = 4 - (myadaptnum * 2);
9186 } else { /* 315/330 series */
9188 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9190 if(VBFlags2 & VB2_SISBRIDGE) {
9191 if(myadaptnum == 2) {
9196 if(myadaptnum == 1) {
9198 if(VBFlags2 & VB2_SISBRIDGE) {
9199 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9200 SiS_Pr->SiS_DDC_Index = 0x0f;
9204 if((cr32 & 0x80) && (checkcr32)) {
9205 if(myadaptnum >= 1) {
9206 if(!(cr32 & 0x08)) {
9208 if(!(cr32 & 0x10)) return 0xFFFF;
9214 if(myadaptnum == 1) {
9216 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9222 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9223 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9225 SiS_SetupDDCN(SiS_Pr);
9227 #ifdef SIS_XORG_XF86
9229 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9230 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9236 static unsigned short
9237 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9239 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9240 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9243 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9249 static unsigned short
9250 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9252 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9253 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9259 static unsigned short
9260 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9262 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9263 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9268 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9270 SiS_SetSCLKLow(SiS_Pr);
9272 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9273 SiS_Pr->SiS_DDC_Index,
9274 SiS_Pr->SiS_DDC_NData,
9275 SiS_Pr->SiS_DDC_Data);
9277 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9278 SiS_Pr->SiS_DDC_Index,
9279 SiS_Pr->SiS_DDC_NData,
9282 SiS_SetSCLKHigh(SiS_Pr);
9285 static unsigned short
9286 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9288 unsigned char mask, value;
9289 unsigned short temp, ret=0;
9290 BOOLEAN failed = FALSE;
9292 SiS_SetSwitchDDC2(SiS_Pr);
9293 if(SiS_PrepareDDC(SiS_Pr)) {
9294 SiS_SetStop(SiS_Pr);
9295 #ifdef SIS_XORG_XF86
9297 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9304 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9305 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9306 SiS_SendACK(SiS_Pr, 0);
9313 #ifdef SIS_XORG_XF86
9315 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9320 if(failed == FALSE) {
9321 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9322 SiS_SendACK(SiS_Pr, 1);
9324 if(temp == value) ret = 0;
9327 #ifdef SIS_XORG_XF86
9329 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9332 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9333 if(temp == 0x30) ret = 0;
9337 SiS_SetStop(SiS_Pr);
9341 #ifndef SIS_XORG_XF86
9345 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9347 unsigned short flag;
9350 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9351 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9352 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9353 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9354 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9355 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9356 if(!(flag & 0x1a)) flag = 0;
9360 #ifndef SIS_XORG_XF86
9364 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9366 unsigned short flag, length, i;
9367 unsigned char chksum,gotcha;
9369 if(DDCdatatype > 4) return 0xFFFF;
9372 SiS_SetSwitchDDC2(SiS_Pr);
9373 if(!(SiS_PrepareDDC(SiS_Pr))) {
9375 if(DDCdatatype != 1) length = 255;
9378 for(i=0; i<length; i++) {
9379 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9380 chksum += buffer[i];
9381 gotcha |= buffer[i];
9382 SiS_SendACK(SiS_Pr, 0);
9384 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9385 chksum += buffer[i];
9386 SiS_SendACK(SiS_Pr, 1);
9387 if(gotcha) flag = (unsigned short)chksum;
9392 SiS_SetStop(SiS_Pr);
9396 /* Our private DDC functions
9398 It complies somewhat with the corresponding VESA function
9399 in arguments and return values.
9401 Since this is probably called before the mode is changed,
9402 we use our pre-detected pSiS-values instead of SiS_Pr as
9403 regards chipset and video bridge type.
9406 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9407 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9408 LCDA is CRT1, but DDC is read from CRT2 port.
9409 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9410 buffer: ptr to 256 data bytes which will be filled with read data.
9412 Returns 0xFFFF if error, otherwise
9413 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9414 if DDCdatatype = 0: Returns supported DDC modes
9418 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9419 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9420 unsigned int VBFlags2)
9422 unsigned char sr1f, cr17=1;
9423 unsigned short result;
9431 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9434 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE, VBFlags2) == 0xFFFF)
9437 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9438 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9439 if(VGAEngine == SIS_300_VGA) {
9440 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9442 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9443 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9444 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9447 if((sr1f) || (!cr17)) {
9448 SiS_WaitRetrace1(SiS_Pr);
9449 SiS_WaitRetrace1(SiS_Pr);
9450 SiS_WaitRetrace1(SiS_Pr);
9451 SiS_WaitRetrace1(SiS_Pr);
9454 if(DDCdatatype == 0) {
9455 result = SiS_ProbeDDC(SiS_Pr);
9457 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9458 if((!result) && (DDCdatatype == 1)) {
9459 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9460 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9461 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9462 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9463 (buffer[0x12] == 1)) {
9464 if(!SiS_Pr->DDCPortMixup) {
9466 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9468 if(buffer[0x14] & 0x80) result = 0xFFFE;
9474 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9475 if(VGAEngine == SIS_300_VGA) {
9476 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9481 /* Generic I2C functions for Chrontel & DDC --------- */
9484 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9486 SiS_SetSCLKHigh(SiS_Pr);
9487 SiS_WaitRetrace1(SiS_Pr);
9489 SiS_SetSCLKLow(SiS_Pr);
9490 SiS_WaitRetrace1(SiS_Pr);
9494 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9496 SiS_WaitRetrace1(SiS_Pr);
9497 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9500 /* Set I2C start condition */
9501 /* This is done by a SD high-to-low transition while SC is high */
9502 static unsigned short
9503 SiS_SetStart(struct SiS_Private *SiS_Pr)
9505 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9506 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9507 SiS_Pr->SiS_DDC_Index,
9508 SiS_Pr->SiS_DDC_NData,
9509 SiS_Pr->SiS_DDC_Data); /* SD->high */
9510 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9511 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9512 SiS_Pr->SiS_DDC_Index,
9513 SiS_Pr->SiS_DDC_NData,
9514 0x00); /* SD->low = start condition */
9515 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9519 /* Set I2C stop condition */
9520 /* This is done by a SD low-to-high transition while SC is high */
9521 static unsigned short
9522 SiS_SetStop(struct SiS_Private *SiS_Pr)
9524 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9525 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9526 SiS_Pr->SiS_DDC_Index,
9527 SiS_Pr->SiS_DDC_NData,
9528 0x00); /* SD->low */
9529 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9530 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9531 SiS_Pr->SiS_DDC_Index,
9532 SiS_Pr->SiS_DDC_NData,
9533 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9534 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9538 /* Write 8 bits of data */
9539 static unsigned short
9540 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9542 unsigned short i,flag,temp;
9545 for(i = 0; i < 8; i++) {
9546 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9548 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9549 SiS_Pr->SiS_DDC_Index,
9550 SiS_Pr->SiS_DDC_NData,
9551 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9553 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9554 SiS_Pr->SiS_DDC_Index,
9555 SiS_Pr->SiS_DDC_NData,
9556 0x00); /* Write bit (0) to SD */
9558 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9561 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9565 static unsigned short
9566 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9568 unsigned short i, temp, getdata;
9571 for(i = 0; i < 8; i++) {
9573 SiS_SetSCLKLow(SiS_Pr);
9574 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9575 SiS_Pr->SiS_DDC_Index,
9576 SiS_Pr->SiS_DDC_NData,
9577 SiS_Pr->SiS_DDC_Data);
9578 SiS_SetSCLKHigh(SiS_Pr);
9579 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9580 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9585 static unsigned short
9586 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9588 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9589 SiS_Pr->SiS_DDC_Index,
9590 SiS_Pr->SiS_DDC_NClk,
9591 0x00); /* SetSCLKLow() */
9592 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9596 static unsigned short
9597 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9599 unsigned short temp, watchdog=1000;
9601 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9602 SiS_Pr->SiS_DDC_Index,
9603 SiS_Pr->SiS_DDC_NClk,
9604 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9606 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9607 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9609 #ifdef SIS_XORG_XF86
9611 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
9616 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9620 /* Check I2C acknowledge */
9621 /* Returns 0 if ack ok, non-0 if ack not ok */
9622 static unsigned short
9623 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9625 unsigned short tempah;
9627 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9628 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9629 SiS_Pr->SiS_DDC_Index,
9630 SiS_Pr->SiS_DDC_NData,
9631 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9632 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9633 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9634 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9635 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9639 /* End of I2C functions ----------------------- */
9642 /* =============== SiS 315/330 O.E.M. ================= */
9646 static unsigned short
9647 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9649 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9650 unsigned short romptr;
9652 if(SiS_Pr->ChipType < SIS_330) {
9653 romptr = SISGETROMW(0x128);
9654 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9655 romptr = SISGETROMW(0x12a);
9657 romptr = SISGETROMW(0x1a8);
9658 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9659 romptr = SISGETROMW(0x1aa);
9664 static unsigned short
9665 GetLCDromptr(struct SiS_Private *SiS_Pr)
9667 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9668 unsigned short romptr;
9670 if(SiS_Pr->ChipType < SIS_330) {
9671 romptr = SISGETROMW(0x120);
9672 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9673 romptr = SISGETROMW(0x122);
9675 romptr = SISGETROMW(0x1a0);
9676 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9677 romptr = SISGETROMW(0x1a2);
9682 static unsigned short
9683 GetTVromptr(struct SiS_Private *SiS_Pr)
9685 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9686 unsigned short romptr;
9688 if(SiS_Pr->ChipType < SIS_330) {
9689 romptr = SISGETROMW(0x114);
9690 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9691 romptr = SISGETROMW(0x11a);
9693 romptr = SISGETROMW(0x194);
9694 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9695 romptr = SISGETROMW(0x19a);
9700 static unsigned short
9701 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9703 unsigned short index;
9705 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9706 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9707 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9710 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9711 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9717 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9718 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9719 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9720 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9721 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9723 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9727 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9728 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9732 static unsigned short
9733 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9735 unsigned short index;
9737 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9738 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9739 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9743 static unsigned short
9744 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9746 unsigned short index;
9749 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9750 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9752 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9756 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9757 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9765 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9767 unsigned short index = 0, temp = 0;
9769 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9770 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9771 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9772 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9773 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9775 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9776 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9779 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9780 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9781 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9787 return (unsigned int)(index | (temp << 16));
9791 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9793 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9798 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9800 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9805 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9809 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9810 if(SiS_Pr->SiS_ROMNew) {
9811 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9812 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9813 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9814 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9816 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9817 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9818 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9819 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9822 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9828 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9830 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9831 unsigned short delay=0,index,myindex,temp,romptr=0;
9832 BOOLEAN dochiptest = TRUE;
9834 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9835 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9837 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9840 /* Find delay (from ROM, internal tables, PCI subsystem) */
9842 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9844 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9845 romptr = GetRAMDACromptr(SiS_Pr);
9847 if(romptr) delay = ROMAddr[romptr];
9850 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9853 } else if(IS_SIS740) {
9855 } else if(SiS_Pr->ChipType < SIS_330) {
9860 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9865 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9867 BOOLEAN gotitfrompci = FALSE;
9869 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9871 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9872 if(SiS_Pr->PDC != -1) {
9873 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9874 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9878 if(SiS_Pr->PDCA != -1) {
9879 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9880 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9887 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9888 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9890 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9893 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9896 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9898 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9901 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9902 if(IS_SIS740) delay = 0x01;
9905 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9910 /* This is a piece of typical SiS crap: They code the OEM LCD
9911 * delay into the code, at no defined place in the BIOS.
9912 * We now have to start doing a PCI subsystem check here.
9915 switch(SiS_Pr->SiS_CustomT) {
9916 case CUT_COMPAQ1280:
9917 case CUT_COMPAQ12802:
9918 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9919 gotitfrompci = TRUE;
9925 case CUT_CLEVO14002:
9926 gotitfrompci = TRUE;
9931 case CUT_CLEVO10242:
9932 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9933 gotitfrompci = TRUE;
9936 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9942 /* Could we find it through the PCI ID? If no, use ROM or table */
9946 index = GetLCDPtrIndexBIOS(SiS_Pr);
9947 myindex = GetLCDPtrIndex(SiS_Pr);
9949 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9951 if(SiS_IsNotM650orLater(SiS_Pr)) {
9953 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9954 /* Always use the second pointer on 650; some BIOSes */
9955 /* still carry old 301 data at the first location */
9956 /* romptr = SISGETROMW(0x120); */
9957 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9958 romptr = SISGETROMW(0x122);
9960 delay = ROMAddr[(romptr + index)];
9962 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9967 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
9968 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
9969 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
9973 } else if(SiS_Pr->SiS_UseROM &&
9974 (!(SiS_Pr->SiS_ROMNew)) &&
9975 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
9976 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
9977 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
9978 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
9979 ((romptr = GetLCDromptr(SiS_Pr)))) {
9981 /* Data for 1280x1024 wrong in 301B BIOS */
9982 /* Data for 1600x1200 wrong in 301C BIOS */
9983 delay = ROMAddr[(romptr + index)];
9985 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9987 if(IS_SIS740) delay = 0x03;
9992 delay = SiS310_LCDDelayCompensation_301[myindex];
9993 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9994 if(IS_SIS740) delay = 0x01;
9995 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
9996 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9997 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9998 if(IS_SIS740) delay = 0x01; /* ? */
10000 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10001 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10002 if(IS_SIS740) delay = 0x01;
10003 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10008 } /* got it from PCI */
10010 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10011 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10012 dochiptest = FALSE;
10015 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10017 index = GetTVPtrIndex(SiS_Pr);
10019 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10021 if(SiS_IsNotM650orLater(SiS_Pr)) {
10023 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10024 /* Always use the second pointer on 650; some BIOSes */
10025 /* still carry old 301 data at the first location */
10026 /* romptr = SISGETROMW(0x114); */
10027 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10028 romptr = SISGETROMW(0x11a);
10029 if(!romptr) return;
10030 delay = ROMAddr[romptr + index];
10034 delay = SiS310_TVDelayCompensation_301B[index];
10040 switch(SiS_Pr->SiS_CustomT) {
10041 case CUT_COMPAQ1280:
10042 case CUT_COMPAQ12802:
10043 case CUT_CLEVO1400:
10044 case CUT_CLEVO14002:
10046 dochiptest = FALSE;
10048 case CUT_CLEVO1024:
10049 case CUT_CLEVO10242:
10051 dochiptest = FALSE;
10054 delay = SiS310_TVDelayCompensation_651301LV[index];
10055 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10056 delay = SiS310_TVDelayCompensation_651302LV[index];
10061 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10063 romptr = GetTVromptr(SiS_Pr);
10064 if(!romptr) return;
10065 delay = ROMAddr[romptr + index];
10067 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10069 delay = SiS310_TVDelayCompensation_LVDS[index];
10073 delay = SiS310_TVDelayCompensation_301[index];
10074 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10076 delay = SiS310_TVDelayCompensation_740301B[index];
10077 /* LV: use 301 data? BIOS bug? */
10079 delay = SiS310_TVDelayCompensation_301B[index];
10080 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10086 if(SiS_LCDAEnabled(SiS_Pr)) {
10088 dochiptest = FALSE;
10095 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10097 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10099 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10100 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
10103 } else if(temp == 6) {
10106 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
10109 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10113 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10117 } else { /* LVDS */
10119 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10120 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10122 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10124 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10126 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10135 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10137 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10138 unsigned short index,temp,temp1,romptr=0;
10140 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10143 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10145 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10147 temp = GetTVPtrIndex(SiS_Pr);
10148 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10151 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10152 if(SiS_Pr->ChipType >= SIS_661) {
10153 temp1 = GetOEMTVPtr661(SiS_Pr);
10155 romptr = SISGETROMW(0x260);
10156 if(SiS_Pr->ChipType >= SIS_760) {
10157 romptr = SISGETROMW(0x360);
10159 } else if(SiS_Pr->ChipType >= SIS_330) {
10160 romptr = SISGETROMW(0x192);
10162 romptr = SISGETROMW(0x112);
10168 temp = ROMAddr[romptr + temp1 + index];
10170 temp = SiS310_TVAntiFlick1[temp][index];
10174 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10178 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10180 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10181 unsigned short index,temp,temp1,romptr=0;
10183 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10186 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10188 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10190 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10191 if(SiS_Pr->ChipType >= SIS_661) {
10192 romptr = SISGETROMW(0x26c);
10193 if(SiS_Pr->ChipType >= SIS_760) {
10194 romptr = SISGETROMW(0x36c);
10196 temp1 = GetOEMTVPtr661(SiS_Pr);
10198 } else if(SiS_Pr->ChipType >= SIS_330) {
10199 romptr = SISGETROMW(0x1a4);
10201 romptr = SISGETROMW(0x124);
10207 temp = ROMAddr[romptr + temp1 + index];
10209 temp = SiS310_TVEdge1[temp][index];
10212 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10216 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10218 unsigned short index, temp, i, j;
10220 if(ModeNo <= 0x13) {
10221 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10223 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10226 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10228 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10229 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10230 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10231 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10233 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10234 for(i=0x35, j=0; i<=0x38; i++, j++) {
10235 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10237 for(i=0x48; i<=0x4A; i++, j++) {
10238 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10241 for(i=0x35, j=0; i<=0x38; i++, j++) {
10242 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10248 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10250 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10251 unsigned short index,temp,i,j,resinfo,romptr=0;
10252 unsigned int lindex;
10254 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10256 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10257 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10259 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10260 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10262 for(j=0, i=0x31; i<=0x34; i++, j++) {
10263 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10268 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10269 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10272 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10274 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10277 temp = GetTVPtrIndex(SiS_Pr);
10278 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10279 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10281 if(SiS_Pr->SiS_UseROM) {
10282 romptr = SISGETROMW(0x116);
10283 if(SiS_Pr->ChipType >= SIS_330) {
10284 romptr = SISGETROMW(0x196);
10286 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10287 romptr = SISGETROMW(0x11c);
10288 if(SiS_Pr->ChipType >= SIS_330) {
10289 romptr = SISGETROMW(0x19c);
10291 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10292 romptr = SISGETROMW(0x116);
10293 if(SiS_Pr->ChipType >= SIS_330) {
10294 romptr = SISGETROMW(0x196);
10300 romptr += (temp << 2);
10301 for(j=0, i=0x31; i<=0x34; i++, j++) {
10302 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10306 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10307 for(j=0, i=0x31; i<=0x34; i++, j++) {
10308 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10309 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10310 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10311 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10313 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10317 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10318 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10319 if((resinfo == SIS_RI_640x480) ||
10320 (resinfo == SIS_RI_800x600)) {
10321 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10322 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10323 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10324 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10325 } else if(resinfo == SIS_RI_1024x768) {
10326 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10327 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10328 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10329 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10336 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10337 unsigned short ModeIdIndex, unsigned short RTI)
10339 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10340 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10342 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10345 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10346 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10348 if(SiS_Pr->SiS_ROMNew) {
10349 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10350 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10351 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10353 if(SiS_Pr->UseCustomMode) {
10354 index = SiS_Pr->CSRClock;
10355 } else if(ModeNo > 0x13) {
10356 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10357 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10359 if(index < 25) index = 25;
10360 index = ((index / 25) - 1) << 1;
10361 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10364 romptr = SISGETROMW(0x104);
10365 delay = ROMAddr[romptr + index];
10366 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10367 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10368 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10370 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10371 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10377 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10379 if(SiS_Pr->UseCustomMode) delay = 0x04;
10380 else if(ModeNo <= 0x13) delay = 0x04;
10381 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10382 delay |= (delay << 8);
10384 if(SiS_Pr->ChipType >= XGI_20) {
10387 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10390 if(SiS_Pr->SiS_XGIROM) {
10391 index = GetTVPtrIndex(SiS_Pr);
10392 if((romptr = SISGETROMW(0x35e))) {
10393 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10394 delay |= (delay << 8);
10398 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10399 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10405 } else if(SiS_Pr->ChipType >= SIS_340) {
10408 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10411 /* TODO (eventually) */
10413 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10417 index = GetOEMTVPtr661(SiS_Pr);
10418 if(SiS_Pr->SiS_ROMNew) {
10419 romptr = SISGETROMW(0x106);
10420 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10421 delay = ROMAddr[romptr + index];
10424 if(index > 3) delay = 0;
10427 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10429 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10431 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10432 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10434 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10436 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10437 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10438 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10442 /* TMDS: Set our own, since BIOS has no idea */
10443 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10444 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10445 switch(SiS_Pr->SiS_LCDResInfo) {
10446 case Panel_1024x768: delay = 0x0008; break;
10447 case Panel_1280x720: delay = 0x0004; break;
10448 case Panel_1280x768:
10449 case Panel_1280x768_2:delay = 0x0004; break;
10450 case Panel_1280x800:
10451 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10452 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10453 case Panel_1280x1024: delay = 0x1e04; break;
10454 case Panel_1400x1050: delay = 0x0004; break;
10455 case Panel_1600x1200: delay = 0x0400; break;
10456 case Panel_1680x1050: delay = 0x0e04; break;
10458 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10460 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10462 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10464 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10472 /* Override by detected or user-set values */
10473 /* (but only if, for some reason, we can't read value from BIOS) */
10474 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10475 delay = SiS_Pr->PDC & 0x1f;
10477 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10478 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10485 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10487 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10488 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10491 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10496 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10498 unsigned short infoflag;
10499 unsigned char temp;
10501 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10503 if(ModeNo <= 0x13) {
10504 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10505 } else if(SiS_Pr->UseCustomMode) {
10506 infoflag = SiS_Pr->CInfoFlag;
10508 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10511 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10512 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10517 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10518 temp = (infoflag >> 6) | 0x0c;
10519 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10521 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10523 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10526 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10528 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10530 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10531 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10533 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10540 SetPanelParms661(struct SiS_Private *SiS_Pr)
10542 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10543 unsigned short romptr, temp1, temp2;
10545 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10546 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10549 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10550 if(SiS_Pr->LVDSHL != -1) {
10551 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10555 if(SiS_Pr->SiS_ROMNew) {
10557 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10558 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10559 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10561 if(SiS_Pr->LVDSHL != -1) {
10565 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10567 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10568 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10569 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10577 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10579 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10580 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10581 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10582 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10583 SetPanelParms661(SiS_Pr);
10586 SetDelayComp(SiS_Pr,ModeNo);
10589 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10590 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10591 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10592 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10593 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10594 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10600 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10601 unsigned short ModeIdIndex, unsigned short RRTI)
10603 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10605 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10607 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10608 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10609 SetPanelParms661(SiS_Pr);
10612 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10613 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10614 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10615 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10616 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10617 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10624 * This finalizes some CRT2 registers for the very panel used.
10625 * If we have a backup if these registers, we use it; otherwise
10626 * we set the register according to most BIOSes. However, this
10627 * function looks quite different in every BIOS, so you better
10628 * pray that we have a backup...
10631 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10633 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10634 unsigned short resinfo,modeflag;
10636 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10637 if(SiS_Pr->SiS_ROMNew) return;
10639 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10640 if(SiS_Pr->LVDSHL != -1) {
10641 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10645 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10646 if(SiS_Pr->UseCustomMode) return;
10648 switch(SiS_Pr->SiS_CustomT) {
10649 case CUT_COMPAQ1280:
10650 case CUT_COMPAQ12802:
10651 case CUT_CLEVO1400:
10652 case CUT_CLEVO14002:
10656 if(ModeNo <= 0x13) {
10657 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10658 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10660 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10661 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10665 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10666 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10667 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10669 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10674 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10675 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10676 /* Maybe all panels? */
10677 if(SiS_Pr->LVDSHL == -1) {
10678 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10684 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10685 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10686 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10687 if(SiS_Pr->LVDSHL == -1) {
10688 /* Maybe all panels? */
10689 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10691 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10692 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10694 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10695 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10696 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10697 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10705 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10706 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10707 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10708 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10710 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10712 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10714 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10715 if(SiS_Pr->LVDSHL == -1) {
10716 /* Maybe ACER only? */
10717 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10720 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10721 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10722 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10723 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10724 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10725 if(tempch == 0x03) {
10726 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10727 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10728 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10729 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10731 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
10732 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10733 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10734 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10735 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10736 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10737 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10738 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10739 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10740 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10741 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10742 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10743 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10744 if(ModeNo <= 0x13) {
10745 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10746 if((resinfo == 0) || (resinfo == 2)) return;
10747 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10748 if((resinfo == 1) || (resinfo == 3)) return;
10750 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10751 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10752 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10754 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10756 temp = tempbx & 0xff;
10757 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10758 temp = (tempbx >> 8) & 0x03;
10759 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10762 } else if(ModeNo <= 0x13) {
10764 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10765 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10766 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10767 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10769 if(!(modeflag & HalfDCLK)) {
10770 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10771 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10772 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10773 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10774 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10775 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10776 if(ModeNo == 0x12) {
10779 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10780 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10781 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10782 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10783 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10784 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10787 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10788 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10791 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10799 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10803 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10804 tempbx = (tempbh << 8) | tempbl;
10805 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10806 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10807 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10810 if(tempbx > 770) tempbx = 770;
10811 if(SiS_Pr->SiS_VGAVDE < 600) {
10812 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10813 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10814 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10820 temp = tempbx & 0xff;
10821 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10822 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10823 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10830 /* ================= SiS 300 O.E.M. ================== */
10835 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10836 unsigned short RefTabIndex)
10838 unsigned short crt2crtc=0, modeflag, myindex=0;
10839 unsigned char temp;
10842 if(ModeNo <= 0x13) {
10843 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10844 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10846 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10847 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10852 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10853 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10856 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10857 if(modeflag & HalfDCLK) myindex = 1;
10859 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10860 for(i=0; i<7; i++) {
10861 if(barco_p1[myindex][crt2crtc][i][0]) {
10862 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10863 barco_p1[myindex][crt2crtc][i][0],
10864 barco_p1[myindex][crt2crtc][i][2],
10865 barco_p1[myindex][crt2crtc][i][1]);
10869 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10871 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10873 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10878 static unsigned short
10879 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10881 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10882 unsigned short tempbx=0,romptr=0;
10883 static const unsigned char customtable300[] = {
10884 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10885 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10887 static const unsigned char customtable630[] = {
10888 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10889 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10892 if(SiS_Pr->ChipType == SIS_300) {
10894 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10895 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10897 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10898 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10899 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10901 if(SiS_Pr->SiS_UseROM) {
10902 if(ROMAddr[0x235] & 0x80) {
10903 tempbx = SiS_Pr->SiS_LCDTypeInfo;
10905 romptr = SISGETROMW(0x255);
10906 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10907 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10908 if(tempbx == 0xFF) return 0xFFFF;
10911 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10918 if(SiS_Pr->SiS_UseROM) {
10919 romptr = SISGETROMW(0x255);
10920 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10921 else tempbx = 0xff;
10923 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10925 if(tempbx == 0xFF) return 0xFFFF;
10927 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10928 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10931 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10932 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10933 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10941 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10943 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10944 unsigned short index,temp,romptr=0;
10946 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10948 if(SiS_Pr->SiS_UseROM) {
10949 if(!(ROMAddr[0x237] & 0x01)) return;
10950 if(!(ROMAddr[0x237] & 0x02)) return;
10951 romptr = SISGETROMW(0x24b);
10954 /* The Panel Compensation Delay should be set according to tables
10955 * here. Unfortunately, various BIOS versions don't care about
10956 * a uniform way using eg. ROM byte 0x220, but use different
10957 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10958 * Thus we don't set this if the user selected a custom pdc or if
10959 * we otherwise detected a valid pdc.
10961 if(SiS_Pr->PDC != -1) return;
10963 temp = GetOEMLCDPtr(SiS_Pr, 0);
10965 if(SiS_Pr->UseCustomMode)
10968 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
10970 if(SiS_Pr->ChipType != SIS_300) {
10972 romptr += (temp * 2);
10973 romptr = SISGETROMW(romptr);
10975 temp = ROMAddr[romptr];
10977 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10978 temp = SiS300_OEMLCDDelay2[temp][index];
10980 temp = SiS300_OEMLCDDelay3[temp][index];
10984 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
10986 romptr += (temp * 2);
10987 romptr = SISGETROMW(romptr);
10989 temp = ROMAddr[romptr];
10991 temp = SiS300_OEMLCDDelay5[temp][index];
10994 if(SiS_Pr->SiS_UseROM) {
10995 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
10997 romptr += (temp * 2);
10998 romptr = SISGETROMW(romptr);
11000 temp = ROMAddr[romptr];
11002 temp = SiS300_OEMLCDDelay4[temp][index];
11005 temp = SiS300_OEMLCDDelay4[temp][index];
11010 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11014 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11016 #if 0 /* Unfinished; Data table missing */
11017 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11018 unsigned short index,temp;
11020 if((SiS_Pr->SiS_UseROM) {
11021 if(!(ROMAddr[0x237] & 0x01)) return;
11022 if(!(ROMAddr[0x237] & 0x04)) return;
11023 /* No rom pointer in BIOS header! */
11026 temp = GetOEMLCDPtr(SiS_Pr, 1);
11027 if(temp == 0xFFFF) return;
11029 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11030 for(i=0x14, j=0; i<=0x17; i++, j++) {
11031 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11033 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11035 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11036 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11037 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11038 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11039 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11040 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11045 static unsigned short
11046 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11048 unsigned short index;
11051 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11052 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11053 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11054 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11055 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11057 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11058 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11064 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11066 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11067 unsigned short index,temp,romptr=0;
11069 if(SiS_Pr->SiS_UseROM) {
11070 if(!(ROMAddr[0x238] & 0x01)) return;
11071 if(!(ROMAddr[0x238] & 0x02)) return;
11072 romptr = SISGETROMW(0x241);
11075 temp = GetOEMTVPtr(SiS_Pr);
11077 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11080 romptr += (temp * 2);
11081 romptr = SISGETROMW(romptr);
11083 temp = ROMAddr[romptr];
11085 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11086 temp = SiS300_OEMTVDelay301[temp][index];
11088 temp = SiS300_OEMTVDelayLVDS[temp][index];
11092 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11096 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11098 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11099 unsigned short index,temp,romptr=0;
11101 if(SiS_Pr->SiS_UseROM) {
11102 if(!(ROMAddr[0x238] & 0x01)) return;
11103 if(!(ROMAddr[0x238] & 0x04)) return;
11104 romptr = SISGETROMW(0x243);
11107 temp = GetOEMTVPtr(SiS_Pr);
11109 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11112 romptr += (temp * 2);
11113 romptr = SISGETROMW(romptr);
11115 temp = ROMAddr[romptr];
11117 temp = SiS300_OEMTVFlicker[temp][index];
11120 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11124 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11126 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11127 unsigned short index,i,j,temp,romptr=0;
11129 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11131 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11133 if(SiS_Pr->SiS_UseROM) {
11134 if(!(ROMAddr[0x238] & 0x01)) return;
11135 if(!(ROMAddr[0x238] & 0x08)) return;
11136 romptr = SISGETROMW(0x245);
11139 temp = GetOEMTVPtr(SiS_Pr);
11141 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11143 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11144 for(i=0x31, j=0; i<=0x34; i++, j++) {
11145 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11149 romptr += (temp * 2);
11150 romptr = SISGETROMW(romptr);
11151 romptr += (index * 4);
11152 for(i=0x31, j=0; i<=0x34; i++, j++) {
11153 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11156 for(i=0x31, j=0; i<=0x34; i++, j++) {
11157 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11164 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11166 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11167 unsigned short index,temp,i,j,romptr=0;
11169 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11171 if(SiS_Pr->SiS_UseROM) {
11172 if(!(ROMAddr[0x238] & 0x01)) return;
11173 if(!(ROMAddr[0x238] & 0x10)) return;
11174 romptr = SISGETROMW(0x247);
11177 temp = GetOEMTVPtr(SiS_Pr);
11179 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11180 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11181 /* NTSCJ uses NTSC filters */
11183 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11185 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11186 for(i=0x35, j=0; i<=0x38; i++, j++) {
11187 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11189 for(i=0x48; i<=0x4A; i++, j++) {
11190 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11193 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11194 romptr += (temp * 2);
11195 romptr = SISGETROMW(romptr);
11196 romptr += (index * 4);
11197 for(i=0x35, j=0; i<=0x38; i++, j++) {
11198 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11201 for(i=0x35, j=0; i<=0x38; i++, j++) {
11202 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11208 static unsigned short
11209 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11211 unsigned short ModeIdIndex;
11212 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11214 if(*ModeNo <= 5) *ModeNo |= 1;
11216 for(ModeIdIndex=0; ; ModeIdIndex++) {
11217 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11218 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11221 if(*ModeNo != 0x07) {
11222 if(*ModeNo > 0x03) return ModeIdIndex;
11223 if(VGAINFO & 0x80) return ModeIdIndex;
11227 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11228 /* else 350 lines */
11229 return ModeIdIndex;
11233 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11234 unsigned short RefTableIndex)
11236 unsigned short OEMModeIdIndex = 0;
11238 if(!SiS_Pr->UseCustomMode) {
11239 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11240 if(!(OEMModeIdIndex)) return;
11243 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11244 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11245 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11246 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11249 if(SiS_Pr->UseCustomMode) return;
11250 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11251 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11252 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11253 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11254 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11255 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);