GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / video / sis / init301.c
blobbd731d72d4c63902be109dbdeebf77661c8084c9
1 /* $XFree86$ */
2 /* $XdotOrg$ */
3 /*
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],
7 * XGI V3XT/V5/V8, Z7
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
13 * apply:
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.
19 * *
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.
24 * *
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
33 * * are met:
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.
41 * *
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.
56 * Used by permission.
60 #ifdef HAVE_CONFIG_H
61 #include "config.h"
62 #endif
64 #define SET_EMI /* 302LV/ELV: Set EMI values */
66 #define SET_PWD /* 301/302LV: Set PWD */
68 #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
69 #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
70 #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
72 #include "init301.h"
74 #ifdef SIS300
75 #include "oem300.h"
76 #endif
78 #ifdef SIS315H
79 #include "oem310.h"
80 #endif
82 #define SiS_I2CDELAY 1000
83 #define SiS_I2CDELAYSHORT 150
85 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
86 #ifdef SIS_LINUX_KERNEL
87 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
88 #endif
90 /*********************************************/
91 /* HELPER: Lock/Unlock CRT2 */
92 /*********************************************/
94 void
95 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
97 if(SiS_Pr->ChipType == XGI_20)
98 return;
99 else if(SiS_Pr->ChipType >= SIS_315H)
100 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
101 else
102 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
105 #ifdef SIS_LINUX_KERNEL
106 static
107 #endif
108 void
109 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
111 if(SiS_Pr->ChipType == XGI_20)
112 return;
113 else if(SiS_Pr->ChipType >= SIS_315H)
114 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
115 else
116 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
119 /*********************************************/
120 /* HELPER: Write SR11 */
121 /*********************************************/
123 static void
124 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
126 if(SiS_Pr->ChipType >= SIS_661) {
127 DataAND &= 0x0f;
128 DataOR &= 0x0f;
130 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
133 /*********************************************/
134 /* HELPER: Get Pointer to LCD structure */
135 /*********************************************/
137 #ifdef SIS315H
138 static unsigned char *
139 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
141 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
142 unsigned char *myptr = NULL;
143 unsigned short romindex = 0, reg = 0, idx = 0;
145 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
146 * due to the variaty of panels the BIOS doesn't know about.
147 * Exception: If the BIOS has better knowledge (such as in case
148 * of machines with a 301C and a panel that does not support DDC)
149 * use the BIOS data as well.
152 if((SiS_Pr->SiS_ROMNew) &&
153 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
155 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
156 else reg = 0x7d;
158 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
160 if(idx < (8*26)) {
161 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
163 romindex = SISGETROMW(0x100);
164 if(romindex) {
165 romindex += idx;
166 myptr = &ROMAddr[romindex];
169 return myptr;
172 static unsigned short
173 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
175 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
176 unsigned short romptr = 0;
178 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
179 * due to the variaty of panels the BIOS doesn't know about.
180 * Exception: If the BIOS has better knowledge (such as in case
181 * of machines with a 301C and a panel that does not support DDC)
182 * use the BIOS data as well.
185 if((SiS_Pr->SiS_ROMNew) &&
186 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
187 romptr = SISGETROMW(0x102);
188 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
191 return romptr;
193 #endif
195 /*********************************************/
196 /* Adjust Rate for CRT2 */
197 /*********************************************/
199 static bool
200 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
201 unsigned short RRTI, unsigned short *i)
203 unsigned short checkmask=0, modeid, infoflag;
205 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
207 if(SiS_Pr->SiS_VBType & VB_SISVB) {
209 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
211 checkmask |= SupportRAMDAC2;
212 if(SiS_Pr->ChipType >= SIS_315H) {
213 checkmask |= SupportRAMDAC2_135;
214 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
215 checkmask |= SupportRAMDAC2_162;
216 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
217 checkmask |= SupportRAMDAC2_202;
222 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
224 checkmask |= SupportLCD;
225 if(SiS_Pr->ChipType >= SIS_315H) {
226 if(SiS_Pr->SiS_VBType & VB_SISVB) {
227 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
228 if(modeid == 0x2e) checkmask |= Support64048060Hz;
233 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
235 checkmask |= SupportHiVision;
237 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
239 checkmask |= SupportTV;
240 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
241 checkmask |= SupportTV1024;
242 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
243 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
244 checkmask |= SupportYPbPr750p;
251 } else { /* LVDS */
253 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
254 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
255 checkmask |= SupportCHTV;
259 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
260 checkmask |= SupportLCD;
265 /* Look backwards in table for matching CRT2 mode */
266 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
267 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
268 if(infoflag & checkmask) return true;
269 if((*i) == 0) break;
272 /* Look through the whole mode-section of the table from the beginning
273 * for a matching CRT2 mode if no mode was found yet.
275 for((*i) = 0; ; (*i)++) {
276 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
277 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
278 if(infoflag & checkmask) return true;
280 return false;
283 /*********************************************/
284 /* Get rate index */
285 /*********************************************/
287 unsigned short
288 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
290 unsigned short RRTI,i,backup_i;
291 unsigned short modeflag,index,temp,backupindex;
292 static const unsigned short LCDRefreshIndex[] = {
293 0x00, 0x00, 0x01, 0x01,
294 0x01, 0x01, 0x01, 0x01,
295 0x01, 0x01, 0x01, 0x01,
296 0x01, 0x01, 0x01, 0x01,
297 0x00, 0x00, 0x00, 0x00
300 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
301 if(ModeNo == 0xfe) return 0;
303 if(ModeNo <= 0x13) {
304 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
305 } else {
306 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
309 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
310 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
311 if(modeflag & HalfDCLK) return 0;
315 if(ModeNo < 0x14) return 0xFFFF;
317 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
318 backupindex = index;
320 if(index > 0) index--;
322 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
323 if(SiS_Pr->SiS_VBType & VB_SISVB) {
324 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
325 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
326 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
328 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
329 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
330 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
331 if(index > temp) index = temp;
334 } else {
335 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
336 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
337 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
342 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
343 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
345 if(SiS_Pr->ChipType >= SIS_315H) {
346 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
347 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
348 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
349 if(backupindex <= 1) RRTI++;
354 i = 0;
355 do {
356 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
357 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
358 temp &= ModeTypeMask;
359 if(temp < SiS_Pr->SiS_ModeType) break;
360 i++;
361 index--;
362 } while(index != 0xFFFF);
364 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
365 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
366 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
367 if(temp & InterlaceMode) i++;
371 i--;
373 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
374 backup_i = i;
375 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
376 i = backup_i;
380 return (RRTI + i);
383 /*********************************************/
384 /* STORE CRT2 INFO in CR34 */
385 /*********************************************/
387 static void
388 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
390 unsigned short temp1, temp2;
392 /* Store CRT1 ModeNo in CR34 */
393 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
394 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
395 temp2 = ~(SetInSlaveMode >> 8);
396 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
399 /*********************************************/
400 /* HELPER: GET SOME DATA FROM BIOS ROM */
401 /*********************************************/
403 #ifdef SIS300
404 static bool
405 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
407 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
408 unsigned short temp,temp1;
410 if(SiS_Pr->SiS_UseROM) {
411 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
412 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
413 temp1 = SISGETROMW(0x23b);
414 if(temp1 & temp) return true;
417 return false;
420 static bool
421 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
423 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
424 unsigned short temp,temp1;
426 if(SiS_Pr->SiS_UseROM) {
427 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
428 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
429 temp1 = SISGETROMW(0x23d);
430 if(temp1 & temp) return true;
433 return false;
435 #endif
437 /*********************************************/
438 /* HELPER: DELAY FUNCTIONS */
439 /*********************************************/
441 void
442 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
444 while (delaytime-- > 0)
445 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
448 #if defined(SIS300) || defined(SIS315H)
449 static void
450 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
452 SiS_DDC2Delay(SiS_Pr, delay * 36);
454 #endif
456 #ifdef SIS315H
457 static void
458 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
460 while(delay--) {
461 SiS_GenericDelay(SiS_Pr, 6623);
464 #endif
466 #if defined(SIS300) || defined(SIS315H)
467 static void
468 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
470 while(delay--) {
471 SiS_GenericDelay(SiS_Pr, 66);
474 #endif
476 static void
477 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
479 #if defined(SIS300) || defined(SIS315H)
480 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
481 unsigned short PanelID, DelayIndex, Delay=0;
482 #endif
484 if(SiS_Pr->ChipType < SIS_315H) {
486 #ifdef SIS300
488 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
489 if(SiS_Pr->SiS_VBType & VB_SISVB) {
490 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
491 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
493 DelayIndex = PanelID >> 4;
494 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
495 Delay = 3;
496 } else {
497 if(DelayTime >= 2) DelayTime -= 2;
498 if(!(DelayTime & 0x01)) {
499 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
500 } else {
501 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
503 if(SiS_Pr->SiS_UseROM) {
504 if(ROMAddr[0x220] & 0x40) {
505 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
506 else Delay = (unsigned short)ROMAddr[0x226];
510 SiS_ShortDelay(SiS_Pr, Delay);
512 #endif /* SIS300 */
514 } else {
516 #ifdef SIS315H
518 if((SiS_Pr->ChipType >= SIS_661) ||
519 (SiS_Pr->ChipType <= SIS_315PRO) ||
520 (SiS_Pr->ChipType == SIS_330) ||
521 (SiS_Pr->SiS_ROMNew)) {
523 if(!(DelayTime & 0x01)) {
524 SiS_DDC2Delay(SiS_Pr, 0x1000);
525 } else {
526 SiS_DDC2Delay(SiS_Pr, 0x4000);
529 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
530 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
531 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
533 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
534 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
535 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
536 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
538 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
539 DelayIndex = PanelID & 0x0f;
540 } else {
541 DelayIndex = PanelID >> 4;
543 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
544 Delay = 3;
545 } else {
546 if(DelayTime >= 2) DelayTime -= 2;
547 if(!(DelayTime & 0x01)) {
548 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
549 } else {
550 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
552 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
553 if(ROMAddr[0x13c] & 0x40) {
554 if(!(DelayTime & 0x01)) {
555 Delay = (unsigned short)ROMAddr[0x17e];
556 } else {
557 Delay = (unsigned short)ROMAddr[0x17f];
562 SiS_ShortDelay(SiS_Pr, Delay);
565 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
567 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
568 if(!(DelayTime & 0x01)) {
569 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
570 } else {
571 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
573 Delay <<= 8;
574 SiS_DDC2Delay(SiS_Pr, Delay);
578 #endif /* SIS315H */
583 #ifdef SIS315H
584 static void
585 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
587 int i;
588 for(i = 0; i < DelayLoop; i++) {
589 SiS_PanelDelay(SiS_Pr, DelayTime);
592 #endif
594 /*********************************************/
595 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
596 /*********************************************/
598 void
599 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
601 unsigned short watchdog;
603 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
604 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
606 watchdog = 65535;
607 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
608 watchdog = 65535;
609 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
612 #if defined(SIS300) || defined(SIS315H)
613 static void
614 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
616 unsigned short watchdog;
618 watchdog = 65535;
619 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
620 watchdog = 65535;
621 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
623 #endif
625 static void
626 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
628 if(SiS_Pr->ChipType < SIS_315H) {
629 #ifdef SIS300
630 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
631 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
633 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
634 SiS_WaitRetrace1(SiS_Pr);
635 } else {
636 SiS_WaitRetrace2(SiS_Pr, 0x25);
638 #endif
639 } else {
640 #ifdef SIS315H
641 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
642 SiS_WaitRetrace1(SiS_Pr);
643 } else {
644 SiS_WaitRetrace2(SiS_Pr, 0x30);
646 #endif
650 static void
651 SiS_VBWait(struct SiS_Private *SiS_Pr)
653 unsigned short tempal,temp,i,j;
655 temp = 0;
656 for(i = 0; i < 3; i++) {
657 for(j = 0; j < 100; j++) {
658 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
659 if(temp & 0x01) {
660 if((tempal & 0x08)) continue;
661 else break;
662 } else {
663 if(!(tempal & 0x08)) continue;
664 else break;
667 temp ^= 0x01;
671 static void
672 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
674 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
675 SiS_VBWait(SiS_Pr);
676 } else {
677 SiS_WaitRetrace1(SiS_Pr);
681 /*********************************************/
682 /* HELPER: MISC */
683 /*********************************************/
685 #ifdef SIS300
686 static bool
687 SiS_Is301B(struct SiS_Private *SiS_Pr)
689 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
690 return false;
692 #endif
694 static bool
695 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
697 if(SiS_Pr->ChipType == SIS_730) {
698 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
700 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
701 return false;
704 bool
705 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
707 #ifdef SIS315H
708 if(SiS_Pr->ChipType >= SIS_315H) {
709 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
710 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
713 #endif
714 return false;
717 bool
718 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
720 #ifdef SIS315H
721 unsigned short flag;
723 if(SiS_Pr->ChipType >= SIS_315H) {
724 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
725 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
727 #endif
728 return false;
731 #ifdef SIS315H
732 static bool
733 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
735 if(SiS_IsVAMode(SiS_Pr)) return true;
736 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
737 return false;
739 #endif
741 static bool
742 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
744 #ifdef SIS315H
745 if(SiS_Pr->ChipType >= SIS_315H) {
746 if((SiS_CRT2IsLCD(SiS_Pr)) ||
747 (SiS_IsVAMode(SiS_Pr))) {
748 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
751 #endif
752 return false;
755 #ifdef SIS315H
756 static bool
757 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
759 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
760 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
761 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
763 return false;
765 #endif
767 #ifdef SIS315H
768 static bool
769 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
771 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
772 return false;
774 #endif
776 #ifdef SIS315H
777 static bool
778 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
780 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
781 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
783 return false;
785 #endif
787 #ifdef SIS315H
788 static bool
789 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
791 unsigned short flag;
793 if(SiS_Pr->ChipType == SIS_650) {
794 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
795 /* Check for revision != A0 only */
796 if((flag == 0xe0) || (flag == 0xc0) ||
797 (flag == 0xb0) || (flag == 0x90)) return false;
798 } else if(SiS_Pr->ChipType >= SIS_661) return false;
799 return true;
801 #endif
803 #ifdef SIS315H
804 static bool
805 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
807 if(SiS_Pr->ChipType >= SIS_315H) {
808 /* YPrPb = 0x08 */
809 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
811 return false;
813 #endif
815 #ifdef SIS315H
816 static bool
817 SiS_IsChScart(struct SiS_Private *SiS_Pr)
819 if(SiS_Pr->ChipType >= SIS_315H) {
820 /* Scart = 0x04 */
821 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
823 return false;
825 #endif
827 #ifdef SIS315H
828 static bool
829 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
831 unsigned short flag;
833 if(SiS_Pr->ChipType >= SIS_315H) {
834 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
835 if(flag & SetCRT2ToTV) return true;
836 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
837 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
838 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
839 } else {
840 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
841 if(flag & SetCRT2ToTV) return true;
843 return false;
845 #endif
847 #ifdef SIS315H
848 static bool
849 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
851 unsigned short flag;
853 if(SiS_Pr->ChipType >= SIS_315H) {
854 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
855 if(flag & SetCRT2ToLCD) return true;
856 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
857 if(flag & SetToLCDA) return true;
858 } else {
859 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
860 if(flag & SetCRT2ToLCD) return true;
862 return false;
864 #endif
866 static bool
867 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
869 unsigned short flag;
871 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
872 return true;
873 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
874 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
875 if((flag == 1) || (flag == 2)) return true;
877 return false;
880 static bool
881 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
883 unsigned short flag;
885 if(SiS_HaveBridge(SiS_Pr)) {
886 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
887 if(SiS_Pr->ChipType < SIS_315H) {
888 flag &= 0xa0;
889 if((flag == 0x80) || (flag == 0x20)) return true;
890 } else {
891 flag &= 0x50;
892 if((flag == 0x40) || (flag == 0x10)) return true;
895 return false;
898 static bool
899 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
901 unsigned short flag1;
903 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
904 if(flag1 & (SetInSlaveMode >> 8)) return true;
905 return false;
908 /*********************************************/
909 /* GET VIDEO BRIDGE CONFIG INFO */
910 /*********************************************/
912 /* Setup general purpose IO for Chrontel communication */
913 #ifdef SIS300
914 void
915 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
917 unsigned int acpibase;
918 unsigned short temp;
920 if(!(SiS_Pr->SiS_ChSW)) return;
922 #ifdef SIS_LINUX_KERNEL
923 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
924 #else
925 acpibase = pciReadLong(0x00000800, 0x74);
926 #endif
927 acpibase &= 0xFFFF;
928 if(!acpibase) return;
929 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
930 temp &= 0xFEFF;
931 SiS_SetRegShort((acpibase + 0x3c), temp);
932 temp = SiS_GetRegShort((acpibase + 0x3c));
933 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
934 temp &= 0xFEFF;
935 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
936 SiS_SetRegShort((acpibase + 0x3a), temp);
937 temp = SiS_GetRegShort((acpibase + 0x3a));
939 #endif
941 void
942 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
943 unsigned short ModeIdIndex, int checkcrt2mode)
945 unsigned short tempax, tempbx, temp;
946 unsigned short modeflag, resinfo = 0;
948 SiS_Pr->SiS_SetFlag = 0;
950 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
952 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
954 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
955 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
958 tempbx = 0;
960 if(SiS_HaveBridge(SiS_Pr)) {
962 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
963 tempbx |= temp;
964 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
965 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
966 tempbx |= tempax;
968 #ifdef SIS315H
969 if(SiS_Pr->ChipType >= SIS_315H) {
970 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
971 if(ModeNo == 0x03) {
972 /* Mode 0x03 is never in driver mode */
973 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
975 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
976 /* Reset LCDA setting if not driver mode */
977 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
979 if(IS_SIS650) {
980 if(SiS_Pr->SiS_UseLCDA) {
981 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
982 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
983 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
988 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
989 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
990 tempbx |= SetCRT2ToLCDA;
994 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
995 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
996 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
997 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
998 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
999 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1000 tempbx |= SetCRT2ToYPbPr525750;
1005 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1006 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1007 if(temp & SetToLCDA) {
1008 tempbx |= SetCRT2ToLCDA;
1010 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1011 if(temp & EnableCHYPbPr) {
1012 tempbx |= SetCRT2ToCHYPbPr;
1018 #endif /* SIS315H */
1020 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1021 tempbx &= ~(SetCRT2ToRAMDAC);
1024 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1025 temp = SetCRT2ToSVIDEO |
1026 SetCRT2ToAVIDEO |
1027 SetCRT2ToSCART |
1028 SetCRT2ToLCDA |
1029 SetCRT2ToLCD |
1030 SetCRT2ToRAMDAC |
1031 SetCRT2ToHiVision |
1032 SetCRT2ToYPbPr525750;
1033 } else {
1034 if(SiS_Pr->ChipType >= SIS_315H) {
1035 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1036 temp = SetCRT2ToAVIDEO |
1037 SetCRT2ToSVIDEO |
1038 SetCRT2ToSCART |
1039 SetCRT2ToLCDA |
1040 SetCRT2ToLCD |
1041 SetCRT2ToCHYPbPr;
1042 } else {
1043 temp = SetCRT2ToLCDA |
1044 SetCRT2ToLCD;
1046 } else {
1047 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1048 temp = SetCRT2ToTV | SetCRT2ToLCD;
1049 } else {
1050 temp = SetCRT2ToLCD;
1055 if(!(tempbx & temp)) {
1056 tempax = DisableCRT2Display;
1057 tempbx = 0;
1060 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1062 unsigned short clearmask = ( DriverMode |
1063 DisableCRT2Display |
1064 LoadDACFlag |
1065 SetNotSimuMode |
1066 SetInSlaveMode |
1067 SetPALTV |
1068 SwitchCRT2 |
1069 SetSimuScanMode );
1071 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1072 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1073 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1074 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1075 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1076 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1078 } else {
1080 if(SiS_Pr->ChipType >= SIS_315H) {
1081 if(tempbx & SetCRT2ToLCDA) {
1082 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1085 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1086 if(tempbx & SetCRT2ToTV) {
1087 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1090 if(tempbx & SetCRT2ToLCD) {
1091 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1093 if(SiS_Pr->ChipType >= SIS_315H) {
1094 if(tempbx & SetCRT2ToLCDA) {
1095 tempbx |= SetCRT2ToLCD;
1101 if(tempax & DisableCRT2Display) {
1102 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1103 tempbx = SetSimuScanMode | DisableCRT2Display;
1107 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1109 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1110 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1111 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1112 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1113 modeflag &= (~CRT2Mode);
1117 if(!(tempbx & SetSimuScanMode)) {
1118 if(tempbx & SwitchCRT2) {
1119 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1120 if(resinfo != SIS_RI_1600x1200) {
1121 tempbx |= SetSimuScanMode;
1124 } else {
1125 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1126 if(!(tempbx & DriverMode)) {
1127 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1128 tempbx |= SetSimuScanMode;
1135 if(!(tempbx & DisableCRT2Display)) {
1136 if(tempbx & DriverMode) {
1137 if(tempbx & SetSimuScanMode) {
1138 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1139 if(resinfo != SIS_RI_1600x1200) {
1140 tempbx |= SetInSlaveMode;
1144 } else {
1145 tempbx |= SetInSlaveMode;
1151 SiS_Pr->SiS_VBInfo = tempbx;
1153 #ifdef SIS300
1154 if(SiS_Pr->ChipType == SIS_630) {
1155 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1157 #endif
1159 #ifdef SIS_LINUX_KERNEL
1160 #endif
1161 #ifdef SIS_XORG_XF86
1162 #ifdef TWDEBUG
1163 xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1164 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1165 #endif
1166 #endif
1169 /*********************************************/
1170 /* DETERMINE YPbPr MODE */
1171 /*********************************************/
1173 void
1174 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1177 unsigned char temp;
1179 /* Note: This variable is only used on 30xLV systems.
1180 * CR38 has a different meaning on LVDS/CH7019 systems.
1181 * On 661 and later, these bits moved to CR35.
1183 * On 301, 301B, only HiVision 1080i is supported.
1184 * On 30xLV, 301C, only YPbPr 1080i is supported.
1187 SiS_Pr->SiS_YPbPr = 0;
1188 if(SiS_Pr->ChipType >= SIS_661) return;
1190 if(SiS_Pr->SiS_VBType) {
1191 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1192 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1196 if(SiS_Pr->ChipType >= SIS_315H) {
1197 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1198 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1199 if(temp & 0x08) {
1200 switch((temp >> 4)) {
1201 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1202 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1203 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1204 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1212 /*********************************************/
1213 /* DETERMINE TVMode flag */
1214 /*********************************************/
1216 void
1217 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1219 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1220 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1221 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1223 SiS_Pr->SiS_TVMode = 0;
1225 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1226 if(SiS_Pr->UseCustomMode) return;
1228 if(ModeNo > 0x13) {
1229 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1232 if(SiS_Pr->ChipType < SIS_661) {
1234 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1236 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1237 temp = 0;
1238 if((SiS_Pr->ChipType == SIS_630) ||
1239 (SiS_Pr->ChipType == SIS_730)) {
1240 temp = 0x35;
1241 romindex = 0xfe;
1242 } else if(SiS_Pr->ChipType >= SIS_315H) {
1243 temp = 0x38;
1244 if(SiS_Pr->ChipType < XGI_20) {
1245 romindex = 0xf3;
1246 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1249 if(temp) {
1250 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1251 OutputSelect = ROMAddr[romindex];
1252 if(!(OutputSelect & EnablePALMN)) {
1253 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1256 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1257 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1258 if(temp1 & EnablePALM) { /* 0x40 */
1259 SiS_Pr->SiS_TVMode |= TVSetPALM;
1260 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1261 } else if(temp1 & EnablePALN) { /* 0x80 */
1262 SiS_Pr->SiS_TVMode |= TVSetPALN;
1264 } else {
1265 if(temp1 & EnableNTSCJ) { /* 0x40 */
1266 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1270 /* Translate HiVision/YPbPr to our new flags */
1271 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1272 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1273 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1274 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1275 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1276 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1277 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1278 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1279 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1280 SiS_Pr->SiS_TVMode |= TVSetPAL;
1283 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1284 if(SiS_Pr->SiS_CHOverScan) {
1285 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1286 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1287 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1288 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1290 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1291 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1292 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1293 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1296 if(SiS_Pr->SiS_CHSOverScan) {
1297 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1300 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1301 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1302 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1303 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1304 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1305 } else {
1306 if(temp & EnableNTSCJ) {
1307 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1313 } else { /* 661 and later */
1315 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1316 if(temp1 & 0x01) {
1317 SiS_Pr->SiS_TVMode |= TVSetPAL;
1318 if(temp1 & 0x08) {
1319 SiS_Pr->SiS_TVMode |= TVSetPALN;
1320 } else if(temp1 & 0x04) {
1321 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1322 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1324 SiS_Pr->SiS_TVMode |= TVSetPALM;
1326 } else {
1327 if(temp1 & 0x02) {
1328 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1331 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1332 if(SiS_Pr->SiS_CHOverScan) {
1333 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1334 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1338 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1339 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1340 temp1 &= 0xe0;
1341 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1342 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1343 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1344 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1345 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1347 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1348 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1349 SiS_Pr->SiS_TVMode |= TVAspect169;
1350 } else {
1351 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1352 if(temp1 & 0x02) {
1353 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1354 SiS_Pr->SiS_TVMode |= TVAspect169;
1355 } else {
1356 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1358 } else {
1359 SiS_Pr->SiS_TVMode |= TVAspect43;
1366 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1368 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1370 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1371 SiS_Pr->SiS_TVMode |= TVSetPAL;
1372 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1373 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1374 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1375 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1379 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1380 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1381 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1385 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1386 if(resinfo == SIS_RI_1024x768) {
1387 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1388 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1389 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1390 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1395 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1396 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1397 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1398 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1399 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1400 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1401 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1402 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1403 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1409 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1411 #ifdef SIS_XORG_XF86
1412 #ifdef TWDEBUG
1413 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1414 #endif
1415 #endif
1418 /*********************************************/
1419 /* GET LCD INFO */
1420 /*********************************************/
1422 static unsigned short
1423 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1425 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1426 /* Translate my LCDResInfo to BIOS value */
1427 switch(temp) {
1428 case Panel_1280x768_2: temp = Panel_1280x768; break;
1429 case Panel_1280x800_2: temp = Panel_1280x800; break;
1430 case Panel_1280x854: temp = Panel661_1280x854; break;
1432 return temp;
1435 static void
1436 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1438 #ifdef SIS315H
1439 unsigned char *ROMAddr;
1440 unsigned short temp;
1442 #ifdef SIS_XORG_XF86
1443 #ifdef TWDEBUG
1444 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1445 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1446 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1447 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1448 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1449 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1450 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1451 #endif
1452 #endif
1454 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1455 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1456 SiS_Pr->SiS_NeedRomModeData = true;
1457 SiS_Pr->PanelHT = temp;
1459 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1460 SiS_Pr->SiS_NeedRomModeData = true;
1461 SiS_Pr->PanelVT = temp;
1463 SiS_Pr->PanelHRS = SISGETROMW(10);
1464 SiS_Pr->PanelHRE = SISGETROMW(12);
1465 SiS_Pr->PanelVRS = SISGETROMW(14);
1466 SiS_Pr->PanelVRE = SISGETROMW(16);
1467 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1468 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1469 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1470 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1471 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1472 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1473 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1475 #ifdef SIS_XORG_XF86
1476 #ifdef TWDEBUG
1477 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1478 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1479 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1480 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1481 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1482 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1483 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1484 #endif
1485 #endif
1488 #endif
1491 static void
1492 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1493 const unsigned char *nonscalingmodes)
1495 int i = 0;
1496 while(nonscalingmodes[i] != 0xff) {
1497 if(nonscalingmodes[i++] == resinfo) {
1498 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1499 (SiS_Pr->UsePanelScaler == -1)) {
1500 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1502 break;
1507 void
1508 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1510 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1511 bool panelcanscale = false;
1512 #ifdef SIS300
1513 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1514 static const unsigned char SiS300SeriesLCDRes[] =
1515 { 0, 1, 2, 3, 7, 4, 5, 8,
1516 0, 0, 10, 0, 0, 0, 0, 15 };
1517 #endif
1518 #ifdef SIS315H
1519 unsigned char *myptr = NULL;
1520 #endif
1522 SiS_Pr->SiS_LCDResInfo = 0;
1523 SiS_Pr->SiS_LCDTypeInfo = 0;
1524 SiS_Pr->SiS_LCDInfo = 0;
1525 SiS_Pr->PanelHRS = 999; /* HSync start */
1526 SiS_Pr->PanelHRE = 999; /* HSync end */
1527 SiS_Pr->PanelVRS = 999; /* VSync start */
1528 SiS_Pr->PanelVRE = 999; /* VSync end */
1529 SiS_Pr->SiS_NeedRomModeData = false;
1531 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1532 SiS_Pr->Alternate1600x1200 = false;
1534 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1536 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1538 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1539 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1540 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1541 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1544 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1546 /* For broken BIOSes: Assume 1024x768 */
1547 if(temp == 0) temp = 0x02;
1549 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1550 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1551 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1552 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1553 } else {
1554 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1556 temp &= 0x0f;
1557 #ifdef SIS300
1558 if(SiS_Pr->ChipType < SIS_315H) {
1559 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1560 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1561 if(temp < 0x0f) temp &= 0x07;
1563 /* Translate 300 series LCDRes to 315 series for unified usage */
1564 temp = SiS300SeriesLCDRes[temp];
1566 #endif
1568 /* Translate to our internal types */
1569 #ifdef SIS315H
1570 if(SiS_Pr->ChipType == SIS_550) {
1571 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1572 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1573 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1574 } else if(SiS_Pr->ChipType >= SIS_661) {
1575 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1577 #endif
1579 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1580 if(temp == Panel310_1280x768) {
1581 temp = Panel_1280x768_2;
1583 if(SiS_Pr->SiS_ROMNew) {
1584 if(temp == Panel661_1280x800) {
1585 temp = Panel_1280x800_2;
1590 SiS_Pr->SiS_LCDResInfo = temp;
1592 #ifdef SIS300
1593 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1594 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1595 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1596 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1597 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1598 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1599 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1602 #endif
1604 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1605 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1606 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1607 } else {
1608 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1609 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1612 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1613 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1614 /* Need temp below! */
1616 /* These must/can't scale no matter what */
1617 switch(SiS_Pr->SiS_LCDResInfo) {
1618 case Panel_320x240_1:
1619 case Panel_320x240_2:
1620 case Panel_320x240_3:
1621 case Panel_1280x960:
1622 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1623 break;
1624 case Panel_640x480:
1625 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1628 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1630 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1631 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1633 /* Dual link, Pass 1:1 BIOS default, etc. */
1634 #ifdef SIS315H
1635 if(SiS_Pr->ChipType >= SIS_661) {
1636 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1637 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1639 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1640 if(SiS_Pr->SiS_ROMNew) {
1641 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1642 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1643 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1646 } else if(SiS_Pr->ChipType >= SIS_315H) {
1647 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1648 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1650 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1651 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1652 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1653 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1654 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1655 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1657 } else if(!(SiS_Pr->SiS_ROMNew)) {
1658 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1659 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1660 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1661 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1663 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1664 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1665 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1666 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1667 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1672 #endif
1674 /* Pass 1:1 */
1675 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1676 /* Always center screen on LVDS (if scaling is disabled) */
1677 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1678 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1679 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1680 /* Always center screen on SiS LVDS (if scaling is disabled) */
1681 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1682 } else {
1683 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1684 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1685 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1689 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1690 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1692 switch(SiS_Pr->SiS_LCDResInfo) {
1693 case Panel_320x240_1:
1694 case Panel_320x240_2:
1695 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1696 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1697 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1698 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1699 break;
1700 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1701 SiS_Pr->PanelVRE = 3;
1702 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1703 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1704 break;
1705 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1706 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1707 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1708 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1709 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1710 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1711 break;
1712 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1713 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1714 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1715 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1716 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1717 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1718 break;
1719 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1720 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1721 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1722 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1723 if(SiS_Pr->ChipType < SIS_315H) {
1724 SiS_Pr->PanelHRS = 23;
1725 SiS_Pr->PanelVRE = 5;
1727 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1728 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1729 SiS_GetLCDInfoBIOS(SiS_Pr);
1730 break;
1731 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1732 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1733 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1734 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1735 if(SiS_Pr->ChipType < SIS_315H) {
1736 SiS_Pr->PanelHRS = 23;
1737 SiS_Pr->PanelVRE = 5;
1739 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1740 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1741 break;
1742 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1743 break;
1744 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1745 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1746 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1747 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1748 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1749 /* Data above for TMDS (projector); get from BIOS for LVDS */
1750 SiS_GetLCDInfoBIOS(SiS_Pr);
1751 break;
1752 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1753 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1754 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1755 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1756 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1757 } else {
1758 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1759 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1760 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1761 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1762 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1764 break;
1765 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1766 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1767 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1768 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1769 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1770 SiS_GetLCDInfoBIOS(SiS_Pr);
1771 break;
1772 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1773 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1774 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1775 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1776 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1777 SiS_GetLCDInfoBIOS(SiS_Pr);
1778 break;
1779 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1780 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1781 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1782 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1783 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1784 SiS_GetLCDInfoBIOS(SiS_Pr);
1785 break;
1786 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1787 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1788 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1789 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1790 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1791 SiS_GetLCDInfoBIOS(SiS_Pr);
1792 break;
1793 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1794 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1795 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1796 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1797 if(resinfo == SIS_RI_1280x1024) {
1798 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1799 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1801 break;
1802 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1803 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1804 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1805 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1806 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1807 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1808 SiS_GetLCDInfoBIOS(SiS_Pr);
1809 break;
1810 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
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->PanelVCLKIdx315 = VCLK108_2_315;
1815 SiS_GetLCDInfoBIOS(SiS_Pr);
1816 break;
1817 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1818 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1819 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1820 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1821 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1822 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1823 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1824 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1825 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1826 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1827 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1828 SiS_Pr->Alternate1600x1200 = true;
1830 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1831 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1832 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1833 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1835 SiS_GetLCDInfoBIOS(SiS_Pr);
1836 break;
1837 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1838 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1839 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1840 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1841 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1842 SiS_GetLCDInfoBIOS(SiS_Pr);
1843 break;
1844 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1845 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1846 break;
1847 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1848 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1849 break;
1850 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1851 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1852 break;
1853 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1854 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1855 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1856 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1857 if(SiS_Pr->CP_PreferredIndex != -1) {
1858 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1859 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1860 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1861 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1862 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1863 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1864 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1865 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1866 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1867 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1868 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1869 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1870 if(SiS_Pr->CP_PrefClock) {
1871 int idx;
1872 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1873 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1874 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1875 else idx = VCLK_CUSTOM_315;
1876 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1877 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1878 SiS_Pr->SiS_VCLKData[idx].SR2B =
1879 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1880 SiS_Pr->SiS_VCLKData[idx].SR2C =
1881 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1884 break;
1885 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1886 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1887 break;
1890 /* Special cases */
1891 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1892 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1893 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1894 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1895 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1896 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1897 SiS_Pr->PanelHRS = 999;
1898 SiS_Pr->PanelHRE = 999;
1901 if( (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->PanelVRS = 999;
1906 SiS_Pr->PanelVRE = 999;
1909 /* DontExpand overrule */
1910 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1912 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1913 /* No scaling for this mode on any panel (LCD=CRT2)*/
1914 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1917 switch(SiS_Pr->SiS_LCDResInfo) {
1919 case Panel_Custom:
1920 case Panel_1152x864:
1921 case Panel_1280x768: /* TMDS only */
1922 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1923 break;
1925 case Panel_800x600: {
1926 static const unsigned char nonscalingmodes[] = {
1927 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1929 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1930 break;
1932 case Panel_1024x768: {
1933 static const unsigned char nonscalingmodes[] = {
1934 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1935 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1936 0xff
1938 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1939 break;
1941 case Panel_1280x720: {
1942 static const unsigned char nonscalingmodes[] = {
1943 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1944 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1945 0xff
1947 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1948 if(SiS_Pr->PanelHT == 1650) {
1949 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1951 break;
1953 case Panel_1280x768_2: { /* LVDS only */
1954 static const unsigned char nonscalingmodes[] = {
1955 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1956 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1957 SIS_RI_1152x768,0xff
1959 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1960 switch(resinfo) {
1961 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1962 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1964 break;
1966 break;
1968 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1969 static const unsigned char nonscalingmodes[] = {
1970 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1971 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1972 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1974 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1975 break;
1977 case Panel_1280x800_2: { /* SiS LVDS */
1978 static const unsigned char nonscalingmodes[] = {
1979 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1980 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1981 SIS_RI_1152x768,0xff
1983 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1984 switch(resinfo) {
1985 case SIS_RI_1280x720:
1986 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1987 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1989 break;
1991 break;
1993 case Panel_1280x854: { /* SiS LVDS */
1994 static const unsigned char nonscalingmodes[] = {
1995 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1996 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1997 SIS_RI_1152x768,0xff
1999 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2000 switch(resinfo) {
2001 case SIS_RI_1280x720:
2002 case SIS_RI_1280x768:
2003 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2004 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2006 break;
2008 break;
2010 case Panel_1280x960: {
2011 static const unsigned char nonscalingmodes[] = {
2012 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2013 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2014 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2015 SIS_RI_1280x854,0xff
2017 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2018 break;
2020 case Panel_1280x1024: {
2021 static const unsigned char nonscalingmodes[] = {
2022 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2023 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2024 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2025 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2027 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2028 break;
2030 case Panel_1400x1050: {
2031 static const unsigned char nonscalingmodes[] = {
2032 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2033 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2034 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2035 SIS_RI_1280x960,0xff
2037 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2038 switch(resinfo) {
2039 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2040 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2042 break;
2043 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2044 break;
2046 break;
2048 case Panel_1600x1200: {
2049 static const unsigned char nonscalingmodes[] = {
2050 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2051 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2052 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2053 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2055 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2056 break;
2058 case Panel_1680x1050: {
2059 static const unsigned char nonscalingmodes[] = {
2060 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2061 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2062 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2063 SIS_RI_1360x1024,0xff
2065 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2066 break;
2071 #ifdef SIS300
2072 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2073 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2074 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2078 if(SiS_Pr->ChipType < SIS_315H) {
2079 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2080 if(SiS_Pr->SiS_UseROM) {
2081 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2082 if(!(ROMAddr[0x235] & 0x02)) {
2083 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2087 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2088 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2089 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2093 #endif
2095 /* Special cases */
2097 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2098 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2101 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2102 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2105 switch(SiS_Pr->SiS_LCDResInfo) {
2106 case Panel_640x480:
2107 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2108 break;
2109 case Panel_1280x800:
2110 /* Don't pass 1:1 by default (TMDS special) */
2111 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2112 break;
2113 case Panel_1280x960:
2114 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2115 break;
2116 case Panel_Custom:
2117 if((!SiS_Pr->CP_PrefClock) ||
2118 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2119 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2121 break;
2124 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2125 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2128 /* (In)validate LCDPass11 flag */
2129 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2130 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2133 /* LVDS DDA */
2134 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2136 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2137 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2138 if(ModeNo == 0x12) {
2139 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2140 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2142 } else if(ModeNo > 0x13) {
2143 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2144 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2145 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2146 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2154 if(modeflag & HalfDCLK) {
2155 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2156 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2157 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2158 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2159 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2160 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2161 } else if(ModeNo > 0x13) {
2162 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2163 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2164 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2165 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2172 /* VESA timing */
2173 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2174 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2175 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2177 } else {
2178 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2181 #ifdef SIS_LINUX_KERNEL
2182 #endif
2183 #ifdef SIS_XORG_XF86
2184 xf86DrvMsgVerb(0, X_PROBED, 4,
2185 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2186 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2187 #endif
2190 /*********************************************/
2191 /* GET VCLK */
2192 /*********************************************/
2194 unsigned short
2195 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2196 unsigned short RefreshRateTableIndex)
2198 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2199 unsigned short modeflag, resinfo, tempbx;
2200 const unsigned char *CHTVVCLKPtr = NULL;
2202 if(ModeNo <= 0x13) {
2203 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2204 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2205 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2206 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2207 VCLKIndexGENCRT = VCLKIndexGEN;
2208 } else {
2209 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2210 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2211 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2212 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2213 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2214 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2217 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2219 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2221 CRT2Index >>= 6;
2222 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2224 if(SiS_Pr->ChipType < SIS_315H) {
2225 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2226 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2227 VCLKIndex = VCLKIndexGEN;
2229 } else {
2230 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2231 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2232 switch(resinfo) {
2233 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2234 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2235 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2236 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2237 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2238 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2239 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2240 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2241 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2242 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2243 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2244 default: VCLKIndex = VCLKIndexGEN;
2247 if(ModeNo <= 0x13) {
2248 if(SiS_Pr->ChipType <= SIS_315PRO) {
2249 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2250 } else {
2251 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2254 if(SiS_Pr->ChipType <= SIS_315PRO) {
2255 if(VCLKIndex == 0) VCLKIndex = 0x41;
2256 if(VCLKIndex == 1) VCLKIndex = 0x43;
2257 if(VCLKIndex == 4) VCLKIndex = 0x44;
2262 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2264 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2265 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2266 else VCLKIndex = HiTVVCLK;
2267 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2268 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2269 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2270 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2271 else VCLKIndex = TVVCLK;
2273 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2274 else VCLKIndex += TVCLKBASE_315;
2276 } else { /* VGA2 */
2278 VCLKIndex = VCLKIndexGENCRT;
2279 if(SiS_Pr->ChipType < SIS_315H) {
2280 if(ModeNo > 0x13) {
2281 if( (SiS_Pr->ChipType == SIS_630) &&
2282 (SiS_Pr->ChipRevision >= 0x30)) {
2283 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2285 /* Better VGA2 clock for 1280x1024@75 */
2286 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2291 } else { /* If not programming CRT2 */
2293 VCLKIndex = VCLKIndexGENCRT;
2294 if(SiS_Pr->ChipType < SIS_315H) {
2295 if(ModeNo > 0x13) {
2296 if( (SiS_Pr->ChipType != SIS_630) &&
2297 (SiS_Pr->ChipType != SIS_300) ) {
2298 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2304 } else { /* LVDS */
2306 VCLKIndex = CRT2Index;
2308 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2310 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2312 VCLKIndex &= 0x1f;
2313 tempbx = 0;
2314 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2315 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2316 tempbx += 2;
2317 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2318 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2320 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2321 tempbx = 4;
2322 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2323 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2324 tempbx = 6;
2325 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2328 switch(tempbx) {
2329 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2330 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2331 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2332 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2333 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2334 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2335 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2336 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2337 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2338 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2340 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2342 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2344 if(SiS_Pr->ChipType < SIS_315H) {
2345 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2346 } else {
2347 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2350 #ifdef SIS300
2351 /* Special Timing: Barco iQ Pro R series */
2352 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2354 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2355 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2356 if(SiS_Pr->ChipType < SIS_315H) {
2357 VCLKIndex = VCLK34_300;
2358 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2359 } else {
2360 VCLKIndex = VCLK34_315;
2361 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2364 #endif
2366 } else {
2368 VCLKIndex = VCLKIndexGENCRT;
2369 if(SiS_Pr->ChipType < SIS_315H) {
2370 if(ModeNo > 0x13) {
2371 if( (SiS_Pr->ChipType == SIS_630) &&
2372 (SiS_Pr->ChipRevision >= 0x30) ) {
2373 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2379 } else { /* if not programming CRT2 */
2381 VCLKIndex = VCLKIndexGENCRT;
2382 if(SiS_Pr->ChipType < SIS_315H) {
2383 if(ModeNo > 0x13) {
2384 if( (SiS_Pr->ChipType != SIS_630) &&
2385 (SiS_Pr->ChipType != SIS_300) ) {
2386 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2395 #ifdef SIS_XORG_XF86
2396 #ifdef TWDEBUG
2397 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2398 #endif
2399 #endif
2401 return VCLKIndex;
2404 /*********************************************/
2405 /* SET CRT2 MODE TYPE REGISTERS */
2406 /*********************************************/
2408 static void
2409 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2411 unsigned short i, j, modeflag, tempah=0;
2412 short tempcl;
2413 #if defined(SIS300) || defined(SIS315H)
2414 unsigned short tempbl;
2415 #endif
2416 #ifdef SIS315H
2417 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2418 unsigned short tempah2, tempbl2;
2419 #endif
2421 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2423 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2425 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2426 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2428 } else {
2430 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2431 if(SiS_Pr->ChipType >= SIS_315H) {
2432 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2435 tempcl = SiS_Pr->SiS_ModeType;
2437 if(SiS_Pr->ChipType < SIS_315H) {
2439 #ifdef SIS300 /* ---- 300 series ---- */
2441 /* For 301BDH: (with LCD via LVDS) */
2442 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2443 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2444 tempbl &= 0xef;
2445 tempbl |= 0x02;
2446 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2447 tempbl |= 0x10;
2448 tempbl &= 0xfd;
2450 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2453 if(ModeNo > 0x13) {
2454 tempcl -= ModeVGA;
2455 if(tempcl >= 0) {
2456 tempah = ((0x10 >> tempcl) | 0x80);
2458 } else tempah = 0x80;
2460 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2462 #endif /* SIS300 */
2464 } else {
2466 #ifdef SIS315H /* ------- 315/330 series ------ */
2468 if(ModeNo > 0x13) {
2469 tempcl -= ModeVGA;
2470 if(tempcl >= 0) {
2471 tempah = (0x08 >> tempcl);
2472 if (tempah == 0) tempah = 1;
2473 tempah |= 0x40;
2475 } else tempah = 0x40;
2477 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2479 #endif /* SIS315H */
2483 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2485 if(SiS_Pr->ChipType < SIS_315H) {
2486 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2487 } else {
2488 #ifdef SIS315H
2489 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2491 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2492 if(IS_SIS740) {
2493 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2494 } else {
2495 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2498 #endif
2501 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2503 tempah = 0x01;
2504 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2505 tempah |= 0x02;
2507 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2508 tempah ^= 0x05;
2509 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2510 tempah ^= 0x01;
2514 if(SiS_Pr->ChipType < SIS_315H) {
2516 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2518 tempah = (tempah << 5) & 0xFF;
2519 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2520 tempah = (tempah >> 5) & 0xFF;
2522 } else {
2524 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2525 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2526 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2527 tempah &= ~0x08;
2531 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2532 tempah |= 0x10;
2535 tempah |= 0x80;
2536 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2537 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2540 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2541 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2542 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2543 tempah |= 0x20;
2548 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2550 tempah = 0x80;
2551 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2552 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2555 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2557 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2558 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2559 tempah |= 0x40;
2563 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2565 } else { /* LVDS */
2567 if(SiS_Pr->ChipType >= SIS_315H) {
2569 #ifdef SIS315H
2570 /* LVDS can only be slave in 8bpp modes */
2571 tempah = 0x80;
2572 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2573 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2574 tempah |= 0x02;
2578 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2580 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2582 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2584 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2585 #endif
2587 } else {
2589 #ifdef SIS300
2590 tempah = 0;
2591 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2592 tempah |= 0x02;
2594 tempah <<= 5;
2596 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2598 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2599 #endif
2605 } /* LCDA */
2607 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2609 if(SiS_Pr->ChipType >= SIS_315H) {
2611 #ifdef SIS315H
2612 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2614 /* The following is nearly unpreditable and varies from machine
2615 * to machine. Especially the 301DH seems to be a real trouble
2616 * maker. Some BIOSes simply set the registers (like in the
2617 * NoLCD-if-statements here), some set them according to the
2618 * LCDA stuff. It is very likely that some machines are not
2619 * treated correctly in the following, very case-orientated
2620 * code. What do I do then...?
2623 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2625 if(!(IS_SIS740)) {
2626 tempah = 0x04; /* For all bridges */
2627 tempbl = 0xfb;
2628 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2629 tempah = 0x00;
2630 if(SiS_IsDualEdge(SiS_Pr)) {
2631 tempbl = 0xff;
2634 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2637 /* The following two are responsible for eventually wrong colors
2638 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2639 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2640 * in a 650 box (Jake). What is the criteria?
2641 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2642 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2643 * chipset than the bridge revision.
2646 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2647 tempah = 0x30;
2648 tempbl = 0xc0;
2649 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2650 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2651 tempah = 0x00;
2652 tempbl = 0x00;
2654 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2655 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2656 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2657 /* Fixes "TV-blue-bug" on 315+301 */
2658 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2659 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2660 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2661 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2662 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2663 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2664 tempah = 0x30; tempah2 = 0xc0;
2665 tempbl = 0xcf; tempbl2 = 0x3f;
2666 if(SiS_Pr->SiS_TVBlue == 0) {
2667 tempah = tempah2 = 0x00;
2668 } else if(SiS_Pr->SiS_TVBlue == -1) {
2669 /* Set on 651/M650, clear on 315/650 */
2670 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2671 tempah = tempah2 = 0x00;
2674 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2675 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2676 } else {
2677 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2678 tempbl = 0xcf; tempbl2 = 0x3f;
2679 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2680 tempah = tempah2 = 0x00;
2681 if(SiS_IsDualEdge(SiS_Pr)) {
2682 tempbl = tempbl2 = 0xff;
2685 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2686 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2689 if(IS_SIS740) {
2690 tempah = 0x80;
2691 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2692 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2693 } else {
2694 tempah = 0x00;
2695 tempbl = 0x7f;
2696 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2697 tempbl = 0xff;
2698 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2700 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2703 #endif /* SIS315H */
2705 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2707 #ifdef SIS300
2708 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2710 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2711 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2712 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2713 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2714 } else {
2715 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2717 #endif
2721 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2722 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2723 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2724 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2728 } else { /* LVDS */
2730 #ifdef SIS315H
2731 if(SiS_Pr->ChipType >= SIS_315H) {
2733 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2735 tempah = 0x04;
2736 tempbl = 0xfb;
2737 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2738 tempah = 0x00;
2739 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2741 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2743 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2744 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2747 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2749 } else if(SiS_Pr->ChipType == SIS_550) {
2751 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2752 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2757 #endif
2763 /*********************************************/
2764 /* GET RESOLUTION DATA */
2765 /*********************************************/
2767 unsigned short
2768 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2770 if(ModeNo <= 0x13)
2771 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2772 else
2773 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2776 static void
2777 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2779 unsigned short xres, yres, modeflag=0, resindex;
2781 if(SiS_Pr->UseCustomMode) {
2782 xres = SiS_Pr->CHDisplay;
2783 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2784 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2785 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2786 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2787 return;
2790 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2792 if(ModeNo <= 0x13) {
2793 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2794 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2795 } else {
2796 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2797 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2798 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2801 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2803 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2804 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2805 if(yres == 350) yres = 400;
2807 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2808 if(ModeNo == 0x12) yres = 400;
2812 if(modeflag & HalfDCLK) xres <<= 1;
2813 if(modeflag & DoubleScanMode) yres <<= 1;
2817 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2819 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2820 switch(SiS_Pr->SiS_LCDResInfo) {
2821 case Panel_1024x768:
2822 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2823 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2824 if(yres == 350) yres = 357;
2825 if(yres == 400) yres = 420;
2826 if(yres == 480) yres = 525;
2829 break;
2830 case Panel_1280x1024:
2831 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2832 /* BIOS bug - does this regardless of scaling */
2833 if(yres == 400) yres = 405;
2835 if(yres == 350) yres = 360;
2836 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2837 if(yres == 360) yres = 375;
2839 break;
2840 case Panel_1600x1200:
2841 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2842 if(yres == 1024) yres = 1056;
2844 break;
2848 } else {
2850 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2851 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2852 if(xres == 720) xres = 640;
2854 } else if(xres == 720) xres = 640;
2856 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2857 yres = 400;
2858 if(SiS_Pr->ChipType >= SIS_315H) {
2859 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2860 } else {
2861 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2863 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2867 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2868 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2871 /*********************************************/
2872 /* GET CRT2 TIMING DATA */
2873 /*********************************************/
2875 static void
2876 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2877 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2878 unsigned short *ResIndex)
2880 unsigned short tempbx=0, tempal=0, resinfo=0;
2882 if(ModeNo <= 0x13) {
2883 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2884 } else {
2885 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2886 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2889 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2891 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2893 tempbx = SiS_Pr->SiS_LCDResInfo;
2894 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2896 /* patch index */
2897 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2898 if (resinfo == SIS_RI_1280x800) tempal = 9;
2899 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2900 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2901 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2902 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2903 if (resinfo == SIS_RI_1280x768) tempal = 9;
2906 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2907 /* Pass 1:1 only (center-screen handled outside) */
2908 /* This is never called for the panel's native resolution */
2909 /* since Pass1:1 will not be set in this case */
2910 tempbx = 100;
2911 if(ModeNo >= 0x13) {
2912 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2916 #ifdef SIS315H
2917 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2918 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2919 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2920 tempbx = 200;
2921 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2925 #endif
2927 } else { /* TV */
2929 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2930 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2931 tempbx = 2;
2932 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2933 tempbx = 13;
2934 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2936 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2937 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2938 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2939 else tempbx = 5;
2940 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2941 } else {
2942 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2943 else tempbx = 4;
2944 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2949 tempal &= 0x3F;
2951 if(ModeNo > 0x13) {
2952 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2953 switch(resinfo) {
2954 case SIS_RI_720x480:
2955 tempal = 6;
2956 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
2957 break;
2958 case SIS_RI_720x576:
2959 case SIS_RI_768x576:
2960 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2961 tempal = 6;
2962 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2963 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
2965 break;
2966 case SIS_RI_800x480:
2967 tempal = 4;
2968 break;
2969 case SIS_RI_512x384:
2970 case SIS_RI_1024x768:
2971 tempal = 7;
2972 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2973 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
2975 break;
2976 case SIS_RI_1280x720:
2977 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2978 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
2980 break;
2985 *CRT2Index = tempbx;
2986 *ResIndex = tempal;
2988 } else { /* LVDS, 301B-DH (if running on LCD) */
2990 tempbx = 0;
2991 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2993 tempbx = 90;
2994 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2995 tempbx = 92;
2996 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2997 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2999 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3000 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3002 if(tempbx != 99) {
3003 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3006 } else {
3008 switch(SiS_Pr->SiS_LCDResInfo) {
3009 case Panel_640x480: tempbx = 12; break;
3010 case Panel_320x240_1: tempbx = 10; break;
3011 case Panel_320x240_2:
3012 case Panel_320x240_3: tempbx = 14; break;
3013 case Panel_800x600: tempbx = 16; break;
3014 case Panel_1024x600: tempbx = 18; break;
3015 case Panel_1152x768:
3016 case Panel_1024x768: tempbx = 20; break;
3017 case Panel_1280x768: tempbx = 22; break;
3018 case Panel_1280x1024: tempbx = 24; break;
3019 case Panel_1400x1050: tempbx = 26; break;
3020 case Panel_1600x1200: tempbx = 28; break;
3021 #ifdef SIS300
3022 case Panel_Barco1366: tempbx = 80; break;
3023 #endif
3026 switch(SiS_Pr->SiS_LCDResInfo) {
3027 case Panel_320x240_1:
3028 case Panel_320x240_2:
3029 case Panel_320x240_3:
3030 case Panel_640x480:
3031 break;
3032 default:
3033 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3036 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3038 #ifdef SIS300
3039 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3040 tempbx = 82;
3041 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3042 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3043 tempbx = 84;
3044 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3046 #endif
3050 (*CRT2Index) = tempbx;
3051 (*ResIndex) = tempal & 0x1F;
3055 static void
3056 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3057 unsigned short RefreshRateTableIndex)
3059 unsigned short tempax=0, tempbx=0, index, dotclock;
3060 unsigned short temp1=0, modeflag=0, tempcx=0;
3062 SiS_Pr->SiS_RVBHCMAX = 1;
3063 SiS_Pr->SiS_RVBHCFACT = 1;
3065 if(ModeNo <= 0x13) {
3067 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3068 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3070 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3071 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3072 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3074 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3076 } else {
3078 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3079 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3081 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3082 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3083 tempax &= 0x03FF;
3084 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3085 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3086 tempcx &= 0x0100;
3087 tempcx <<= 2;
3088 tempbx |= tempcx;
3089 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3091 dotclock = 8;
3095 if(temp1 & 0x01) tempbx |= 0x0100;
3096 if(temp1 & 0x20) tempbx |= 0x0200;
3098 tempax += 5;
3099 tempax *= dotclock;
3100 if(modeflag & HalfDCLK) tempax <<= 1;
3102 tempbx++;
3104 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3105 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3108 static void
3109 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3110 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3112 unsigned short ResIndex;
3114 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3115 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3116 if(SiS_Pr->UseCustomMode) {
3117 ResIndex = SiS_Pr->CHTotal;
3118 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3119 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3120 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3121 } else {
3122 if(ModeNo < 0x13) {
3123 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3124 } else {
3125 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3127 if(ResIndex == 0x09) {
3128 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3129 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3131 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3132 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3133 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3134 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3136 } else {
3137 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3138 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3140 } else {
3141 /* This handles custom modes and custom panels */
3142 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3143 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3144 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3145 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3146 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3147 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3151 static void
3152 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3153 unsigned short RefreshRateTableIndex)
3155 unsigned short CRT2Index, ResIndex, backup;
3156 const struct SiS_LVDSData *LVDSData = NULL;
3158 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3160 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3161 SiS_Pr->SiS_RVBHCMAX = 1;
3162 SiS_Pr->SiS_RVBHCFACT = 1;
3163 SiS_Pr->SiS_NewFlickerMode = 0;
3164 SiS_Pr->SiS_RVBHRS = 50;
3165 SiS_Pr->SiS_RY1COE = 0;
3166 SiS_Pr->SiS_RY2COE = 0;
3167 SiS_Pr->SiS_RY3COE = 0;
3168 SiS_Pr->SiS_RY4COE = 0;
3169 SiS_Pr->SiS_RVBHRS2 = 0;
3172 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3174 #ifdef SIS315H
3175 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3176 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3177 #endif
3179 } else {
3181 /* 301BDH needs LVDS Data */
3182 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3183 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3184 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3187 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3188 &CRT2Index, &ResIndex);
3190 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3192 switch(CRT2Index) {
3193 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3194 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3195 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3196 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3197 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3198 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3199 #ifdef SIS300
3200 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3201 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3202 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3203 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3204 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3205 #endif
3206 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3207 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3208 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3209 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3210 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3211 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3212 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3213 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3214 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3217 if(LVDSData) {
3218 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3219 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3220 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3221 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3222 } else {
3223 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3226 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3227 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3228 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3229 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3230 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3231 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3232 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3233 #ifdef SIS300
3234 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3235 if(ResIndex < 0x08) {
3236 SiS_Pr->SiS_HDE = 1280;
3237 SiS_Pr->SiS_VDE = 1024;
3240 #endif
3246 static void
3247 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3248 unsigned short RefreshRateTableIndex)
3250 unsigned char *ROMAddr = NULL;
3251 unsigned short tempax, tempbx, modeflag, romptr=0;
3252 unsigned short resinfo, CRT2Index, ResIndex;
3253 const struct SiS_LCDData *LCDPtr = NULL;
3254 const struct SiS_TVData *TVPtr = NULL;
3255 #ifdef SIS315H
3256 short resinfo661;
3257 #endif
3259 if(ModeNo <= 0x13) {
3260 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3261 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3262 } else if(SiS_Pr->UseCustomMode) {
3263 modeflag = SiS_Pr->CModeFlag;
3264 resinfo = 0;
3265 } else {
3266 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3267 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3268 #ifdef SIS315H
3269 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3270 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3271 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3272 (resinfo661 >= 0) &&
3273 (SiS_Pr->SiS_NeedRomModeData) ) {
3274 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3275 if((romptr = (SISGETROMW(21)))) {
3276 romptr += (resinfo661 * 10);
3277 ROMAddr = SiS_Pr->VirtualRomBase;
3281 #endif
3284 SiS_Pr->SiS_NewFlickerMode = 0;
3285 SiS_Pr->SiS_RVBHRS = 50;
3286 SiS_Pr->SiS_RY1COE = 0;
3287 SiS_Pr->SiS_RY2COE = 0;
3288 SiS_Pr->SiS_RY3COE = 0;
3289 SiS_Pr->SiS_RY4COE = 0;
3290 SiS_Pr->SiS_RVBHRS2 = 0;
3292 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3294 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3296 if(SiS_Pr->UseCustomMode) {
3298 SiS_Pr->SiS_RVBHCMAX = 1;
3299 SiS_Pr->SiS_RVBHCFACT = 1;
3300 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3301 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3303 tempax = SiS_Pr->CHTotal;
3304 if(modeflag & HalfDCLK) tempax <<= 1;
3305 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3306 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3308 } else {
3310 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3314 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3316 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3317 &CRT2Index,&ResIndex);
3319 switch(CRT2Index) {
3320 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3321 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3322 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3323 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3324 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3325 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3326 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3327 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3328 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3329 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3330 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3331 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3332 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3333 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3336 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3337 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3338 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3339 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3340 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3341 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3342 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3343 if(modeflag & HalfDCLK) {
3344 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3345 if(SiS_Pr->SiS_RVBHRS2) {
3346 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3347 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3348 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3349 else SiS_Pr->SiS_RVBHRS2 += tempax;
3351 } else {
3352 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3354 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3356 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3358 if((resinfo == SIS_RI_960x600) ||
3359 (resinfo == SIS_RI_1024x768) ||
3360 (resinfo == SIS_RI_1280x1024) ||
3361 (resinfo == SIS_RI_1280x720)) {
3362 SiS_Pr->SiS_NewFlickerMode = 0x40;
3365 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3367 SiS_Pr->SiS_HT = ExtHiTVHT;
3368 SiS_Pr->SiS_VT = ExtHiTVVT;
3369 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3370 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3371 SiS_Pr->SiS_HT = StHiTVHT;
3372 SiS_Pr->SiS_VT = StHiTVVT;
3376 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3378 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3379 SiS_Pr->SiS_HT = 1650;
3380 SiS_Pr->SiS_VT = 750;
3381 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3382 SiS_Pr->SiS_HT = NTSCHT;
3383 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3384 SiS_Pr->SiS_VT = NTSCVT;
3385 } else {
3386 SiS_Pr->SiS_HT = NTSCHT;
3387 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3388 SiS_Pr->SiS_VT = NTSCVT;
3391 } else {
3393 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3394 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3395 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3396 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3398 if(modeflag & HalfDCLK) {
3399 SiS_Pr->SiS_RY1COE = 0x00;
3400 SiS_Pr->SiS_RY2COE = 0xf4;
3401 SiS_Pr->SiS_RY3COE = 0x10;
3402 SiS_Pr->SiS_RY4COE = 0x38;
3405 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3406 SiS_Pr->SiS_HT = NTSCHT;
3407 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3408 SiS_Pr->SiS_VT = NTSCVT;
3409 } else {
3410 SiS_Pr->SiS_HT = PALHT;
3411 SiS_Pr->SiS_VT = PALVT;
3416 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3418 SiS_Pr->SiS_RVBHCMAX = 1;
3419 SiS_Pr->SiS_RVBHCFACT = 1;
3421 if(SiS_Pr->UseCustomMode) {
3423 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3424 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3426 tempax = SiS_Pr->CHTotal;
3427 if(modeflag & HalfDCLK) tempax <<= 1;
3428 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3429 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3431 } else {
3433 bool gotit = false;
3435 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3437 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3438 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3439 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3440 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3441 gotit = true;
3443 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3445 #ifdef SIS315H
3446 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3447 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3448 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3449 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3450 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3451 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3452 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3453 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3454 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3455 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3456 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3457 else SiS_Pr->SiS_RVBHRS2 += tempax;
3459 if(SiS_Pr->SiS_VGAHT) gotit = true;
3460 else {
3461 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3462 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3463 SiS_Pr->SiS_RVBHCMAX = 1;
3464 SiS_Pr->SiS_RVBHCFACT = 1;
3465 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3466 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3467 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3468 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3469 SiS_Pr->SiS_RVBHRS2 = 0;
3470 gotit = true;
3472 #endif
3476 if(!gotit) {
3478 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3479 &CRT2Index,&ResIndex);
3481 switch(CRT2Index) {
3482 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3483 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3484 case Panel_1280x720 :
3485 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3486 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3487 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3488 case Panel_1280x800 :
3489 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3490 case Panel_1280x800_2 :
3491 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3492 case Panel_1280x854 :
3493 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3494 case Panel_1280x960 :
3495 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3496 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3497 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3498 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3499 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3500 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3501 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3502 case Panel_1680x1050 :
3503 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3504 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3505 #ifdef SIS315H
3506 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3507 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3508 #endif
3509 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3512 #ifdef SIS_XORG_XF86
3513 #ifdef TWDEBUG
3514 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3515 #endif
3516 #endif
3518 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3519 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3520 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3521 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3522 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3523 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3527 tempax = SiS_Pr->PanelXRes;
3528 tempbx = SiS_Pr->PanelYRes;
3530 switch(SiS_Pr->SiS_LCDResInfo) {
3531 case Panel_1024x768:
3532 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3533 if(SiS_Pr->ChipType < SIS_315H) {
3534 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3535 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3537 } else {
3538 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3539 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3540 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3541 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3542 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3543 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3545 break;
3546 case Panel_1280x960:
3547 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3548 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3549 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3550 break;
3551 case Panel_1280x1024:
3552 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3553 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3554 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3555 break;
3556 case Panel_1600x1200:
3557 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3558 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3559 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3561 break;
3564 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3565 tempax = SiS_Pr->SiS_VGAHDE;
3566 tempbx = SiS_Pr->SiS_VGAVDE;
3569 SiS_Pr->SiS_HDE = tempax;
3570 SiS_Pr->SiS_VDE = tempbx;
3575 static void
3576 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3577 unsigned short RefreshRateTableIndex)
3580 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3582 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3583 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3584 } else {
3585 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3586 /* Need LVDS Data for LCD on 301B-DH */
3587 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3588 } else {
3589 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3593 } else {
3595 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3600 /*********************************************/
3601 /* GET LVDS DES (SKEW) DATA */
3602 /*********************************************/
3604 static const struct SiS_LVDSDes *
3605 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3607 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3609 #ifdef SIS300
3610 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3612 if(SiS_Pr->ChipType < SIS_315H) {
3613 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3614 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3615 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3616 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3617 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3619 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3620 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3621 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3622 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3628 #endif
3629 return PanelDesPtr;
3632 static void
3633 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3634 unsigned short RefreshRateTableIndex)
3636 unsigned short modeflag, ResIndex;
3637 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3639 SiS_Pr->SiS_LCDHDES = 0;
3640 SiS_Pr->SiS_LCDVDES = 0;
3642 /* Some special cases */
3643 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3645 /* Trumpion */
3646 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3647 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3648 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3649 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3652 return;
3655 /* 640x480 on LVDS */
3656 if(SiS_Pr->ChipType < SIS_315H) {
3657 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3658 SiS_Pr->SiS_LCDHDES = 8;
3659 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3660 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3661 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3662 return;
3666 } /* LCD */
3668 if( (SiS_Pr->UseCustomMode) ||
3669 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3670 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3671 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3672 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3673 return;
3676 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3677 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3679 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3681 #ifdef SIS315H
3682 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3683 /* non-pass 1:1 only, see above */
3684 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3685 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3687 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3688 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3691 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3692 switch(SiS_Pr->SiS_CustomT) {
3693 case CUT_UNIWILL1024:
3694 case CUT_UNIWILL10242:
3695 case CUT_CLEVO1400:
3696 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3697 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3699 break;
3701 switch(SiS_Pr->SiS_LCDResInfo) {
3702 case Panel_1280x1024:
3703 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3704 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3706 break;
3707 case Panel_1280x800: /* Verified for Averatec 6240 */
3708 case Panel_1280x800_2: /* Verified for Asus A4L */
3709 case Panel_1280x854:
3710 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3711 break;
3714 #endif
3716 } else {
3718 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3720 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3721 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3724 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3726 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3727 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3729 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3731 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3732 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3734 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3735 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3736 } else {
3737 if(SiS_Pr->ChipType < SIS_315H) {
3738 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3739 } else {
3740 switch(SiS_Pr->SiS_LCDResInfo) {
3741 case Panel_800x600:
3742 case Panel_1024x768:
3743 case Panel_1280x1024:
3744 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3745 break;
3746 case Panel_1400x1050:
3747 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3748 break;
3753 } else {
3755 if(SiS_Pr->ChipType < SIS_315H) {
3756 #ifdef SIS300
3757 switch(SiS_Pr->SiS_LCDResInfo) {
3758 case Panel_800x600:
3759 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3760 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3761 } else {
3762 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3763 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3764 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3765 else SiS_Pr->SiS_LCDVDES -= 4;
3767 break;
3768 case Panel_1024x768:
3769 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3770 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3771 } else {
3772 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3773 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3774 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3776 break;
3777 case Panel_1024x600:
3778 default:
3779 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3780 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3781 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3782 } else {
3783 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3785 break;
3788 switch(SiS_Pr->SiS_LCDTypeInfo) {
3789 case 1:
3790 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3791 break;
3792 case 3: /* 640x480 only? */
3793 SiS_Pr->SiS_LCDHDES = 8;
3794 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3795 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3796 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3797 break;
3799 #endif
3800 } else {
3801 #ifdef SIS315H
3802 switch(SiS_Pr->SiS_LCDResInfo) {
3803 case Panel_1024x768:
3804 case Panel_1280x1024:
3805 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3806 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3808 break;
3809 case Panel_320x240_1:
3810 case Panel_320x240_2:
3811 case Panel_320x240_3:
3812 SiS_Pr->SiS_LCDVDES = 524;
3813 break;
3815 #endif
3819 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3820 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3821 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3822 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3823 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3824 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3825 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3826 if(SiS_Pr->ChipType < SIS_315H) {
3827 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3828 } else {
3829 #ifdef SIS315H
3830 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3831 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3832 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3833 if(!(modeflag & HalfDCLK)) {
3834 SiS_Pr->SiS_LCDHDES = 320;
3835 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3836 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3838 #endif
3847 /*********************************************/
3848 /* DISABLE VIDEO BRIDGE */
3849 /*********************************************/
3851 #ifdef SIS315H
3852 static int
3853 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3855 int ret = 0;
3856 #ifdef SET_PWD
3857 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3858 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3859 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3860 unsigned short temp;
3862 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3863 (romptr) &&
3864 (SiS_Pr->SiS_PWDOffset) ) {
3865 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3866 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3867 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3868 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3869 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3870 temp = 0x00;
3871 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3872 temp = 0x80;
3873 ret = 1;
3875 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3876 #ifdef SIS_XORG_XF86
3877 #ifdef TWDEBUG
3878 xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
3879 #endif
3880 #endif
3882 #endif
3883 return ret;
3885 #endif
3887 /* NEVER use any variables (VBInfo), this will be called
3888 * from outside the context of modeswitch!
3889 * MUST call getVBType before calling this
3891 void
3892 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3894 #ifdef SIS315H
3895 unsigned short tempah, pushax=0, modenum;
3896 #endif
3897 unsigned short temp=0;
3899 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3901 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3903 if(SiS_Pr->ChipType < SIS_315H) {
3905 #ifdef SIS300 /* 300 series */
3907 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3908 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3909 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3910 } else {
3911 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3913 SiS_PanelDelay(SiS_Pr, 3);
3915 if(SiS_Is301B(SiS_Pr)) {
3916 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3917 SiS_ShortDelay(SiS_Pr,1);
3919 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3920 SiS_DisplayOff(SiS_Pr);
3921 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3922 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3923 SiS_UnLockCRT2(SiS_Pr);
3924 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3925 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3926 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3928 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3929 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3930 SiS_PanelDelay(SiS_Pr, 2);
3931 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3932 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3933 } else {
3934 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3938 #endif /* SIS300 */
3940 } else {
3942 #ifdef SIS315H /* 315 series */
3944 int didpwd = 0;
3945 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3946 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
3948 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3950 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3952 #ifdef SET_EMI
3953 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3954 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3955 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3958 #endif
3960 didpwd = SiS_HandlePWD(SiS_Pr);
3962 if( (modenum <= 0x13) ||
3963 (SiS_IsVAMode(SiS_Pr)) ||
3964 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3965 if(!didpwd) {
3966 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3967 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3968 } else {
3969 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3973 if(!custom1) {
3974 SiS_DDC2Delay(SiS_Pr,0xff00);
3975 SiS_DDC2Delay(SiS_Pr,0xe000);
3976 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3977 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3978 if(IS_SIS740) {
3979 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3981 SiS_PanelDelay(SiS_Pr, 3);
3986 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
3987 /* if(SiS_Pr->ChipType < SIS_340) {*/
3988 tempah = 0xef;
3989 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
3990 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3991 /*}*/
3994 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3995 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3998 tempah = 0x3f;
3999 if(SiS_IsDualEdge(SiS_Pr)) {
4000 tempah = 0x7f;
4001 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4003 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4005 if((SiS_IsVAMode(SiS_Pr)) ||
4006 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4008 SiS_DisplayOff(SiS_Pr);
4009 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4010 SiS_PanelDelay(SiS_Pr, 2);
4012 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4013 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4017 if((!(SiS_IsVAMode(SiS_Pr))) ||
4018 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4020 if(!(SiS_IsDualEdge(SiS_Pr))) {
4021 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4022 SiS_DisplayOff(SiS_Pr);
4024 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4026 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4027 SiS_PanelDelay(SiS_Pr, 2);
4030 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4031 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4032 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4033 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4034 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4038 if(SiS_IsNotM650orLater(SiS_Pr)) {
4039 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4042 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4044 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4045 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4046 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4048 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4049 if(!didpwd) {
4050 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4052 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4055 if(!custom1) {
4056 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4057 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4058 if(SiS_IsVAorLCD(SiS_Pr)) {
4059 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4066 #endif /* SIS315H */
4070 } else { /* ============ For 301 ================ */
4072 if(SiS_Pr->ChipType < SIS_315H) {
4073 #ifdef SIS300
4074 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4075 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4076 SiS_PanelDelay(SiS_Pr, 3);
4078 #endif
4081 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4082 SiS_DisplayOff(SiS_Pr);
4084 if(SiS_Pr->ChipType >= SIS_315H) {
4085 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4088 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4090 if(SiS_Pr->ChipType >= SIS_315H) {
4091 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4092 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4093 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4094 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4095 } else {
4096 #ifdef SIS300
4097 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4098 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4099 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4100 SiS_PanelDelay(SiS_Pr, 2);
4101 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4103 #endif
4108 } else { /* ============ For LVDS =============*/
4110 if(SiS_Pr->ChipType < SIS_315H) {
4112 #ifdef SIS300 /* 300 series */
4114 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4115 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4118 if(SiS_Pr->ChipType == SIS_730) {
4119 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4120 SiS_WaitVBRetrace(SiS_Pr);
4122 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4123 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4124 SiS_PanelDelay(SiS_Pr, 3);
4126 } else {
4127 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4128 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4129 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4130 SiS_WaitVBRetrace(SiS_Pr);
4131 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4132 SiS_DisplayOff(SiS_Pr);
4134 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4135 SiS_PanelDelay(SiS_Pr, 3);
4141 SiS_DisplayOff(SiS_Pr);
4143 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4145 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4146 SiS_UnLockCRT2(SiS_Pr);
4147 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4148 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4150 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4151 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4152 SiS_PanelDelay(SiS_Pr, 2);
4153 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4156 #endif /* SIS300 */
4158 } else {
4160 #ifdef SIS315H /* 315 series */
4162 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4163 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4164 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4165 /* } */
4168 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4170 if(SiS_Pr->ChipType == SIS_740) {
4171 temp = SiS_GetCH701x(SiS_Pr,0x61);
4172 if(temp < 1) {
4173 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4174 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4177 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4178 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4179 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4183 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4184 (SiS_IsVAMode(SiS_Pr)) ) {
4185 SiS_Chrontel701xBLOff(SiS_Pr);
4186 SiS_Chrontel701xOff(SiS_Pr);
4189 if(SiS_Pr->ChipType != SIS_740) {
4190 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4191 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4192 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4198 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4199 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4200 SiS_PanelDelay(SiS_Pr, 3);
4203 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4204 (!(SiS_IsDualEdge(SiS_Pr))) ||
4205 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4206 SiS_DisplayOff(SiS_Pr);
4209 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4210 (!(SiS_IsDualEdge(SiS_Pr))) ||
4211 (!(SiS_IsVAMode(SiS_Pr))) ) {
4212 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4215 if(SiS_Pr->ChipType == SIS_740) {
4216 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4219 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4221 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4222 (!(SiS_IsDualEdge(SiS_Pr))) ||
4223 (!(SiS_IsVAMode(SiS_Pr))) ) {
4224 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4227 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4228 if(SiS_CRT2IsLCD(SiS_Pr)) {
4229 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4230 if(SiS_Pr->ChipType == SIS_550) {
4231 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4232 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4235 } else {
4236 if(SiS_Pr->ChipType == SIS_740) {
4237 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4238 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4240 } else if(SiS_IsVAMode(SiS_Pr)) {
4241 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4245 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4246 if(SiS_IsDualEdge(SiS_Pr)) {
4247 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4248 } else {
4249 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4253 SiS_UnLockCRT2(SiS_Pr);
4255 if(SiS_Pr->ChipType == SIS_550) {
4256 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4257 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4258 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4259 (!(SiS_IsDualEdge(SiS_Pr))) ||
4260 (!(SiS_IsVAMode(SiS_Pr))) ) {
4261 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4264 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4265 if(SiS_CRT2IsLCD(SiS_Pr)) {
4266 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4267 SiS_PanelDelay(SiS_Pr, 2);
4268 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4273 #endif /* SIS315H */
4275 } /* 315 series */
4277 } /* LVDS */
4281 /*********************************************/
4282 /* ENABLE VIDEO BRIDGE */
4283 /*********************************************/
4285 /* NEVER use any variables (VBInfo), this will be called
4286 * from outside the context of a mode switch!
4287 * MUST call getVBType before calling this
4289 #ifdef SIS_LINUX_KERNEL
4290 static
4291 #endif
4292 void
4293 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4295 unsigned short temp=0, tempah;
4296 #ifdef SIS315H
4297 unsigned short temp1, pushax=0;
4298 bool delaylong = false;
4299 #endif
4301 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4303 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4305 if(SiS_Pr->ChipType < SIS_315H) {
4307 #ifdef SIS300 /* 300 series */
4309 if(SiS_CRT2IsLCD(SiS_Pr)) {
4310 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4311 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4312 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4313 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4315 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4316 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4317 SiS_PanelDelay(SiS_Pr, 0);
4322 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4323 (SiS_CRT2IsLCD(SiS_Pr))) {
4325 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4326 SiS_DisplayOn(SiS_Pr);
4327 SiS_UnLockCRT2(SiS_Pr);
4328 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4329 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4330 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4331 } else {
4332 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4334 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4335 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4336 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4337 SiS_PanelDelay(SiS_Pr, 1);
4339 SiS_WaitVBRetrace(SiS_Pr);
4340 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4344 } else {
4346 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4347 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4348 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4349 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4351 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4352 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4353 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4354 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4355 SiS_DisplayOn(SiS_Pr);
4356 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4357 if(SiS_CRT2IsLCD(SiS_Pr)) {
4358 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4359 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4360 SiS_PanelDelay(SiS_Pr, 1);
4362 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4370 #endif /* SIS300 */
4372 } else {
4374 #ifdef SIS315H /* 315 series */
4376 #ifdef SET_EMI
4377 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4378 int didpwd = 0;
4379 /* unsigned short emidelay=0; */
4380 #endif
4382 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4383 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4384 #ifdef SET_EMI
4385 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4386 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4388 #endif
4391 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4392 /*if(SiS_Pr->ChipType < SIS_340) { */
4393 tempah = 0x10;
4394 if(SiS_LCDAEnabled(SiS_Pr)) {
4395 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4396 else tempah = 0x08;
4398 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4399 /*}*/
4402 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4404 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4405 SiS_DisplayOff(SiS_Pr);
4406 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4407 if(IS_SIS740) {
4408 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4411 didpwd = SiS_HandlePWD(SiS_Pr);
4413 if(SiS_IsVAorLCD(SiS_Pr)) {
4414 if(!didpwd) {
4415 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4416 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4417 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4418 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4419 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4420 SiS_GenericDelay(SiS_Pr, 17664);
4423 } else {
4424 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4425 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4426 SiS_GenericDelay(SiS_Pr, 17664);
4431 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4432 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4433 delaylong = true;
4438 if(!(SiS_IsVAMode(SiS_Pr))) {
4440 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4441 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4442 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4443 if(!(tempah & SetCRT2ToRAMDAC)) {
4444 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4447 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4449 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4451 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4452 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4454 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4455 SiS_PanelDelay(SiS_Pr, 2);
4458 } else {
4460 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4464 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4465 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4467 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4468 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4469 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4470 /* Enable "LVDS PLL power on" (even on 301C) */
4471 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4472 /* Enable "LVDS Driver Power on" (even on 301C) */
4473 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4477 tempah = 0xc0;
4478 if(SiS_IsDualEdge(SiS_Pr)) {
4479 tempah = 0x80;
4480 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4482 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4484 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4486 SiS_PanelDelay(SiS_Pr, 2);
4488 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4489 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4491 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4492 #ifdef SET_EMI
4493 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4494 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4495 SiS_GenericDelay(SiS_Pr, 2048);
4497 #endif
4498 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4500 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4501 #ifdef SET_EMI
4502 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4504 if(SiS_Pr->SiS_ROMNew) {
4505 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4506 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4507 if(romptr) {
4508 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4509 SiS_Pr->EMI_30 = 0;
4510 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4511 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4512 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4513 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4514 /* emidelay = SISGETROMW((romptr + 0x22)); */
4515 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4519 /* (P4_30|0x40) */
4520 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4521 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4522 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4523 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4524 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4525 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4526 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4527 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4528 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4530 if(SiS_Pr->HaveEMI) {
4531 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4532 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4533 } else {
4534 r30 = 0;
4538 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4539 switch((cr36 & 0x0f)) {
4540 case 2:
4541 r30 |= 0x40;
4542 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4543 if(!SiS_Pr->HaveEMI) {
4544 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4545 if((cr36 & 0xf0) == 0x30) {
4546 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4549 break;
4550 case 3: /* 1280x1024 */
4551 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4552 if(!SiS_Pr->HaveEMI) {
4553 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4554 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4555 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4558 break;
4559 case 9: /* 1400x1050 */
4560 r30 |= 0x40;
4561 if(!SiS_Pr->HaveEMI) {
4562 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4563 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4564 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4567 break;
4568 case 11: /* 1600x1200 - unknown */
4569 r30 |= 0x40;
4570 if(!SiS_Pr->HaveEMI) {
4571 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4576 /* BIOS values don't work so well sometimes */
4577 if(!SiS_Pr->OverruleEMI) {
4578 #ifdef COMPAL_HACK
4579 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4580 if((cr36 & 0x0f) == 0x09) {
4581 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4584 #endif
4585 #ifdef COMPAQ_HACK
4586 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4587 if((cr36 & 0x0f) == 0x03) {
4588 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4591 #endif
4592 #ifdef ASUS_HACK
4593 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4594 if((cr36 & 0x0f) == 0x02) {
4595 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4596 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4597 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4598 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4601 #endif
4604 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4605 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4606 SiS_GenericDelay(SiS_Pr, 2048);
4608 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4609 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4610 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4611 #endif /* SET_EMI */
4613 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4615 #ifdef SET_EMI
4616 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4617 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4618 if(r30 & 0x40) {
4619 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4620 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4621 if(delaylong) {
4622 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4623 delaylong = false;
4625 SiS_WaitVBRetrace(SiS_Pr);
4626 SiS_WaitVBRetrace(SiS_Pr);
4627 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4628 SiS_GenericDelay(SiS_Pr, 1280);
4630 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4631 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4634 #endif
4638 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4639 if(SiS_IsVAorLCD(SiS_Pr)) {
4640 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4641 if(delaylong) {
4642 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4644 SiS_WaitVBRetrace(SiS_Pr);
4645 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4646 SiS_GenericDelay(SiS_Pr, 2048);
4647 SiS_WaitVBRetrace(SiS_Pr);
4649 if(!didpwd) {
4650 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4651 } else {
4652 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4657 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4658 SiS_DisplayOn(SiS_Pr);
4659 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4663 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4664 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4667 #endif /* SIS315H */
4671 } else { /* ============ For 301 ================ */
4673 if(SiS_Pr->ChipType < SIS_315H) {
4674 if(SiS_CRT2IsLCD(SiS_Pr)) {
4675 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4676 SiS_PanelDelay(SiS_Pr, 0);
4680 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4681 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4682 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4683 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4685 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4687 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4689 if(SiS_Pr->ChipType >= SIS_315H) {
4690 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4691 if(!(temp & 0x80)) {
4692 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4696 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4698 SiS_VBLongWait(SiS_Pr);
4699 SiS_DisplayOn(SiS_Pr);
4700 if(SiS_Pr->ChipType >= SIS_315H) {
4701 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4703 SiS_VBLongWait(SiS_Pr);
4705 if(SiS_Pr->ChipType < SIS_315H) {
4706 if(SiS_CRT2IsLCD(SiS_Pr)) {
4707 SiS_PanelDelay(SiS_Pr, 1);
4708 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4714 } else { /* =================== For LVDS ================== */
4716 if(SiS_Pr->ChipType < SIS_315H) {
4718 #ifdef SIS300 /* 300 series */
4720 if(SiS_CRT2IsLCD(SiS_Pr)) {
4721 if(SiS_Pr->ChipType == SIS_730) {
4722 SiS_PanelDelay(SiS_Pr, 1);
4723 SiS_PanelDelay(SiS_Pr, 1);
4724 SiS_PanelDelay(SiS_Pr, 1);
4726 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4727 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4728 SiS_PanelDelay(SiS_Pr, 0);
4732 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4733 SiS_DisplayOn(SiS_Pr);
4734 SiS_UnLockCRT2(SiS_Pr);
4735 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4736 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4737 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4738 } else {
4739 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4742 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4743 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4744 SiS_WaitVBRetrace(SiS_Pr);
4745 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4749 if(SiS_CRT2IsLCD(SiS_Pr)) {
4750 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4751 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4752 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4753 SiS_PanelDelay(SiS_Pr, 1);
4754 SiS_PanelDelay(SiS_Pr, 1);
4756 SiS_WaitVBRetrace(SiS_Pr);
4757 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4762 #endif /* SIS300 */
4764 } else {
4766 #ifdef SIS315H /* 315 series */
4768 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4769 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4770 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4771 /*}*/
4774 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4775 if(SiS_CRT2IsLCD(SiS_Pr)) {
4776 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4777 SiS_PanelDelay(SiS_Pr, 0);
4781 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4782 SiS_UnLockCRT2(SiS_Pr);
4784 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4786 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4787 temp = SiS_GetCH701x(SiS_Pr,0x66);
4788 temp &= 0x20;
4789 SiS_Chrontel701xBLOff(SiS_Pr);
4792 if(SiS_Pr->ChipType != SIS_550) {
4793 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4796 if(SiS_Pr->ChipType == SIS_740) {
4797 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4798 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4799 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4804 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4805 if(!(temp1 & 0x80)) {
4806 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4809 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4810 if(temp) {
4811 SiS_Chrontel701xBLOn(SiS_Pr);
4815 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4816 if(SiS_CRT2IsLCD(SiS_Pr)) {
4817 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4818 if(SiS_Pr->ChipType == SIS_550) {
4819 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4820 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4823 } else if(SiS_IsVAMode(SiS_Pr)) {
4824 if(SiS_Pr->ChipType != SIS_740) {
4825 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4829 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4830 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4833 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4834 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4835 SiS_Chrontel701xOn(SiS_Pr);
4837 if( (SiS_IsVAMode(SiS_Pr)) ||
4838 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4839 SiS_ChrontelDoSomething1(SiS_Pr);
4843 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4844 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4845 if( (SiS_IsVAMode(SiS_Pr)) ||
4846 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4847 SiS_Chrontel701xBLOn(SiS_Pr);
4848 SiS_ChrontelInitTVVSync(SiS_Pr);
4851 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4852 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4853 if(SiS_CRT2IsLCD(SiS_Pr)) {
4854 SiS_PanelDelay(SiS_Pr, 1);
4855 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4860 #endif /* SIS315H */
4862 } /* 310 series */
4864 } /* LVDS */
4868 /*********************************************/
4869 /* SET PART 1 REGISTER GROUP */
4870 /*********************************************/
4872 /* Set CRT2 OFFSET / PITCH */
4873 static void
4874 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4875 unsigned short RRTI)
4877 unsigned short offset;
4878 unsigned char temp;
4880 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4882 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4885 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4887 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4888 if(offset & 0x07) temp++;
4889 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4892 /* Set CRT2 sync and PanelLink mode */
4893 static void
4894 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4896 unsigned short tempah=0, tempbl, infoflag;
4898 tempbl = 0xC0;
4900 if(SiS_Pr->UseCustomMode) {
4901 infoflag = SiS_Pr->CInfoFlag;
4902 } else {
4903 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4906 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4908 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4909 tempah = 0;
4910 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4911 tempah = SiS_Pr->SiS_LCDInfo;
4912 } else tempah = infoflag >> 8;
4913 tempah &= 0xC0;
4914 tempah |= 0x20;
4915 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4916 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4917 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4918 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4919 tempah |= 0xf0;
4921 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4922 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4923 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4924 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4925 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4926 tempah |= 0x30;
4928 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4929 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4930 tempah &= ~0xc0;
4933 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4934 if(SiS_Pr->ChipType >= SIS_315H) {
4935 tempah >>= 3;
4936 tempah &= 0x18;
4937 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4938 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4939 } else {
4940 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4942 } else {
4943 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4946 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4948 if(SiS_Pr->ChipType < SIS_315H) {
4950 #ifdef SIS300 /* ---- 300 series --- */
4952 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4954 tempah = infoflag >> 8;
4955 tempbl = 0;
4956 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4957 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4958 tempah = SiS_Pr->SiS_LCDInfo;
4959 tempbl = (tempah >> 6) & 0x03;
4962 tempah &= 0xC0;
4963 tempah |= 0x20;
4964 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4965 tempah |= 0xc0;
4966 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4967 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4968 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4971 } else { /* 630 - 301 */
4973 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4974 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4975 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4979 #endif /* SIS300 */
4981 } else {
4983 #ifdef SIS315H /* ------- 315 series ------ */
4985 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
4987 tempbl = 0;
4988 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4989 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4990 tempah = infoflag >> 8;
4991 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4992 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4994 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4995 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4996 tempah = infoflag >> 8;
4997 tempbl = 0x03;
4998 } else {
4999 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5000 tempbl = (tempah >> 6) & 0x03;
5001 tempbl |= 0x08;
5002 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5004 tempah &= 0xC0;
5005 tempah |= 0x20;
5006 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5007 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
5008 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5009 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5010 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5011 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5015 } else { /* 315 - TMDS */
5017 tempah = tempbl = infoflag >> 8;
5018 if(!SiS_Pr->UseCustomMode) {
5019 tempbl = 0;
5020 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5021 if(ModeNo <= 0x13) {
5022 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5025 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5026 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5027 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5028 tempah = SiS_Pr->SiS_LCDInfo;
5029 tempbl = (tempah >> 6) & 0x03;
5034 tempah &= 0xC0;
5035 tempah |= 0x20;
5036 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5037 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5038 /* Imitate BIOS bug */
5039 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5041 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5042 tempah >>= 3;
5043 tempah &= 0x18;
5044 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5045 } else {
5046 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5047 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5048 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5049 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5055 #endif /* SIS315H */
5060 /* Set CRT2 FIFO on 300/540/630/730 */
5061 #ifdef SIS300
5062 static void
5063 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5065 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5066 unsigned short temp, index, modeidindex, refreshratetableindex;
5067 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5068 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5069 unsigned int data, pci50, pciA0;
5070 static const unsigned char colortharray[] = {
5071 1, 1, 2, 2, 3, 4
5074 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5076 if(!SiS_Pr->CRT1UsesCustomMode) {
5078 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5079 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5080 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5081 SiS_Pr->SiS_SelectCRT2Rate = 0;
5082 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5084 if(CRT1ModeNo >= 0x13) {
5085 /* Get VCLK */
5086 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5087 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5089 /* Get colordepth */
5090 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5091 if(!colorth) colorth++;
5094 } else {
5096 CRT1ModeNo = 0xfe;
5098 /* Get VCLK */
5099 VCLK = SiS_Pr->CSRClock_CRT1;
5101 /* Get color depth */
5102 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5106 if(CRT1ModeNo >= 0x13) {
5107 /* Get MCLK */
5108 if(SiS_Pr->ChipType == SIS_300) {
5109 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5110 } else {
5111 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5113 index &= 0x07;
5114 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5116 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5117 if(!temp) temp++;
5118 temp <<= 2;
5120 data2 = temp - ((colorth * VCLK) / MCLK);
5122 temp = (28 * 16) % data2;
5123 data2 = (28 * 16) / data2;
5124 if(temp) data2++;
5126 if(SiS_Pr->ChipType == SIS_300) {
5128 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5129 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5131 } else {
5133 #ifdef SIS_LINUX_KERNEL
5134 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5135 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5136 #else
5137 pci50 = pciReadLong(0x00000000, 0x50);
5138 pciA0 = pciReadLong(0x00000000, 0xA0);
5139 #endif
5141 if(SiS_Pr->ChipType == SIS_730) {
5143 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5144 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5146 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5147 index = 0; /* -- do it like the BIOS anyway... */
5149 } else {
5151 pci50 >>= 24;
5152 pciA0 >>= 24;
5154 index = (pci50 >> 1) & 0x07;
5156 if(pci50 & 0x01) index += 6;
5157 if(!(pciA0 & 0x01)) index += 24;
5159 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5163 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5164 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5168 data += data2; /* CRT1 Request Period */
5170 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5171 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5173 if(!SiS_Pr->UseCustomMode) {
5175 CRT2ModeNo = ModeNo;
5176 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5178 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5180 /* Get VCLK */
5181 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5182 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5184 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5185 if(SiS_Pr->SiS_UseROM) {
5186 if(ROMAddr[0x220] & 0x01) {
5187 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5192 } else {
5194 /* Get VCLK */
5195 CRT2ModeNo = 0xfe;
5196 VCLK = SiS_Pr->CSRClock;
5200 /* Get colordepth */
5201 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5202 if(!colorth) colorth++;
5204 data = data * VCLK * colorth;
5205 temp = data % (MCLK << 4);
5206 data = data / (MCLK << 4);
5207 if(temp) data++;
5209 if(data < 6) data = 6;
5210 else if(data > 0x14) data = 0x14;
5212 if(SiS_Pr->ChipType == SIS_300) {
5213 temp = 0x16;
5214 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5215 temp = 0x13;
5216 } else {
5217 temp = 0x16;
5218 if(( (SiS_Pr->ChipType == SIS_630) ||
5219 (SiS_Pr->ChipType == SIS_730) ) &&
5220 (SiS_Pr->ChipRevision >= 0x30))
5221 temp = 0x1b;
5223 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5225 if((SiS_Pr->ChipType == SIS_630) &&
5226 (SiS_Pr->ChipRevision >= 0x30)) {
5227 if(data > 0x13) data = 0x13;
5229 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5231 } else { /* If mode <= 0x13, we just restore everything */
5233 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5234 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5238 #endif
5240 /* Set CRT2 FIFO on 315/330 series */
5241 #ifdef SIS315H
5242 static void
5243 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5245 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5246 if( (SiS_Pr->ChipType == SIS_760) &&
5247 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5248 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5249 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5250 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5251 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5252 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5253 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5254 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5255 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5256 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5257 } else {
5258 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5262 #endif
5264 static unsigned short
5265 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5267 unsigned int tempax,tempbx;
5269 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5270 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5271 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5272 return (unsigned short)tempax;
5275 /* Set Part 1 / SiS bridge slave mode */
5276 static void
5277 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5278 unsigned short RefreshRateTableIndex)
5280 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5281 static const unsigned short CRTranslation[] = {
5282 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5283 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5284 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5285 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5286 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5287 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5290 if(ModeNo <= 0x13) {
5291 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5292 } else if(SiS_Pr->UseCustomMode) {
5293 modeflag = SiS_Pr->CModeFlag;
5294 xres = SiS_Pr->CHDisplay;
5295 } else {
5296 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5297 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5300 /* The following is only done if bridge is in slave mode: */
5302 if(SiS_Pr->ChipType >= SIS_315H) {
5303 if(xres >= 1600) { /* BIOS: == 1600 */
5304 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5308 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5310 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5311 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5313 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5314 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5315 SiS_Pr->CHBlankStart += 16;
5318 SiS_Pr->CHBlankEnd = 32;
5319 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5320 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5323 temp = SiS_Pr->SiS_VGAHT - 96;
5324 if(!(modeflag & HalfDCLK)) temp -= 32;
5325 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5326 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5327 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5328 temp -= 3;
5329 temp <<= 3;
5330 } else {
5331 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5333 SiS_Pr->CHSyncStart = temp;
5335 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5337 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5339 VGAVDE = SiS_Pr->SiS_VGAVDE;
5340 if (VGAVDE == 357) VGAVDE = 350;
5341 else if(VGAVDE == 360) VGAVDE = 350;
5342 else if(VGAVDE == 375) VGAVDE = 350;
5343 else if(VGAVDE == 405) VGAVDE = 400;
5344 else if(VGAVDE == 420) VGAVDE = 400;
5345 else if(VGAVDE == 525) VGAVDE = 480;
5346 else if(VGAVDE == 1056) VGAVDE = 1024;
5347 SiS_Pr->CVDisplay = VGAVDE;
5349 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5351 SiS_Pr->CVBlankEnd = 1;
5352 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5354 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5355 SiS_Pr->CVSyncStart = VGAVDE + temp;
5357 temp >>= 3;
5358 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5360 SiS_CalcCRRegisters(SiS_Pr, 0);
5361 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5363 for(i = 0; i <= 7; i++) {
5364 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5366 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5367 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5369 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5370 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5372 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5373 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5376 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5377 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5379 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5380 if(modeflag & DoubleScanMode) temp |= 0x80;
5381 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5383 temp = 0;
5384 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5385 if(modeflag & HalfDCLK) temp |= 0x08;
5386 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5388 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5389 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5391 temp = 0;
5392 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5393 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5395 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5397 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5398 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5400 #ifdef SIS_XORG_XF86
5401 #ifdef TWDEBUG
5402 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
5403 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
5404 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
5405 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
5407 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5408 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
5409 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
5410 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
5411 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
5412 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5413 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
5414 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
5415 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
5416 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
5417 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
5418 #endif
5419 #endif
5422 /* Setup panel link
5423 * This is used for LVDS, LCDA and Chrontel TV output
5424 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5426 static void
5427 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5428 unsigned short RefreshRateTableIndex)
5430 unsigned short modeflag, resinfo = 0;
5431 unsigned short push2, tempax, tempbx, tempcx, temp;
5432 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5433 bool islvds = false, issis = false, chkdclkfirst = false;
5434 #ifdef SIS300
5435 unsigned short crt2crtc = 0;
5436 #endif
5437 #ifdef SIS315H
5438 unsigned short pushcx;
5439 #endif
5441 if(ModeNo <= 0x13) {
5442 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5443 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5444 #ifdef SIS300
5445 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5446 #endif
5447 } else if(SiS_Pr->UseCustomMode) {
5448 modeflag = SiS_Pr->CModeFlag;
5449 } else {
5450 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5451 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5452 #ifdef SIS300
5453 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5454 #endif
5457 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5458 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5459 islvds = true;
5462 /* is really sis if sis bridge, but not 301B-DH */
5463 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5464 issis = true;
5467 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5468 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5469 chkdclkfirst = true;
5473 #ifdef SIS315H
5474 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5475 if(IS_SIS330) {
5476 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5477 } else if(IS_SIS740) {
5478 if(islvds) {
5479 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5480 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5481 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5482 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5484 } else {
5485 if(islvds) {
5486 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5487 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5488 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5489 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5490 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5491 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5492 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5493 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5499 #endif
5501 /* Horizontal */
5503 tempax = SiS_Pr->SiS_LCDHDES;
5504 if(islvds) {
5505 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5506 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5507 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5508 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5509 tempax -= 8;
5515 temp = (tempax & 0x0007);
5516 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5517 temp = (tempax >> 3) & 0x00FF;
5518 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5520 tempbx = SiS_Pr->SiS_HDE;
5521 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5522 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5523 tempbx = SiS_Pr->PanelXRes;
5525 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5526 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5527 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5528 tempbx >>= 1;
5532 tempax += tempbx;
5533 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5535 temp = tempax;
5536 if(temp & 0x07) temp += 8;
5537 temp >>= 3;
5538 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5540 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5542 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5543 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5544 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5548 tempcx += tempax;
5549 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5551 temp = (tempcx >> 3) & 0x00FF;
5552 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5553 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5554 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5555 switch(ModeNo) {
5556 case 0x04:
5557 case 0x05:
5558 case 0x0d: temp = 0x56; break;
5559 case 0x10: temp = 0x60; break;
5560 case 0x13: temp = 0x5f; break;
5561 case 0x40:
5562 case 0x41:
5563 case 0x4f:
5564 case 0x43:
5565 case 0x44:
5566 case 0x62:
5567 case 0x56:
5568 case 0x53:
5569 case 0x5d:
5570 case 0x5e: temp = 0x54; break;
5575 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5577 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5578 temp += 2;
5579 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5580 temp += 8;
5581 if(SiS_Pr->PanelHRE != 999) {
5582 temp = tempcx + SiS_Pr->PanelHRE;
5583 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5584 temp >>= 3;
5587 } else {
5588 temp += 10;
5591 temp &= 0x1F;
5592 temp |= ((tempcx & 0x07) << 5);
5593 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5595 /* Vertical */
5597 tempax = SiS_Pr->SiS_VGAVDE;
5598 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5599 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5600 tempax = SiS_Pr->PanelYRes;
5604 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5605 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5607 push2 = tempbx;
5609 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5610 if(SiS_Pr->ChipType < SIS_315H) {
5611 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5612 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5613 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5617 if(islvds) tempcx >>= 1;
5618 else tempcx >>= 2;
5620 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5621 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5622 (SiS_Pr->PanelVRS != 999) ) {
5623 tempcx = SiS_Pr->PanelVRS;
5624 tempbx += tempcx;
5625 if(issis) tempbx++;
5626 } else {
5627 tempbx += tempcx;
5628 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5629 else if(issis) tempbx++;
5632 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5634 temp = tempbx & 0x00FF;
5635 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5636 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5637 if(ModeNo == 0x10) temp = 0xa9;
5640 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5642 tempcx >>= 3;
5643 tempcx++;
5645 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5646 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5647 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5651 tempcx += tempbx;
5652 temp = tempcx & 0x000F;
5653 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5655 temp = ((tempbx >> 8) & 0x07) << 3;
5656 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5657 if(SiS_Pr->SiS_HDE != 640) {
5658 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5660 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5661 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5662 tempbx = 0x87;
5663 if((SiS_Pr->ChipType >= SIS_315H) ||
5664 (SiS_Pr->ChipRevision >= 0x30)) {
5665 tempbx = 0x07;
5666 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5667 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5669 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5670 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5671 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5672 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5673 } else {
5674 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5678 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5680 tempbx = push2; /* BPLVDEE */
5682 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5684 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5685 switch(SiS_Pr->SiS_LCDResInfo) {
5686 case Panel_640x480:
5687 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5688 tempcx = SiS_Pr->SiS_VGAVDE;
5689 break;
5690 case Panel_800x600:
5691 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5692 if(resinfo == SIS_RI_800x600) tempcx++;
5694 break;
5695 case Panel_1024x600:
5696 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5697 if(resinfo == SIS_RI_1024x600) tempcx++;
5698 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5699 if(resinfo == SIS_RI_800x600) tempcx++;
5702 break;
5703 case Panel_1024x768:
5704 if(SiS_Pr->ChipType < SIS_315H) {
5705 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5706 if(resinfo == SIS_RI_1024x768) tempcx++;
5709 break;
5713 temp = ((tempbx >> 8) & 0x07) << 3;
5714 temp |= ((tempcx >> 8) & 0x07);
5715 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5716 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5717 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5719 /* Vertical scaling */
5721 if(SiS_Pr->ChipType < SIS_315H) {
5723 #ifdef SIS300 /* 300 series */
5724 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5725 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5726 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5727 if(temp) tempeax++;
5729 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5731 temp = (unsigned short)(tempeax & 0x00FF);
5732 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5733 tempvcfact = temp;
5734 #endif /* SIS300 */
5736 } else {
5738 #ifdef SIS315H /* 315 series */
5739 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5740 tempebx = SiS_Pr->SiS_VDE;
5741 temp = (tempeax % tempebx);
5742 tempeax = tempeax / tempebx;
5743 if(temp) tempeax++;
5744 tempvcfact = tempeax;
5746 temp = (unsigned short)(tempeax & 0x00FF);
5747 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5748 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5749 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5750 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5751 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5752 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5754 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5755 temp = (unsigned short)(tempeax & 0x00FF);
5756 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5757 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5758 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5759 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5760 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5761 temp = 0;
5762 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5763 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5765 #endif
5769 /* Horizontal scaling */
5771 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5772 if(chkdclkfirst) {
5773 if(modeflag & HalfDCLK) tempeax >>= 1;
5775 tempebx = tempeax << 16;
5776 if(SiS_Pr->SiS_HDE == tempeax) {
5777 tempecx = 0xFFFF;
5778 } else {
5779 tempecx = tempebx / SiS_Pr->SiS_HDE;
5780 if(SiS_Pr->ChipType >= SIS_315H) {
5781 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5785 if(SiS_Pr->ChipType >= SIS_315H) {
5786 tempeax = (tempebx / tempecx) - 1;
5787 } else {
5788 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5790 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5791 temp = (unsigned short)(tempecx & 0x00FF);
5792 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5794 if(SiS_Pr->ChipType >= SIS_315H) {
5795 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5796 tempbx = (unsigned short)(tempeax & 0xFFFF);
5797 } else {
5798 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5799 tempbx = tempvcfact & 0x3f;
5800 if(tempbx == 0) tempbx = 64;
5801 tempeax /= tempbx;
5802 tempbx = (unsigned short)(tempeax & 0xFFFF);
5804 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5805 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5806 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5807 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5810 temp = ((tempbx >> 8) & 0x07) << 3;
5811 temp = temp | ((tempecx >> 8) & 0x07);
5812 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5813 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5815 tempecx >>= 16; /* BPLHCFACT */
5816 if(!chkdclkfirst) {
5817 if(modeflag & HalfDCLK) tempecx >>= 1;
5819 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5820 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5821 temp = (unsigned short)(tempecx & 0x00FF);
5822 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5824 #ifdef SIS315H
5825 if(SiS_Pr->ChipType >= SIS_315H) {
5826 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5827 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5828 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5830 } else {
5831 if(islvds) {
5832 if(SiS_Pr->ChipType == SIS_740) {
5833 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5834 } else {
5835 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5840 #endif
5842 #ifdef SIS300
5843 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5844 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5845 unsigned char *trumpdata;
5846 int i, j = crt2crtc;
5847 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5848 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5849 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5851 if(SiS_Pr->SiS_UseROM) {
5852 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5853 } else {
5854 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5855 trumpdata = &SiS300_TrumpionData[j][0];
5858 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5859 for(i=0; i<5; i++) {
5860 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5862 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5863 if(ModeNo == 0x13) {
5864 for(i=0; i<4; i++) {
5865 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5867 } else if(ModeNo == 0x10) {
5868 for(i=0; i<4; i++) {
5869 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5870 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5874 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5876 #endif
5878 #ifdef SIS315H
5879 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5880 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5881 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5882 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5883 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5885 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5886 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5887 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5888 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5889 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5890 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5891 tempax += 64;
5892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5893 temp = (tempax >> 8) << 3;
5894 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5895 tempax += 32; /* Blpe = lBlps+32 */
5896 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5897 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
5898 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5900 tempax = SiS_Pr->SiS_VDE;
5901 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5902 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5903 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5904 tempax >>= 1;
5905 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5906 temp = (tempax >> 8) << 3;
5907 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5909 tempeax = SiS_Pr->SiS_HDE;
5910 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5911 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5912 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5913 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5914 temp = tempeax & 0x7f;
5915 tempeax >>= 7;
5916 if(temp) tempeax++;
5917 temp = tempeax & 0x3f;
5918 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5919 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5920 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5921 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5922 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5924 tempax = SiS_Pr->SiS_HDE;
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;
5928 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5929 pushcx = tempax;
5930 temp = tempax & 0x00FF;
5931 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5932 temp = ((tempax & 0xFF00) >> 8) << 3;
5933 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5935 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5936 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5937 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5938 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5939 tempeax = tempax * pushcx;
5940 temp = tempeax & 0xFF;
5941 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5942 temp = (tempeax & 0xFF00) >> 8;
5943 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5944 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5945 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5946 temp = ((tempeax & 0x01000000) >> 24) << 7;
5947 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
5949 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5950 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5951 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5952 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5953 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5955 if(SiS_Pr->SiS_IF_DEF_FSTN) {
5956 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5957 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5958 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5959 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5960 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5961 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5962 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5963 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5964 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5965 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5966 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5967 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5968 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5969 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5970 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5971 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5972 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
5973 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
5974 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
5975 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
5978 #endif /* SIS315H */
5981 /* Set Part 1 */
5982 static void
5983 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5984 unsigned short RefreshRateTableIndex)
5986 #if defined(SIS300) || defined(SIS315H)
5987 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5988 #endif
5989 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
5990 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
5991 #ifdef SIS315H
5992 unsigned short tempbl=0;
5993 #endif
5995 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5996 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5997 return;
6000 if(ModeNo <= 0x13) {
6001 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6002 } else if(SiS_Pr->UseCustomMode) {
6003 modeflag = SiS_Pr->CModeFlag;
6004 } else {
6005 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6006 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6007 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6010 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6012 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6013 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6014 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6016 if(SiS_Pr->ChipType < SIS_315H ) {
6017 #ifdef SIS300
6018 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6019 #endif
6020 } else {
6021 #ifdef SIS315H
6022 SiS_SetCRT2FIFO_310(SiS_Pr);
6023 #endif
6026 /* 1. Horizontal setup */
6028 if(SiS_Pr->ChipType < SIS_315H ) {
6030 #ifdef SIS300 /* ------------- 300 series --------------*/
6032 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6033 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6035 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6036 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6038 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6039 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6041 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6042 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6043 tempbx = pushbx + tempcx;
6044 tempcx <<= 1;
6045 tempcx += tempbx;
6047 bridgeadd = 12;
6049 #endif /* SIS300 */
6051 } else {
6053 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6055 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6056 if(modeflag & HalfDCLK) {
6057 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6058 tempcx >>= 1;
6059 } else {
6060 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6061 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6062 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6063 tempcx = SiS_Pr->SiS_HT - tempax;
6067 tempcx--;
6068 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6069 temp = (tempcx >> 4) & 0xF0;
6070 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6072 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6073 tempbx = SiS_Pr->SiS_VGAHDE;
6074 tempcx -= tempbx;
6075 tempcx >>= 2;
6076 if(modeflag & HalfDCLK) {
6077 tempbx >>= 1;
6078 tempcx >>= 1;
6080 tempbx += 16;
6082 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6084 pushbx = tempbx;
6085 tempcx >>= 1;
6086 tempbx += tempcx;
6087 tempcx += tempbx;
6089 bridgeadd = 16;
6091 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6092 if(SiS_Pr->ChipType >= SIS_661) {
6093 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6094 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6095 if(resinfo == SIS_RI_1280x1024) {
6096 tempcx = (tempcx & 0xff00) | 0x30;
6097 } else if(resinfo == SIS_RI_1600x1200) {
6098 tempcx = (tempcx & 0xff00) | 0xff;
6104 #endif /* SIS315H */
6106 } /* 315/330 series */
6108 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6110 if(SiS_Pr->UseCustomMode) {
6111 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6112 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6113 tempax = SiS_Pr->SiS_VGAHT;
6114 if(modeflag & HalfDCLK) tempax >>= 1;
6115 tempax--;
6116 if(tempcx > tempax) tempcx = tempax;
6119 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6120 unsigned char cr4, cr14, cr5, cr15;
6121 if(SiS_Pr->UseCustomMode) {
6122 cr4 = SiS_Pr->CCRT1CRTC[4];
6123 cr14 = SiS_Pr->CCRT1CRTC[14];
6124 cr5 = SiS_Pr->CCRT1CRTC[5];
6125 cr15 = SiS_Pr->CCRT1CRTC[15];
6126 } else {
6127 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6128 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6129 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6130 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6132 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6133 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6134 tempcx &= 0x00FF;
6135 tempcx |= (tempbx & 0xFF00);
6136 tempbx += bridgeadd;
6137 tempcx += bridgeadd;
6138 tempax = SiS_Pr->SiS_VGAHT;
6139 if(modeflag & HalfDCLK) tempax >>= 1;
6140 tempax--;
6141 if(tempcx > tempax) tempcx = tempax;
6144 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6145 tempbx = 1040;
6146 tempcx = 1044; /* HWCursor bug! */
6151 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6153 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6155 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6156 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6158 /* 2. Vertical setup */
6160 tempcx = SiS_Pr->SiS_VGAVT - 1;
6161 temp = tempcx & 0x00FF;
6163 if(SiS_Pr->ChipType < SIS_661) {
6164 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6165 if(SiS_Pr->ChipType < SIS_315H) {
6166 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6167 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6168 temp--;
6171 } else {
6172 temp--;
6174 } else if(SiS_Pr->ChipType >= SIS_315H) {
6175 temp--;
6178 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6180 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6181 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6183 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6184 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6186 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6187 tempbx++;
6188 tempax = tempbx;
6189 tempcx++;
6190 tempcx -= tempax;
6191 tempcx >>= 2;
6192 tempbx += tempcx;
6193 if(tempcx < 4) tempcx = 4;
6194 tempcx >>= 2;
6195 tempcx += tempbx;
6196 tempcx++;
6197 } else {
6198 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6199 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6202 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6203 if(SiS_Pr->UseCustomMode) {
6204 tempbx = SiS_Pr->CVSyncStart;
6205 tempcx = SiS_Pr->CVSyncEnd;
6207 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6208 unsigned char cr8, cr7, cr13;
6209 if(SiS_Pr->UseCustomMode) {
6210 cr8 = SiS_Pr->CCRT1CRTC[8];
6211 cr7 = SiS_Pr->CCRT1CRTC[7];
6212 cr13 = SiS_Pr->CCRT1CRTC[13];
6213 tempcx = SiS_Pr->CCRT1CRTC[9];
6214 } else {
6215 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6216 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6217 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6218 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6220 tempbx = cr8;
6221 if(cr7 & 0x04) tempbx |= 0x0100;
6222 if(cr7 & 0x80) tempbx |= 0x0200;
6223 if(cr13 & 0x08) tempbx |= 0x0400;
6226 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6228 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6229 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6231 /* 3. Panel delay compensation */
6233 if(SiS_Pr->ChipType < SIS_315H) {
6235 #ifdef SIS300 /* ---------- 300 series -------------- */
6237 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6238 temp = 0x20;
6239 if(SiS_Pr->ChipType == SIS_300) {
6240 temp = 0x10;
6241 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6242 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6244 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6245 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6247 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6248 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6249 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6250 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6251 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6252 else temp = 0x20;
6254 if(SiS_Pr->SiS_UseROM) {
6255 if(ROMAddr[0x220] & 0x80) {
6256 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6257 temp = ROMAddr[0x221];
6258 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6259 temp = ROMAddr[0x222];
6260 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6261 temp = ROMAddr[0x223];
6262 else
6263 temp = ROMAddr[0x224];
6266 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6267 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6270 } else {
6271 temp = 0x20;
6272 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6273 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6275 if(SiS_Pr->SiS_UseROM) {
6276 if(ROMAddr[0x220] & 0x80) {
6277 temp = ROMAddr[0x220];
6280 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6281 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6285 temp &= 0x3c;
6287 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6289 #endif /* SIS300 */
6291 } else {
6293 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6295 if(SiS_Pr->ChipType < SIS_661) {
6297 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6299 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6300 else temp = 0x00;
6302 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6303 tempbl = 0xF0;
6304 if(SiS_Pr->ChipType == SIS_650) {
6305 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6306 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6310 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6311 temp = 0x08;
6312 tempbl = 0;
6313 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6314 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6318 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6321 } /* < 661 */
6323 tempax = 0;
6324 if(modeflag & DoubleScanMode) tempax |= 0x80;
6325 if(modeflag & HalfDCLK) tempax |= 0x40;
6326 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6328 #endif /* SIS315H */
6332 } /* Slavemode */
6334 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6335 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6336 /* For 301BDH with LCD, we set up the Panel Link */
6337 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6338 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6339 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6341 } else {
6342 if(SiS_Pr->ChipType < SIS_315H) {
6343 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6344 } else {
6345 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6346 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6347 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6349 } else {
6350 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6356 /*********************************************/
6357 /* SET PART 2 REGISTER GROUP */
6358 /*********************************************/
6360 #ifdef SIS315H
6361 static unsigned char *
6362 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6364 const unsigned char *tableptr = NULL;
6365 unsigned short a, b, p = 0;
6367 a = SiS_Pr->SiS_VGAHDE;
6368 b = SiS_Pr->SiS_HDE;
6369 if(tabletype) {
6370 a = SiS_Pr->SiS_VGAVDE;
6371 b = SiS_Pr->SiS_VDE;
6374 if(a < b) {
6375 tableptr = SiS_Part2CLVX_1;
6376 } else if(a == b) {
6377 tableptr = SiS_Part2CLVX_2;
6378 } else {
6379 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6380 tableptr = SiS_Part2CLVX_4;
6381 } else {
6382 tableptr = SiS_Part2CLVX_3;
6384 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6385 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6386 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6387 else tableptr = SiS_Part2CLVX_5;
6388 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6389 tableptr = SiS_Part2CLVX_6;
6391 do {
6392 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6393 p += 0x42;
6394 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6395 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6397 p += 2;
6398 return ((unsigned char *)&tableptr[p]);
6401 static void
6402 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6403 unsigned short RefreshRateTableIndex)
6405 unsigned char *tableptr;
6406 unsigned char temp;
6407 int i, j;
6409 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6411 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6412 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6413 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6415 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6416 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6417 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6418 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6421 temp = 0x10;
6422 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6423 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6426 static bool
6427 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6428 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6429 unsigned short *ResIndex)
6432 if(SiS_Pr->ChipType < SIS_315H) return false;
6434 if(ModeNo <= 0x13)
6435 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6436 else
6437 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6439 (*ResIndex) &= 0x3f;
6440 (*CRT2Index) = 0;
6442 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6443 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6444 (*CRT2Index) = 200;
6448 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6449 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6450 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6453 return (((*CRT2Index) != 0));
6455 #endif
6457 #ifdef SIS300
6458 static void
6459 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6461 unsigned short tempcx;
6462 static const unsigned char atable[] = {
6463 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6464 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6467 if(!SiS_Pr->UseCustomMode) {
6468 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6469 (SiS_Pr->ChipType == SIS_730) ) &&
6470 (SiS_Pr->ChipRevision > 2) ) &&
6471 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6472 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6473 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6474 if(ModeNo == 0x13) {
6475 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6476 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6477 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6478 } else if((crt2crtc & 0x3F) == 4) {
6479 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6480 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6481 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6482 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6483 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6487 if(SiS_Pr->ChipType < SIS_315H) {
6488 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6489 crt2crtc &= 0x1f;
6490 tempcx = 0;
6491 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6492 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6493 tempcx += 7;
6496 tempcx += crt2crtc;
6497 if(crt2crtc >= 4) {
6498 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6501 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6502 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6503 if(crt2crtc == 4) {
6504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6508 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6509 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6515 /* For ECS A907. Highly preliminary. */
6516 static void
6517 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6518 unsigned short ModeNo)
6520 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6521 unsigned short crt2crtc, resindex;
6522 int i, j;
6524 if(SiS_Pr->ChipType != SIS_300) return;
6525 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6526 if(SiS_Pr->UseCustomMode) return;
6528 if(ModeNo <= 0x13) {
6529 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6530 } else {
6531 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6534 resindex = crt2crtc & 0x3F;
6535 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6536 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6538 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6539 if(ModeNo > 0x13) {
6540 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6541 resindex = 4;
6544 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6545 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6546 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6547 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6549 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6550 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6552 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6553 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6555 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6556 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6558 #endif
6560 static void
6561 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6563 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6564 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6565 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6567 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6568 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6569 const unsigned char specialtv[] = {
6570 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6571 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6572 0x58,0xe4,0x73,0xda,0x13
6574 int i, j;
6575 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6576 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6578 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6579 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6580 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6581 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6582 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6583 } else {
6584 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6585 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6589 } else {
6590 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6591 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6592 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6593 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6594 } else {
6595 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6596 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6601 static void
6602 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6604 unsigned short temp;
6606 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6607 if(SiS_Pr->SiS_VGAVDE == 525) {
6608 temp = 0xc3;
6609 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6610 temp++;
6611 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6613 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6614 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6615 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6616 temp = 0x4d;
6617 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6618 temp++;
6619 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6621 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6625 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6626 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6627 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6628 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6629 /* Not always for LV, see SetGrp2 */
6631 temp = 1;
6632 if(ModeNo <= 0x13) temp = 3;
6633 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6638 static void
6639 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6640 unsigned short RefreshRateTableIndex)
6642 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6643 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6644 unsigned int longtemp, PhaseIndex;
6645 bool newtvphase;
6646 const unsigned char *TimingPoint;
6647 #ifdef SIS315H
6648 unsigned short resindex, CRT2Index;
6649 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6651 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6652 #endif
6654 if(ModeNo <= 0x13) {
6655 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6656 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6657 } else if(SiS_Pr->UseCustomMode) {
6658 modeflag = SiS_Pr->CModeFlag;
6659 crt2crtc = 0;
6660 } else {
6661 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6662 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6665 temp = 0;
6666 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6667 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6668 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6669 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6671 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6673 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6675 PhaseIndex = 0x01; /* SiS_PALPhase */
6676 TimingPoint = SiS_Pr->SiS_PALTiming;
6678 newtvphase = false;
6679 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6680 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6681 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6682 newtvphase = true;
6685 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6687 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6688 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6689 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6690 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6691 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6695 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6697 i = 0;
6698 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6699 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6701 TimingPoint = &SiS_YPbPrTable[i][0];
6703 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6705 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6707 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6709 } else {
6711 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6712 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6713 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6717 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6718 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6719 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6722 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6723 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6724 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6725 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6726 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6727 } else {
6728 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6732 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6733 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6736 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6737 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6739 for(i = 0x39; i <= 0x45; i++, j++) {
6740 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6743 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6744 if(SiS_Pr->SiS_ModeType != ModeText) {
6745 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6749 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6751 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6752 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6753 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6754 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6756 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6757 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
6758 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6759 else tempax = 440; /* NTSC, YPbPr 525 */
6761 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6762 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6763 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6765 tempax -= SiS_Pr->SiS_VDE;
6766 tempax >>= 1;
6767 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6768 tempax >>= 1;
6770 tempax &= 0x00ff;
6772 temp = tempax + (unsigned short)TimingPoint[0];
6773 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6775 temp = tempax + (unsigned short)TimingPoint[1];
6776 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6778 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6779 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6780 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6781 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6782 } else {
6783 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6784 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6790 tempcx = SiS_Pr->SiS_HT;
6791 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6792 tempcx--;
6793 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6794 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6795 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6797 tempcx = SiS_Pr->SiS_HT >> 1;
6798 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6799 tempcx += 7;
6800 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6801 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6803 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6804 tempbx += tempcx;
6805 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6806 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6808 tempbx += 8;
6809 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6810 tempbx -= 4;
6811 tempcx = tempbx;
6813 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6815 j += 2;
6816 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6817 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6818 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6820 tempcx += 8;
6821 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6822 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6824 tempcx = SiS_Pr->SiS_HT >> 1;
6825 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6826 j += 2;
6827 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6828 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6830 tempcx -= 11;
6831 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6832 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6834 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6836 tempbx = SiS_Pr->SiS_VDE;
6837 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6838 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6839 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6840 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6841 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6842 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6843 tempbx >>= 1;
6844 if(SiS_Pr->ChipType >= SIS_315H) {
6845 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6846 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6847 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6848 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6849 if(crt2crtc == 4) tempbx++;
6853 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6854 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6855 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6857 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6858 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6862 tempbx -= 2;
6863 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6865 temp = (tempcx >> 8) & 0x0F;
6866 temp |= ((tempbx >> 2) & 0xC0);
6867 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6868 temp |= 0x10;
6869 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6871 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6873 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6874 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6877 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6878 tempbx = SiS_Pr->SiS_VDE;
6879 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6880 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6881 tempbx >>= 1;
6883 tempbx -= 3;
6884 temp = ((tempbx >> 3) & 0x60) | 0x18;
6885 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6886 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6888 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6889 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6893 tempbx = 0;
6894 if(!(modeflag & HalfDCLK)) {
6895 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6896 tempax = 0;
6897 tempbx |= 0x20;
6901 tempch = tempcl = 0x01;
6902 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6903 if(SiS_Pr->SiS_VGAHDE >= 960) {
6904 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6905 tempcl = 0x20;
6906 if(SiS_Pr->SiS_VGAHDE >= 1280) {
6907 tempch = 20;
6908 tempbx &= ~0x20;
6909 } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6910 tempch = 25;
6911 } else {
6912 tempch = 25; /* OK */
6918 if(!(tempbx & 0x20)) {
6919 if(modeflag & HalfDCLK) tempcl <<= 1;
6920 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6921 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6922 tempax = longtemp / SiS_Pr->SiS_HDE;
6923 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6924 tempbx |= ((tempax >> 8) & 0x1F);
6925 tempcx = tempax >> 13;
6928 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6929 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6931 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6933 tempcx &= 0x07;
6934 if(tempbx & 0x20) tempcx = 0;
6935 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6937 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6938 tempbx = 0x0382;
6939 tempcx = 0x007e;
6940 } else {
6941 tempbx = 0x0369;
6942 tempcx = 0x0061;
6944 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6945 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6946 temp = (tempcx & 0x0300) >> 6;
6947 temp |= ((tempbx >> 8) & 0x03);
6948 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6949 temp |= 0x10;
6950 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
6951 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6953 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
6955 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
6956 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
6958 SiS_SetTVSpecial(SiS_Pr, ModeNo);
6960 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
6961 temp = 0;
6962 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
6963 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
6968 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6969 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
6970 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
6971 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
6973 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
6976 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6977 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6978 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
6982 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
6984 /* From here: Part2 LCD setup */
6986 tempbx = SiS_Pr->SiS_HDE;
6987 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
6988 tempbx--; /* RHACTE = HDE - 1 */
6989 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
6990 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
6992 temp = 0x01;
6993 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
6994 if(SiS_Pr->SiS_ModeType == ModeEGA) {
6995 if(SiS_Pr->SiS_VGAHDE >= 1024) {
6996 temp = 0x02;
6997 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
6998 temp = 0x01;
7003 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7005 tempbx = SiS_Pr->SiS_VDE - 1;
7006 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7007 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7009 tempcx = SiS_Pr->SiS_VT - 1;
7010 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7011 temp = (tempcx >> 3) & 0xE0;
7012 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7013 /* Enable dithering; only do this for 32bpp mode */
7014 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7015 temp |= 0x10;
7018 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7020 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7021 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7023 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7024 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7026 #ifdef SIS315H
7027 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7028 &CRT2Index, &resindex)) {
7029 switch(CRT2Index) {
7030 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7031 default:
7032 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7035 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7036 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7037 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7038 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7040 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7041 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7043 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7044 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7046 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7047 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7049 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7051 } else {
7052 #endif
7054 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7055 /* Clevo dual-link 1024x768 */
7056 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7057 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7059 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7060 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7061 tempbx = SiS_Pr->SiS_VDE - 1;
7062 tempcx = SiS_Pr->SiS_VT - 1;
7063 } else {
7064 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7065 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7067 } else {
7068 tempbx = SiS_Pr->PanelYRes;
7069 tempcx = SiS_Pr->SiS_VT;
7070 tempax = 1;
7071 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7072 tempax = SiS_Pr->PanelYRes;
7073 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7074 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7075 tempax = tempcx = 0;
7076 } else {
7077 tempax -= SiS_Pr->SiS_VDE;
7079 tempax >>= 1;
7081 tempcx -= tempax; /* lcdvdes */
7082 tempbx -= tempax; /* lcdvdee */
7085 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7087 #ifdef SIS_XORG_XF86
7088 #ifdef TWDEBUG
7089 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7090 #endif
7091 #endif
7093 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7094 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7096 temp = (tempbx >> 5) & 0x38;
7097 temp |= ((tempcx >> 8) & 0x07);
7098 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7100 tempax = SiS_Pr->SiS_VDE;
7101 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7102 tempax = SiS_Pr->PanelYRes;
7104 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7105 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7106 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7107 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7111 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7112 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7113 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7114 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7115 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7116 if(tempax % 4) { tempax >>= 2; tempax++; }
7117 else { tempax >>= 2; }
7118 tempbx -= (tempax - 1);
7119 } else {
7120 tempbx -= 10;
7121 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7125 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7126 tempbx++;
7127 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7128 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7129 tempbx = 770;
7130 tempcx = 3;
7135 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7137 if(SiS_Pr->UseCustomMode) {
7138 tempbx = SiS_Pr->CVSyncStart;
7141 #ifdef SIS_XORG_XF86
7142 #ifdef TWDEBUG
7143 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7144 #endif
7145 #endif
7147 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7149 temp = (tempbx >> 4) & 0xF0;
7150 tempbx += (tempcx + 1);
7151 temp |= (tempbx & 0x0F);
7153 if(SiS_Pr->UseCustomMode) {
7154 temp &= 0xf0;
7155 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7158 #ifdef SIS_XORG_XF86
7159 #ifdef TWDEBUG
7160 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7161 #endif
7162 #endif
7164 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7166 #ifdef SIS300
7167 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7168 #endif
7170 bridgeoffset = 7;
7171 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7172 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7173 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7174 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7175 /* Higher bridgeoffset shifts to the LEFT */
7177 temp = 0;
7178 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7179 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7180 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7181 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7184 temp += bridgeoffset;
7185 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7186 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7188 tempcx = SiS_Pr->SiS_HT;
7189 tempax = tempbx = SiS_Pr->SiS_HDE;
7190 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7191 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7192 tempax = SiS_Pr->PanelXRes;
7193 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7196 if(SiS_IsDualLink(SiS_Pr)) {
7197 tempcx >>= 1;
7198 tempbx >>= 1;
7199 tempax >>= 1;
7202 #ifdef SIS_XORG_XF86
7203 #ifdef TWDEBUG
7204 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7205 #endif
7206 #endif
7208 tempbx += bridgeoffset;
7210 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7211 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7213 tempcx = (tempcx - tempax) >> 2;
7215 tempbx += tempcx;
7216 push2 = tempbx;
7218 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7219 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7220 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7221 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7226 if(SiS_Pr->UseCustomMode) {
7227 tempbx = SiS_Pr->CHSyncStart;
7228 if(modeflag & HalfDCLK) tempbx <<= 1;
7229 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7230 tempbx += bridgeoffset;
7233 #ifdef SIS_XORG_XF86
7234 #ifdef TWDEBUG
7235 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7236 #endif
7237 #endif
7239 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7240 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7242 tempbx = push2;
7244 tempcx <<= 1;
7245 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7246 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7248 tempbx += tempcx;
7250 if(SiS_Pr->UseCustomMode) {
7251 tempbx = SiS_Pr->CHSyncEnd;
7252 if(modeflag & HalfDCLK) tempbx <<= 1;
7253 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7254 tempbx += bridgeoffset;
7257 #ifdef SIS_XORG_XF86
7258 #ifdef TWDEBUG
7259 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7260 #endif
7261 #endif
7263 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7265 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7267 #ifdef SIS300
7268 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7269 #endif
7270 #ifdef SIS315H
7271 } /* CRT2-LCD from table */
7272 #endif
7275 /*********************************************/
7276 /* SET PART 3 REGISTER GROUP */
7277 /*********************************************/
7279 static void
7280 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7282 unsigned short i;
7283 const unsigned char *tempdi;
7285 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7287 #ifndef SIS_CP
7288 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7289 #else
7290 SIS_CP_INIT301_CP
7291 #endif
7293 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7294 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7295 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7296 } else {
7297 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7298 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7301 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7302 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7303 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7304 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7307 tempdi = NULL;
7308 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7309 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7310 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7311 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7313 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7314 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7315 tempdi = SiS_HiTVGroup3_1;
7316 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7319 if(tempdi) {
7320 for(i=0; i<=0x3E; i++) {
7321 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7323 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7324 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7325 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7330 #ifdef SIS_CP
7331 SIS_CP_INIT301_CP2
7332 #endif
7335 /*********************************************/
7336 /* SET PART 4 REGISTER GROUP */
7337 /*********************************************/
7339 #ifdef SIS315H
7341 static void
7342 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7344 unsigned short temp, temp1, resinfo = 0;
7345 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7347 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7348 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7350 if(SiS_Pr->ChipType >= XGI_20) return;
7352 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7353 if(!(ROMAddr[0x61] & 0x04)) return;
7356 if(ModeNo > 0x13) {
7357 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7360 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7361 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7362 if(!(temp & 0x01)) {
7363 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7364 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7365 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7366 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7368 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7369 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7370 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7371 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7372 else temp = 0x0402;
7373 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7374 temp1 = 0;
7375 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7376 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7377 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7378 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7379 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7380 if(ModeNo > 0x13) {
7381 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7383 } else {
7384 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7385 if(temp1 == 0x01) temp |= 0x01;
7386 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7387 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7388 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7389 if(ModeNo > 0x13) {
7390 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7398 #endif
7400 static void
7401 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7402 unsigned short RefreshRateTableIndex)
7404 unsigned short vclkindex, temp, reg1, reg2;
7406 if(SiS_Pr->UseCustomMode) {
7407 reg1 = SiS_Pr->CSR2B;
7408 reg2 = SiS_Pr->CSR2C;
7409 } else {
7410 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7411 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7412 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7415 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7416 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7417 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7418 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7419 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7420 } else {
7421 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7422 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7424 } else {
7425 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7426 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7427 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7429 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7430 temp = 0x08;
7431 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7432 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7435 static void
7436 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7438 if(SiS_Pr->ChipType >= SIS_315H) {
7439 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7440 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7441 (SiS_IsVAMode(SiS_Pr))) {
7442 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7443 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7444 } else {
7445 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7450 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7451 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7452 #ifdef SET_EMI
7453 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7454 #endif
7455 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7459 static void
7460 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7461 unsigned short RefreshRateTableIndex)
7463 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7464 unsigned int tempebx, tempeax, templong;
7466 if(ModeNo <= 0x13) {
7467 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7468 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7469 } else if(SiS_Pr->UseCustomMode) {
7470 modeflag = SiS_Pr->CModeFlag;
7471 resinfo = 0;
7472 } else {
7473 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7474 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7477 if(SiS_Pr->ChipType >= SIS_315H) {
7478 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7479 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7480 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7485 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7486 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7487 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7491 if(SiS_Pr->ChipType >= SIS_315H) {
7492 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7493 SiS_SetDualLinkEtc(SiS_Pr);
7494 return;
7498 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7500 tempbx = SiS_Pr->SiS_RVBHCMAX;
7501 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7503 temp = (tempbx >> 1) & 0x80;
7505 tempcx = SiS_Pr->SiS_VGAHT - 1;
7506 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7508 temp |= ((tempcx >> 5) & 0x78);
7510 tempcx = SiS_Pr->SiS_VGAVT - 1;
7511 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7512 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7514 temp |= ((tempcx >> 8) & 0x07);
7515 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7517 tempbx = SiS_Pr->SiS_VGAHDE;
7518 if(modeflag & HalfDCLK) tempbx >>= 1;
7519 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7521 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7522 temp = 0;
7523 if(tempbx > 800) temp = 0x60;
7524 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7525 temp = 0;
7526 if(tempbx > 1024) temp = 0xC0;
7527 else if(tempbx >= 960) temp = 0xA0;
7528 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7529 temp = 0;
7530 if(tempbx >= 1280) temp = 0x40;
7531 else if(tempbx >= 1024) temp = 0x20;
7532 } else {
7533 temp = 0x80;
7534 if(tempbx >= 1024) temp = 0xA0;
7537 temp |= SiS_Pr->Init_P4_0E;
7539 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7540 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7541 temp &= 0xf0;
7542 temp |= 0x0A;
7546 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7548 tempeax = SiS_Pr->SiS_VGAVDE;
7549 tempebx = SiS_Pr->SiS_VDE;
7550 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7551 if(!(temp & 0xE0)) tempebx >>=1;
7554 tempcx = SiS_Pr->SiS_RVBHRS;
7555 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7556 tempcx >>= 8;
7557 tempcx |= 0x40;
7559 if(tempeax <= tempebx) {
7560 tempcx ^= 0x40;
7561 } else {
7562 tempeax -= tempebx;
7565 tempeax *= (256 * 1024);
7566 templong = tempeax % tempebx;
7567 tempeax /= tempebx;
7568 if(templong) tempeax++;
7570 temp = (unsigned short)(tempeax & 0x000000FF);
7571 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7572 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7573 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7574 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7575 temp |= (tempcx & 0x4F);
7576 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7578 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7580 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7582 /* Calc Linebuffer max address and set/clear decimode */
7583 tempbx = 0;
7584 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7585 tempax = SiS_Pr->SiS_VGAHDE;
7586 if(modeflag & HalfDCLK) tempax >>= 1;
7587 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7588 if(tempax > 800) {
7589 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7590 tempax -= 800;
7591 } else {
7592 tempbx = 0x08;
7593 if(tempax == 960) tempax *= 25; /* Correct */
7594 else if(tempax == 1024) tempax *= 25;
7595 else tempax *= 20;
7596 temp = tempax % 32;
7597 tempax /= 32;
7598 if(temp) tempax++;
7599 tempax++;
7600 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7601 if(resinfo == SIS_RI_1024x768 ||
7602 resinfo == SIS_RI_1024x576 ||
7603 resinfo == SIS_RI_1280x1024 ||
7604 resinfo == SIS_RI_1280x720) {
7605 /* Otherwise white line or garbage at right edge */
7606 tempax = (tempax & 0xff00) | 0x20;
7611 tempax--;
7612 temp = ((tempax >> 4) & 0x30) | tempbx;
7613 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7614 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7616 temp = 0x0036; tempbx = 0xD0;
7617 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7618 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7620 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7621 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7622 temp |= 0x01;
7623 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7624 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7625 temp &= ~0x01;
7630 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7632 tempbx = SiS_Pr->SiS_HT >> 1;
7633 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7634 tempbx -= 2;
7635 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7636 temp = (tempbx >> 5) & 0x38;
7637 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7639 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7640 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7641 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7642 /* LCD-too-dark-error-source, see FinalizeLCD() */
7646 SiS_SetDualLinkEtc(SiS_Pr);
7648 } /* 301B */
7650 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7653 /*********************************************/
7654 /* SET PART 5 REGISTER GROUP */
7655 /*********************************************/
7657 static void
7658 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7661 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7663 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7664 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7665 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7666 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7671 /*********************************************/
7672 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7673 /*********************************************/
7675 static bool
7676 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7677 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7678 unsigned short *DisplayType)
7680 unsigned short modeflag = 0;
7681 bool checkhd = true;
7683 /* Pass 1:1 not supported here */
7685 if(ModeNo <= 0x13) {
7686 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7687 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7688 } else {
7689 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7690 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7693 (*ResIndex) &= 0x3F;
7695 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7697 (*DisplayType) = 80;
7698 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7699 (*DisplayType) = 82;
7700 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7701 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7704 if((*DisplayType) != 84) {
7705 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7708 } else {
7710 (*DisplayType = 0);
7711 switch(SiS_Pr->SiS_LCDResInfo) {
7712 case Panel_320x240_1: (*DisplayType) = 50;
7713 checkhd = false;
7714 break;
7715 case Panel_320x240_2: (*DisplayType) = 14;
7716 break;
7717 case Panel_320x240_3: (*DisplayType) = 18;
7718 break;
7719 case Panel_640x480: (*DisplayType) = 10;
7720 break;
7721 case Panel_1024x600: (*DisplayType) = 26;
7722 break;
7723 default: return true;
7726 if(checkhd) {
7727 if(modeflag & HalfDCLK) (*DisplayType)++;
7730 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7731 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7736 return true;
7739 static void
7740 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7741 unsigned short RefreshRateTableIndex)
7743 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7744 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7745 static const unsigned short CRIdx[] = {
7746 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7747 0x07, 0x10, 0x11, 0x15, 0x16
7750 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7751 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7752 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7753 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7754 return;
7756 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7757 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7758 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7760 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7761 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7762 } else return;
7764 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7766 if(SiS_Pr->ChipType < SIS_315H) {
7767 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7770 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7771 &ResIndex, &DisplayType))) {
7772 return;
7775 switch(DisplayType) {
7776 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7777 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7778 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7779 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7780 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7781 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7782 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7783 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7784 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7785 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7786 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7787 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7790 if(LVDSCRT1Ptr) {
7792 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7794 for(i = 0; i <= 10; i++) {
7795 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7796 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7799 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7800 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7801 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7804 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7805 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7807 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7808 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7810 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7811 if(modeflag & DoubleScanMode) tempah |= 0x80;
7812 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7814 } else {
7816 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7821 /*********************************************/
7822 /* SET CRT2 ECLK */
7823 /*********************************************/
7825 static void
7826 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7827 unsigned short RefreshRateTableIndex)
7829 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7830 unsigned short clkbase, vclkindex = 0;
7831 unsigned char sr2b, sr2c;
7833 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7834 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7835 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7836 RefreshRateTableIndex--;
7838 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7839 RefreshRateTableIndex);
7840 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7841 } else {
7842 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7843 RefreshRateTableIndex);
7846 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7847 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7849 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7850 if(SiS_Pr->SiS_UseROM) {
7851 if(ROMAddr[0x220] & 0x01) {
7852 sr2b = ROMAddr[0x227];
7853 sr2c = ROMAddr[0x228];
7858 clkbase = 0x02B;
7859 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7860 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7861 clkbase += 3;
7865 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7866 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7867 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7868 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7869 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7870 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7871 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7872 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7873 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7876 /*********************************************/
7877 /* SET UP CHRONTEL CHIPS */
7878 /*********************************************/
7880 static void
7881 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7882 unsigned short RefreshRateTableIndex)
7884 unsigned short TVType, resindex;
7885 const struct SiS_CHTVRegData *CHTVRegData = NULL;
7887 if(ModeNo <= 0x13)
7888 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7889 else
7890 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7892 resindex &= 0x3F;
7894 TVType = 0;
7895 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7896 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7897 TVType += 2;
7898 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7899 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7901 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7902 TVType = 4;
7903 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7904 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7905 TVType = 6;
7906 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7910 switch(TVType) {
7911 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7912 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7913 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
7914 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7915 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7916 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7917 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7918 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7919 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7920 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7924 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7926 #ifdef SIS300
7928 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7930 /* We don't support modes >800x600 */
7931 if (resindex > 5) return;
7933 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7934 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7935 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
7936 } else {
7937 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7938 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
7941 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
7942 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
7943 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
7944 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
7945 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
7947 /* Set minimum flicker filter for Luma channel (SR1-0=00),
7948 minimum text enhancement (S3-2=10),
7949 maximum flicker filter for Chroma channel (S5-4=10)
7950 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
7952 SiS_SetCH700x(SiS_Pr,0x01,0x28);
7954 /* Set video bandwidth
7955 High bandwidth Luma composite video filter(S0=1)
7956 low bandwidth Luma S-video filter (S2-1=00)
7957 disable peak filter in S-video channel (S3=0)
7958 high bandwidth Chroma Filter (S5-4=11)
7959 =00110001=0x31
7961 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
7963 /* Register 0x3D does not exist in non-macrovision register map
7964 (Maybe this is a macrovision register?)
7966 #ifndef SIS_CP
7967 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
7968 #endif
7970 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
7971 all other bits a read-only. Macrovision?
7973 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
7975 /* Register 0x11 only contains 3 writable bits (S0-S2) for
7976 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
7978 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
7980 /* Clear DSEN
7982 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
7984 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
7985 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
7986 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
7987 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7988 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
7989 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
7990 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
7991 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
7992 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
7993 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
7994 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
7995 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
7996 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
7997 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
7998 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
7999 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
8001 } else {
8002 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8003 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8004 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8005 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8006 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8007 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8010 } else { /* ---- PAL ---- */
8011 /* We don't play around with FSCI in PAL mode */
8012 if(resindex == 0x04) {
8013 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8014 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8015 } else {
8016 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8017 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8021 #endif /* 300 */
8023 } else {
8025 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8027 #ifdef SIS315H
8029 unsigned short temp;
8031 /* We don't support modes >1024x768 */
8032 if (resindex > 6) return;
8034 temp = CHTVRegData[resindex].Reg[0];
8035 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8036 SiS_SetCH701x(SiS_Pr,0x00,temp);
8038 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8039 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8040 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8041 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8042 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8043 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8045 temp = CHTVRegData[resindex].Reg[7];
8046 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8047 SiS_SetCH701x(SiS_Pr,0x07,temp);
8049 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8050 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8051 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8052 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8053 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8054 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8055 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8056 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8058 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8059 /* D1 should be set for PAL, PAL-N and NTSC-J,
8060 but I won't do that for PAL unless somebody
8061 tells me to do so. Since the BIOS uses
8062 non-default CIV values and blacklevels,
8063 this might be compensated anyway.
8065 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8066 SiS_SetCH701x(SiS_Pr,0x21,temp);
8068 #endif /* 315 */
8072 #ifdef SIS_CP
8073 SIS_CP_INIT301_CP3
8074 #endif
8078 #ifdef SIS315H /* ----------- 315 series only ---------- */
8080 void
8081 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8083 unsigned short temp;
8085 /* Enable Chrontel 7019 LCD panel backlight */
8086 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8087 if(SiS_Pr->ChipType == SIS_740) {
8088 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8089 } else {
8090 temp = SiS_GetCH701x(SiS_Pr,0x66);
8091 temp |= 0x20;
8092 SiS_SetCH701x(SiS_Pr,0x66,temp);
8097 void
8098 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8100 unsigned short temp;
8102 /* Disable Chrontel 7019 LCD panel backlight */
8103 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8104 temp = SiS_GetCH701x(SiS_Pr,0x66);
8105 temp &= 0xDF;
8106 SiS_SetCH701x(SiS_Pr,0x66,temp);
8110 static void
8111 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8113 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8114 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8115 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8116 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8117 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8118 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8119 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8120 const unsigned char *tableptr = NULL;
8121 int i;
8123 /* Set up Power up/down timing */
8125 if(SiS_Pr->ChipType == SIS_740) {
8126 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8127 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8128 else tableptr = table1024_740;
8129 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8130 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8131 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8132 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8133 else tableptr = table1400_740;
8134 } else return;
8135 } else {
8136 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8137 tableptr = table1024_650;
8138 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8139 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8140 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8141 tableptr = table1400_650;
8142 } else return;
8145 for(i=0; i<5; i++) {
8146 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8150 static void
8151 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8153 const unsigned char *tableptr = NULL;
8154 unsigned short tempbh;
8155 int i;
8156 static const unsigned char regtable[] = {
8157 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8158 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8160 static const unsigned char table1024_740[] = {
8161 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8162 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8164 static const unsigned char table1280_740[] = {
8165 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8166 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8168 static const unsigned char table1400_740[] = {
8169 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8170 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8172 static const unsigned char table1600_740[] = {
8173 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8174 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8176 static const unsigned char table1024_650[] = {
8177 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8178 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8180 static const unsigned char table1280_650[] = {
8181 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8182 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8184 static const unsigned char table1400_650[] = {
8185 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8186 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8188 static const unsigned char table1600_650[] = {
8189 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8190 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8193 if(SiS_Pr->ChipType == SIS_740) {
8194 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8195 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8196 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8197 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8198 else return;
8199 } else {
8200 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8201 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8202 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8203 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8204 else return;
8207 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8208 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8209 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8210 if(tempbh == 0xc8) {
8211 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8212 } else if(tempbh == 0xdb) {
8213 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8214 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8215 } else if(tempbh == 0xde) {
8216 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8220 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8221 else tempbh = 0x0c;
8223 for(i = 0; i < tempbh; i++) {
8224 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8226 SiS_ChrontelPowerSequencing(SiS_Pr);
8227 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8228 tempbh |= 0xc0;
8229 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8231 if(SiS_Pr->ChipType == SIS_740) {
8232 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8233 tempbh &= 0xfb;
8234 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8235 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8236 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8237 tempbh |= 0x40;
8238 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8239 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8240 tempbh &= 0x3f;
8241 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8245 static void
8246 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8248 unsigned char temp, temp1;
8250 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8251 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8252 temp = SiS_GetCH701x(SiS_Pr,0x47);
8253 temp &= 0x7f; /* Use external VSYNC */
8254 SiS_SetCH701x(SiS_Pr,0x47,temp);
8255 SiS_LongDelay(SiS_Pr, 3);
8256 temp = SiS_GetCH701x(SiS_Pr,0x47);
8257 temp |= 0x80; /* Use internal VSYNC */
8258 SiS_SetCH701x(SiS_Pr,0x47,temp);
8259 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8262 static void
8263 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8265 unsigned short temp;
8267 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8268 if(SiS_Pr->ChipType == SIS_740) {
8269 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8270 temp |= 0x04; /* Invert XCLK phase */
8271 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8273 if(SiS_IsYPbPr(SiS_Pr)) {
8274 temp = SiS_GetCH701x(SiS_Pr,0x01);
8275 temp &= 0x3f;
8276 temp |= 0x80; /* Enable YPrPb (HDTV) */
8277 SiS_SetCH701x(SiS_Pr,0x01,temp);
8279 if(SiS_IsChScart(SiS_Pr)) {
8280 temp = SiS_GetCH701x(SiS_Pr,0x01);
8281 temp &= 0x3f;
8282 temp |= 0xc0; /* Enable SCART + CVBS */
8283 SiS_SetCH701x(SiS_Pr,0x01,temp);
8285 if(SiS_Pr->ChipType == SIS_740) {
8286 SiS_ChrontelResetVSync(SiS_Pr);
8287 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8288 } else {
8289 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8290 temp = SiS_GetCH701x(SiS_Pr,0x49);
8291 if(SiS_IsYPbPr(SiS_Pr)) {
8292 temp = SiS_GetCH701x(SiS_Pr,0x73);
8293 temp |= 0x60;
8294 SiS_SetCH701x(SiS_Pr,0x73,temp);
8296 temp = SiS_GetCH701x(SiS_Pr,0x47);
8297 temp &= 0x7f;
8298 SiS_SetCH701x(SiS_Pr,0x47,temp);
8299 SiS_LongDelay(SiS_Pr, 2);
8300 temp = SiS_GetCH701x(SiS_Pr,0x47);
8301 temp |= 0x80;
8302 SiS_SetCH701x(SiS_Pr,0x47,temp);
8307 static void
8308 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8310 unsigned short temp;
8312 /* Complete power down of LVDS */
8313 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8314 if(SiS_Pr->ChipType == SIS_740) {
8315 SiS_LongDelay(SiS_Pr, 1);
8316 SiS_GenericDelay(SiS_Pr, 5887);
8317 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8318 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8319 } else {
8320 SiS_LongDelay(SiS_Pr, 2);
8321 temp = SiS_GetCH701x(SiS_Pr,0x76);
8322 temp &= 0xfc;
8323 SiS_SetCH701x(SiS_Pr,0x76,temp);
8324 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8329 static void
8330 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8332 unsigned short temp;
8334 if(SiS_Pr->ChipType == SIS_740) {
8336 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8337 temp &= 0x01;
8338 if(!temp) {
8340 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8341 temp = SiS_GetCH701x(SiS_Pr,0x49);
8342 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8345 /* Reset Chrontel 7019 datapath */
8346 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8347 SiS_LongDelay(SiS_Pr, 1);
8348 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8350 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8351 SiS_ChrontelResetVSync(SiS_Pr);
8352 SiS_SetCH701x(SiS_Pr,0x49,temp);
8355 } else {
8357 /* Clear/set/clear GPIO */
8358 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8359 temp &= 0xef;
8360 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8361 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8362 temp |= 0x10;
8363 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8364 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8365 temp &= 0xef;
8366 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8367 temp = SiS_GetCH701x(SiS_Pr,0x61);
8368 if(!temp) {
8369 SiS_SetCH701xForLCD(SiS_Pr);
8373 } else { /* 650 */
8374 /* Reset Chrontel 7019 datapath */
8375 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8376 SiS_LongDelay(SiS_Pr, 1);
8377 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8381 static void
8382 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8384 unsigned short temp;
8386 if(SiS_Pr->ChipType == SIS_740) {
8388 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8389 SiS_ChrontelResetVSync(SiS_Pr);
8392 } else {
8394 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8395 temp = SiS_GetCH701x(SiS_Pr,0x49);
8396 temp &= 1;
8397 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8398 temp = SiS_GetCH701x(SiS_Pr,0x47);
8399 temp &= 0x70;
8400 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8401 SiS_LongDelay(SiS_Pr, 3);
8402 temp = SiS_GetCH701x(SiS_Pr,0x47);
8403 temp |= 0x80;
8404 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8410 static void
8411 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8413 unsigned short temp,temp1;
8415 if(SiS_Pr->ChipType == SIS_740) {
8417 temp = SiS_GetCH701x(SiS_Pr,0x61);
8418 if(temp < 1) {
8419 temp++;
8420 SiS_SetCH701x(SiS_Pr,0x61,temp);
8422 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8423 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8424 SiS_LongDelay(SiS_Pr, 1);
8425 SiS_GenericDelay(SiS_Pr, 5887);
8427 } else { /* 650 */
8429 temp1 = 0;
8430 temp = SiS_GetCH701x(SiS_Pr,0x61);
8431 if(temp < 2) {
8432 temp++;
8433 SiS_SetCH701x(SiS_Pr,0x61,temp);
8434 temp1 = 1;
8436 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8437 temp = SiS_GetCH701x(SiS_Pr,0x66);
8438 temp |= 0x5f;
8439 SiS_SetCH701x(SiS_Pr,0x66,temp);
8440 if(ModeNo > 0x13) {
8441 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8442 SiS_GenericDelay(SiS_Pr, 1023);
8443 } else {
8444 SiS_GenericDelay(SiS_Pr, 767);
8446 } else {
8447 if(!temp1)
8448 SiS_GenericDelay(SiS_Pr, 767);
8450 temp = SiS_GetCH701x(SiS_Pr,0x76);
8451 temp |= 0x03;
8452 SiS_SetCH701x(SiS_Pr,0x76,temp);
8453 temp = SiS_GetCH701x(SiS_Pr,0x66);
8454 temp &= 0x7f;
8455 SiS_SetCH701x(SiS_Pr,0x66,temp);
8456 SiS_LongDelay(SiS_Pr, 1);
8461 static void
8462 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8464 unsigned short temp;
8466 SiS_LongDelay(SiS_Pr, 1);
8468 do {
8469 temp = SiS_GetCH701x(SiS_Pr,0x66);
8470 temp &= 0x04; /* PLL stable? -> bail out */
8471 if(temp == 0x04) break;
8473 if(SiS_Pr->ChipType == SIS_740) {
8474 /* Power down LVDS output, PLL normal operation */
8475 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8478 SiS_SetCH701xForLCD(SiS_Pr);
8480 temp = SiS_GetCH701x(SiS_Pr,0x76);
8481 temp &= 0xfb; /* Reset PLL */
8482 SiS_SetCH701x(SiS_Pr,0x76,temp);
8483 SiS_LongDelay(SiS_Pr, 2);
8484 temp = SiS_GetCH701x(SiS_Pr,0x76);
8485 temp |= 0x04; /* PLL normal operation */
8486 SiS_SetCH701x(SiS_Pr,0x76,temp);
8487 if(SiS_Pr->ChipType == SIS_740) {
8488 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8489 } else {
8490 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8492 SiS_LongDelay(SiS_Pr, 2);
8493 } while(0);
8495 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8498 static void
8499 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8501 unsigned short temp;
8503 temp = SiS_GetCH701x(SiS_Pr,0x03);
8504 temp |= 0x80; /* Set datapath 1 to TV */
8505 temp &= 0xbf; /* Set datapath 2 to LVDS */
8506 SiS_SetCH701x(SiS_Pr,0x03,temp);
8508 if(SiS_Pr->ChipType == SIS_740) {
8510 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8511 temp &= 0xfb; /* Normal XCLK phase */
8512 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8514 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8516 temp = SiS_GetCH701x(SiS_Pr,0x64);
8517 temp |= 0x40; /* ? Bit not defined */
8518 SiS_SetCH701x(SiS_Pr,0x64,temp);
8520 temp = SiS_GetCH701x(SiS_Pr,0x03);
8521 temp &= 0x3f; /* D1 input to both LVDS and TV */
8522 SiS_SetCH701x(SiS_Pr,0x03,temp);
8524 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8525 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8526 SiS_LongDelay(SiS_Pr, 1);
8527 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8528 SiS_ChrontelResetDB(SiS_Pr);
8529 SiS_ChrontelDoSomething2(SiS_Pr);
8530 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8531 } else {
8532 temp = SiS_GetCH701x(SiS_Pr,0x66);
8533 if(temp != 0x45) {
8534 SiS_ChrontelResetDB(SiS_Pr);
8535 SiS_ChrontelDoSomething2(SiS_Pr);
8536 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8540 } else { /* 650 */
8542 SiS_ChrontelResetDB(SiS_Pr);
8543 SiS_ChrontelDoSomething2(SiS_Pr);
8544 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8545 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8546 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8551 #endif /* 315 series */
8553 /*********************************************/
8554 /* MAIN: SET CRT2 REGISTER GROUP */
8555 /*********************************************/
8557 bool
8558 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8560 #ifdef SIS300
8561 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8562 #endif
8563 unsigned short ModeIdIndex, RefreshRateTableIndex;
8565 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8567 if(!SiS_Pr->UseCustomMode) {
8568 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8569 } else {
8570 ModeIdIndex = 0;
8573 /* Used for shifting CR33 */
8574 SiS_Pr->SiS_SelectCRT2Rate = 4;
8576 SiS_UnLockCRT2(SiS_Pr);
8578 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8580 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8582 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8583 SiS_DisableBridge(SiS_Pr);
8584 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8585 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8587 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8590 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8591 SiS_LockCRT2(SiS_Pr);
8592 SiS_DisplayOn(SiS_Pr);
8593 return true;
8596 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8598 /* Set up Panel Link for LVDS and LCDA */
8599 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8600 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8601 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8602 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8603 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8606 #ifdef SIS_XORG_XF86
8607 #ifdef TWDEBUG
8608 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8609 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8610 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8611 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8612 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8613 #endif
8614 #endif
8616 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8617 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8620 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8622 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8624 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8625 #ifdef SIS315H
8626 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8627 #endif
8628 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8629 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8630 #ifdef SIS315H
8631 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8632 #endif
8633 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8635 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8637 /* For 301BDH (Panel link initialization): */
8638 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8640 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8641 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8642 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8645 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8649 } else {
8651 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8653 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8655 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8657 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8658 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8659 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8660 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8661 #ifdef SIS315H
8662 SiS_SetCH701xForLCD(SiS_Pr);
8663 #endif
8666 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8667 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8674 #ifdef SIS300
8675 if(SiS_Pr->ChipType < SIS_315H) {
8676 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8677 if(SiS_Pr->SiS_UseOEM) {
8678 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8679 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8680 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8682 } else {
8683 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8686 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8687 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8688 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8689 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8691 SiS_DisplayOn(SiS_Pr);
8695 #endif
8697 #ifdef SIS315H
8698 if(SiS_Pr->ChipType >= SIS_315H) {
8699 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8700 if(SiS_Pr->ChipType < SIS_661) {
8701 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8702 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8703 } else {
8704 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8706 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8709 #endif
8711 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8712 SiS_EnableBridge(SiS_Pr);
8715 SiS_DisplayOn(SiS_Pr);
8717 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8718 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8719 /* Disable LCD panel when using TV */
8720 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8721 } else {
8722 /* Disable TV when using LCD */
8723 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8727 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8728 SiS_LockCRT2(SiS_Pr);
8731 return true;
8735 /*********************************************/
8736 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8737 /*********************************************/
8739 void
8740 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8742 /* Switch on LCD backlight on SiS30xLV */
8743 SiS_DDC2Delay(SiS_Pr,0xff00);
8744 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8745 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8746 SiS_WaitVBRetrace(SiS_Pr);
8748 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8749 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8753 void
8754 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8756 /* Switch off LCD backlight on SiS30xLV */
8757 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8758 SiS_DDC2Delay(SiS_Pr,0xff00);
8761 /*********************************************/
8762 /* DDC RELATED FUNCTIONS */
8763 /*********************************************/
8765 static void
8766 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8768 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8769 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8770 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8771 SiS_Pr->SiS_DDC_NData &= 0x0f;
8772 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8776 #ifdef SIS300
8777 static unsigned char *
8778 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8780 int i, j, num;
8781 unsigned short tempah,temp;
8782 unsigned char *mydataptr;
8784 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8785 mydataptr = dataptr;
8786 num = *mydataptr++;
8787 if(!num) return mydataptr;
8788 if(i) {
8789 SiS_SetStop(SiS_Pr);
8790 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8792 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8793 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8794 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8795 if(temp) continue; /* (ERROR: no ack) */
8796 tempah = *mydataptr++;
8797 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8798 if(temp) continue; /* (ERROR: no ack) */
8799 for(j=0; j<num; j++) {
8800 tempah = *mydataptr++;
8801 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8802 if(temp) break;
8804 if(temp) continue;
8805 if(SiS_SetStop(SiS_Pr)) continue;
8806 return mydataptr;
8808 return NULL;
8811 static bool
8812 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8814 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8815 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8816 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8817 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8818 SiS_SetupDDCN(SiS_Pr);
8820 SiS_SetSwitchDDC2(SiS_Pr);
8822 while(*dataptr) {
8823 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8824 if(!dataptr) return false;
8826 #ifdef SIS_XORG_XF86
8827 #ifdef TWDEBUG
8828 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
8829 #endif
8830 #endif
8831 return true;
8833 #endif
8835 /* The Chrontel 700x is connected to the 630/730 via
8836 * the 630/730's DDC/I2C port.
8838 * On 630(S)T chipset, the index changed from 0x11 to
8839 * 0x0a, possibly for working around the DDC problems
8842 static bool
8843 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8845 unsigned short temp, i;
8847 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8848 if(i) {
8849 SiS_SetStop(SiS_Pr);
8850 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8852 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8853 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8854 if(temp) continue; /* (ERROR: no ack) */
8855 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
8856 if(temp) continue; /* (ERROR: no ack) */
8857 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
8858 if(temp) continue; /* (ERROR: no ack) */
8859 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
8860 SiS_Pr->SiS_ChrontelInit = 1;
8861 return true;
8863 return false;
8866 /* Write to Chrontel 700x */
8867 void
8868 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8870 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8872 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8874 if(!(SiS_Pr->SiS_ChrontelInit)) {
8875 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8876 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8877 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8878 SiS_SetupDDCN(SiS_Pr);
8881 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
8882 (!(SiS_Pr->SiS_ChrontelInit)) ) {
8883 SiS_Pr->SiS_DDC_Index = 0x0a;
8884 SiS_Pr->SiS_DDC_Data = 0x80;
8885 SiS_Pr->SiS_DDC_Clk = 0x40;
8886 SiS_SetupDDCN(SiS_Pr);
8888 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
8892 /* Write to Chrontel 701x */
8893 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
8894 void
8895 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8897 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8898 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8899 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8900 SiS_SetupDDCN(SiS_Pr);
8901 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8902 SiS_SetChReg(SiS_Pr, reg, val, 0);
8905 #ifdef SIS_LINUX_KERNEL
8906 static
8907 #endif
8908 void
8909 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8911 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8912 SiS_SetCH700x(SiS_Pr, reg, val);
8913 else
8914 SiS_SetCH701x(SiS_Pr, reg, val);
8917 static unsigned short
8918 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
8920 unsigned short tempah, temp, i;
8922 for(i=0; i<20; i++) { /* Do 20 attempts to read */
8923 if(i) {
8924 SiS_SetStop(SiS_Pr);
8925 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8927 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8928 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8929 if(temp) continue; /* (ERROR: no ack) */
8930 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
8931 if(temp) continue; /* (ERROR: no ack) */
8932 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
8933 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
8934 if(temp) continue; /* (ERROR: no ack) */
8935 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
8936 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
8937 SiS_Pr->SiS_ChrontelInit = 1;
8938 return tempah;
8940 return 0xFFFF;
8943 /* Read from Chrontel 700x */
8944 /* Parameter is [Register no (S7-S0)] */
8945 unsigned short
8946 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8948 unsigned short result;
8950 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8952 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8954 if(!(SiS_Pr->SiS_ChrontelInit)) {
8955 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8956 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8957 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8958 SiS_SetupDDCN(SiS_Pr);
8961 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8963 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
8964 (!SiS_Pr->SiS_ChrontelInit) ) {
8966 SiS_Pr->SiS_DDC_Index = 0x0a;
8967 SiS_Pr->SiS_DDC_Data = 0x80;
8968 SiS_Pr->SiS_DDC_Clk = 0x40;
8969 SiS_SetupDDCN(SiS_Pr);
8971 result = SiS_GetChReg(SiS_Pr,0x80);
8973 return result;
8976 /* Read from Chrontel 701x */
8977 /* Parameter is [Register no (S7-S0)] */
8978 unsigned short
8979 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8981 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8982 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8983 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8984 SiS_SetupDDCN(SiS_Pr);
8985 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8987 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8989 return SiS_GetChReg(SiS_Pr,0);
8992 /* Read from Chrontel 70xx */
8993 /* Parameter is [Register no (S7-S0)] */
8994 #ifdef SIS_LINUX_KERNEL
8995 static
8996 #endif
8997 unsigned short
8998 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9000 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9001 return SiS_GetCH700x(SiS_Pr, tempbx);
9002 else
9003 return SiS_GetCH701x(SiS_Pr, tempbx);
9006 void
9007 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9008 unsigned char myor, unsigned short myand)
9010 unsigned short tempbl;
9012 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9013 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9016 /* Our own DDC functions */
9017 #ifndef SIS_XORG_XF86
9018 static
9019 #endif
9020 unsigned short
9021 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9022 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
9023 unsigned int VBFlags2)
9025 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9026 unsigned char flag, cr32;
9027 unsigned short temp = 0, myadaptnum = adaptnum;
9029 if(adaptnum != 0) {
9030 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9031 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9034 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9036 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9038 SiS_Pr->SiS_DDC_SecAddr = 0;
9039 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9040 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9041 SiS_Pr->SiS_DDC_Index = 0x11;
9042 flag = 0xff;
9044 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9047 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9049 if(myadaptnum != 0) {
9050 flag = 0;
9051 if(VBFlags2 & VB2_SISBRIDGE) {
9052 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9053 SiS_Pr->SiS_DDC_Index = 0x0f;
9057 if(!(VBFlags2 & VB2_301)) {
9058 if((cr32 & 0x80) && (checkcr32)) {
9059 if(myadaptnum >= 1) {
9060 if(!(cr32 & 0x08)) {
9061 myadaptnum = 1;
9062 if(!(cr32 & 0x10)) return 0xFFFF;
9068 temp = 4 - (myadaptnum * 2);
9069 if(flag) temp = 0;
9071 } else { /* 315/330 series */
9073 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9075 if(VBFlags2 & VB2_SISBRIDGE) {
9076 if(myadaptnum == 2) {
9077 myadaptnum = 1;
9081 if(myadaptnum == 1) {
9082 flag = 0;
9083 if(VBFlags2 & VB2_SISBRIDGE) {
9084 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9085 SiS_Pr->SiS_DDC_Index = 0x0f;
9089 if((cr32 & 0x80) && (checkcr32)) {
9090 if(myadaptnum >= 1) {
9091 if(!(cr32 & 0x08)) {
9092 myadaptnum = 1;
9093 if(!(cr32 & 0x10)) return 0xFFFF;
9098 temp = myadaptnum;
9099 if(myadaptnum == 1) {
9100 temp = 0;
9101 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9104 if(flag) temp = 0;
9107 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9108 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9110 SiS_SetupDDCN(SiS_Pr);
9112 #ifdef SIS_XORG_XF86
9113 #ifdef TWDEBUG
9114 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9115 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9116 #endif
9117 #endif
9118 return 0;
9121 static unsigned short
9122 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9124 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9125 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9126 return 0xFFFF;
9128 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9129 return 0xFFFF;
9131 return 0;
9134 static unsigned short
9135 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9137 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9138 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9139 return 0xFFFF;
9141 return 0;
9144 static unsigned short
9145 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9147 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9148 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9149 return 0;
9152 static void
9153 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9155 SiS_SetSCLKLow(SiS_Pr);
9156 if(yesno) {
9157 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9158 SiS_Pr->SiS_DDC_Index,
9159 SiS_Pr->SiS_DDC_NData,
9160 SiS_Pr->SiS_DDC_Data);
9161 } else {
9162 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9163 SiS_Pr->SiS_DDC_Index,
9164 SiS_Pr->SiS_DDC_NData,
9167 SiS_SetSCLKHigh(SiS_Pr);
9170 static unsigned short
9171 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9173 unsigned char mask, value;
9174 unsigned short temp, ret=0;
9175 bool failed = false;
9177 SiS_SetSwitchDDC2(SiS_Pr);
9178 if(SiS_PrepareDDC(SiS_Pr)) {
9179 SiS_SetStop(SiS_Pr);
9180 #ifdef SIS_XORG_XF86
9181 #ifdef TWDEBUG
9182 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9183 #endif
9184 #endif
9185 return 0xFFFF;
9187 mask = 0xf0;
9188 value = 0x20;
9189 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9190 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9191 SiS_SendACK(SiS_Pr, 0);
9192 if(temp == 0) {
9193 mask = 0xff;
9194 value = 0xff;
9195 } else {
9196 failed = true;
9197 ret = 0xFFFF;
9198 #ifdef SIS_XORG_XF86
9199 #ifdef TWDEBUG
9200 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9201 #endif
9202 #endif
9205 if(!failed) {
9206 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9207 SiS_SendACK(SiS_Pr, 1);
9208 temp &= mask;
9209 if(temp == value) ret = 0;
9210 else {
9211 ret = 0xFFFF;
9212 #ifdef SIS_XORG_XF86
9213 #ifdef TWDEBUG
9214 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9215 #endif
9216 #endif
9217 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9218 if(temp == 0x30) ret = 0;
9222 SiS_SetStop(SiS_Pr);
9223 return ret;
9226 #ifndef SIS_XORG_XF86
9227 static
9228 #endif
9229 unsigned short
9230 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9232 unsigned short flag;
9234 flag = 0x180;
9235 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9236 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9237 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9238 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9239 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9240 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9241 if(!(flag & 0x1a)) flag = 0;
9242 return flag;
9245 #ifndef SIS_XORG_XF86
9246 static
9247 #endif
9248 unsigned short
9249 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9251 unsigned short flag, length, i;
9252 unsigned char chksum,gotcha;
9254 if(DDCdatatype > 4) return 0xFFFF;
9256 flag = 0;
9257 SiS_SetSwitchDDC2(SiS_Pr);
9258 if(!(SiS_PrepareDDC(SiS_Pr))) {
9259 length = 127;
9260 if(DDCdatatype != 1) length = 255;
9261 chksum = 0;
9262 gotcha = 0;
9263 for(i=0; i<length; i++) {
9264 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9265 chksum += buffer[i];
9266 gotcha |= buffer[i];
9267 SiS_SendACK(SiS_Pr, 0);
9269 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9270 chksum += buffer[i];
9271 SiS_SendACK(SiS_Pr, 1);
9272 if(gotcha) flag = (unsigned short)chksum;
9273 else flag = 0xFFFF;
9274 } else {
9275 flag = 0xFFFF;
9277 SiS_SetStop(SiS_Pr);
9278 return flag;
9281 /* Our private DDC functions
9283 It complies somewhat with the corresponding VESA function
9284 in arguments and return values.
9286 Since this is probably called before the mode is changed,
9287 we use our pre-detected pSiS-values instead of SiS_Pr as
9288 regards chipset and video bridge type.
9290 Arguments:
9291 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9292 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9293 LCDA is CRT1, but DDC is read from CRT2 port.
9294 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9295 buffer: ptr to 256 data bytes which will be filled with read data.
9297 Returns 0xFFFF if error, otherwise
9298 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9299 if DDCdatatype = 0: Returns supported DDC modes
9302 unsigned short
9303 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9304 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9305 unsigned int VBFlags2)
9307 unsigned char sr1f, cr17=1;
9308 unsigned short result;
9310 if(adaptnum > 2)
9311 return 0xFFFF;
9313 if(DDCdatatype > 4)
9314 return 0xFFFF;
9316 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9317 return 0xFFFF;
9319 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9320 return 0xFFFF;
9322 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9323 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9324 if(VGAEngine == SIS_300_VGA) {
9325 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9326 if(!cr17) {
9327 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9328 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9329 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9332 if((sr1f) || (!cr17)) {
9333 SiS_WaitRetrace1(SiS_Pr);
9334 SiS_WaitRetrace1(SiS_Pr);
9335 SiS_WaitRetrace1(SiS_Pr);
9336 SiS_WaitRetrace1(SiS_Pr);
9339 if(DDCdatatype == 0) {
9340 result = SiS_ProbeDDC(SiS_Pr);
9341 } else {
9342 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9343 if((!result) && (DDCdatatype == 1)) {
9344 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9345 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9346 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9347 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9348 (buffer[0x12] == 1)) {
9349 if(!SiS_Pr->DDCPortMixup) {
9350 if(adaptnum == 1) {
9351 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9352 } else {
9353 if(buffer[0x14] & 0x80) result = 0xFFFE;
9359 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9360 if(VGAEngine == SIS_300_VGA) {
9361 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9363 return result;
9366 /* Generic I2C functions for Chrontel & DDC --------- */
9368 static void
9369 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9371 SiS_SetSCLKHigh(SiS_Pr);
9372 SiS_WaitRetrace1(SiS_Pr);
9374 SiS_SetSCLKLow(SiS_Pr);
9375 SiS_WaitRetrace1(SiS_Pr);
9378 unsigned short
9379 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9381 SiS_WaitRetrace1(SiS_Pr);
9382 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9385 /* Set I2C start condition */
9386 /* This is done by a SD high-to-low transition while SC is high */
9387 static unsigned short
9388 SiS_SetStart(struct SiS_Private *SiS_Pr)
9390 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9391 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9392 SiS_Pr->SiS_DDC_Index,
9393 SiS_Pr->SiS_DDC_NData,
9394 SiS_Pr->SiS_DDC_Data); /* SD->high */
9395 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9396 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9397 SiS_Pr->SiS_DDC_Index,
9398 SiS_Pr->SiS_DDC_NData,
9399 0x00); /* SD->low = start condition */
9400 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9401 return 0;
9404 /* Set I2C stop condition */
9405 /* This is done by a SD low-to-high transition while SC is high */
9406 static unsigned short
9407 SiS_SetStop(struct SiS_Private *SiS_Pr)
9409 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9410 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9411 SiS_Pr->SiS_DDC_Index,
9412 SiS_Pr->SiS_DDC_NData,
9413 0x00); /* SD->low */
9414 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9415 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9416 SiS_Pr->SiS_DDC_Index,
9417 SiS_Pr->SiS_DDC_NData,
9418 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9419 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9420 return 0;
9423 /* Write 8 bits of data */
9424 static unsigned short
9425 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9427 unsigned short i,flag,temp;
9429 flag = 0x80;
9430 for(i = 0; i < 8; i++) {
9431 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9432 if(tempax & flag) {
9433 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9434 SiS_Pr->SiS_DDC_Index,
9435 SiS_Pr->SiS_DDC_NData,
9436 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9437 } else {
9438 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9439 SiS_Pr->SiS_DDC_Index,
9440 SiS_Pr->SiS_DDC_NData,
9441 0x00); /* Write bit (0) to SD */
9443 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9444 flag >>= 1;
9446 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9447 return temp;
9450 static unsigned short
9451 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9453 unsigned short i, temp, getdata;
9455 getdata = 0;
9456 for(i = 0; i < 8; i++) {
9457 getdata <<= 1;
9458 SiS_SetSCLKLow(SiS_Pr);
9459 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9460 SiS_Pr->SiS_DDC_Index,
9461 SiS_Pr->SiS_DDC_NData,
9462 SiS_Pr->SiS_DDC_Data);
9463 SiS_SetSCLKHigh(SiS_Pr);
9464 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9465 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9467 return getdata;
9470 static unsigned short
9471 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9473 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9474 SiS_Pr->SiS_DDC_Index,
9475 SiS_Pr->SiS_DDC_NClk,
9476 0x00); /* SetSCLKLow() */
9477 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9478 return 0;
9481 static unsigned short
9482 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9484 unsigned short temp, watchdog=1000;
9486 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9487 SiS_Pr->SiS_DDC_Index,
9488 SiS_Pr->SiS_DDC_NClk,
9489 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9490 do {
9491 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9492 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9493 if (!watchdog) {
9494 #ifdef SIS_XORG_XF86
9495 #ifdef TWDEBUG
9496 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
9497 #endif
9498 #endif
9499 return 0xFFFF;
9501 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9502 return 0;
9505 /* Check I2C acknowledge */
9506 /* Returns 0 if ack ok, non-0 if ack not ok */
9507 static unsigned short
9508 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9510 unsigned short tempah;
9512 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9513 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9514 SiS_Pr->SiS_DDC_Index,
9515 SiS_Pr->SiS_DDC_NData,
9516 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9517 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9518 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9519 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9520 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9521 return 0;
9524 /* End of I2C functions ----------------------- */
9527 /* =============== SiS 315/330 O.E.M. ================= */
9529 #ifdef SIS315H
9531 static unsigned short
9532 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9534 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9535 unsigned short romptr;
9537 if(SiS_Pr->ChipType < SIS_330) {
9538 romptr = SISGETROMW(0x128);
9539 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9540 romptr = SISGETROMW(0x12a);
9541 } else {
9542 romptr = SISGETROMW(0x1a8);
9543 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9544 romptr = SISGETROMW(0x1aa);
9546 return romptr;
9549 static unsigned short
9550 GetLCDromptr(struct SiS_Private *SiS_Pr)
9552 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9553 unsigned short romptr;
9555 if(SiS_Pr->ChipType < SIS_330) {
9556 romptr = SISGETROMW(0x120);
9557 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9558 romptr = SISGETROMW(0x122);
9559 } else {
9560 romptr = SISGETROMW(0x1a0);
9561 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9562 romptr = SISGETROMW(0x1a2);
9564 return romptr;
9567 static unsigned short
9568 GetTVromptr(struct SiS_Private *SiS_Pr)
9570 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9571 unsigned short romptr;
9573 if(SiS_Pr->ChipType < SIS_330) {
9574 romptr = SISGETROMW(0x114);
9575 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9576 romptr = SISGETROMW(0x11a);
9577 } else {
9578 romptr = SISGETROMW(0x194);
9579 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9580 romptr = SISGETROMW(0x19a);
9582 return romptr;
9585 static unsigned short
9586 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9588 unsigned short index;
9590 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9591 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9592 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9593 index >>= 4;
9594 index *= 3;
9595 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9596 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9597 return index;
9602 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9603 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9604 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9605 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9606 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9607 } else {
9608 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9610 index--;
9611 index *= 3;
9612 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9613 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9614 return index;
9617 static unsigned short
9618 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9620 unsigned short index;
9622 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9623 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9624 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9625 return index;
9628 static unsigned short
9629 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9631 unsigned short index;
9633 index = 0;
9634 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9635 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9637 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9639 index <<= 1;
9641 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9642 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9643 index++;
9646 return index;
9649 static unsigned int
9650 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9652 unsigned short index = 0, temp = 0;
9654 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9655 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9656 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9657 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9658 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9659 index = 4;
9660 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9661 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9664 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9665 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9666 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9667 index += addme;
9668 temp++;
9670 temp += 0x0100;
9672 return (unsigned int)(index | (temp << 16));
9675 static unsigned int
9676 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9678 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9682 static int
9683 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9685 int index = 0;
9687 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9688 if(SiS_Pr->SiS_ROMNew) {
9689 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9690 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9691 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9692 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9693 } else {
9694 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9695 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9696 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9697 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9700 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9702 return index;
9705 static void
9706 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9708 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9709 unsigned short delay=0,index,myindex,temp,romptr=0;
9710 bool dochiptest = true;
9712 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9713 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9714 } else {
9715 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9718 /* Find delay (from ROM, internal tables, PCI subsystem) */
9720 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9722 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9723 romptr = GetRAMDACromptr(SiS_Pr);
9725 if(romptr) delay = ROMAddr[romptr];
9726 else {
9727 delay = 0x04;
9728 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9729 if(IS_SIS650) {
9730 delay = 0x0a;
9731 } else if(IS_SIS740) {
9732 delay = 0x00;
9733 } else if(SiS_Pr->ChipType < SIS_330) {
9734 delay = 0x0c;
9735 } else {
9736 delay = 0x0c;
9738 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9739 delay = 0x00;
9743 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9745 bool gotitfrompci = false;
9747 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9749 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9750 if(SiS_Pr->PDC != -1) {
9751 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9752 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9753 return;
9755 } else {
9756 if(SiS_Pr->PDCA != -1) {
9757 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9758 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9759 return;
9763 /* Custom Panel? */
9765 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9766 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9767 delay = 0x00;
9768 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9769 delay = 0x20;
9771 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9772 } else {
9773 delay = 0x0c;
9774 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9775 delay = 0x03;
9776 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9777 delay = 0x00;
9779 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9780 if(IS_SIS740) delay = 0x01;
9781 else delay = 0x03;
9783 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9785 return;
9788 /* This is a piece of typical SiS crap: They code the OEM LCD
9789 * delay into the code, at no defined place in the BIOS.
9790 * We now have to start doing a PCI subsystem check here.
9793 switch(SiS_Pr->SiS_CustomT) {
9794 case CUT_COMPAQ1280:
9795 case CUT_COMPAQ12802:
9796 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9797 gotitfrompci = true;
9798 dochiptest = false;
9799 delay = 0x03;
9801 break;
9802 case CUT_CLEVO1400:
9803 case CUT_CLEVO14002:
9804 gotitfrompci = true;
9805 dochiptest = false;
9806 delay = 0x02;
9807 break;
9808 case CUT_CLEVO1024:
9809 case CUT_CLEVO10242:
9810 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9811 gotitfrompci = true;
9812 dochiptest = false;
9813 delay = 0x33;
9814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9815 delay &= 0x0f;
9817 break;
9820 /* Could we find it through the PCI ID? If no, use ROM or table */
9822 if(!gotitfrompci) {
9824 index = GetLCDPtrIndexBIOS(SiS_Pr);
9825 myindex = GetLCDPtrIndex(SiS_Pr);
9827 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9829 if(SiS_IsNotM650orLater(SiS_Pr)) {
9831 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9832 /* Always use the second pointer on 650; some BIOSes */
9833 /* still carry old 301 data at the first location */
9834 /* romptr = SISGETROMW(0x120); */
9835 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9836 romptr = SISGETROMW(0x122);
9837 if(!romptr) return;
9838 delay = ROMAddr[(romptr + index)];
9839 } else {
9840 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9843 } else {
9845 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
9846 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
9847 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
9851 } else if(SiS_Pr->SiS_UseROM &&
9852 (!(SiS_Pr->SiS_ROMNew)) &&
9853 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
9854 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
9855 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
9856 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
9857 ((romptr = GetLCDromptr(SiS_Pr)))) {
9859 /* Data for 1280x1024 wrong in 301B BIOS */
9860 /* Data for 1600x1200 wrong in 301C BIOS */
9861 delay = ROMAddr[(romptr + index)];
9863 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9865 if(IS_SIS740) delay = 0x03;
9866 else delay = 0x00;
9868 } else {
9870 delay = SiS310_LCDDelayCompensation_301[myindex];
9871 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9872 if(IS_SIS740) delay = 0x01;
9873 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
9874 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9875 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9876 if(IS_SIS740) delay = 0x01; /* ? */
9877 else delay = 0x03;
9878 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
9879 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9880 if(IS_SIS740) delay = 0x01;
9881 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
9886 } /* got it from PCI */
9888 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9889 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
9890 dochiptest = false;
9893 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
9895 index = GetTVPtrIndex(SiS_Pr);
9897 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9899 if(SiS_IsNotM650orLater(SiS_Pr)) {
9901 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9902 /* Always use the second pointer on 650; some BIOSes */
9903 /* still carry old 301 data at the first location */
9904 /* romptr = SISGETROMW(0x114); */
9905 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9906 romptr = SISGETROMW(0x11a);
9907 if(!romptr) return;
9908 delay = ROMAddr[romptr + index];
9910 } else {
9912 delay = SiS310_TVDelayCompensation_301B[index];
9916 } else {
9918 switch(SiS_Pr->SiS_CustomT) {
9919 case CUT_COMPAQ1280:
9920 case CUT_COMPAQ12802:
9921 case CUT_CLEVO1400:
9922 case CUT_CLEVO14002:
9923 delay = 0x02;
9924 dochiptest = false;
9925 break;
9926 case CUT_CLEVO1024:
9927 case CUT_CLEVO10242:
9928 delay = 0x03;
9929 dochiptest = false;
9930 break;
9931 default:
9932 delay = SiS310_TVDelayCompensation_651301LV[index];
9933 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
9934 delay = SiS310_TVDelayCompensation_651302LV[index];
9939 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9941 romptr = GetTVromptr(SiS_Pr);
9942 if(!romptr) return;
9943 delay = ROMAddr[romptr + index];
9945 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9947 delay = SiS310_TVDelayCompensation_LVDS[index];
9949 } else {
9951 delay = SiS310_TVDelayCompensation_301[index];
9952 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9953 if(IS_SIS740) {
9954 delay = SiS310_TVDelayCompensation_740301B[index];
9955 /* LV: use 301 data? BIOS bug? */
9956 } else {
9957 delay = SiS310_TVDelayCompensation_301B[index];
9958 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
9964 if(SiS_LCDAEnabled(SiS_Pr)) {
9965 delay &= 0x0f;
9966 dochiptest = false;
9969 } else return;
9971 /* Write delay */
9973 if(SiS_Pr->SiS_VBType & VB_SISVB) {
9975 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
9977 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
9978 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
9979 delay &= 0x0f;
9980 delay |= 0xb0;
9981 } else if(temp == 6) {
9982 delay &= 0x0f;
9983 delay |= 0xc0;
9984 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
9985 delay = 0x35;
9987 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9989 } else {
9991 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9995 } else { /* LVDS */
9997 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9998 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9999 } else {
10000 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10001 delay <<= 4;
10002 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10003 } else {
10004 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10012 static void
10013 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10015 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10016 unsigned short index,temp,temp1,romptr=0;
10018 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10020 if(ModeNo<=0x13)
10021 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10022 else
10023 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10025 temp = GetTVPtrIndex(SiS_Pr);
10026 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10027 temp1 = temp;
10029 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10030 if(SiS_Pr->ChipType >= SIS_661) {
10031 temp1 = GetOEMTVPtr661(SiS_Pr);
10032 temp1 >>= 1;
10033 romptr = SISGETROMW(0x260);
10034 if(SiS_Pr->ChipType >= SIS_760) {
10035 romptr = SISGETROMW(0x360);
10037 } else if(SiS_Pr->ChipType >= SIS_330) {
10038 romptr = SISGETROMW(0x192);
10039 } else {
10040 romptr = SISGETROMW(0x112);
10044 if(romptr) {
10045 temp1 <<= 1;
10046 temp = ROMAddr[romptr + temp1 + index];
10047 } else {
10048 temp = SiS310_TVAntiFlick1[temp][index];
10050 temp <<= 4;
10052 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10055 static void
10056 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10058 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10059 unsigned short index,temp,temp1,romptr=0;
10061 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10063 if(ModeNo <= 0x13)
10064 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10065 else
10066 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10068 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10069 if(SiS_Pr->ChipType >= SIS_661) {
10070 romptr = SISGETROMW(0x26c);
10071 if(SiS_Pr->ChipType >= SIS_760) {
10072 romptr = SISGETROMW(0x36c);
10074 temp1 = GetOEMTVPtr661(SiS_Pr);
10075 temp1 >>= 1;
10076 } else if(SiS_Pr->ChipType >= SIS_330) {
10077 romptr = SISGETROMW(0x1a4);
10078 } else {
10079 romptr = SISGETROMW(0x124);
10083 if(romptr) {
10084 temp1 <<= 1;
10085 temp = ROMAddr[romptr + temp1 + index];
10086 } else {
10087 temp = SiS310_TVEdge1[temp][index];
10089 temp <<= 5;
10090 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10093 static void
10094 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10096 unsigned short index, temp, i, j;
10098 if(ModeNo <= 0x13) {
10099 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10100 } else {
10101 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10104 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10106 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10107 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10108 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10109 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10111 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10112 for(i=0x35, j=0; i<=0x38; i++, j++) {
10113 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10115 for(i=0x48; i<=0x4A; i++, j++) {
10116 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10118 } else {
10119 for(i=0x35, j=0; i<=0x38; i++, j++) {
10120 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10125 static void
10126 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10128 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10129 unsigned short index,temp,i,j,resinfo,romptr=0;
10130 unsigned int lindex;
10132 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10134 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10135 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10137 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10138 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10139 lindex <<= 2;
10140 for(j=0, i=0x31; i<=0x34; i++, j++) {
10141 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10143 return;
10146 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10147 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10149 if(ModeNo<=0x13) {
10150 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10151 } else {
10152 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10155 temp = GetTVPtrIndex(SiS_Pr);
10156 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10157 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10159 if(SiS_Pr->SiS_UseROM) {
10160 romptr = SISGETROMW(0x116);
10161 if(SiS_Pr->ChipType >= SIS_330) {
10162 romptr = SISGETROMW(0x196);
10164 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10165 romptr = SISGETROMW(0x11c);
10166 if(SiS_Pr->ChipType >= SIS_330) {
10167 romptr = SISGETROMW(0x19c);
10169 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10170 romptr = SISGETROMW(0x116);
10171 if(SiS_Pr->ChipType >= SIS_330) {
10172 romptr = SISGETROMW(0x196);
10177 if(romptr) {
10178 romptr += (temp << 2);
10179 for(j=0, i=0x31; i<=0x34; i++, j++) {
10180 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10182 } else {
10183 index = temp % 2;
10184 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10185 for(j=0, i=0x31; i<=0x34; i++, j++) {
10186 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10187 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10188 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10189 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10190 else
10191 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10195 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10196 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10197 if((resinfo == SIS_RI_640x480) ||
10198 (resinfo == SIS_RI_800x600)) {
10199 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10200 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10201 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10202 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10203 } else if(resinfo == SIS_RI_1024x768) {
10204 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10205 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10206 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10207 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10213 static void
10214 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10215 unsigned short ModeIdIndex, unsigned short RTI)
10217 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10218 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10220 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10221 return;
10223 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10224 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10226 if(SiS_Pr->SiS_ROMNew) {
10227 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10228 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10229 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10230 index = 25;
10231 if(SiS_Pr->UseCustomMode) {
10232 index = SiS_Pr->CSRClock;
10233 } else if(ModeNo > 0x13) {
10234 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10235 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10237 if(index < 25) index = 25;
10238 index = ((index / 25) - 1) << 1;
10239 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10240 index++;
10242 romptr = SISGETROMW(0x104);
10243 delay = ROMAddr[romptr + index];
10244 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10245 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10246 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10247 } else {
10248 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10249 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10251 return;
10255 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10257 if(SiS_Pr->UseCustomMode) delay = 0x04;
10258 else if(ModeNo <= 0x13) delay = 0x04;
10259 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10260 delay |= (delay << 8);
10262 if(SiS_Pr->ChipType >= XGI_20) {
10264 delay = 0x0606;
10265 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10267 delay = 0x0404;
10268 if(SiS_Pr->SiS_XGIROM) {
10269 index = GetTVPtrIndex(SiS_Pr);
10270 if((romptr = SISGETROMW(0x35e))) {
10271 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10272 delay |= (delay << 8);
10276 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10277 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10278 delay -= 0x0404;
10283 } else if(SiS_Pr->ChipType >= SIS_340) {
10285 delay = 0x0606;
10286 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10287 delay = 0x0404;
10289 /* TODO (eventually) */
10291 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10293 /* 3. TV */
10295 index = GetOEMTVPtr661(SiS_Pr);
10296 if(SiS_Pr->SiS_ROMNew) {
10297 romptr = SISGETROMW(0x106);
10298 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10299 delay = ROMAddr[romptr + index];
10300 } else {
10301 delay = 0x04;
10302 if(index > 3) delay = 0;
10305 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10307 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10309 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10310 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10312 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10314 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10315 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10316 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10318 } else {
10320 /* TMDS: Set our own, since BIOS has no idea */
10321 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10322 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10323 switch(SiS_Pr->SiS_LCDResInfo) {
10324 case Panel_1024x768: delay = 0x0008; break;
10325 case Panel_1280x720: delay = 0x0004; break;
10326 case Panel_1280x768:
10327 case Panel_1280x768_2:delay = 0x0004; break;
10328 case Panel_1280x800:
10329 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10330 case Panel_1280x854: delay = 0x0004; break;
10331 case Panel_1280x1024: delay = 0x1e04; break;
10332 case Panel_1400x1050: delay = 0x0004; break;
10333 case Panel_1600x1200: delay = 0x0400; break;
10334 case Panel_1680x1050: delay = 0x0e04; break;
10335 default:
10336 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10337 delay = 0x0008;
10338 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10339 delay = 0x1e04;
10340 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10341 delay = 0x0004;
10342 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10343 delay = 0x0400;
10344 } else
10345 delay = 0x0e04;
10346 break;
10350 /* Override by detected or user-set values */
10351 /* (but only if, for some reason, we can't read value from BIOS) */
10352 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10353 delay = SiS_Pr->PDC & 0x1f;
10355 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10356 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10363 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10364 delay >>= 8;
10365 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10366 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10367 } else {
10368 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10369 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10373 static void
10374 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10376 unsigned short infoflag;
10377 unsigned char temp;
10379 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10381 if(ModeNo <= 0x13) {
10382 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10383 } else if(SiS_Pr->UseCustomMode) {
10384 infoflag = SiS_Pr->CInfoFlag;
10385 } else {
10386 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10389 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10390 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10393 infoflag &= 0xc0;
10395 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10396 temp = (infoflag >> 6) | 0x0c;
10397 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10398 temp ^= 0x04;
10399 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10401 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10402 } else {
10403 temp = 0x30;
10404 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10405 temp |= infoflag;
10406 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10407 temp = 0;
10408 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10409 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10411 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10417 static void
10418 SetPanelParms661(struct SiS_Private *SiS_Pr)
10420 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10421 unsigned short romptr, temp1, temp2;
10423 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10424 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10427 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10428 if(SiS_Pr->LVDSHL != -1) {
10429 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10433 if(SiS_Pr->SiS_ROMNew) {
10435 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10436 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10437 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10438 temp2 = 0xfc;
10439 if(SiS_Pr->LVDSHL != -1) {
10440 temp1 &= 0xfc;
10441 temp2 = 0xf3;
10443 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10445 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10446 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10447 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10454 static void
10455 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10457 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10458 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10459 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10460 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10461 SetPanelParms661(SiS_Pr);
10463 } else {
10464 SetDelayComp(SiS_Pr,ModeNo);
10467 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10468 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10469 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10470 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10471 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10472 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10477 static void
10478 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10479 unsigned short ModeIdIndex, unsigned short RRTI)
10481 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10483 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10485 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10486 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10487 SetPanelParms661(SiS_Pr);
10490 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10491 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10492 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10493 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10494 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10495 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10501 /* FinalizeLCD
10502 * This finalizes some CRT2 registers for the very panel used.
10503 * If we have a backup if these registers, we use it; otherwise
10504 * we set the register according to most BIOSes. However, this
10505 * function looks quite different in every BIOS, so you better
10506 * pray that we have a backup...
10508 static void
10509 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10511 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10512 unsigned short resinfo,modeflag;
10514 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10515 if(SiS_Pr->SiS_ROMNew) return;
10517 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10518 if(SiS_Pr->LVDSHL != -1) {
10519 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10523 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10524 if(SiS_Pr->UseCustomMode) return;
10526 switch(SiS_Pr->SiS_CustomT) {
10527 case CUT_COMPAQ1280:
10528 case CUT_COMPAQ12802:
10529 case CUT_CLEVO1400:
10530 case CUT_CLEVO14002:
10531 return;
10534 if(ModeNo <= 0x13) {
10535 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10536 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10537 } else {
10538 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10539 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10542 if(IS_SIS650) {
10543 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10544 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10545 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10546 } else {
10547 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10552 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10553 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10554 /* Maybe all panels? */
10555 if(SiS_Pr->LVDSHL == -1) {
10556 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10558 return;
10562 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10563 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10564 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10565 if(SiS_Pr->LVDSHL == -1) {
10566 /* Maybe all panels? */
10567 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10569 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10570 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10571 if(tempch == 3) {
10572 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10573 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10574 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10575 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10578 return;
10583 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10584 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10585 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10586 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10587 #ifdef SET_EMI
10588 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10589 #endif
10590 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10592 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10593 if(SiS_Pr->LVDSHL == -1) {
10594 /* Maybe ACER only? */
10595 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10598 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10599 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10600 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10601 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10602 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10603 if(tempch == 0x03) {
10604 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10605 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10606 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10607 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10609 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10610 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10611 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10612 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10613 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10614 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10615 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10616 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10617 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10618 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10619 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10620 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10621 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10622 if(ModeNo <= 0x13) {
10623 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10624 if((resinfo == 0) || (resinfo == 2)) return;
10625 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10626 if((resinfo == 1) || (resinfo == 3)) return;
10628 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10629 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10630 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10632 } else if(ModeNo <= 0x13) {
10633 if(ModeNo <= 1) {
10634 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10635 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10636 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10637 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10639 if(!(modeflag & HalfDCLK)) {
10640 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10641 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10642 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10643 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10644 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10645 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10646 if(ModeNo == 0x12) {
10647 switch(tempch) {
10648 case 0:
10649 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10650 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10651 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10652 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10653 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10654 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10655 break;
10656 case 2:
10657 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10658 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10659 break;
10660 case 3:
10661 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10662 break;
10668 } else {
10669 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10670 tempcl &= 0x0f;
10671 tempbh &= 0x70;
10672 tempbh >>= 4;
10673 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10674 tempbx = (tempbh << 8) | tempbl;
10675 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10676 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10677 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10678 tempbx = 770;
10679 } else {
10680 if(tempbx > 770) tempbx = 770;
10681 if(SiS_Pr->SiS_VGAVDE < 600) {
10682 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10683 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10684 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10685 tempbx -= tempax;
10688 } else return;
10690 temp = tempbx & 0xff;
10691 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10692 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10693 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10698 #endif
10700 /* ================= SiS 300 O.E.M. ================== */
10702 #ifdef SIS300
10704 static void
10705 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10706 unsigned short RefTabIndex)
10708 unsigned short crt2crtc=0, modeflag, myindex=0;
10709 unsigned char temp;
10710 int i;
10712 if(ModeNo <= 0x13) {
10713 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10714 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10715 } else {
10716 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10717 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10720 crt2crtc &= 0x3f;
10722 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10723 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10726 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10727 if(modeflag & HalfDCLK) myindex = 1;
10729 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10730 for(i=0; i<7; i++) {
10731 if(barco_p1[myindex][crt2crtc][i][0]) {
10732 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10733 barco_p1[myindex][crt2crtc][i][0],
10734 barco_p1[myindex][crt2crtc][i][2],
10735 barco_p1[myindex][crt2crtc][i][1]);
10739 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10740 if(temp & 0x80) {
10741 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10742 temp++;
10743 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10748 static unsigned short
10749 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10751 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10752 unsigned short tempbx=0,romptr=0;
10753 static const unsigned char customtable300[] = {
10754 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10755 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10757 static const unsigned char customtable630[] = {
10758 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10759 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10762 if(SiS_Pr->ChipType == SIS_300) {
10764 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10765 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10766 tempbx -= 2;
10767 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10768 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10769 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10771 if(SiS_Pr->SiS_UseROM) {
10772 if(ROMAddr[0x235] & 0x80) {
10773 tempbx = SiS_Pr->SiS_LCDTypeInfo;
10774 if(Flag) {
10775 romptr = SISGETROMW(0x255);
10776 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10777 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10778 if(tempbx == 0xFF) return 0xFFFF;
10780 tempbx <<= 1;
10781 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10785 } else {
10787 if(Flag) {
10788 if(SiS_Pr->SiS_UseROM) {
10789 romptr = SISGETROMW(0x255);
10790 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10791 else tempbx = 0xff;
10792 } else {
10793 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10795 if(tempbx == 0xFF) return 0xFFFF;
10796 tempbx <<= 2;
10797 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10798 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10799 return tempbx;
10801 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10802 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10803 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10807 return tempbx;
10810 static void
10811 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10813 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10814 unsigned short index,temp,romptr=0;
10816 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10818 if(SiS_Pr->SiS_UseROM) {
10819 if(!(ROMAddr[0x237] & 0x01)) return;
10820 if(!(ROMAddr[0x237] & 0x02)) return;
10821 romptr = SISGETROMW(0x24b);
10824 /* The Panel Compensation Delay should be set according to tables
10825 * here. Unfortunately, various BIOS versions don't care about
10826 * a uniform way using eg. ROM byte 0x220, but use different
10827 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10828 * Thus we don't set this if the user selected a custom pdc or if
10829 * we otherwise detected a valid pdc.
10831 if(SiS_Pr->PDC != -1) return;
10833 temp = GetOEMLCDPtr(SiS_Pr, 0);
10835 if(SiS_Pr->UseCustomMode)
10836 index = 0;
10837 else
10838 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
10840 if(SiS_Pr->ChipType != SIS_300) {
10841 if(romptr) {
10842 romptr += (temp * 2);
10843 romptr = SISGETROMW(romptr);
10844 romptr += index;
10845 temp = ROMAddr[romptr];
10846 } else {
10847 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10848 temp = SiS300_OEMLCDDelay2[temp][index];
10849 } else {
10850 temp = SiS300_OEMLCDDelay3[temp][index];
10853 } else {
10854 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
10855 if(romptr) {
10856 romptr += (temp * 2);
10857 romptr = SISGETROMW(romptr);
10858 romptr += index;
10859 temp = ROMAddr[romptr];
10860 } else {
10861 temp = SiS300_OEMLCDDelay5[temp][index];
10863 } else {
10864 if(SiS_Pr->SiS_UseROM) {
10865 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
10866 if(romptr) {
10867 romptr += (temp * 2);
10868 romptr = SISGETROMW(romptr);
10869 romptr += index;
10870 temp = ROMAddr[romptr];
10871 } else {
10872 temp = SiS300_OEMLCDDelay4[temp][index];
10874 } else {
10875 temp = SiS300_OEMLCDDelay4[temp][index];
10879 temp &= 0x3c;
10880 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
10883 static void
10884 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10888 static unsigned short
10889 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
10891 unsigned short index;
10893 index = 0;
10894 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
10895 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10896 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
10897 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
10898 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10899 } else {
10900 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
10901 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10903 return index;
10906 static void
10907 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10909 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10910 unsigned short index,temp,romptr=0;
10912 if(SiS_Pr->SiS_UseROM) {
10913 if(!(ROMAddr[0x238] & 0x01)) return;
10914 if(!(ROMAddr[0x238] & 0x02)) return;
10915 romptr = SISGETROMW(0x241);
10918 temp = GetOEMTVPtr(SiS_Pr);
10920 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
10922 if(romptr) {
10923 romptr += (temp * 2);
10924 romptr = SISGETROMW(romptr);
10925 romptr += index;
10926 temp = ROMAddr[romptr];
10927 } else {
10928 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10929 temp = SiS300_OEMTVDelay301[temp][index];
10930 } else {
10931 temp = SiS300_OEMTVDelayLVDS[temp][index];
10934 temp &= 0x3c;
10935 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
10938 static void
10939 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10941 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10942 unsigned short index,temp,romptr=0;
10944 if(SiS_Pr->SiS_UseROM) {
10945 if(!(ROMAddr[0x238] & 0x01)) return;
10946 if(!(ROMAddr[0x238] & 0x04)) return;
10947 romptr = SISGETROMW(0x243);
10950 temp = GetOEMTVPtr(SiS_Pr);
10952 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
10954 if(romptr) {
10955 romptr += (temp * 2);
10956 romptr = SISGETROMW(romptr);
10957 romptr += index;
10958 temp = ROMAddr[romptr];
10959 } else {
10960 temp = SiS300_OEMTVFlicker[temp][index];
10962 temp &= 0x70;
10963 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
10966 static void
10967 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10969 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10970 unsigned short index,i,j,temp,romptr=0;
10972 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
10974 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
10976 if(SiS_Pr->SiS_UseROM) {
10977 if(!(ROMAddr[0x238] & 0x01)) return;
10978 if(!(ROMAddr[0x238] & 0x08)) return;
10979 romptr = SISGETROMW(0x245);
10982 temp = GetOEMTVPtr(SiS_Pr);
10984 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
10986 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10987 for(i=0x31, j=0; i<=0x34; i++, j++) {
10988 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
10990 } else {
10991 if(romptr) {
10992 romptr += (temp * 2);
10993 romptr = SISGETROMW(romptr);
10994 romptr += (index * 4);
10995 for(i=0x31, j=0; i<=0x34; i++, j++) {
10996 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10998 } else {
10999 for(i=0x31, j=0; i<=0x34; i++, j++) {
11000 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11006 static void
11007 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11009 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11010 unsigned short index,temp,i,j,romptr=0;
11012 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11014 if(SiS_Pr->SiS_UseROM) {
11015 if(!(ROMAddr[0x238] & 0x01)) return;
11016 if(!(ROMAddr[0x238] & 0x10)) return;
11017 romptr = SISGETROMW(0x247);
11020 temp = GetOEMTVPtr(SiS_Pr);
11022 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11023 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11024 /* NTSCJ uses NTSC filters */
11026 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11028 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11029 for(i=0x35, j=0; i<=0x38; i++, j++) {
11030 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11032 for(i=0x48; i<=0x4A; i++, j++) {
11033 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11035 } else {
11036 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11037 romptr += (temp * 2);
11038 romptr = SISGETROMW(romptr);
11039 romptr += (index * 4);
11040 for(i=0x35, j=0; i<=0x38; i++, j++) {
11041 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11043 } else {
11044 for(i=0x35, j=0; i<=0x38; i++, j++) {
11045 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11051 static unsigned short
11052 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11054 unsigned short ModeIdIndex;
11055 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11057 if(*ModeNo <= 5) *ModeNo |= 1;
11059 for(ModeIdIndex=0; ; ModeIdIndex++) {
11060 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11061 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11064 if(*ModeNo != 0x07) {
11065 if(*ModeNo > 0x03) return ModeIdIndex;
11066 if(VGAINFO & 0x80) return ModeIdIndex;
11067 ModeIdIndex++;
11070 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11071 /* else 350 lines */
11072 return ModeIdIndex;
11075 static void
11076 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11077 unsigned short RefTableIndex)
11079 unsigned short OEMModeIdIndex = 0;
11081 if(!SiS_Pr->UseCustomMode) {
11082 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11083 if(!(OEMModeIdIndex)) return;
11086 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11087 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11088 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11089 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11092 if(SiS_Pr->UseCustomMode) return;
11093 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11094 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11095 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11096 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11097 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11098 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11102 #endif