4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730,
6 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
12 * If distributed as part of the Linux kernel, the following license terms
15 * * This program is free software; you can redistribute it and/or modify
16 * * it under the terms of the GNU General Public License as published by
17 * * the Free Software Foundation; either version 2 of the named License,
18 * * or any later version.
20 * * This program is distributed in the hope that it will be useful,
21 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * * GNU General Public License for more details.
25 * * You should have received a copy of the GNU General Public License
26 * * along with this program; if not, write to the Free Software
27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
29 * Otherwise, the following license terms apply:
31 * * Redistribution and use in source and binary forms, with or without
32 * * modification, are permitted provided that the following conditions
34 * * 1) Redistributions of source code must retain the above copyright
35 * * notice, this list of conditions and the following disclaimer.
36 * * 2) Redistributions in binary form must reproduce the above copyright
37 * * notice, this list of conditions and the following disclaimer in the
38 * * documentation and/or other materials provided with the distribution.
39 * * 3) The name of the author may not be used to endorse or promote products
40 * * derived from this software without specific prior written permission.
42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 * Author: Thomas Winischhofer <thomas@winischhofer.net>
55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
61 #define SET_EMI /* 302LV/ELV: Set EMI values */
65 #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) */
74 #ifdef CONFIG_FB_SIS_300
78 #ifdef CONFIG_FB_SIS_315
82 #define SiS_I2CDELAY 1000
83 #define SiS_I2CDELAYSHORT 150
85 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
86 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
88 /*********************************************/
89 /* HELPER: Lock/Unlock CRT2 */
90 /*********************************************/
93 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
95 if(SiS_Pr->ChipType == XGI_20)
97 else if(SiS_Pr->ChipType >= SIS_315H)
98 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
100 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
105 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
107 if(SiS_Pr->ChipType == XGI_20)
109 else if(SiS_Pr->ChipType >= SIS_315H)
110 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
112 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
115 /*********************************************/
116 /* HELPER: Write SR11 */
117 /*********************************************/
120 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
122 if(SiS_Pr->ChipType >= SIS_661) {
126 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
129 /*********************************************/
130 /* HELPER: Get Pointer to LCD structure */
131 /*********************************************/
133 #ifdef CONFIG_FB_SIS_315
134 static unsigned char *
135 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
137 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
138 unsigned char *myptr = NULL;
139 unsigned short romindex = 0, reg = 0, idx = 0;
141 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
142 * due to the variaty of panels the BIOS doesn't know about.
143 * Exception: If the BIOS has better knowledge (such as in case
144 * of machines with a 301C and a panel that does not support DDC)
145 * use the BIOS data as well.
148 if((SiS_Pr->SiS_ROMNew) &&
149 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
151 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
154 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
157 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
159 romindex = SISGETROMW(0x100);
162 myptr = &ROMAddr[romindex];
168 static unsigned short
169 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
171 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
172 unsigned short romptr = 0;
174 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
175 * due to the variaty of panels the BIOS doesn't know about.
176 * Exception: If the BIOS has better knowledge (such as in case
177 * of machines with a 301C and a panel that does not support DDC)
178 * use the BIOS data as well.
181 if((SiS_Pr->SiS_ROMNew) &&
182 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
183 romptr = SISGETROMW(0x102);
184 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
191 /*********************************************/
192 /* Adjust Rate for CRT2 */
193 /*********************************************/
196 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
197 unsigned short RRTI, unsigned short *i)
199 unsigned short checkmask=0, modeid, infoflag;
201 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
203 if(SiS_Pr->SiS_VBType & VB_SISVB) {
205 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
207 checkmask |= SupportRAMDAC2;
208 if(SiS_Pr->ChipType >= SIS_315H) {
209 checkmask |= SupportRAMDAC2_135;
210 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
211 checkmask |= SupportRAMDAC2_162;
212 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
213 checkmask |= SupportRAMDAC2_202;
218 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
220 checkmask |= SupportLCD;
221 if(SiS_Pr->ChipType >= SIS_315H) {
222 if(SiS_Pr->SiS_VBType & VB_SISVB) {
223 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
224 if(modeid == 0x2e) checkmask |= Support64048060Hz;
229 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
231 checkmask |= SupportHiVision;
233 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
235 checkmask |= SupportTV;
236 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
237 checkmask |= SupportTV1024;
238 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
239 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
240 checkmask |= SupportYPbPr750p;
249 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
250 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
251 checkmask |= SupportCHTV;
255 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
256 checkmask |= SupportLCD;
261 /* Look backwards in table for matching CRT2 mode */
262 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
263 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
264 if(infoflag & checkmask) return true;
268 /* Look through the whole mode-section of the table from the beginning
269 * for a matching CRT2 mode if no mode was found yet.
271 for((*i) = 0; ; (*i)++) {
272 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
273 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
274 if(infoflag & checkmask) return true;
279 /*********************************************/
281 /*********************************************/
284 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
286 unsigned short RRTI,i,backup_i;
287 unsigned short modeflag,index,temp,backupindex;
288 static const unsigned short LCDRefreshIndex[] = {
289 0x00, 0x00, 0x01, 0x01,
290 0x01, 0x01, 0x01, 0x01,
291 0x01, 0x01, 0x01, 0x01,
292 0x01, 0x01, 0x01, 0x01,
293 0x00, 0x00, 0x00, 0x00
296 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
297 if(ModeNo == 0xfe) return 0;
300 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
302 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
305 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
306 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
307 if(modeflag & HalfDCLK) return 0;
311 if(ModeNo < 0x14) return 0xFFFF;
313 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
316 if(index > 0) index--;
318 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
319 if(SiS_Pr->SiS_VBType & VB_SISVB) {
320 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
321 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
322 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
324 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
325 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
326 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
327 if(index > temp) index = temp;
331 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
332 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
333 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
338 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
339 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
341 if(SiS_Pr->ChipType >= SIS_315H) {
342 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
343 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
344 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
345 if(backupindex <= 1) RRTI++;
352 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
353 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
354 temp &= ModeTypeMask;
355 if(temp < SiS_Pr->SiS_ModeType) break;
358 } while(index != 0xFFFF);
360 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
361 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
362 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
363 if(temp & InterlaceMode) i++;
369 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
371 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
379 /*********************************************/
380 /* STORE CRT2 INFO in CR34 */
381 /*********************************************/
384 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
386 unsigned short temp1, temp2;
388 /* Store CRT1 ModeNo in CR34 */
389 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
390 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
391 temp2 = ~(SetInSlaveMode >> 8);
392 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
395 /*********************************************/
396 /* HELPER: GET SOME DATA FROM BIOS ROM */
397 /*********************************************/
399 #ifdef CONFIG_FB_SIS_300
401 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
403 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
404 unsigned short temp,temp1;
406 if(SiS_Pr->SiS_UseROM) {
407 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
408 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
409 temp1 = SISGETROMW(0x23b);
410 if(temp1 & temp) return true;
417 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
419 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
420 unsigned short temp,temp1;
422 if(SiS_Pr->SiS_UseROM) {
423 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
424 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
425 temp1 = SISGETROMW(0x23d);
426 if(temp1 & temp) return true;
433 /*********************************************/
434 /* HELPER: DELAY FUNCTIONS */
435 /*********************************************/
438 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
440 while (delaytime-- > 0)
441 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
444 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
446 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
448 SiS_DDC2Delay(SiS_Pr, delay * 36);
452 #ifdef CONFIG_FB_SIS_315
454 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
457 SiS_GenericDelay(SiS_Pr, 6623);
462 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
464 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
467 SiS_GenericDelay(SiS_Pr, 66);
473 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
475 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
476 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
477 unsigned short PanelID, DelayIndex, Delay=0;
480 if(SiS_Pr->ChipType < SIS_315H) {
482 #ifdef CONFIG_FB_SIS_300
484 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
485 if(SiS_Pr->SiS_VBType & VB_SISVB) {
486 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
487 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
489 DelayIndex = PanelID >> 4;
490 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
493 if(DelayTime >= 2) DelayTime -= 2;
494 if(!(DelayTime & 0x01)) {
495 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
497 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
499 if(SiS_Pr->SiS_UseROM) {
500 if(ROMAddr[0x220] & 0x40) {
501 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
502 else Delay = (unsigned short)ROMAddr[0x226];
506 SiS_ShortDelay(SiS_Pr, Delay);
508 #endif /* CONFIG_FB_SIS_300 */
512 #ifdef CONFIG_FB_SIS_315
514 if((SiS_Pr->ChipType >= SIS_661) ||
515 (SiS_Pr->ChipType <= SIS_315PRO) ||
516 (SiS_Pr->ChipType == SIS_330) ||
517 (SiS_Pr->SiS_ROMNew)) {
519 if(!(DelayTime & 0x01)) {
520 SiS_DDC2Delay(SiS_Pr, 0x1000);
522 SiS_DDC2Delay(SiS_Pr, 0x4000);
525 } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 315 series, LVDS; Special */
527 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
528 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
529 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
530 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
532 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
533 DelayIndex = PanelID & 0x0f;
535 DelayIndex = PanelID >> 4;
537 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
540 if(DelayTime >= 2) DelayTime -= 2;
541 if(!(DelayTime & 0x01)) {
542 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
544 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
546 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
547 if(ROMAddr[0x13c] & 0x40) {
548 if(!(DelayTime & 0x01)) {
549 Delay = (unsigned short)ROMAddr[0x17e];
551 Delay = (unsigned short)ROMAddr[0x17f];
556 SiS_ShortDelay(SiS_Pr, Delay);
559 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
561 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
562 if(!(DelayTime & 0x01)) {
563 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
565 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
568 SiS_DDC2Delay(SiS_Pr, Delay);
572 #endif /* CONFIG_FB_SIS_315 */
577 #ifdef CONFIG_FB_SIS_315
579 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
582 for(i = 0; i < DelayLoop; i++) {
583 SiS_PanelDelay(SiS_Pr, DelayTime);
588 /*********************************************/
589 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
590 /*********************************************/
593 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
595 unsigned short watchdog;
597 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
598 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
601 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
603 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
606 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
608 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
610 unsigned short watchdog;
613 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
615 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
620 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
622 if(SiS_Pr->ChipType < SIS_315H) {
623 #ifdef CONFIG_FB_SIS_300
624 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
625 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
627 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
628 SiS_WaitRetrace1(SiS_Pr);
630 SiS_WaitRetrace2(SiS_Pr, 0x25);
634 #ifdef CONFIG_FB_SIS_315
635 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
636 SiS_WaitRetrace1(SiS_Pr);
638 SiS_WaitRetrace2(SiS_Pr, 0x30);
645 SiS_VBWait(struct SiS_Private *SiS_Pr)
647 unsigned short tempal,temp,i,j;
650 for(i = 0; i < 3; i++) {
651 for(j = 0; j < 100; j++) {
652 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
654 if((tempal & 0x08)) continue;
657 if(!(tempal & 0x08)) continue;
666 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
668 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
671 SiS_WaitRetrace1(SiS_Pr);
675 /*********************************************/
677 /*********************************************/
679 #ifdef CONFIG_FB_SIS_300
681 SiS_Is301B(struct SiS_Private *SiS_Pr)
683 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
689 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
691 if(SiS_Pr->ChipType == SIS_730) {
692 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
694 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
699 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
701 #ifdef CONFIG_FB_SIS_315
702 if(SiS_Pr->ChipType >= SIS_315H) {
703 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
704 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
712 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
714 #ifdef CONFIG_FB_SIS_315
717 if(SiS_Pr->ChipType >= SIS_315H) {
718 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
719 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
725 #ifdef CONFIG_FB_SIS_315
727 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
729 if(SiS_IsVAMode(SiS_Pr)) return true;
730 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
736 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
738 #ifdef CONFIG_FB_SIS_315
739 if(SiS_Pr->ChipType >= SIS_315H) {
740 if((SiS_CRT2IsLCD(SiS_Pr)) ||
741 (SiS_IsVAMode(SiS_Pr))) {
742 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
749 #ifdef CONFIG_FB_SIS_315
751 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
753 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
754 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
755 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
761 #ifdef CONFIG_FB_SIS_315
763 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
765 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
770 #ifdef CONFIG_FB_SIS_315
772 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
774 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
775 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
781 #ifdef CONFIG_FB_SIS_315
783 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
787 if(SiS_Pr->ChipType == SIS_650) {
788 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
789 /* Check for revision != A0 only */
790 if((flag == 0xe0) || (flag == 0xc0) ||
791 (flag == 0xb0) || (flag == 0x90)) return false;
792 } else if(SiS_Pr->ChipType >= SIS_661) return false;
797 #ifdef CONFIG_FB_SIS_315
799 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
801 if(SiS_Pr->ChipType >= SIS_315H) {
803 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
809 #ifdef CONFIG_FB_SIS_315
811 SiS_IsChScart(struct SiS_Private *SiS_Pr)
813 if(SiS_Pr->ChipType >= SIS_315H) {
815 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
821 #ifdef CONFIG_FB_SIS_315
823 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
827 if(SiS_Pr->ChipType >= SIS_315H) {
828 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
829 if(flag & SetCRT2ToTV) return true;
830 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
831 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
832 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
834 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
835 if(flag & SetCRT2ToTV) return true;
841 #ifdef CONFIG_FB_SIS_315
843 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
847 if(SiS_Pr->ChipType >= SIS_315H) {
848 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
849 if(flag & SetCRT2ToLCD) return true;
850 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
851 if(flag & SetToLCDA) return true;
853 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
854 if(flag & SetCRT2ToLCD) return true;
861 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
865 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
867 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
868 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
869 if((flag == 1) || (flag == 2)) return true;
875 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
879 if(SiS_HaveBridge(SiS_Pr)) {
880 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
881 if(SiS_Pr->ChipType < SIS_315H) {
883 if((flag == 0x80) || (flag == 0x20)) return true;
886 if((flag == 0x40) || (flag == 0x10)) return true;
893 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
895 unsigned short flag1;
897 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
898 if(flag1 & (SetInSlaveMode >> 8)) return true;
902 /*********************************************/
903 /* GET VIDEO BRIDGE CONFIG INFO */
904 /*********************************************/
906 /* Setup general purpose IO for Chrontel communication */
907 #ifdef CONFIG_FB_SIS_300
909 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
911 unsigned int acpibase;
914 if(!(SiS_Pr->SiS_ChSW)) return;
916 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
918 if(!acpibase) return;
919 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
921 SiS_SetRegShort((acpibase + 0x3c), temp);
922 temp = SiS_GetRegShort((acpibase + 0x3c));
923 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
925 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
926 SiS_SetRegShort((acpibase + 0x3a), temp);
927 temp = SiS_GetRegShort((acpibase + 0x3a));
932 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
933 unsigned short ModeIdIndex, int checkcrt2mode)
935 unsigned short tempax, tempbx, temp;
936 unsigned short modeflag, resinfo = 0;
938 SiS_Pr->SiS_SetFlag = 0;
940 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
942 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
944 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
945 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
950 if(SiS_HaveBridge(SiS_Pr)) {
952 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
954 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
955 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
958 #ifdef CONFIG_FB_SIS_315
959 if(SiS_Pr->ChipType >= SIS_315H) {
960 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
962 /* Mode 0x03 is never in driver mode */
963 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
965 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
966 /* Reset LCDA setting if not driver mode */
967 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
970 if(SiS_Pr->SiS_UseLCDA) {
971 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
972 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
973 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
978 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
979 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
980 tempbx |= SetCRT2ToLCDA;
984 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
985 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
986 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
987 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
988 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
989 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
990 tempbx |= SetCRT2ToYPbPr525750;
995 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
996 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
997 if(temp & SetToLCDA) {
998 tempbx |= SetCRT2ToLCDA;
1000 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1001 if(temp & EnableCHYPbPr) {
1002 tempbx |= SetCRT2ToCHYPbPr;
1008 #endif /* CONFIG_FB_SIS_315 */
1010 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1011 tempbx &= ~(SetCRT2ToRAMDAC);
1014 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1015 temp = SetCRT2ToSVIDEO |
1022 SetCRT2ToYPbPr525750;
1024 if(SiS_Pr->ChipType >= SIS_315H) {
1025 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1026 temp = SetCRT2ToAVIDEO |
1033 temp = SetCRT2ToLCDA |
1037 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1038 temp = SetCRT2ToTV | SetCRT2ToLCD;
1040 temp = SetCRT2ToLCD;
1045 if(!(tempbx & temp)) {
1046 tempax = DisableCRT2Display;
1050 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1052 unsigned short clearmask = ( DriverMode |
1053 DisableCRT2Display |
1061 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1062 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1063 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1064 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1065 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1066 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1070 if(SiS_Pr->ChipType >= SIS_315H) {
1071 if(tempbx & SetCRT2ToLCDA) {
1072 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1075 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1076 if(tempbx & SetCRT2ToTV) {
1077 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1080 if(tempbx & SetCRT2ToLCD) {
1081 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1083 if(SiS_Pr->ChipType >= SIS_315H) {
1084 if(tempbx & SetCRT2ToLCDA) {
1085 tempbx |= SetCRT2ToLCD;
1091 if(tempax & DisableCRT2Display) {
1092 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1093 tempbx = SetSimuScanMode | DisableCRT2Display;
1097 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1099 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1100 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1101 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1102 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1103 modeflag &= (~CRT2Mode);
1107 if(!(tempbx & SetSimuScanMode)) {
1108 if(tempbx & SwitchCRT2) {
1109 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1110 if(resinfo != SIS_RI_1600x1200) {
1111 tempbx |= SetSimuScanMode;
1115 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1116 if(!(tempbx & DriverMode)) {
1117 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1118 tempbx |= SetSimuScanMode;
1125 if(!(tempbx & DisableCRT2Display)) {
1126 if(tempbx & DriverMode) {
1127 if(tempbx & SetSimuScanMode) {
1128 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1129 if(resinfo != SIS_RI_1600x1200) {
1130 tempbx |= SetInSlaveMode;
1135 tempbx |= SetInSlaveMode;
1141 SiS_Pr->SiS_VBInfo = tempbx;
1143 #ifdef CONFIG_FB_SIS_300
1144 if(SiS_Pr->ChipType == SIS_630) {
1145 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1150 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1151 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1155 /*********************************************/
1156 /* DETERMINE YPbPr MODE */
1157 /*********************************************/
1160 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1165 /* Note: This variable is only used on 30xLV systems.
1166 * CR38 has a different meaning on LVDS/CH7019 systems.
1167 * On 661 and later, these bits moved to CR35.
1169 * On 301, 301B, only HiVision 1080i is supported.
1170 * On 30xLV, 301C, only YPbPr 1080i is supported.
1173 SiS_Pr->SiS_YPbPr = 0;
1174 if(SiS_Pr->ChipType >= SIS_661) return;
1176 if(SiS_Pr->SiS_VBType) {
1177 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1178 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1182 if(SiS_Pr->ChipType >= SIS_315H) {
1183 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1184 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1186 switch((temp >> 4)) {
1187 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1188 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1189 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1190 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1198 /*********************************************/
1199 /* DETERMINE TVMode flag */
1200 /*********************************************/
1203 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1205 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1206 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1207 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1209 SiS_Pr->SiS_TVMode = 0;
1211 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1212 if(SiS_Pr->UseCustomMode) return;
1215 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1218 if(SiS_Pr->ChipType < SIS_661) {
1220 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1222 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1224 if((SiS_Pr->ChipType == SIS_630) ||
1225 (SiS_Pr->ChipType == SIS_730)) {
1228 } else if(SiS_Pr->ChipType >= SIS_315H) {
1230 if(SiS_Pr->ChipType < XGI_20) {
1232 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1236 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1237 OutputSelect = ROMAddr[romindex];
1238 if(!(OutputSelect & EnablePALMN)) {
1239 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1242 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1243 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1244 if(temp1 & EnablePALM) { /* 0x40 */
1245 SiS_Pr->SiS_TVMode |= TVSetPALM;
1246 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1247 } else if(temp1 & EnablePALN) { /* 0x80 */
1248 SiS_Pr->SiS_TVMode |= TVSetPALN;
1251 if(temp1 & EnableNTSCJ) { /* 0x40 */
1252 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1256 /* Translate HiVision/YPbPr to our new flags */
1257 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1258 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1259 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1260 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1261 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1262 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1263 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1264 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1265 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1266 SiS_Pr->SiS_TVMode |= TVSetPAL;
1269 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1270 if(SiS_Pr->SiS_CHOverScan) {
1271 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1272 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1273 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1274 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1276 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1277 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1278 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1279 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1282 if(SiS_Pr->SiS_CHSOverScan) {
1283 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1286 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1287 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1288 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1289 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1290 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1292 if(temp & EnableNTSCJ) {
1293 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1299 } else { /* 661 and later */
1301 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1303 SiS_Pr->SiS_TVMode |= TVSetPAL;
1305 SiS_Pr->SiS_TVMode |= TVSetPALN;
1306 } else if(temp1 & 0x04) {
1307 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1308 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1310 SiS_Pr->SiS_TVMode |= TVSetPALM;
1314 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1317 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1318 if(SiS_Pr->SiS_CHOverScan) {
1319 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1320 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1324 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1325 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1327 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1328 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1329 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1330 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1331 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1333 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1334 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1335 SiS_Pr->SiS_TVMode |= TVAspect169;
1337 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1339 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1340 SiS_Pr->SiS_TVMode |= TVAspect169;
1342 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1345 SiS_Pr->SiS_TVMode |= TVAspect43;
1352 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1354 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1356 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1357 SiS_Pr->SiS_TVMode |= TVSetPAL;
1358 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1359 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1360 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1361 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1365 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1366 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1367 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1371 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1372 if(resinfo == SIS_RI_1024x768) {
1373 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1374 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1375 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1376 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1381 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1382 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1383 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1384 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1385 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1386 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1387 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1388 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1389 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1395 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1398 /*********************************************/
1400 /*********************************************/
1402 static unsigned short
1403 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1405 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1406 /* Translate my LCDResInfo to BIOS value */
1408 case Panel_1280x768_2: temp = Panel_1280x768; break;
1409 case Panel_1280x800_2: temp = Panel_1280x800; break;
1410 case Panel_1280x854: temp = Panel661_1280x854; break;
1416 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1418 #ifdef CONFIG_FB_SIS_315
1419 unsigned char *ROMAddr;
1420 unsigned short temp;
1422 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1423 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1424 SiS_Pr->SiS_NeedRomModeData = true;
1425 SiS_Pr->PanelHT = temp;
1427 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1428 SiS_Pr->SiS_NeedRomModeData = true;
1429 SiS_Pr->PanelVT = temp;
1431 SiS_Pr->PanelHRS = SISGETROMW(10);
1432 SiS_Pr->PanelHRE = SISGETROMW(12);
1433 SiS_Pr->PanelVRS = SISGETROMW(14);
1434 SiS_Pr->PanelVRE = SISGETROMW(16);
1435 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1436 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1437 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1438 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1439 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1440 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1441 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1448 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1449 const unsigned char *nonscalingmodes)
1452 while(nonscalingmodes[i] != 0xff) {
1453 if(nonscalingmodes[i++] == resinfo) {
1454 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1455 (SiS_Pr->UsePanelScaler == -1)) {
1456 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1464 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1466 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1467 bool panelcanscale = false;
1468 #ifdef CONFIG_FB_SIS_300
1469 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1470 static const unsigned char SiS300SeriesLCDRes[] =
1471 { 0, 1, 2, 3, 7, 4, 5, 8,
1472 0, 0, 10, 0, 0, 0, 0, 15 };
1474 #ifdef CONFIG_FB_SIS_315
1475 unsigned char *myptr = NULL;
1478 SiS_Pr->SiS_LCDResInfo = 0;
1479 SiS_Pr->SiS_LCDTypeInfo = 0;
1480 SiS_Pr->SiS_LCDInfo = 0;
1481 SiS_Pr->PanelHRS = 999; /* HSync start */
1482 SiS_Pr->PanelHRE = 999; /* HSync end */
1483 SiS_Pr->PanelVRS = 999; /* VSync start */
1484 SiS_Pr->PanelVRE = 999; /* VSync end */
1485 SiS_Pr->SiS_NeedRomModeData = false;
1487 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1488 SiS_Pr->Alternate1600x1200 = false;
1490 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1492 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1494 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1495 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1496 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1497 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1500 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1502 /* For broken BIOSes: Assume 1024x768 */
1503 if(temp == 0) temp = 0x02;
1505 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1506 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1507 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1508 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1510 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1513 #ifdef CONFIG_FB_SIS_300
1514 if(SiS_Pr->ChipType < SIS_315H) {
1515 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1516 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1517 if(temp < 0x0f) temp &= 0x07;
1519 /* Translate 300 series LCDRes to 315 series for unified usage */
1520 temp = SiS300SeriesLCDRes[temp];
1524 /* Translate to our internal types */
1525 #ifdef CONFIG_FB_SIS_315
1526 if(SiS_Pr->ChipType == SIS_550) {
1527 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1528 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1529 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1530 } else if(SiS_Pr->ChipType >= SIS_661) {
1531 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1535 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1536 if(temp == Panel310_1280x768) {
1537 temp = Panel_1280x768_2;
1539 if(SiS_Pr->SiS_ROMNew) {
1540 if(temp == Panel661_1280x800) {
1541 temp = Panel_1280x800_2;
1546 SiS_Pr->SiS_LCDResInfo = temp;
1548 #ifdef CONFIG_FB_SIS_300
1549 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1550 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1551 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1552 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1553 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1554 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1555 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1560 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1561 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1562 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1564 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1565 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1568 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1569 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1570 /* Need temp below! */
1572 /* These must/can't scale no matter what */
1573 switch(SiS_Pr->SiS_LCDResInfo) {
1574 case Panel_320x240_1:
1575 case Panel_320x240_2:
1576 case Panel_320x240_3:
1577 case Panel_1280x960:
1578 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1581 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1584 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1586 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1587 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1589 /* Dual link, Pass 1:1 BIOS default, etc. */
1590 #ifdef CONFIG_FB_SIS_315
1591 if(SiS_Pr->ChipType >= SIS_661) {
1592 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1593 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1595 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1596 if(SiS_Pr->SiS_ROMNew) {
1597 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1598 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1599 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1602 } else if(SiS_Pr->ChipType >= SIS_315H) {
1603 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1604 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1606 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1607 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1608 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1609 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1610 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1611 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1613 } else if(!(SiS_Pr->SiS_ROMNew)) {
1614 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1615 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1616 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1617 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1619 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1620 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1621 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1622 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1623 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1631 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1632 /* Always center screen on LVDS (if scaling is disabled) */
1633 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1634 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1635 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1636 /* Always center screen on SiS LVDS (if scaling is disabled) */
1637 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1639 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1640 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1641 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1645 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1646 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1648 switch(SiS_Pr->SiS_LCDResInfo) {
1649 case Panel_320x240_1:
1650 case Panel_320x240_2:
1651 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1652 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1653 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1654 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1656 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1657 SiS_Pr->PanelVRE = 3;
1658 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1659 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1661 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1662 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1663 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1664 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1665 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1666 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1668 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1669 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1670 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1671 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1672 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1673 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1675 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1676 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1677 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1678 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1679 if(SiS_Pr->ChipType < SIS_315H) {
1680 SiS_Pr->PanelHRS = 23;
1681 SiS_Pr->PanelVRE = 5;
1683 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1684 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1685 SiS_GetLCDInfoBIOS(SiS_Pr);
1687 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1688 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1689 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1690 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1691 if(SiS_Pr->ChipType < SIS_315H) {
1692 SiS_Pr->PanelHRS = 23;
1693 SiS_Pr->PanelVRE = 5;
1695 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1696 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1698 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1700 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1701 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1702 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1703 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1704 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1705 /* Data above for TMDS (projector); get from BIOS for LVDS */
1706 SiS_GetLCDInfoBIOS(SiS_Pr);
1708 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1709 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1710 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1711 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1712 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1714 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1715 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1716 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1717 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1718 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1721 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1722 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1723 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1724 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1725 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1726 SiS_GetLCDInfoBIOS(SiS_Pr);
1728 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1729 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1730 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1731 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1732 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1733 SiS_GetLCDInfoBIOS(SiS_Pr);
1735 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1736 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1737 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1738 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1739 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1740 SiS_GetLCDInfoBIOS(SiS_Pr);
1742 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1743 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1744 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1745 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1746 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1747 SiS_GetLCDInfoBIOS(SiS_Pr);
1749 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1750 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1751 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1752 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1753 if(resinfo == SIS_RI_1280x1024) {
1754 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1755 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1758 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1759 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1760 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1761 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1762 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1763 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1764 SiS_GetLCDInfoBIOS(SiS_Pr);
1766 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1767 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1768 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1769 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1770 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1771 SiS_GetLCDInfoBIOS(SiS_Pr);
1773 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1774 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1775 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1776 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1777 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1778 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1779 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1780 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1781 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1782 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1783 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1784 SiS_Pr->Alternate1600x1200 = true;
1786 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1787 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1788 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1789 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1791 SiS_GetLCDInfoBIOS(SiS_Pr);
1793 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1794 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1795 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1796 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1797 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1798 SiS_GetLCDInfoBIOS(SiS_Pr);
1800 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1801 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1803 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1804 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1806 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1807 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1809 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1810 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1811 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1812 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1813 if(SiS_Pr->CP_PreferredIndex != -1) {
1814 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1815 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1816 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1817 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1818 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1819 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1820 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1821 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1822 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1823 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1824 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1825 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1826 if(SiS_Pr->CP_PrefClock) {
1828 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1829 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1830 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1831 else idx = VCLK_CUSTOM_315;
1832 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1833 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1834 SiS_Pr->SiS_VCLKData[idx].SR2B =
1835 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1836 SiS_Pr->SiS_VCLKData[idx].SR2C =
1837 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1841 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1842 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1847 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1848 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1849 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1850 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1851 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1852 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1853 SiS_Pr->PanelHRS = 999;
1854 SiS_Pr->PanelHRE = 999;
1857 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1858 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1859 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1860 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1861 SiS_Pr->PanelVRS = 999;
1862 SiS_Pr->PanelVRE = 999;
1865 /* DontExpand overrule */
1866 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1868 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1869 /* No scaling for this mode on any panel (LCD=CRT2)*/
1870 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1873 switch(SiS_Pr->SiS_LCDResInfo) {
1876 case Panel_1152x864:
1877 case Panel_1280x768: /* TMDS only */
1878 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1881 case Panel_800x600: {
1882 static const unsigned char nonscalingmodes[] = {
1883 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1885 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1888 case Panel_1024x768: {
1889 static const unsigned char nonscalingmodes[] = {
1890 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1891 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1894 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1897 case Panel_1280x720: {
1898 static const unsigned char nonscalingmodes[] = {
1899 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1900 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1903 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1904 if(SiS_Pr->PanelHT == 1650) {
1905 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1909 case Panel_1280x768_2: { /* LVDS only */
1910 static const unsigned char nonscalingmodes[] = {
1911 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1912 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1913 SIS_RI_1152x768,0xff
1915 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1917 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1918 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1924 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1925 static const unsigned char nonscalingmodes[] = {
1926 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1927 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1928 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1930 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1933 case Panel_1280x800_2: { /* SiS LVDS */
1934 static const unsigned char nonscalingmodes[] = {
1935 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1936 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1937 SIS_RI_1152x768,0xff
1939 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1941 case SIS_RI_1280x720:
1942 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1943 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1949 case Panel_1280x854: { /* SiS LVDS */
1950 static const unsigned char nonscalingmodes[] = {
1951 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1952 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1953 SIS_RI_1152x768,0xff
1955 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1957 case SIS_RI_1280x720:
1958 case SIS_RI_1280x768:
1959 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
1960 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1966 case Panel_1280x960: {
1967 static const unsigned char nonscalingmodes[] = {
1968 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1969 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1970 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1971 SIS_RI_1280x854,0xff
1973 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1976 case Panel_1280x1024: {
1977 static const unsigned char nonscalingmodes[] = {
1978 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1979 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1980 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1981 SIS_RI_1280x854,SIS_RI_1280x960,0xff
1983 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1986 case Panel_1400x1050: {
1987 static const unsigned char nonscalingmodes[] = {
1988 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1989 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1990 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
1991 SIS_RI_1280x960,0xff
1993 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1995 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1996 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1999 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2004 case Panel_1600x1200: {
2005 static const unsigned char nonscalingmodes[] = {
2006 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2007 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2008 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2009 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2011 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2014 case Panel_1680x1050: {
2015 static const unsigned char nonscalingmodes[] = {
2016 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2017 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2018 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2019 SIS_RI_1360x1024,0xff
2021 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2027 #ifdef CONFIG_FB_SIS_300
2028 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2029 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2030 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2034 if(SiS_Pr->ChipType < SIS_315H) {
2035 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2036 if(SiS_Pr->SiS_UseROM) {
2037 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2038 if(!(ROMAddr[0x235] & 0x02)) {
2039 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2043 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2044 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2045 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2053 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2054 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2057 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2058 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2061 switch(SiS_Pr->SiS_LCDResInfo) {
2063 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2065 case Panel_1280x800:
2066 /* Don't pass 1:1 by default (TMDS special) */
2067 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2069 case Panel_1280x960:
2070 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2073 if((!SiS_Pr->CP_PrefClock) ||
2074 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2075 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2080 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2081 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2084 /* (In)validate LCDPass11 flag */
2085 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2086 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2090 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2092 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2093 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2094 if(ModeNo == 0x12) {
2095 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2096 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2098 } else if(ModeNo > 0x13) {
2099 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2100 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2101 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2102 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2110 if(modeflag & HalfDCLK) {
2111 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2112 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2113 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2114 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2115 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2116 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2117 } else if(ModeNo > 0x13) {
2118 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2119 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2120 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2121 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2129 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2130 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2131 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2134 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2138 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2139 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2143 /*********************************************/
2145 /*********************************************/
2148 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2149 unsigned short RefreshRateTableIndex)
2151 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2152 unsigned short resinfo, tempbx;
2153 const unsigned char *CHTVVCLKPtr = NULL;
2155 if(ModeNo <= 0x13) {
2156 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2157 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2158 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2159 VCLKIndexGENCRT = VCLKIndexGEN;
2161 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2162 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2163 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2164 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2165 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2168 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2170 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2173 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2175 if(SiS_Pr->ChipType < SIS_315H) {
2176 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2177 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2178 VCLKIndex = VCLKIndexGEN;
2181 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2182 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2184 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2185 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2186 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2187 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2188 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2189 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2190 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2191 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2192 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2193 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2194 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2195 default: VCLKIndex = VCLKIndexGEN;
2198 if(ModeNo <= 0x13) {
2199 if(SiS_Pr->ChipType <= SIS_315PRO) {
2200 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2202 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2205 if(SiS_Pr->ChipType <= SIS_315PRO) {
2206 if(VCLKIndex == 0) VCLKIndex = 0x41;
2207 if(VCLKIndex == 1) VCLKIndex = 0x43;
2208 if(VCLKIndex == 4) VCLKIndex = 0x44;
2213 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2215 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2216 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2217 else VCLKIndex = HiTVVCLK;
2218 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2219 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2220 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2221 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2222 else VCLKIndex = TVVCLK;
2224 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2225 else VCLKIndex += TVCLKBASE_315;
2229 VCLKIndex = VCLKIndexGENCRT;
2230 if(SiS_Pr->ChipType < SIS_315H) {
2232 if( (SiS_Pr->ChipType == SIS_630) &&
2233 (SiS_Pr->ChipRevision >= 0x30)) {
2234 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2236 /* Better VGA2 clock for 1280x1024@75 */
2237 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2242 } else { /* If not programming CRT2 */
2244 VCLKIndex = VCLKIndexGENCRT;
2245 if(SiS_Pr->ChipType < SIS_315H) {
2247 if( (SiS_Pr->ChipType != SIS_630) &&
2248 (SiS_Pr->ChipType != SIS_300) ) {
2249 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2257 VCLKIndex = CRT2Index;
2259 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2261 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2265 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2266 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2268 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2269 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2271 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2273 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2274 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2276 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2280 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2281 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2282 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2283 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2284 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2285 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2286 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2287 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2288 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2289 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2291 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2293 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2295 if(SiS_Pr->ChipType < SIS_315H) {
2296 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2298 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2301 #ifdef CONFIG_FB_SIS_300
2302 /* Special Timing: Barco iQ Pro R series */
2303 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2305 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2306 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2307 if(SiS_Pr->ChipType < SIS_315H) {
2308 VCLKIndex = VCLK34_300;
2309 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2311 VCLKIndex = VCLK34_315;
2312 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2319 VCLKIndex = VCLKIndexGENCRT;
2320 if(SiS_Pr->ChipType < SIS_315H) {
2322 if( (SiS_Pr->ChipType == SIS_630) &&
2323 (SiS_Pr->ChipRevision >= 0x30) ) {
2324 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2330 } else { /* if not programming CRT2 */
2332 VCLKIndex = VCLKIndexGENCRT;
2333 if(SiS_Pr->ChipType < SIS_315H) {
2335 if( (SiS_Pr->ChipType != SIS_630) &&
2336 (SiS_Pr->ChipType != SIS_300) ) {
2337 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2340 if(SiS_Pr->ChipType == SIS_730) {
2341 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2342 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2355 /*********************************************/
2356 /* SET CRT2 MODE TYPE REGISTERS */
2357 /*********************************************/
2360 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2362 unsigned short i, j, modeflag, tempah=0;
2364 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2365 unsigned short tempbl;
2367 #ifdef CONFIG_FB_SIS_315
2368 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2369 unsigned short tempah2, tempbl2;
2372 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2374 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2376 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2377 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2381 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2382 if(SiS_Pr->ChipType >= SIS_315H) {
2383 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2386 tempcl = SiS_Pr->SiS_ModeType;
2388 if(SiS_Pr->ChipType < SIS_315H) {
2390 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */
2392 /* For 301BDH: (with LCD via LVDS) */
2393 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2394 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2397 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2401 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2407 tempah = ((0x10 >> tempcl) | 0x80);
2409 } else tempah = 0x80;
2411 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2413 #endif /* CONFIG_FB_SIS_300 */
2417 #ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */
2422 tempah = (0x08 >> tempcl);
2423 if (tempah == 0) tempah = 1;
2426 } else tempah = 0x40;
2428 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2430 #endif /* CONFIG_FB_SIS_315 */
2434 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2436 if(SiS_Pr->ChipType < SIS_315H) {
2437 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2439 #ifdef CONFIG_FB_SIS_315
2440 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2441 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2442 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2444 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2446 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2452 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2455 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2458 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2460 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2465 if(SiS_Pr->ChipType < SIS_315H) {
2467 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2469 tempah = (tempah << 5) & 0xFF;
2470 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2471 tempah = (tempah >> 5) & 0xFF;
2475 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2476 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2477 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2482 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2487 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2488 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2491 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2492 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2493 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2499 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2502 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2503 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2506 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2508 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2509 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2514 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2518 if(SiS_Pr->ChipType >= SIS_315H) {
2520 #ifdef CONFIG_FB_SIS_315
2521 /* LVDS can only be slave in 8bpp modes */
2523 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2524 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2529 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2531 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2533 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2535 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2540 #ifdef CONFIG_FB_SIS_300
2542 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2547 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2549 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2558 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2560 if(SiS_Pr->ChipType >= SIS_315H) {
2562 #ifdef CONFIG_FB_SIS_315
2563 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2565 /* The following is nearly unpreditable and varies from machine
2566 * to machine. Especially the 301DH seems to be a real trouble
2567 * maker. Some BIOSes simply set the registers (like in the
2568 * NoLCD-if-statements here), some set them according to the
2569 * LCDA stuff. It is very likely that some machines are not
2570 * treated correctly in the following, very case-orientated
2571 * code. What do I do then...?
2574 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2577 tempah = 0x04; /* For all bridges */
2579 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2581 if(SiS_IsDualEdge(SiS_Pr)) {
2585 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2588 /* The following two are responsible for eventually wrong colors
2589 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2590 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2591 * in a 650 box (Jake). What is the criteria?
2592 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2593 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2594 * chipset than the bridge revision.
2597 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2600 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2601 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2605 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2606 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2607 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2608 /* Fixes "TV-blue-bug" on 315+301 */
2609 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2610 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2611 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2612 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2613 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2614 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2615 tempah = 0x30; tempah2 = 0xc0;
2616 tempbl = 0xcf; tempbl2 = 0x3f;
2617 if(SiS_Pr->SiS_TVBlue == 0) {
2618 tempah = tempah2 = 0x00;
2619 } else if(SiS_Pr->SiS_TVBlue == -1) {
2620 /* Set on 651/M650, clear on 315/650 */
2621 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2622 tempah = tempah2 = 0x00;
2625 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2626 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2628 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2629 tempbl = 0xcf; tempbl2 = 0x3f;
2630 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2631 tempah = tempah2 = 0x00;
2632 if(SiS_IsDualEdge(SiS_Pr)) {
2633 tempbl = tempbl2 = 0xff;
2636 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2637 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2642 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2643 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2647 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2649 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2651 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2654 #endif /* CONFIG_FB_SIS_315 */
2656 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2658 #ifdef CONFIG_FB_SIS_300
2659 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2661 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2662 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2663 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2664 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2666 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2672 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2673 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2674 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2675 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2681 #ifdef CONFIG_FB_SIS_315
2682 if(SiS_Pr->ChipType >= SIS_315H) {
2684 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2688 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2690 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2692 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2694 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2695 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2698 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2700 } else if(SiS_Pr->ChipType == SIS_550) {
2702 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2703 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2714 /*********************************************/
2715 /* GET RESOLUTION DATA */
2716 /*********************************************/
2719 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2722 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2724 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2728 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2730 unsigned short xres, yres, modeflag=0, resindex;
2732 if(SiS_Pr->UseCustomMode) {
2733 xres = SiS_Pr->CHDisplay;
2734 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2735 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2736 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2737 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2741 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2743 if(ModeNo <= 0x13) {
2744 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2745 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2747 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2748 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2749 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2752 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2754 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2755 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2756 if(yres == 350) yres = 400;
2758 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2759 if(ModeNo == 0x12) yres = 400;
2763 if(modeflag & HalfDCLK) xres <<= 1;
2764 if(modeflag & DoubleScanMode) yres <<= 1;
2768 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2770 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2771 switch(SiS_Pr->SiS_LCDResInfo) {
2772 case Panel_1024x768:
2773 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2774 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2775 if(yres == 350) yres = 357;
2776 if(yres == 400) yres = 420;
2777 if(yres == 480) yres = 525;
2781 case Panel_1280x1024:
2782 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2783 /* BIOS bug - does this regardless of scaling */
2784 if(yres == 400) yres = 405;
2786 if(yres == 350) yres = 360;
2787 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2788 if(yres == 360) yres = 375;
2791 case Panel_1600x1200:
2792 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2793 if(yres == 1024) yres = 1056;
2801 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2802 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2803 if(xres == 720) xres = 640;
2805 } else if(xres == 720) xres = 640;
2807 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2809 if(SiS_Pr->ChipType >= SIS_315H) {
2810 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2812 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2814 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2818 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2819 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2822 /*********************************************/
2823 /* GET CRT2 TIMING DATA */
2824 /*********************************************/
2827 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2828 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2829 unsigned short *ResIndex)
2831 unsigned short tempbx=0, tempal=0, resinfo=0;
2833 if(ModeNo <= 0x13) {
2834 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2836 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2837 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2840 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2842 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2844 tempbx = SiS_Pr->SiS_LCDResInfo;
2845 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2848 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2849 if (resinfo == SIS_RI_1280x800) tempal = 9;
2850 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2851 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2852 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2853 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2854 if (resinfo == SIS_RI_1280x768) tempal = 9;
2857 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2858 /* Pass 1:1 only (center-screen handled outside) */
2859 /* This is never called for the panel's native resolution */
2860 /* since Pass1:1 will not be set in this case */
2862 if(ModeNo >= 0x13) {
2863 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2867 #ifdef CONFIG_FB_SIS_315
2868 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2869 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2870 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2872 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2880 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2881 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2883 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2885 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2887 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2888 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2889 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2891 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2893 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2895 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2903 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2905 case SIS_RI_720x480:
2907 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
2909 case SIS_RI_720x576:
2910 case SIS_RI_768x576:
2911 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2913 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2914 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
2917 case SIS_RI_800x480:
2920 case SIS_RI_512x384:
2921 case SIS_RI_1024x768:
2923 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2924 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
2927 case SIS_RI_1280x720:
2928 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2929 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
2936 *CRT2Index = tempbx;
2939 } else { /* LVDS, 301B-DH (if running on LCD) */
2942 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2945 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2947 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2948 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2950 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
2951 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
2954 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
2959 switch(SiS_Pr->SiS_LCDResInfo) {
2960 case Panel_640x480: tempbx = 12; break;
2961 case Panel_320x240_1: tempbx = 10; break;
2962 case Panel_320x240_2:
2963 case Panel_320x240_3: tempbx = 14; break;
2964 case Panel_800x600: tempbx = 16; break;
2965 case Panel_1024x600: tempbx = 18; break;
2966 case Panel_1152x768:
2967 case Panel_1024x768: tempbx = 20; break;
2968 case Panel_1280x768: tempbx = 22; break;
2969 case Panel_1280x1024: tempbx = 24; break;
2970 case Panel_1400x1050: tempbx = 26; break;
2971 case Panel_1600x1200: tempbx = 28; break;
2972 #ifdef CONFIG_FB_SIS_300
2973 case Panel_Barco1366: tempbx = 80; break;
2977 switch(SiS_Pr->SiS_LCDResInfo) {
2978 case Panel_320x240_1:
2979 case Panel_320x240_2:
2980 case Panel_320x240_3:
2984 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2987 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
2989 #ifdef CONFIG_FB_SIS_300
2990 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
2992 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2993 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2995 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3001 (*CRT2Index) = tempbx;
3002 (*ResIndex) = tempal & 0x1F;
3007 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3008 unsigned short RefreshRateTableIndex)
3010 unsigned short tempax=0, tempbx=0, index, dotclock;
3011 unsigned short temp1=0, modeflag=0, tempcx=0;
3013 SiS_Pr->SiS_RVBHCMAX = 1;
3014 SiS_Pr->SiS_RVBHCFACT = 1;
3016 if(ModeNo <= 0x13) {
3018 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3019 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3021 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3022 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3023 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3025 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3029 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3030 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3032 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3033 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3035 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3036 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3040 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3046 if(temp1 & 0x01) tempbx |= 0x0100;
3047 if(temp1 & 0x20) tempbx |= 0x0200;
3051 if(modeflag & HalfDCLK) tempax <<= 1;
3055 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3056 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3060 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3061 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3063 unsigned short ResIndex;
3065 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3066 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3067 if(SiS_Pr->UseCustomMode) {
3068 ResIndex = SiS_Pr->CHTotal;
3069 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3070 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3071 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3074 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3076 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3078 if(ResIndex == 0x09) {
3079 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3080 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3082 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3083 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3084 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3085 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3088 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3089 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3092 /* This handles custom modes and custom panels */
3093 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3094 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3095 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3096 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3097 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3098 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3103 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3104 unsigned short RefreshRateTableIndex)
3106 unsigned short CRT2Index, ResIndex, backup;
3107 const struct SiS_LVDSData *LVDSData = NULL;
3109 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3111 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3112 SiS_Pr->SiS_RVBHCMAX = 1;
3113 SiS_Pr->SiS_RVBHCFACT = 1;
3114 SiS_Pr->SiS_NewFlickerMode = 0;
3115 SiS_Pr->SiS_RVBHRS = 50;
3116 SiS_Pr->SiS_RY1COE = 0;
3117 SiS_Pr->SiS_RY2COE = 0;
3118 SiS_Pr->SiS_RY3COE = 0;
3119 SiS_Pr->SiS_RY4COE = 0;
3120 SiS_Pr->SiS_RVBHRS2 = 0;
3123 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3125 #ifdef CONFIG_FB_SIS_315
3126 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3127 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3132 /* 301BDH needs LVDS Data */
3133 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3134 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3135 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3138 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3139 &CRT2Index, &ResIndex);
3141 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3144 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3145 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3146 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3147 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3148 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3149 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3150 #ifdef CONFIG_FB_SIS_300
3151 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3152 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3153 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3154 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3155 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3157 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3158 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3159 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3160 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3161 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3162 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3163 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3164 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3165 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3169 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3170 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3171 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3172 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3174 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3177 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3178 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3179 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3180 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3181 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3182 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3183 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3184 #ifdef CONFIG_FB_SIS_300
3185 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3186 if(ResIndex < 0x08) {
3187 SiS_Pr->SiS_HDE = 1280;
3188 SiS_Pr->SiS_VDE = 1024;
3198 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3199 unsigned short RefreshRateTableIndex)
3201 unsigned char *ROMAddr = NULL;
3202 unsigned short tempax, tempbx, modeflag, romptr=0;
3203 unsigned short resinfo, CRT2Index, ResIndex;
3204 const struct SiS_LCDData *LCDPtr = NULL;
3205 const struct SiS_TVData *TVPtr = NULL;
3206 #ifdef CONFIG_FB_SIS_315
3210 if(ModeNo <= 0x13) {
3211 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3212 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3213 } else if(SiS_Pr->UseCustomMode) {
3214 modeflag = SiS_Pr->CModeFlag;
3217 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3218 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3219 #ifdef CONFIG_FB_SIS_315
3220 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3221 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3222 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3223 (resinfo661 >= 0) &&
3224 (SiS_Pr->SiS_NeedRomModeData) ) {
3225 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3226 if((romptr = (SISGETROMW(21)))) {
3227 romptr += (resinfo661 * 10);
3228 ROMAddr = SiS_Pr->VirtualRomBase;
3235 SiS_Pr->SiS_NewFlickerMode = 0;
3236 SiS_Pr->SiS_RVBHRS = 50;
3237 SiS_Pr->SiS_RY1COE = 0;
3238 SiS_Pr->SiS_RY2COE = 0;
3239 SiS_Pr->SiS_RY3COE = 0;
3240 SiS_Pr->SiS_RY4COE = 0;
3241 SiS_Pr->SiS_RVBHRS2 = 0;
3243 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3245 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3247 if(SiS_Pr->UseCustomMode) {
3249 SiS_Pr->SiS_RVBHCMAX = 1;
3250 SiS_Pr->SiS_RVBHCFACT = 1;
3251 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3252 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3254 tempax = SiS_Pr->CHTotal;
3255 if(modeflag & HalfDCLK) tempax <<= 1;
3256 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3257 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3261 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3265 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3267 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3268 &CRT2Index,&ResIndex);
3271 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3272 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3273 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3274 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3275 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3276 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3277 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3278 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3279 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3280 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3281 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3282 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3283 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3284 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3287 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3288 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3289 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3290 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3291 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3292 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3293 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3294 if(modeflag & HalfDCLK) {
3295 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3296 if(SiS_Pr->SiS_RVBHRS2) {
3297 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3298 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3299 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3300 else SiS_Pr->SiS_RVBHRS2 += tempax;
3303 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3305 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3307 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3309 if((resinfo == SIS_RI_960x600) ||
3310 (resinfo == SIS_RI_1024x768) ||
3311 (resinfo == SIS_RI_1280x1024) ||
3312 (resinfo == SIS_RI_1280x720)) {
3313 SiS_Pr->SiS_NewFlickerMode = 0x40;
3316 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3318 SiS_Pr->SiS_HT = ExtHiTVHT;
3319 SiS_Pr->SiS_VT = ExtHiTVVT;
3320 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3321 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3322 SiS_Pr->SiS_HT = StHiTVHT;
3323 SiS_Pr->SiS_VT = StHiTVVT;
3327 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3329 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3330 SiS_Pr->SiS_HT = 1650;
3331 SiS_Pr->SiS_VT = 750;
3332 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3333 SiS_Pr->SiS_HT = NTSCHT;
3334 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3335 SiS_Pr->SiS_VT = NTSCVT;
3337 SiS_Pr->SiS_HT = NTSCHT;
3338 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3339 SiS_Pr->SiS_VT = NTSCVT;
3344 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3345 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3346 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3347 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3349 if(modeflag & HalfDCLK) {
3350 SiS_Pr->SiS_RY1COE = 0x00;
3351 SiS_Pr->SiS_RY2COE = 0xf4;
3352 SiS_Pr->SiS_RY3COE = 0x10;
3353 SiS_Pr->SiS_RY4COE = 0x38;
3356 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3357 SiS_Pr->SiS_HT = NTSCHT;
3358 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3359 SiS_Pr->SiS_VT = NTSCVT;
3361 SiS_Pr->SiS_HT = PALHT;
3362 SiS_Pr->SiS_VT = PALVT;
3367 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3369 SiS_Pr->SiS_RVBHCMAX = 1;
3370 SiS_Pr->SiS_RVBHCFACT = 1;
3372 if(SiS_Pr->UseCustomMode) {
3374 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3375 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3377 tempax = SiS_Pr->CHTotal;
3378 if(modeflag & HalfDCLK) tempax <<= 1;
3379 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3380 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3386 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3388 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3389 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3390 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3391 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3394 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3396 #ifdef CONFIG_FB_SIS_315
3397 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3398 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3399 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3400 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3401 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3402 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3403 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3404 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3405 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3406 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3407 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3408 else SiS_Pr->SiS_RVBHRS2 += tempax;
3410 if(SiS_Pr->SiS_VGAHT) gotit = true;
3412 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3413 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3414 SiS_Pr->SiS_RVBHCMAX = 1;
3415 SiS_Pr->SiS_RVBHCFACT = 1;
3416 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3417 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3418 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3419 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3420 SiS_Pr->SiS_RVBHRS2 = 0;
3429 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3430 &CRT2Index,&ResIndex);
3433 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3434 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3435 case Panel_1280x720 :
3436 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3437 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3438 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3439 case Panel_1280x800 :
3440 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3441 case Panel_1280x800_2 :
3442 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3443 case Panel_1280x854 :
3444 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3445 case Panel_1280x960 :
3446 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3447 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3448 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3449 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3450 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3451 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3452 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3453 case Panel_1680x1050 :
3454 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3455 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3456 #ifdef CONFIG_FB_SIS_315
3457 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3458 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3460 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3463 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3464 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3465 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3466 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3467 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3468 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3472 tempax = SiS_Pr->PanelXRes;
3473 tempbx = SiS_Pr->PanelYRes;
3475 switch(SiS_Pr->SiS_LCDResInfo) {
3476 case Panel_1024x768:
3477 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3478 if(SiS_Pr->ChipType < SIS_315H) {
3479 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3480 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3483 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3484 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3485 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3486 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3487 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3488 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3491 case Panel_1280x960:
3492 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3493 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3494 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3496 case Panel_1280x1024:
3497 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3498 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3499 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3501 case Panel_1600x1200:
3502 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3503 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3504 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3509 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3510 tempax = SiS_Pr->SiS_VGAHDE;
3511 tempbx = SiS_Pr->SiS_VGAVDE;
3514 SiS_Pr->SiS_HDE = tempax;
3515 SiS_Pr->SiS_VDE = tempbx;
3521 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3522 unsigned short RefreshRateTableIndex)
3525 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3527 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3528 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3530 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3531 /* Need LVDS Data for LCD on 301B-DH */
3532 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3534 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3540 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3545 /*********************************************/
3546 /* GET LVDS DES (SKEW) DATA */
3547 /*********************************************/
3549 static const struct SiS_LVDSDes *
3550 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3552 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3554 #ifdef CONFIG_FB_SIS_300
3555 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3557 if(SiS_Pr->ChipType < SIS_315H) {
3558 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3559 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3560 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3561 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3562 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3564 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3565 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3566 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3567 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3578 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3579 unsigned short RefreshRateTableIndex)
3581 unsigned short modeflag, ResIndex;
3582 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3584 SiS_Pr->SiS_LCDHDES = 0;
3585 SiS_Pr->SiS_LCDVDES = 0;
3587 /* Some special cases */
3588 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3591 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3592 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3593 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3594 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3600 /* 640x480 on LVDS */
3601 if(SiS_Pr->ChipType < SIS_315H) {
3602 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3603 SiS_Pr->SiS_LCDHDES = 8;
3604 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3605 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3606 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3613 if( (SiS_Pr->UseCustomMode) ||
3614 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3615 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3616 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3617 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3621 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3622 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3624 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3626 #ifdef CONFIG_FB_SIS_315
3627 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3628 /* non-pass 1:1 only, see above */
3629 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3630 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3632 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3633 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3636 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3637 switch(SiS_Pr->SiS_CustomT) {
3638 case CUT_UNIWILL1024:
3639 case CUT_UNIWILL10242:
3641 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3642 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3646 switch(SiS_Pr->SiS_LCDResInfo) {
3647 case Panel_1280x1024:
3648 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3649 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3652 case Panel_1280x800: /* Verified for Averatec 6240 */
3653 case Panel_1280x800_2: /* Verified for Asus A4L */
3654 case Panel_1280x854: /* Not verified yet FIXME */
3655 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3663 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3665 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3666 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3669 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3671 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3672 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3674 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3676 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3677 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3679 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3680 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3682 if(SiS_Pr->ChipType < SIS_315H) {
3683 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3685 switch(SiS_Pr->SiS_LCDResInfo) {
3687 case Panel_1024x768:
3688 case Panel_1280x1024:
3689 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3691 case Panel_1400x1050:
3692 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3700 if(SiS_Pr->ChipType < SIS_315H) {
3701 #ifdef CONFIG_FB_SIS_300
3702 switch(SiS_Pr->SiS_LCDResInfo) {
3704 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3705 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3707 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3708 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3709 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3710 else SiS_Pr->SiS_LCDVDES -= 4;
3713 case Panel_1024x768:
3714 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3715 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3717 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3718 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3719 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3722 case Panel_1024x600:
3724 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3725 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3726 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3728 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3733 switch(SiS_Pr->SiS_LCDTypeInfo) {
3735 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3737 case 3: /* 640x480 only? */
3738 SiS_Pr->SiS_LCDHDES = 8;
3739 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3740 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3741 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3746 #ifdef CONFIG_FB_SIS_315
3747 switch(SiS_Pr->SiS_LCDResInfo) {
3748 case Panel_1024x768:
3749 case Panel_1280x1024:
3750 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3751 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3754 case Panel_320x240_1:
3755 case Panel_320x240_2:
3756 case Panel_320x240_3:
3757 SiS_Pr->SiS_LCDVDES = 524;
3764 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3765 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3766 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3767 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3768 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3769 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3770 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3771 if(SiS_Pr->ChipType < SIS_315H) {
3772 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3774 #ifdef CONFIG_FB_SIS_315
3775 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3776 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3777 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3778 if(!(modeflag & HalfDCLK)) {
3779 SiS_Pr->SiS_LCDHDES = 320;
3780 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3781 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3792 /*********************************************/
3793 /* DISABLE VIDEO BRIDGE */
3794 /*********************************************/
3796 #ifdef CONFIG_FB_SIS_315
3798 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3802 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3803 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3804 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3805 unsigned short temp;
3807 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3809 (SiS_Pr->SiS_PWDOffset) ) {
3810 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3811 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3812 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3813 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3814 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3816 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3820 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3827 /* NEVER use any variables (VBInfo), this will be called
3828 * from outside the context of modeswitch!
3829 * MUST call getVBType before calling this
3832 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3834 #ifdef CONFIG_FB_SIS_315
3835 unsigned short tempah, pushax=0, modenum;
3837 unsigned short temp=0;
3839 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3841 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3843 if(SiS_Pr->ChipType < SIS_315H) {
3845 #ifdef CONFIG_FB_SIS_300 /* 300 series */
3847 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3848 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3849 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3851 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3853 SiS_PanelDelay(SiS_Pr, 3);
3855 if(SiS_Is301B(SiS_Pr)) {
3856 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3857 SiS_ShortDelay(SiS_Pr,1);
3859 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3860 SiS_DisplayOff(SiS_Pr);
3861 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3862 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3863 SiS_UnLockCRT2(SiS_Pr);
3864 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3865 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3866 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3868 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3869 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3870 SiS_PanelDelay(SiS_Pr, 2);
3871 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3872 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3874 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3878 #endif /* CONFIG_FB_SIS_300 */
3882 #ifdef CONFIG_FB_SIS_315 /* 315 series */
3885 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3886 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
3888 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3890 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3893 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3894 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3895 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3900 didpwd = SiS_HandlePWD(SiS_Pr);
3902 if( (modenum <= 0x13) ||
3903 (SiS_IsVAMode(SiS_Pr)) ||
3904 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3906 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3907 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3909 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3914 SiS_DDC2Delay(SiS_Pr,0xff00);
3915 SiS_DDC2Delay(SiS_Pr,0xe000);
3916 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3917 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3919 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3921 SiS_PanelDelay(SiS_Pr, 3);
3926 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
3927 /* if(SiS_Pr->ChipType < SIS_340) {*/
3929 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
3930 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3934 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3935 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3939 if(SiS_IsDualEdge(SiS_Pr)) {
3941 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
3943 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3945 if((SiS_IsVAMode(SiS_Pr)) ||
3946 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3948 SiS_DisplayOff(SiS_Pr);
3949 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3950 SiS_PanelDelay(SiS_Pr, 2);
3952 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3953 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3957 if((!(SiS_IsVAMode(SiS_Pr))) ||
3958 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3960 if(!(SiS_IsDualEdge(SiS_Pr))) {
3961 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3962 SiS_DisplayOff(SiS_Pr);
3964 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3966 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3967 SiS_PanelDelay(SiS_Pr, 2);
3970 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3971 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3972 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3973 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3974 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3978 if(SiS_IsNotM650orLater(SiS_Pr)) {
3979 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3982 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3984 if( (!(SiS_IsVAMode(SiS_Pr))) &&
3985 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
3986 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3988 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
3990 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3992 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
3996 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3997 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3998 if(SiS_IsVAorLCD(SiS_Pr)) {
3999 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4006 #endif /* CONFIG_FB_SIS_315 */
4010 } else { /* ============ For 301 ================ */
4012 if(SiS_Pr->ChipType < SIS_315H) {
4013 #ifdef CONFIG_FB_SIS_300
4014 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4015 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4016 SiS_PanelDelay(SiS_Pr, 3);
4021 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4022 SiS_DisplayOff(SiS_Pr);
4024 if(SiS_Pr->ChipType >= SIS_315H) {
4025 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4028 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4030 if(SiS_Pr->ChipType >= SIS_315H) {
4031 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4032 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4033 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4034 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4036 #ifdef CONFIG_FB_SIS_300
4037 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4038 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4039 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4040 SiS_PanelDelay(SiS_Pr, 2);
4041 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4048 } else { /* ============ For LVDS =============*/
4050 if(SiS_Pr->ChipType < SIS_315H) {
4052 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4054 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4055 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4058 if(SiS_Pr->ChipType == SIS_730) {
4059 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4060 SiS_WaitVBRetrace(SiS_Pr);
4062 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4063 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4064 SiS_PanelDelay(SiS_Pr, 3);
4067 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4068 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4069 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4070 SiS_WaitVBRetrace(SiS_Pr);
4071 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4072 SiS_DisplayOff(SiS_Pr);
4074 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4075 SiS_PanelDelay(SiS_Pr, 3);
4081 SiS_DisplayOff(SiS_Pr);
4083 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4085 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4086 SiS_UnLockCRT2(SiS_Pr);
4087 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4088 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4090 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4091 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4092 SiS_PanelDelay(SiS_Pr, 2);
4093 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4096 #endif /* CONFIG_FB_SIS_300 */
4100 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4102 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4103 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4104 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4108 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4110 if(SiS_Pr->ChipType == SIS_740) {
4111 temp = SiS_GetCH701x(SiS_Pr,0x61);
4113 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4114 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4117 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4118 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4119 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4123 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4124 (SiS_IsVAMode(SiS_Pr)) ) {
4125 SiS_Chrontel701xBLOff(SiS_Pr);
4126 SiS_Chrontel701xOff(SiS_Pr);
4129 if(SiS_Pr->ChipType != SIS_740) {
4130 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4131 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4132 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4138 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4139 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4140 SiS_PanelDelay(SiS_Pr, 3);
4143 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4144 (!(SiS_IsDualEdge(SiS_Pr))) ||
4145 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4146 SiS_DisplayOff(SiS_Pr);
4149 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4150 (!(SiS_IsDualEdge(SiS_Pr))) ||
4151 (!(SiS_IsVAMode(SiS_Pr))) ) {
4152 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4155 if(SiS_Pr->ChipType == SIS_740) {
4156 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4159 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4161 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4162 (!(SiS_IsDualEdge(SiS_Pr))) ||
4163 (!(SiS_IsVAMode(SiS_Pr))) ) {
4164 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4167 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4168 if(SiS_CRT2IsLCD(SiS_Pr)) {
4169 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4170 if(SiS_Pr->ChipType == SIS_550) {
4171 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4172 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4176 if(SiS_Pr->ChipType == SIS_740) {
4177 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4178 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4180 } else if(SiS_IsVAMode(SiS_Pr)) {
4181 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4185 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4186 if(SiS_IsDualEdge(SiS_Pr)) {
4187 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4189 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4193 SiS_UnLockCRT2(SiS_Pr);
4195 if(SiS_Pr->ChipType == SIS_550) {
4196 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4197 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4198 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4199 (!(SiS_IsDualEdge(SiS_Pr))) ||
4200 (!(SiS_IsVAMode(SiS_Pr))) ) {
4201 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4204 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4205 if(SiS_CRT2IsLCD(SiS_Pr)) {
4206 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4207 SiS_PanelDelay(SiS_Pr, 2);
4208 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4213 #endif /* CONFIG_FB_SIS_315 */
4221 /*********************************************/
4222 /* ENABLE VIDEO BRIDGE */
4223 /*********************************************/
4225 /* NEVER use any variables (VBInfo), this will be called
4226 * from outside the context of a mode switch!
4227 * MUST call getVBType before calling this
4231 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4233 unsigned short temp=0, tempah;
4234 #ifdef CONFIG_FB_SIS_315
4235 unsigned short temp1, pushax=0;
4236 bool delaylong = false;
4239 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4241 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4243 if(SiS_Pr->ChipType < SIS_315H) {
4245 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4247 if(SiS_CRT2IsLCD(SiS_Pr)) {
4248 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4249 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4250 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4251 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4253 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4254 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4255 SiS_PanelDelay(SiS_Pr, 0);
4260 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4261 (SiS_CRT2IsLCD(SiS_Pr))) {
4263 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4264 SiS_DisplayOn(SiS_Pr);
4265 SiS_UnLockCRT2(SiS_Pr);
4266 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4267 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4268 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4270 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4272 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4273 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4274 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4275 SiS_PanelDelay(SiS_Pr, 1);
4277 SiS_WaitVBRetrace(SiS_Pr);
4278 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4284 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4285 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4286 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4287 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4289 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4290 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4291 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4292 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4293 SiS_DisplayOn(SiS_Pr);
4294 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4295 if(SiS_CRT2IsLCD(SiS_Pr)) {
4296 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4297 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4298 SiS_PanelDelay(SiS_Pr, 1);
4300 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4308 #endif /* CONFIG_FB_SIS_300 */
4312 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4315 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4317 /* unsigned short emidelay=0; */
4320 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4321 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4323 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4324 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4329 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4330 /*if(SiS_Pr->ChipType < SIS_340) { */
4332 if(SiS_LCDAEnabled(SiS_Pr)) {
4333 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4336 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4340 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4342 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4343 SiS_DisplayOff(SiS_Pr);
4344 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4346 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4349 didpwd = SiS_HandlePWD(SiS_Pr);
4351 if(SiS_IsVAorLCD(SiS_Pr)) {
4353 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4354 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4355 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4356 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4357 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4358 SiS_GenericDelay(SiS_Pr, 17664);
4362 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4363 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4364 SiS_GenericDelay(SiS_Pr, 17664);
4369 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4370 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4376 if(!(SiS_IsVAMode(SiS_Pr))) {
4378 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4379 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4380 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4381 if(!(tempah & SetCRT2ToRAMDAC)) {
4382 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4385 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4387 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4389 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4390 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4392 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4393 SiS_PanelDelay(SiS_Pr, 2);
4398 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4402 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4403 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4405 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4406 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4407 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4408 /* Enable "LVDS PLL power on" (even on 301C) */
4409 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4410 /* Enable "LVDS Driver Power on" (even on 301C) */
4411 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4416 if(SiS_IsDualEdge(SiS_Pr)) {
4418 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4420 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4422 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4424 SiS_PanelDelay(SiS_Pr, 2);
4426 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4427 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4429 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4431 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4432 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4433 SiS_GenericDelay(SiS_Pr, 2048);
4436 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4438 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4440 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4442 if(SiS_Pr->SiS_ROMNew) {
4443 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4444 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4446 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4448 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4449 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4450 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4451 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4452 /* emidelay = SISGETROMW((romptr + 0x22)); */
4453 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4458 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4459 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4460 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4461 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4462 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4463 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4464 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4465 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4466 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4468 if(SiS_Pr->HaveEMI) {
4469 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4470 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4475 /* EMI_30 is read at driver start; however, the BIOS sets this
4476 * (if it is used) only if the LCD is in use. In case we caught
4477 * the machine while on TV output, this bit is not set and we
4478 * don't know if it should be set - hence our detection is wrong.
4479 * Work-around this here:
4482 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4483 switch((cr36 & 0x0f)) {
4486 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4487 if(!SiS_Pr->HaveEMI) {
4488 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4489 if((cr36 & 0xf0) == 0x30) {
4490 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4494 case 3: /* 1280x1024 */
4495 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4496 if(!SiS_Pr->HaveEMI) {
4497 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4498 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4499 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4503 case 9: /* 1400x1050 */
4505 if(!SiS_Pr->HaveEMI) {
4506 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4507 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4508 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4512 case 11: /* 1600x1200 - unknown */
4514 if(!SiS_Pr->HaveEMI) {
4515 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4520 /* BIOS values don't work so well sometimes */
4521 if(!SiS_Pr->OverruleEMI) {
4523 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4524 if((cr36 & 0x0f) == 0x09) {
4525 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4530 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4531 if((cr36 & 0x0f) == 0x03) {
4532 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4537 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4538 if((cr36 & 0x0f) == 0x02) {
4539 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4540 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4541 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4542 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4548 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4549 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4550 SiS_GenericDelay(SiS_Pr, 2048);
4552 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4553 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4554 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4555 #endif /* SET_EMI */
4557 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4560 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4561 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4563 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4564 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4566 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4569 SiS_WaitVBRetrace(SiS_Pr);
4570 SiS_WaitVBRetrace(SiS_Pr);
4571 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4572 SiS_GenericDelay(SiS_Pr, 1280);
4574 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4575 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4582 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4583 if(SiS_IsVAorLCD(SiS_Pr)) {
4584 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4586 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4588 SiS_WaitVBRetrace(SiS_Pr);
4589 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4590 SiS_GenericDelay(SiS_Pr, 2048);
4591 SiS_WaitVBRetrace(SiS_Pr);
4594 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4596 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4601 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4602 SiS_DisplayOn(SiS_Pr);
4603 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4607 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4608 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4611 #endif /* CONFIG_FB_SIS_315 */
4615 } else { /* ============ For 301 ================ */
4617 if(SiS_Pr->ChipType < SIS_315H) {
4618 if(SiS_CRT2IsLCD(SiS_Pr)) {
4619 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4620 SiS_PanelDelay(SiS_Pr, 0);
4624 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4625 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4626 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4627 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4629 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4631 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4633 if(SiS_Pr->ChipType >= SIS_315H) {
4634 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4635 if(!(temp & 0x80)) {
4636 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4640 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4642 SiS_VBLongWait(SiS_Pr);
4643 SiS_DisplayOn(SiS_Pr);
4644 if(SiS_Pr->ChipType >= SIS_315H) {
4645 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4647 SiS_VBLongWait(SiS_Pr);
4649 if(SiS_Pr->ChipType < SIS_315H) {
4650 if(SiS_CRT2IsLCD(SiS_Pr)) {
4651 SiS_PanelDelay(SiS_Pr, 1);
4652 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4658 } else { /* =================== For LVDS ================== */
4660 if(SiS_Pr->ChipType < SIS_315H) {
4662 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4664 if(SiS_CRT2IsLCD(SiS_Pr)) {
4665 if(SiS_Pr->ChipType == SIS_730) {
4666 SiS_PanelDelay(SiS_Pr, 1);
4667 SiS_PanelDelay(SiS_Pr, 1);
4668 SiS_PanelDelay(SiS_Pr, 1);
4670 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4671 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4672 SiS_PanelDelay(SiS_Pr, 0);
4676 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4677 SiS_DisplayOn(SiS_Pr);
4678 SiS_UnLockCRT2(SiS_Pr);
4679 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4680 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4681 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4683 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4686 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4687 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4688 SiS_WaitVBRetrace(SiS_Pr);
4689 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4693 if(SiS_CRT2IsLCD(SiS_Pr)) {
4694 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4695 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4696 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4697 SiS_PanelDelay(SiS_Pr, 1);
4698 SiS_PanelDelay(SiS_Pr, 1);
4700 SiS_WaitVBRetrace(SiS_Pr);
4701 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4706 #endif /* CONFIG_FB_SIS_300 */
4710 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4712 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4713 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4714 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4718 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4719 if(SiS_CRT2IsLCD(SiS_Pr)) {
4720 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4721 SiS_PanelDelay(SiS_Pr, 0);
4725 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4726 SiS_UnLockCRT2(SiS_Pr);
4728 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4730 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4731 temp = SiS_GetCH701x(SiS_Pr,0x66);
4733 SiS_Chrontel701xBLOff(SiS_Pr);
4736 if(SiS_Pr->ChipType != SIS_550) {
4737 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4740 if(SiS_Pr->ChipType == SIS_740) {
4741 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4742 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4743 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4748 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4749 if(!(temp1 & 0x80)) {
4750 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4753 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4755 SiS_Chrontel701xBLOn(SiS_Pr);
4759 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4760 if(SiS_CRT2IsLCD(SiS_Pr)) {
4761 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4762 if(SiS_Pr->ChipType == SIS_550) {
4763 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4764 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4767 } else if(SiS_IsVAMode(SiS_Pr)) {
4768 if(SiS_Pr->ChipType != SIS_740) {
4769 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4773 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4774 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4777 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4778 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4779 SiS_Chrontel701xOn(SiS_Pr);
4781 if( (SiS_IsVAMode(SiS_Pr)) ||
4782 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4783 SiS_ChrontelDoSomething1(SiS_Pr);
4787 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4788 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4789 if( (SiS_IsVAMode(SiS_Pr)) ||
4790 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4791 SiS_Chrontel701xBLOn(SiS_Pr);
4792 SiS_ChrontelInitTVVSync(SiS_Pr);
4795 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4796 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4797 if(SiS_CRT2IsLCD(SiS_Pr)) {
4798 SiS_PanelDelay(SiS_Pr, 1);
4799 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4804 #endif /* CONFIG_FB_SIS_315 */
4812 /*********************************************/
4813 /* SET PART 1 REGISTER GROUP */
4814 /*********************************************/
4816 /* Set CRT2 OFFSET / PITCH */
4818 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4819 unsigned short RRTI)
4821 unsigned short offset;
4824 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4826 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4828 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4829 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4831 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4832 if(offset & 0x07) temp++;
4833 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4836 /* Set CRT2 sync and PanelLink mode */
4838 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4840 unsigned short tempah=0, tempbl, infoflag;
4844 if(SiS_Pr->UseCustomMode) {
4845 infoflag = SiS_Pr->CInfoFlag;
4847 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4850 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4852 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4854 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4855 tempah = SiS_Pr->SiS_LCDInfo;
4856 } else tempah = infoflag >> 8;
4859 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4860 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4861 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4862 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4865 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4866 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4867 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4868 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4869 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4872 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4873 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4877 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4878 if(SiS_Pr->ChipType >= SIS_315H) {
4881 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4882 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4884 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4887 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4890 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4892 if(SiS_Pr->ChipType < SIS_315H) {
4894 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */
4896 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4898 tempah = infoflag >> 8;
4900 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4901 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4902 tempah = SiS_Pr->SiS_LCDInfo;
4903 tempbl = (tempah >> 6) & 0x03;
4908 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4910 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4911 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4912 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4915 } else { /* 630 - 301 */
4917 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4918 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4919 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4923 #endif /* CONFIG_FB_SIS_300 */
4927 #ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */
4929 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
4932 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4933 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4934 tempah = infoflag >> 8;
4935 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4936 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4938 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4939 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4940 tempah = infoflag >> 8;
4943 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4944 tempbl = (tempah >> 6) & 0x03;
4946 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4950 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4951 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4952 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4953 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4954 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4955 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4959 } else { /* 315 - TMDS */
4961 tempah = tempbl = infoflag >> 8;
4962 if(!SiS_Pr->UseCustomMode) {
4964 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4965 if(ModeNo <= 0x13) {
4966 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4969 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4970 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4971 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4972 tempah = SiS_Pr->SiS_LCDInfo;
4973 tempbl = (tempah >> 6) & 0x03;
4980 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4981 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4982 /* Imitate BIOS bug */
4983 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4985 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4988 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4990 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4991 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4992 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4993 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4999 #endif /* CONFIG_FB_SIS_315 */
5004 /* Set CRT2 FIFO on 300/540/630/730 */
5005 #ifdef CONFIG_FB_SIS_300
5007 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5009 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5010 unsigned short temp, index, modeidindex, refreshratetableindex;
5011 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5012 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5013 unsigned int data, pci50, pciA0;
5014 static const unsigned char colortharray[] = {
5018 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5020 if(!SiS_Pr->CRT1UsesCustomMode) {
5022 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5023 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5024 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5025 SiS_Pr->SiS_SelectCRT2Rate = 0;
5026 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5028 if(CRT1ModeNo >= 0x13) {
5030 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5031 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5033 /* Get colordepth */
5034 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5035 if(!colorth) colorth++;
5043 VCLK = SiS_Pr->CSRClock_CRT1;
5045 /* Get color depth */
5046 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5050 if(CRT1ModeNo >= 0x13) {
5052 if(SiS_Pr->ChipType == SIS_300) {
5053 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5055 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5058 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5060 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5064 data2 = temp - ((colorth * VCLK) / MCLK);
5066 temp = (28 * 16) % data2;
5067 data2 = (28 * 16) / data2;
5070 if(SiS_Pr->ChipType == SIS_300) {
5072 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5073 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5077 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5078 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5080 if(SiS_Pr->ChipType == SIS_730) {
5082 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5083 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5085 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5086 index = 0; /* -- do it like the BIOS anyway... */
5093 index = (pci50 >> 1) & 0x07;
5095 if(pci50 & 0x01) index += 6;
5096 if(!(pciA0 & 0x01)) index += 24;
5098 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5102 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5103 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5107 data += data2; /* CRT1 Request Period */
5109 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5110 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5112 if(!SiS_Pr->UseCustomMode) {
5114 CRT2ModeNo = ModeNo;
5115 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5117 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5120 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5121 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5123 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5124 if(SiS_Pr->SiS_UseROM) {
5125 if(ROMAddr[0x220] & 0x01) {
5126 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5135 VCLK = SiS_Pr->CSRClock;
5139 /* Get colordepth */
5140 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5141 if(!colorth) colorth++;
5143 data = data * VCLK * colorth;
5144 temp = data % (MCLK << 4);
5145 data = data / (MCLK << 4);
5148 if(data < 6) data = 6;
5149 else if(data > 0x14) data = 0x14;
5151 if(SiS_Pr->ChipType == SIS_300) {
5153 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5157 if(( (SiS_Pr->ChipType == SIS_630) ||
5158 (SiS_Pr->ChipType == SIS_730) ) &&
5159 (SiS_Pr->ChipRevision >= 0x30))
5162 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5164 if((SiS_Pr->ChipType == SIS_630) &&
5165 (SiS_Pr->ChipRevision >= 0x30)) {
5166 if(data > 0x13) data = 0x13;
5168 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5170 } else { /* If mode <= 0x13, we just restore everything */
5172 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5173 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5179 /* Set CRT2 FIFO on 315/330 series */
5180 #ifdef CONFIG_FB_SIS_315
5182 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5184 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5185 if( (SiS_Pr->ChipType == SIS_760) &&
5186 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5187 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5188 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5189 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5190 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5191 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5192 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5193 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5194 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5197 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5203 static unsigned short
5204 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5206 unsigned int tempax,tempbx;
5208 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5209 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5210 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5211 return (unsigned short)tempax;
5214 /* Set Part 1 / SiS bridge slave mode */
5216 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5217 unsigned short RefreshRateTableIndex)
5219 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5220 static const unsigned short CRTranslation[] = {
5221 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5222 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5223 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5224 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5225 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5226 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5229 if(ModeNo <= 0x13) {
5230 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5231 } else if(SiS_Pr->UseCustomMode) {
5232 modeflag = SiS_Pr->CModeFlag;
5233 xres = SiS_Pr->CHDisplay;
5235 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5236 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5239 /* The following is only done if bridge is in slave mode: */
5241 if(SiS_Pr->ChipType >= SIS_315H) {
5242 if(xres >= 1600) { /* BIOS: == 1600 */
5243 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5247 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5249 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5250 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5252 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5253 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5254 SiS_Pr->CHBlankStart += 16;
5257 SiS_Pr->CHBlankEnd = 32;
5258 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5259 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5262 temp = SiS_Pr->SiS_VGAHT - 96;
5263 if(!(modeflag & HalfDCLK)) temp -= 32;
5264 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5265 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5266 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5270 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5272 SiS_Pr->CHSyncStart = temp;
5274 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5276 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5278 VGAVDE = SiS_Pr->SiS_VGAVDE;
5279 if (VGAVDE == 357) VGAVDE = 350;
5280 else if(VGAVDE == 360) VGAVDE = 350;
5281 else if(VGAVDE == 375) VGAVDE = 350;
5282 else if(VGAVDE == 405) VGAVDE = 400;
5283 else if(VGAVDE == 420) VGAVDE = 400;
5284 else if(VGAVDE == 525) VGAVDE = 480;
5285 else if(VGAVDE == 1056) VGAVDE = 1024;
5286 SiS_Pr->CVDisplay = VGAVDE;
5288 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5290 SiS_Pr->CVBlankEnd = 1;
5291 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5293 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5294 SiS_Pr->CVSyncStart = VGAVDE + temp;
5297 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5299 SiS_CalcCRRegisters(SiS_Pr, 0);
5300 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5302 for(i = 0; i <= 7; i++) {
5303 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5305 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5306 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5308 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5309 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5311 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5312 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5315 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5316 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5318 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5319 if(modeflag & DoubleScanMode) temp |= 0x80;
5320 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5323 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5324 if(modeflag & HalfDCLK) temp |= 0x08;
5325 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5327 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5328 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5331 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5332 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5334 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5336 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5337 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5341 * This is used for LVDS, LCDA and Chrontel TV output
5342 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5345 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5346 unsigned short RefreshRateTableIndex)
5348 unsigned short modeflag, resinfo = 0;
5349 unsigned short push2, tempax, tempbx, tempcx, temp;
5350 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5351 bool islvds = false, issis = false, chkdclkfirst = false;
5352 #ifdef CONFIG_FB_SIS_300
5353 unsigned short crt2crtc = 0;
5355 #ifdef CONFIG_FB_SIS_315
5356 unsigned short pushcx;
5359 if(ModeNo <= 0x13) {
5360 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5361 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5362 #ifdef CONFIG_FB_SIS_300
5363 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5365 } else if(SiS_Pr->UseCustomMode) {
5366 modeflag = SiS_Pr->CModeFlag;
5368 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5369 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5370 #ifdef CONFIG_FB_SIS_300
5371 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5375 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5376 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5380 /* is really sis if sis bridge, but not 301B-DH */
5381 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5385 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5386 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5387 chkdclkfirst = true;
5391 #ifdef CONFIG_FB_SIS_315
5392 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5394 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5395 } else if(IS_SIS740) {
5397 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5398 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5399 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5400 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5404 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5405 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5406 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5407 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5408 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5409 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5410 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5411 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5421 tempax = SiS_Pr->SiS_LCDHDES;
5423 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5424 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5425 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5426 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5433 temp = (tempax & 0x0007);
5434 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5435 temp = (tempax >> 3) & 0x00FF;
5436 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5438 tempbx = SiS_Pr->SiS_HDE;
5439 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5440 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5441 tempbx = SiS_Pr->PanelXRes;
5443 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5444 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5445 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5451 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5454 if(temp & 0x07) temp += 8;
5456 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5458 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5460 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5461 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5462 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5467 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5469 temp = (tempcx >> 3) & 0x00FF;
5470 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5471 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5472 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5476 case 0x0d: temp = 0x56; break;
5477 case 0x10: temp = 0x60; break;
5478 case 0x13: temp = 0x5f; break;
5488 case 0x5e: temp = 0x54; break;
5493 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5495 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5497 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5499 if(SiS_Pr->PanelHRE != 999) {
5500 temp = tempcx + SiS_Pr->PanelHRE;
5501 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5510 temp |= ((tempcx & 0x07) << 5);
5511 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5515 tempax = SiS_Pr->SiS_VGAVDE;
5516 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5517 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5518 tempax = SiS_Pr->PanelYRes;
5522 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5523 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5527 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5528 if(SiS_Pr->ChipType < SIS_315H) {
5529 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5530 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5531 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5535 if(islvds) tempcx >>= 1;
5538 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5539 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5540 (SiS_Pr->PanelVRS != 999) ) {
5541 tempcx = SiS_Pr->PanelVRS;
5546 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5547 else if(issis) tempbx++;
5550 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5552 temp = tempbx & 0x00FF;
5553 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5554 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5555 if(ModeNo == 0x10) temp = 0xa9;
5558 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5563 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5564 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5565 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5570 temp = tempcx & 0x000F;
5571 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5573 temp = ((tempbx >> 8) & 0x07) << 3;
5574 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5575 if(SiS_Pr->SiS_HDE != 640) {
5576 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5578 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5579 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5581 if((SiS_Pr->ChipType >= SIS_315H) ||
5582 (SiS_Pr->ChipRevision >= 0x30)) {
5584 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5585 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5587 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5588 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5589 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5590 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5592 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5596 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5598 tempbx = push2; /* BPLVDEE */
5600 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5602 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5603 switch(SiS_Pr->SiS_LCDResInfo) {
5605 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5606 tempcx = SiS_Pr->SiS_VGAVDE;
5609 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5610 if(resinfo == SIS_RI_800x600) tempcx++;
5613 case Panel_1024x600:
5614 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5615 if(resinfo == SIS_RI_1024x600) tempcx++;
5616 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5617 if(resinfo == SIS_RI_800x600) tempcx++;
5621 case Panel_1024x768:
5622 if(SiS_Pr->ChipType < SIS_315H) {
5623 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5624 if(resinfo == SIS_RI_1024x768) tempcx++;
5631 temp = ((tempbx >> 8) & 0x07) << 3;
5632 temp |= ((tempcx >> 8) & 0x07);
5633 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5634 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5635 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5637 /* Vertical scaling */
5639 if(SiS_Pr->ChipType < SIS_315H) {
5641 #ifdef CONFIG_FB_SIS_300 /* 300 series */
5642 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5643 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5644 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5647 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5649 temp = (unsigned short)(tempeax & 0x00FF);
5650 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5652 #endif /* CONFIG_FB_SIS_300 */
5656 #ifdef CONFIG_FB_SIS_315 /* 315 series */
5657 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5658 tempebx = SiS_Pr->SiS_VDE;
5659 temp = (tempeax % tempebx);
5660 tempeax = tempeax / tempebx;
5662 tempvcfact = tempeax;
5664 temp = (unsigned short)(tempeax & 0x00FF);
5665 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5666 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5667 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5668 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5669 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5670 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5672 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5673 temp = (unsigned short)(tempeax & 0x00FF);
5674 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5675 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5676 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5677 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5678 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5680 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5681 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5687 /* Horizontal scaling */
5689 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5691 if(modeflag & HalfDCLK) tempeax >>= 1;
5693 tempebx = tempeax << 16;
5694 if(SiS_Pr->SiS_HDE == tempeax) {
5697 tempecx = tempebx / SiS_Pr->SiS_HDE;
5698 if(SiS_Pr->ChipType >= SIS_315H) {
5699 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5703 if(SiS_Pr->ChipType >= SIS_315H) {
5704 tempeax = (tempebx / tempecx) - 1;
5706 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5708 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5709 temp = (unsigned short)(tempecx & 0x00FF);
5710 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5712 if(SiS_Pr->ChipType >= SIS_315H) {
5713 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5714 tempbx = (unsigned short)(tempeax & 0xFFFF);
5716 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5717 tempbx = tempvcfact & 0x3f;
5718 if(tempbx == 0) tempbx = 64;
5720 tempbx = (unsigned short)(tempeax & 0xFFFF);
5722 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5723 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5724 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5725 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5728 temp = ((tempbx >> 8) & 0x07) << 3;
5729 temp = temp | ((tempecx >> 8) & 0x07);
5730 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5731 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5733 tempecx >>= 16; /* BPLHCFACT */
5735 if(modeflag & HalfDCLK) tempecx >>= 1;
5737 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5738 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5739 temp = (unsigned short)(tempecx & 0x00FF);
5740 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5742 #ifdef CONFIG_FB_SIS_315
5743 if(SiS_Pr->ChipType >= SIS_315H) {
5744 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5745 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5746 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5750 if(SiS_Pr->ChipType == SIS_740) {
5751 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5753 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5760 #ifdef CONFIG_FB_SIS_300
5761 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5762 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5763 unsigned char *trumpdata;
5764 int i, j = crt2crtc;
5765 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5766 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5767 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5769 if(SiS_Pr->SiS_UseROM) {
5770 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5772 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5773 trumpdata = &SiS300_TrumpionData[j][0];
5776 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5777 for(i=0; i<5; i++) {
5778 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5780 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5781 if(ModeNo == 0x13) {
5782 for(i=0; i<4; i++) {
5783 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5785 } else if(ModeNo == 0x10) {
5786 for(i=0; i<4; i++) {
5787 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5788 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5792 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5796 #ifdef CONFIG_FB_SIS_315
5797 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5798 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5799 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5800 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5801 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5802 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5803 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5804 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5805 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5806 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5807 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5808 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5810 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5811 temp = (tempax >> 8) << 3;
5812 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5813 tempax += 32; /* Blpe = lBlps+32 */
5814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
5816 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5818 tempax = SiS_Pr->SiS_VDE;
5819 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5820 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5821 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5823 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5824 temp = (tempax >> 8) << 3;
5825 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5827 tempeax = SiS_Pr->SiS_HDE;
5828 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5829 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5830 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5831 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5832 temp = tempeax & 0x7f;
5835 temp = tempeax & 0x3f;
5836 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5838 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5839 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5840 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5842 tempax = SiS_Pr->SiS_HDE;
5843 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5844 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5845 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5846 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5848 temp = tempax & 0x00FF;
5849 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5850 temp = ((tempax & 0xFF00) >> 8) << 3;
5851 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
5853 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5854 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5855 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5856 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5857 tempeax = tempax * pushcx;
5858 temp = tempeax & 0xFF;
5859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5860 temp = (tempeax & 0xFF00) >> 8;
5861 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5862 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5863 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5864 temp = ((tempeax & 0x01000000) >> 24) << 7;
5865 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
5867 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5868 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5869 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5870 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5871 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5873 if(SiS_Pr->SiS_IF_DEF_FSTN) {
5874 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5875 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5876 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5878 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5879 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5880 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5881 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5882 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5883 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5885 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5887 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5888 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5889 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5890 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
5891 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
5892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
5893 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
5896 #endif /* CONFIG_FB_SIS_315 */
5901 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5902 unsigned short RefreshRateTableIndex)
5904 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
5905 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5907 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
5908 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
5909 #ifdef CONFIG_FB_SIS_315
5910 unsigned short tempbl=0;
5913 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5914 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5918 if(ModeNo <= 0x13) {
5919 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5920 } else if(SiS_Pr->UseCustomMode) {
5921 modeflag = SiS_Pr->CModeFlag;
5923 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
5924 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5925 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5928 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5930 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
5931 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
5932 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
5934 if(SiS_Pr->ChipType < SIS_315H ) {
5935 #ifdef CONFIG_FB_SIS_300
5936 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
5939 #ifdef CONFIG_FB_SIS_315
5940 SiS_SetCRT2FIFO_310(SiS_Pr);
5944 /* 1. Horizontal setup */
5946 if(SiS_Pr->ChipType < SIS_315H ) {
5948 #ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/
5950 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
5951 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
5953 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
5954 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
5956 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
5957 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
5959 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
5960 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
5961 tempbx = pushbx + tempcx;
5967 #endif /* CONFIG_FB_SIS_300 */
5971 #ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */
5973 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
5974 if(modeflag & HalfDCLK) {
5975 if(SiS_Pr->SiS_VBType & VB_SISVB) {
5978 tempax = SiS_Pr->SiS_VGAHDE >> 1;
5979 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
5980 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5981 tempcx = SiS_Pr->SiS_HT - tempax;
5986 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
5987 temp = (tempcx >> 4) & 0xF0;
5988 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
5990 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
5991 tempbx = SiS_Pr->SiS_VGAHDE;
5994 if(modeflag & HalfDCLK) {
6000 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6009 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6010 if(SiS_Pr->ChipType >= SIS_661) {
6011 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6012 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6013 if(resinfo == SIS_RI_1280x1024) {
6014 tempcx = (tempcx & 0xff00) | 0x30;
6015 } else if(resinfo == SIS_RI_1600x1200) {
6016 tempcx = (tempcx & 0xff00) | 0xff;
6022 #endif /* CONFIG_FB_SIS_315 */
6024 } /* 315/330 series */
6026 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6028 if(SiS_Pr->UseCustomMode) {
6029 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6030 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6031 tempax = SiS_Pr->SiS_VGAHT;
6032 if(modeflag & HalfDCLK) tempax >>= 1;
6034 if(tempcx > tempax) tempcx = tempax;
6037 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6038 unsigned char cr4, cr14, cr5, cr15;
6039 if(SiS_Pr->UseCustomMode) {
6040 cr4 = SiS_Pr->CCRT1CRTC[4];
6041 cr14 = SiS_Pr->CCRT1CRTC[14];
6042 cr5 = SiS_Pr->CCRT1CRTC[5];
6043 cr15 = SiS_Pr->CCRT1CRTC[15];
6045 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6046 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6047 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6048 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6050 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6051 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6053 tempcx |= (tempbx & 0xFF00);
6054 tempbx += bridgeadd;
6055 tempcx += bridgeadd;
6056 tempax = SiS_Pr->SiS_VGAHT;
6057 if(modeflag & HalfDCLK) tempax >>= 1;
6059 if(tempcx > tempax) tempcx = tempax;
6062 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6064 tempcx = 1044; /* HWCursor bug! */
6069 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6071 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6073 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6074 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6076 /* 2. Vertical setup */
6078 tempcx = SiS_Pr->SiS_VGAVT - 1;
6079 temp = tempcx & 0x00FF;
6081 if(SiS_Pr->ChipType < SIS_661) {
6082 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6083 if(SiS_Pr->ChipType < SIS_315H) {
6084 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6085 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6092 } else if(SiS_Pr->ChipType >= SIS_315H) {
6096 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6098 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6099 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6101 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6102 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6104 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6111 if(tempcx < 4) tempcx = 4;
6116 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6117 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6120 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6121 if(SiS_Pr->UseCustomMode) {
6122 tempbx = SiS_Pr->CVSyncStart;
6123 tempcx = SiS_Pr->CVSyncEnd;
6125 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6126 unsigned char cr8, cr7, cr13;
6127 if(SiS_Pr->UseCustomMode) {
6128 cr8 = SiS_Pr->CCRT1CRTC[8];
6129 cr7 = SiS_Pr->CCRT1CRTC[7];
6130 cr13 = SiS_Pr->CCRT1CRTC[13];
6131 tempcx = SiS_Pr->CCRT1CRTC[9];
6133 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6134 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6135 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6136 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6139 if(cr7 & 0x04) tempbx |= 0x0100;
6140 if(cr7 & 0x80) tempbx |= 0x0200;
6141 if(cr13 & 0x08) tempbx |= 0x0400;
6144 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6146 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6147 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6149 /* 3. Panel delay compensation */
6151 if(SiS_Pr->ChipType < SIS_315H) {
6153 #ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */
6155 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6157 if(SiS_Pr->ChipType == SIS_300) {
6159 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6160 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6162 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6163 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6165 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6166 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6167 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6168 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6169 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6172 if(SiS_Pr->SiS_UseROM) {
6173 if(ROMAddr[0x220] & 0x80) {
6174 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6175 temp = ROMAddr[0x221];
6176 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6177 temp = ROMAddr[0x222];
6178 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6179 temp = ROMAddr[0x223];
6181 temp = ROMAddr[0x224];
6184 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6185 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6190 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6191 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6193 if(SiS_Pr->SiS_UseROM) {
6194 if(ROMAddr[0x220] & 0x80) {
6195 temp = ROMAddr[0x220];
6198 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6199 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6205 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6207 #endif /* CONFIG_FB_SIS_300 */
6211 #ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/
6213 if(SiS_Pr->ChipType < SIS_661) {
6215 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6217 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6220 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6222 if(SiS_Pr->ChipType == SIS_650) {
6223 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6224 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6228 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6231 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6232 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6236 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6242 if(modeflag & DoubleScanMode) tempax |= 0x80;
6243 if(modeflag & HalfDCLK) tempax |= 0x40;
6244 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6246 #endif /* CONFIG_FB_SIS_315 */
6252 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6253 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6254 /* For 301BDH with LCD, we set up the Panel Link */
6255 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6256 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6257 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6260 if(SiS_Pr->ChipType < SIS_315H) {
6261 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6263 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6264 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6265 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6268 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6274 /*********************************************/
6275 /* SET PART 2 REGISTER GROUP */
6276 /*********************************************/
6278 #ifdef CONFIG_FB_SIS_315
6279 static unsigned char *
6280 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6282 const unsigned char *tableptr = NULL;
6283 unsigned short a, b, p = 0;
6285 a = SiS_Pr->SiS_VGAHDE;
6286 b = SiS_Pr->SiS_HDE;
6288 a = SiS_Pr->SiS_VGAVDE;
6289 b = SiS_Pr->SiS_VDE;
6293 tableptr = SiS_Part2CLVX_1;
6295 tableptr = SiS_Part2CLVX_2;
6297 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6298 tableptr = SiS_Part2CLVX_4;
6300 tableptr = SiS_Part2CLVX_3;
6302 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6303 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6304 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6305 else tableptr = SiS_Part2CLVX_5;
6306 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6307 tableptr = SiS_Part2CLVX_6;
6310 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6312 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6313 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6316 return ((unsigned char *)&tableptr[p]);
6320 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6321 unsigned short RefreshRateTableIndex)
6323 unsigned char *tableptr;
6327 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6329 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6330 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6331 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6333 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6334 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6335 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6336 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6340 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6341 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6345 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6346 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6347 unsigned short *ResIndex)
6350 if(SiS_Pr->ChipType < SIS_315H) return false;
6353 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6355 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6357 (*ResIndex) &= 0x3f;
6360 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6361 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6366 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6367 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6368 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6371 return (((*CRT2Index) != 0));
6375 #ifdef CONFIG_FB_SIS_300
6377 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6379 unsigned short tempcx;
6380 static const unsigned char atable[] = {
6381 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6382 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6385 if(!SiS_Pr->UseCustomMode) {
6386 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6387 (SiS_Pr->ChipType == SIS_730) ) &&
6388 (SiS_Pr->ChipRevision > 2) ) &&
6389 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6390 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6391 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6392 if(ModeNo == 0x13) {
6393 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6394 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6395 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6396 } else if((crt2crtc & 0x3F) == 4) {
6397 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6398 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6399 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6400 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6401 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6405 if(SiS_Pr->ChipType < SIS_315H) {
6406 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6409 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6410 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6416 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6419 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6420 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6422 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6426 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6427 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6433 /* For ECS A907. Highly preliminary. */
6435 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6436 unsigned short ModeNo)
6438 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6439 unsigned short crt2crtc, resindex;
6442 if(SiS_Pr->ChipType != SIS_300) return;
6443 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6444 if(SiS_Pr->UseCustomMode) return;
6446 if(ModeNo <= 0x13) {
6447 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6449 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6452 resindex = crt2crtc & 0x3F;
6453 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6454 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6456 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6458 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6462 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6463 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6464 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6465 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6467 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6468 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6470 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6471 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6473 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6474 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6479 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6481 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6482 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6483 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6485 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6486 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6487 const unsigned char specialtv[] = {
6488 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6489 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6490 0x58,0xe4,0x73,0xda,0x13
6493 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6494 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6496 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6497 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6498 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6499 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6500 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6502 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6503 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6508 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6509 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6510 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6511 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6513 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6514 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6520 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6522 unsigned short temp;
6524 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6525 if(SiS_Pr->SiS_VGAVDE == 525) {
6527 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6529 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6531 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6532 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6533 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6535 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6537 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6539 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6543 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6544 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6545 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6546 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6547 /* Not always for LV, see SetGrp2 */
6550 if(ModeNo <= 0x13) temp = 3;
6551 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6554 /* 651+301C, for 1280x768 - do I really need that? */
6555 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6556 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6557 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6558 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6559 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6560 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6561 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6562 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6563 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6564 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6565 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6566 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6567 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6568 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6569 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6570 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6579 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6580 unsigned short RefreshRateTableIndex)
6582 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6583 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6584 unsigned int longtemp, PhaseIndex;
6586 const unsigned char *TimingPoint;
6587 #ifdef CONFIG_FB_SIS_315
6588 unsigned short resindex, CRT2Index;
6589 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6591 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6594 if(ModeNo <= 0x13) {
6595 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6596 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6597 } else if(SiS_Pr->UseCustomMode) {
6598 modeflag = SiS_Pr->CModeFlag;
6601 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6602 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6606 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6607 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6608 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6609 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6611 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6613 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6615 PhaseIndex = 0x01; /* SiS_PALPhase */
6616 TimingPoint = SiS_Pr->SiS_PALTiming;
6619 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6620 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6621 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6625 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6627 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6628 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6629 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6630 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6631 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6635 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6638 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6639 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6641 TimingPoint = &SiS_YPbPrTable[i][0];
6643 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6645 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6647 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6651 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6652 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6653 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6657 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6658 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6659 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6662 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6663 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6664 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6665 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6666 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6668 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6672 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6673 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6676 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6677 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6679 for(i = 0x39; i <= 0x45; i++, j++) {
6680 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6683 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6684 if(SiS_Pr->SiS_ModeType != ModeText) {
6685 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6689 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6691 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6692 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6693 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6694 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6696 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6697 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
6698 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6699 else tempax = 440; /* NTSC, YPbPr 525 */
6701 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6702 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6703 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6705 tempax -= SiS_Pr->SiS_VDE;
6707 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6712 temp = tempax + (unsigned short)TimingPoint[0];
6713 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6715 temp = tempax + (unsigned short)TimingPoint[1];
6716 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6718 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6719 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6720 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6723 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6724 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6730 tempcx = SiS_Pr->SiS_HT;
6731 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6733 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6734 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6735 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6737 tempcx = SiS_Pr->SiS_HT >> 1;
6738 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6740 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6741 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6743 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6745 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6746 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6749 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6753 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6756 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6757 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6758 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6761 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6762 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6764 tempcx = SiS_Pr->SiS_HT >> 1;
6765 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6767 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6768 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6771 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6772 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6774 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6776 tempbx = SiS_Pr->SiS_VDE;
6777 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6778 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6779 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6780 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6781 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6782 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6784 if(SiS_Pr->ChipType >= SIS_315H) {
6785 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6786 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6787 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6788 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6789 if(crt2crtc == 4) tempbx++;
6793 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6794 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6795 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6797 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6798 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6803 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6805 temp = (tempcx >> 8) & 0x0F;
6806 temp |= ((tempbx >> 2) & 0xC0);
6807 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6809 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6811 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6813 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6814 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6817 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6818 tempbx = SiS_Pr->SiS_VDE;
6819 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6820 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6824 temp = ((tempbx >> 3) & 0x60) | 0x18;
6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6828 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6829 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6834 if(!(modeflag & HalfDCLK)) {
6835 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6841 tempch = tempcl = 0x01;
6842 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6843 if(SiS_Pr->SiS_VGAHDE >= 960) {
6844 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6846 if(SiS_Pr->SiS_VGAHDE >= 1280) {
6850 tempch = 25; /* OK */
6856 if(!(tempbx & 0x20)) {
6857 if(modeflag & HalfDCLK) tempcl <<= 1;
6858 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6859 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6860 tempax = longtemp / SiS_Pr->SiS_HDE;
6861 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6862 tempbx |= ((tempax >> 8) & 0x1F);
6863 tempcx = tempax >> 13;
6866 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6867 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6869 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6872 if(tempbx & 0x20) tempcx = 0;
6873 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6875 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6882 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6883 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6884 temp = (tempcx & 0x0300) >> 6;
6885 temp |= ((tempbx >> 8) & 0x03);
6886 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6888 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
6889 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6891 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
6893 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
6894 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
6896 SiS_SetTVSpecial(SiS_Pr, ModeNo);
6898 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
6900 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
6901 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
6906 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6907 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
6908 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
6909 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
6911 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
6914 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6915 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6916 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
6920 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
6922 /* From here: Part2 LCD setup */
6924 tempbx = SiS_Pr->SiS_HDE;
6925 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
6926 tempbx--; /* RHACTE = HDE - 1 */
6927 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
6928 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
6931 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
6932 if(SiS_Pr->SiS_ModeType == ModeEGA) {
6933 if(SiS_Pr->SiS_VGAHDE >= 1024) {
6935 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
6941 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
6943 tempbx = SiS_Pr->SiS_VDE - 1;
6944 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
6945 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
6947 tempcx = SiS_Pr->SiS_VT - 1;
6948 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
6949 temp = (tempcx >> 3) & 0xE0;
6950 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
6951 /* Enable dithering; only do this for 32bpp mode */
6952 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
6956 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
6958 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
6959 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
6961 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
6962 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
6964 #ifdef CONFIG_FB_SIS_315
6965 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
6966 &CRT2Index, &resindex)) {
6968 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
6970 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
6973 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6974 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6975 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6976 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6978 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6979 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6981 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6982 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6984 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6985 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6987 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
6992 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
6993 /* Clevo dual-link 1024x768 */
6994 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
6995 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
6997 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6998 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
6999 tempbx = SiS_Pr->SiS_VDE - 1;
7000 tempcx = SiS_Pr->SiS_VT - 1;
7002 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7003 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7006 tempbx = SiS_Pr->PanelYRes;
7007 tempcx = SiS_Pr->SiS_VT;
7009 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7010 tempax = SiS_Pr->PanelYRes;
7011 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7012 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7013 tempax = tempcx = 0;
7015 tempax -= SiS_Pr->SiS_VDE;
7019 tempcx -= tempax; /* lcdvdes */
7020 tempbx -= tempax; /* lcdvdee */
7023 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7025 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7026 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7028 temp = (tempbx >> 5) & 0x38;
7029 temp |= ((tempcx >> 8) & 0x07);
7030 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7032 tempax = SiS_Pr->SiS_VDE;
7033 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7034 tempax = SiS_Pr->PanelYRes;
7036 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7037 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7038 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7039 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7043 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7044 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7045 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7046 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7047 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7048 if(tempax % 4) { tempax >>= 2; tempax++; }
7049 else { tempax >>= 2; }
7050 tempbx -= (tempax - 1);
7053 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7057 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7059 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7060 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7067 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7069 if(SiS_Pr->UseCustomMode) {
7070 tempbx = SiS_Pr->CVSyncStart;
7073 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7075 temp = (tempbx >> 4) & 0xF0;
7076 tempbx += (tempcx + 1);
7077 temp |= (tempbx & 0x0F);
7079 if(SiS_Pr->UseCustomMode) {
7081 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7084 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7086 #ifdef CONFIG_FB_SIS_300
7087 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7091 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7092 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7093 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7094 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7095 /* Higher bridgeoffset shifts to the LEFT */
7098 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7099 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7100 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7101 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7104 temp += bridgeoffset;
7105 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7106 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7108 tempcx = SiS_Pr->SiS_HT;
7109 tempax = tempbx = SiS_Pr->SiS_HDE;
7110 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7111 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7112 tempax = SiS_Pr->PanelXRes;
7113 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7116 if(SiS_IsDualLink(SiS_Pr)) {
7122 tempbx += bridgeoffset;
7124 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7125 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7127 tempcx = (tempcx - tempax) >> 2;
7132 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7133 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7134 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7135 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7140 if(SiS_Pr->UseCustomMode) {
7141 tempbx = SiS_Pr->CHSyncStart;
7142 if(modeflag & HalfDCLK) tempbx <<= 1;
7143 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7144 tempbx += bridgeoffset;
7147 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7148 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7153 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7154 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7158 if(SiS_Pr->UseCustomMode) {
7159 tempbx = SiS_Pr->CHSyncEnd;
7160 if(modeflag & HalfDCLK) tempbx <<= 1;
7161 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7162 tempbx += bridgeoffset;
7165 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7167 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7169 #ifdef CONFIG_FB_SIS_300
7170 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7172 #ifdef CONFIG_FB_SIS_315
7173 } /* CRT2-LCD from table */
7177 /*********************************************/
7178 /* SET PART 3 REGISTER GROUP */
7179 /*********************************************/
7182 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7185 const unsigned char *tempdi;
7187 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7190 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7195 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7196 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7197 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7199 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7200 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7203 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7204 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7205 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7206 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7210 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7211 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7212 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7213 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7215 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7216 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7217 tempdi = SiS_HiTVGroup3_1;
7218 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7222 for(i=0; i<=0x3E; i++) {
7223 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7225 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7226 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7227 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7237 /*********************************************/
7238 /* SET PART 4 REGISTER GROUP */
7239 /*********************************************/
7241 #ifdef CONFIG_FB_SIS_315
7244 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7246 unsigned short temp, temp1, temp2;
7248 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7249 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7250 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7251 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7252 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7253 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7254 temp = (unsigned short)((int)(temp) + shift);
7255 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7256 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7257 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7258 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7259 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7260 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7265 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7267 unsigned short temp, temp1;
7268 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7270 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7271 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7273 if(SiS_Pr->ChipType >= XGI_20) return;
7275 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7276 if(!(ROMAddr[0x61] & 0x04)) return;
7279 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7280 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7281 if(!(temp & 0x01)) {
7282 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7283 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7284 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7285 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7287 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7288 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7289 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7290 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7292 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7294 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7295 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7296 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7297 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7298 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7300 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7303 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7304 if(temp1 == 0x01) temp |= 0x01;
7305 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7306 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7307 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7309 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7314 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7315 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7316 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7317 if(resinfo == SIS_RI_1024x768) {
7318 SiS_ShiftXPos(SiS_Pr, 97);
7320 SiS_ShiftXPos(SiS_Pr, 111);
7322 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7323 SiS_ShiftXPos(SiS_Pr, 136);
7335 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7336 unsigned short RefreshRateTableIndex)
7338 unsigned short vclkindex, temp, reg1, reg2;
7340 if(SiS_Pr->UseCustomMode) {
7341 reg1 = SiS_Pr->CSR2B;
7342 reg2 = SiS_Pr->CSR2C;
7344 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7345 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7346 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7349 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7350 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7351 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7352 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7353 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7355 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7356 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7359 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7360 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7361 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7363 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7365 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7366 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7370 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7372 if(SiS_Pr->ChipType >= SIS_315H) {
7373 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7374 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7375 (SiS_IsVAMode(SiS_Pr))) {
7376 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7377 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7379 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7384 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7385 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7387 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7389 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7394 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7395 unsigned short RefreshRateTableIndex)
7397 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7398 unsigned int tempebx, tempeax, templong;
7400 if(ModeNo <= 0x13) {
7401 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7402 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7403 } else if(SiS_Pr->UseCustomMode) {
7404 modeflag = SiS_Pr->CModeFlag;
7407 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7408 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7411 if(SiS_Pr->ChipType >= SIS_315H) {
7412 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7413 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7414 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7419 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7420 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7421 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7425 if(SiS_Pr->ChipType >= SIS_315H) {
7426 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7427 SiS_SetDualLinkEtc(SiS_Pr);
7432 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7434 tempbx = SiS_Pr->SiS_RVBHCMAX;
7435 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7437 temp = (tempbx >> 1) & 0x80;
7439 tempcx = SiS_Pr->SiS_VGAHT - 1;
7440 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7442 temp |= ((tempcx >> 5) & 0x78);
7444 tempcx = SiS_Pr->SiS_VGAVT - 1;
7445 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7446 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7448 temp |= ((tempcx >> 8) & 0x07);
7449 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7451 tempbx = SiS_Pr->SiS_VGAHDE;
7452 if(modeflag & HalfDCLK) tempbx >>= 1;
7453 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7455 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7457 if(tempbx > 800) temp = 0x60;
7458 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7460 if(tempbx > 1024) temp = 0xC0;
7461 else if(tempbx >= 960) temp = 0xA0;
7462 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7464 if(tempbx >= 1280) temp = 0x40;
7465 else if(tempbx >= 1024) temp = 0x20;
7468 if(tempbx >= 1024) temp = 0xA0;
7471 temp |= SiS_Pr->Init_P4_0E;
7473 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7474 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7480 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7482 tempeax = SiS_Pr->SiS_VGAVDE;
7483 tempebx = SiS_Pr->SiS_VDE;
7484 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7485 if(!(temp & 0xE0)) tempebx >>=1;
7488 tempcx = SiS_Pr->SiS_RVBHRS;
7489 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7493 if(tempeax <= tempebx) {
7499 tempeax *= (256 * 1024);
7500 templong = tempeax % tempebx;
7502 if(templong) tempeax++;
7504 temp = (unsigned short)(tempeax & 0x000000FF);
7505 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7506 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7507 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7508 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7509 temp |= (tempcx & 0x4F);
7510 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7512 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7514 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7516 /* Calc Linebuffer max address and set/clear decimode */
7518 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7519 tempax = SiS_Pr->SiS_VGAHDE;
7520 if(modeflag & HalfDCLK) tempax >>= 1;
7521 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7523 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7527 if(tempax == 960) tempax *= 25; /* Correct */
7528 else if(tempax == 1024) tempax *= 25;
7534 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7535 if(resinfo == SIS_RI_1024x768 ||
7536 resinfo == SIS_RI_1024x576 ||
7537 resinfo == SIS_RI_1280x1024 ||
7538 resinfo == SIS_RI_1280x720) {
7539 /* Otherwise white line or garbage at right edge */
7540 tempax = (tempax & 0xff00) | 0x20;
7546 temp = ((tempax >> 4) & 0x30) | tempbx;
7547 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7548 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7550 temp = 0x0036; tempbx = 0xD0;
7551 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7552 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7554 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7555 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7557 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7558 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7564 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7566 tempbx = SiS_Pr->SiS_HT >> 1;
7567 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7569 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7570 temp = (tempbx >> 5) & 0x38;
7571 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7573 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7574 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7575 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7576 /* LCD-too-dark-error-source, see FinalizeLCD() */
7580 SiS_SetDualLinkEtc(SiS_Pr);
7584 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7587 /*********************************************/
7588 /* SET PART 5 REGISTER GROUP */
7589 /*********************************************/
7592 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7595 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7597 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7598 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7599 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7600 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7605 /*********************************************/
7606 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7607 /*********************************************/
7610 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7611 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7612 unsigned short *DisplayType)
7614 unsigned short modeflag = 0;
7615 bool checkhd = true;
7617 /* Pass 1:1 not supported here */
7619 if(ModeNo <= 0x13) {
7620 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7621 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7623 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7624 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7627 (*ResIndex) &= 0x3F;
7629 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7631 (*DisplayType) = 80;
7632 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7633 (*DisplayType) = 82;
7634 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7635 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7638 if((*DisplayType) != 84) {
7639 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7645 switch(SiS_Pr->SiS_LCDResInfo) {
7646 case Panel_320x240_1: (*DisplayType) = 50;
7649 case Panel_320x240_2: (*DisplayType) = 14;
7651 case Panel_320x240_3: (*DisplayType) = 18;
7653 case Panel_640x480: (*DisplayType) = 10;
7655 case Panel_1024x600: (*DisplayType) = 26;
7657 default: return true;
7661 if(modeflag & HalfDCLK) (*DisplayType)++;
7664 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7665 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7674 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7675 unsigned short RefreshRateTableIndex)
7677 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7678 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7679 static const unsigned short CRIdx[] = {
7680 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7681 0x07, 0x10, 0x11, 0x15, 0x16
7684 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7685 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7686 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7687 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7690 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7691 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7692 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7694 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7695 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7698 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7700 if(SiS_Pr->ChipType < SIS_315H) {
7701 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7704 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7705 &ResIndex, &DisplayType))) {
7709 switch(DisplayType) {
7710 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7711 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7712 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7713 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7714 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7715 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7716 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7717 #if 0 /* Works better with calculated numbers */
7718 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7719 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7720 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7721 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7723 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7724 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7725 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7726 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7727 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7732 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7734 for(i = 0; i <= 10; i++) {
7735 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7736 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7739 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7740 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7741 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7744 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7745 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7747 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7748 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7750 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7751 if(modeflag & DoubleScanMode) tempah |= 0x80;
7752 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7756 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7761 /*********************************************/
7763 /*********************************************/
7766 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7767 unsigned short RefreshRateTableIndex)
7769 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7770 unsigned short clkbase, vclkindex = 0;
7771 unsigned char sr2b, sr2c;
7773 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7774 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7775 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7776 RefreshRateTableIndex--;
7778 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7779 RefreshRateTableIndex);
7780 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7782 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7783 RefreshRateTableIndex);
7786 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7787 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7789 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7790 if(SiS_Pr->SiS_UseROM) {
7791 if(ROMAddr[0x220] & 0x01) {
7792 sr2b = ROMAddr[0x227];
7793 sr2c = ROMAddr[0x228];
7799 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7800 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7805 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7806 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7807 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7808 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7809 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7810 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7811 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7812 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7813 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7816 /*********************************************/
7817 /* SET UP CHRONTEL CHIPS */
7818 /*********************************************/
7821 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7822 unsigned short RefreshRateTableIndex)
7824 unsigned short TVType, resindex;
7825 const struct SiS_CHTVRegData *CHTVRegData = NULL;
7828 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7830 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7835 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7836 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7838 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7839 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7841 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7843 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7844 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7846 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7851 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7852 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7853 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
7854 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7855 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7856 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7857 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7858 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7859 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7860 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7864 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7866 #ifdef CONFIG_FB_SIS_300
7868 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7870 /* We don't support modes >800x600 */
7871 if (resindex > 5) return;
7873 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7874 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7875 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
7877 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7878 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
7881 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
7882 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
7883 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
7884 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
7885 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
7887 /* Set minimum flicker filter for Luma channel (SR1-0=00),
7888 minimum text enhancement (S3-2=10),
7889 maximum flicker filter for Chroma channel (S5-4=10)
7890 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
7892 SiS_SetCH700x(SiS_Pr,0x01,0x28);
7894 /* Set video bandwidth
7895 High bandwidth Luma composite video filter(S0=1)
7896 low bandwidth Luma S-video filter (S2-1=00)
7897 disable peak filter in S-video channel (S3=0)
7898 high bandwidth Chroma Filter (S5-4=11)
7901 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
7903 /* Register 0x3D does not exist in non-macrovision register map
7904 (Maybe this is a macrovision register?)
7907 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
7910 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
7911 all other bits a read-only. Macrovision?
7913 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
7915 /* Register 0x11 only contains 3 writable bits (S0-S2) for
7916 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
7918 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
7922 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
7924 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
7925 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
7926 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
7927 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7928 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
7929 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
7930 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
7931 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
7932 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
7933 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
7934 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
7935 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
7936 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
7937 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
7938 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
7939 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
7942 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
7943 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7944 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7945 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
7947 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
7948 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
7949 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
7950 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
7951 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
7952 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
7953 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
7954 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
7955 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
7956 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
7957 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
7958 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7959 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7962 } else { /* ---- PAL ---- */
7963 /* We don't play around with FSCI in PAL mode */
7964 SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF); /* loop filter off */
7965 SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE); /* ACIV on */
7972 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
7974 #ifdef CONFIG_FB_SIS_315
7976 unsigned short temp;
7978 /* We don't support modes >1024x768 */
7979 if (resindex > 6) return;
7981 temp = CHTVRegData[resindex].Reg[0];
7982 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
7983 SiS_SetCH701x(SiS_Pr,0x00,temp);
7985 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
7986 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
7987 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
7988 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
7989 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
7990 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
7992 temp = CHTVRegData[resindex].Reg[7];
7993 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
7994 SiS_SetCH701x(SiS_Pr,0x07,temp);
7996 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
7997 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
7998 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
7999 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8000 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8001 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8002 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8003 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8005 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8006 /* D1 should be set for PAL, PAL-N and NTSC-J,
8007 but I won't do that for PAL unless somebody
8008 tells me to do so. Since the BIOS uses
8009 non-default CIV values and blacklevels,
8010 this might be compensated anyway.
8012 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8013 SiS_SetCH701x(SiS_Pr,0x21,temp);
8025 #ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */
8028 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8030 unsigned short temp;
8032 /* Enable Chrontel 7019 LCD panel backlight */
8033 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8034 if(SiS_Pr->ChipType == SIS_740) {
8035 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8037 temp = SiS_GetCH701x(SiS_Pr,0x66);
8039 SiS_SetCH701x(SiS_Pr,0x66,temp);
8045 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8047 unsigned short temp;
8049 /* Disable Chrontel 7019 LCD panel backlight */
8050 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8051 temp = SiS_GetCH701x(SiS_Pr,0x66);
8053 SiS_SetCH701x(SiS_Pr,0x66,temp);
8058 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8060 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8061 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8062 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8063 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8064 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8065 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8066 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8067 const unsigned char *tableptr = NULL;
8070 /* Set up Power up/down timing */
8072 if(SiS_Pr->ChipType == SIS_740) {
8073 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8074 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8075 else tableptr = table1024_740;
8076 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8077 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8078 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8079 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8080 else tableptr = table1400_740;
8083 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8084 tableptr = table1024_650;
8085 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8086 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8087 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8088 tableptr = table1400_650;
8092 for(i=0; i<5; i++) {
8093 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8098 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8100 const unsigned char *tableptr = NULL;
8101 unsigned short tempbh;
8103 static const unsigned char regtable[] = {
8104 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8105 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8107 static const unsigned char table1024_740[] = {
8108 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8109 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8111 static const unsigned char table1280_740[] = {
8112 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8113 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8115 static const unsigned char table1400_740[] = {
8116 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8117 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8119 static const unsigned char table1600_740[] = {
8120 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8121 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8123 static const unsigned char table1024_650[] = {
8124 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8125 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8127 static const unsigned char table1280_650[] = {
8128 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8129 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8131 static const unsigned char table1400_650[] = {
8132 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8133 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8135 static const unsigned char table1600_650[] = {
8136 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8137 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8140 if(SiS_Pr->ChipType == SIS_740) {
8141 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8142 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8143 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8144 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8147 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8148 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8149 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8150 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8154 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8155 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8156 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8157 if(tempbh == 0xc8) {
8158 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8159 } else if(tempbh == 0xdb) {
8160 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8161 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8162 } else if(tempbh == 0xde) {
8163 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8167 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8170 for(i = 0; i < tempbh; i++) {
8171 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8173 SiS_ChrontelPowerSequencing(SiS_Pr);
8174 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8176 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8178 if(SiS_Pr->ChipType == SIS_740) {
8179 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8181 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8182 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8183 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8185 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8186 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8188 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8193 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8195 unsigned char temp, temp1;
8197 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8198 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8199 temp = SiS_GetCH701x(SiS_Pr,0x47);
8200 temp &= 0x7f; /* Use external VSYNC */
8201 SiS_SetCH701x(SiS_Pr,0x47,temp);
8202 SiS_LongDelay(SiS_Pr, 3);
8203 temp = SiS_GetCH701x(SiS_Pr,0x47);
8204 temp |= 0x80; /* Use internal VSYNC */
8205 SiS_SetCH701x(SiS_Pr,0x47,temp);
8206 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8210 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8212 unsigned short temp;
8214 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8215 if(SiS_Pr->ChipType == SIS_740) {
8216 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8217 temp |= 0x04; /* Invert XCLK phase */
8218 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8220 if(SiS_IsYPbPr(SiS_Pr)) {
8221 temp = SiS_GetCH701x(SiS_Pr,0x01);
8223 temp |= 0x80; /* Enable YPrPb (HDTV) */
8224 SiS_SetCH701x(SiS_Pr,0x01,temp);
8226 if(SiS_IsChScart(SiS_Pr)) {
8227 temp = SiS_GetCH701x(SiS_Pr,0x01);
8229 temp |= 0xc0; /* Enable SCART + CVBS */
8230 SiS_SetCH701x(SiS_Pr,0x01,temp);
8232 if(SiS_Pr->ChipType == SIS_740) {
8233 SiS_ChrontelResetVSync(SiS_Pr);
8234 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8236 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8237 temp = SiS_GetCH701x(SiS_Pr,0x49);
8238 if(SiS_IsYPbPr(SiS_Pr)) {
8239 temp = SiS_GetCH701x(SiS_Pr,0x73);
8241 SiS_SetCH701x(SiS_Pr,0x73,temp);
8243 temp = SiS_GetCH701x(SiS_Pr,0x47);
8245 SiS_SetCH701x(SiS_Pr,0x47,temp);
8246 SiS_LongDelay(SiS_Pr, 2);
8247 temp = SiS_GetCH701x(SiS_Pr,0x47);
8249 SiS_SetCH701x(SiS_Pr,0x47,temp);
8255 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8257 unsigned short temp;
8259 /* Complete power down of LVDS */
8260 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8261 if(SiS_Pr->ChipType == SIS_740) {
8262 SiS_LongDelay(SiS_Pr, 1);
8263 SiS_GenericDelay(SiS_Pr, 5887);
8264 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8265 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8267 SiS_LongDelay(SiS_Pr, 2);
8268 temp = SiS_GetCH701x(SiS_Pr,0x76);
8270 SiS_SetCH701x(SiS_Pr,0x76,temp);
8271 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8277 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8279 unsigned short temp;
8281 if(SiS_Pr->ChipType == SIS_740) {
8283 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8287 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8288 temp = SiS_GetCH701x(SiS_Pr,0x49);
8289 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8292 /* Reset Chrontel 7019 datapath */
8293 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8294 SiS_LongDelay(SiS_Pr, 1);
8295 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8297 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8298 SiS_ChrontelResetVSync(SiS_Pr);
8299 SiS_SetCH701x(SiS_Pr,0x49,temp);
8304 /* Clear/set/clear GPIO */
8305 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8307 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8308 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8310 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8311 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8313 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8314 temp = SiS_GetCH701x(SiS_Pr,0x61);
8316 SiS_SetCH701xForLCD(SiS_Pr);
8321 /* Reset Chrontel 7019 datapath */
8322 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8323 SiS_LongDelay(SiS_Pr, 1);
8324 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8329 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8331 unsigned short temp;
8333 if(SiS_Pr->ChipType == SIS_740) {
8335 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8336 SiS_ChrontelResetVSync(SiS_Pr);
8341 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8342 temp = SiS_GetCH701x(SiS_Pr,0x49);
8344 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8345 temp = SiS_GetCH701x(SiS_Pr,0x47);
8347 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8348 SiS_LongDelay(SiS_Pr, 3);
8349 temp = SiS_GetCH701x(SiS_Pr,0x47);
8351 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8358 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8360 unsigned short temp,temp1;
8362 if(SiS_Pr->ChipType == SIS_740) {
8364 temp = SiS_GetCH701x(SiS_Pr,0x61);
8367 SiS_SetCH701x(SiS_Pr,0x61,temp);
8369 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8370 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8371 SiS_LongDelay(SiS_Pr, 1);
8372 SiS_GenericDelay(SiS_Pr, 5887);
8377 temp = SiS_GetCH701x(SiS_Pr,0x61);
8380 SiS_SetCH701x(SiS_Pr,0x61,temp);
8383 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8384 temp = SiS_GetCH701x(SiS_Pr,0x66);
8386 SiS_SetCH701x(SiS_Pr,0x66,temp);
8388 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8389 SiS_GenericDelay(SiS_Pr, 1023);
8391 SiS_GenericDelay(SiS_Pr, 767);
8395 SiS_GenericDelay(SiS_Pr, 767);
8397 temp = SiS_GetCH701x(SiS_Pr,0x76);
8399 SiS_SetCH701x(SiS_Pr,0x76,temp);
8400 temp = SiS_GetCH701x(SiS_Pr,0x66);
8402 SiS_SetCH701x(SiS_Pr,0x66,temp);
8403 SiS_LongDelay(SiS_Pr, 1);
8409 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8411 unsigned short temp;
8413 SiS_LongDelay(SiS_Pr, 1);
8416 temp = SiS_GetCH701x(SiS_Pr,0x66);
8417 temp &= 0x04; /* PLL stable? -> bail out */
8418 if(temp == 0x04) break;
8420 if(SiS_Pr->ChipType == SIS_740) {
8421 /* Power down LVDS output, PLL normal operation */
8422 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8425 SiS_SetCH701xForLCD(SiS_Pr);
8427 temp = SiS_GetCH701x(SiS_Pr,0x76);
8428 temp &= 0xfb; /* Reset PLL */
8429 SiS_SetCH701x(SiS_Pr,0x76,temp);
8430 SiS_LongDelay(SiS_Pr, 2);
8431 temp = SiS_GetCH701x(SiS_Pr,0x76);
8432 temp |= 0x04; /* PLL normal operation */
8433 SiS_SetCH701x(SiS_Pr,0x76,temp);
8434 if(SiS_Pr->ChipType == SIS_740) {
8435 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8437 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8439 SiS_LongDelay(SiS_Pr, 2);
8442 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8446 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8448 unsigned short temp;
8450 temp = SiS_GetCH701x(SiS_Pr,0x03);
8451 temp |= 0x80; /* Set datapath 1 to TV */
8452 temp &= 0xbf; /* Set datapath 2 to LVDS */
8453 SiS_SetCH701x(SiS_Pr,0x03,temp);
8455 if(SiS_Pr->ChipType == SIS_740) {
8457 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8458 temp &= 0xfb; /* Normal XCLK phase */
8459 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8461 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8463 temp = SiS_GetCH701x(SiS_Pr,0x64);
8464 temp |= 0x40; /* ? Bit not defined */
8465 SiS_SetCH701x(SiS_Pr,0x64,temp);
8467 temp = SiS_GetCH701x(SiS_Pr,0x03);
8468 temp &= 0x3f; /* D1 input to both LVDS and TV */
8469 SiS_SetCH701x(SiS_Pr,0x03,temp);
8471 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8472 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8473 SiS_LongDelay(SiS_Pr, 1);
8474 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8475 SiS_ChrontelResetDB(SiS_Pr);
8476 SiS_ChrontelDoSomething2(SiS_Pr);
8477 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8479 temp = SiS_GetCH701x(SiS_Pr,0x66);
8481 SiS_ChrontelResetDB(SiS_Pr);
8482 SiS_ChrontelDoSomething2(SiS_Pr);
8483 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8489 SiS_ChrontelResetDB(SiS_Pr);
8490 SiS_ChrontelDoSomething2(SiS_Pr);
8491 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8492 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8493 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8498 #endif /* 315 series */
8500 /*********************************************/
8501 /* MAIN: SET CRT2 REGISTER GROUP */
8502 /*********************************************/
8505 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8507 #ifdef CONFIG_FB_SIS_300
8508 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8510 unsigned short ModeIdIndex, RefreshRateTableIndex;
8512 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8514 if(!SiS_Pr->UseCustomMode) {
8515 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8520 /* Used for shifting CR33 */
8521 SiS_Pr->SiS_SelectCRT2Rate = 4;
8523 SiS_UnLockCRT2(SiS_Pr);
8525 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8527 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8529 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8530 SiS_DisableBridge(SiS_Pr);
8531 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8532 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8534 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8537 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8538 SiS_LockCRT2(SiS_Pr);
8539 SiS_DisplayOn(SiS_Pr);
8543 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8545 /* Set up Panel Link for LVDS and LCDA */
8546 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8547 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8548 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8549 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8550 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8553 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8554 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8557 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8559 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8561 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8562 #ifdef CONFIG_FB_SIS_315
8563 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8565 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8566 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8567 #ifdef CONFIG_FB_SIS_315
8568 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8570 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8572 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8574 /* For 301BDH (Panel link initialization): */
8575 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8577 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8578 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8579 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8582 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8588 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8590 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8592 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8594 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8595 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8596 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8597 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8598 #ifdef CONFIG_FB_SIS_315
8599 SiS_SetCH701xForLCD(SiS_Pr);
8603 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8604 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8611 #ifdef CONFIG_FB_SIS_300
8612 if(SiS_Pr->ChipType < SIS_315H) {
8613 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8614 if(SiS_Pr->SiS_UseOEM) {
8615 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8616 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8617 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8620 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8623 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8624 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8625 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8626 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8628 SiS_DisplayOn(SiS_Pr);
8634 #ifdef CONFIG_FB_SIS_315
8635 if(SiS_Pr->ChipType >= SIS_315H) {
8636 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8637 if(SiS_Pr->ChipType < SIS_661) {
8638 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8639 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8641 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8643 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8648 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8649 SiS_EnableBridge(SiS_Pr);
8652 SiS_DisplayOn(SiS_Pr);
8654 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8655 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8656 /* Disable LCD panel when using TV */
8657 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8659 /* Disable TV when using LCD */
8660 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8664 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8665 SiS_LockCRT2(SiS_Pr);
8672 /*********************************************/
8673 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8674 /*********************************************/
8677 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8679 /* Switch on LCD backlight on SiS30xLV */
8680 SiS_DDC2Delay(SiS_Pr,0xff00);
8681 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8682 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8683 SiS_WaitVBRetrace(SiS_Pr);
8685 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8686 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8691 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8693 /* Switch off LCD backlight on SiS30xLV */
8694 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8695 SiS_DDC2Delay(SiS_Pr,0xff00);
8698 /*********************************************/
8699 /* DDC RELATED FUNCTIONS */
8700 /*********************************************/
8703 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8705 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8706 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8707 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8708 SiS_Pr->SiS_DDC_NData &= 0x0f;
8709 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8713 #ifdef CONFIG_FB_SIS_300
8714 static unsigned char *
8715 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8718 unsigned short tempah,temp;
8719 unsigned char *mydataptr;
8721 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8722 mydataptr = dataptr;
8724 if(!num) return mydataptr;
8726 SiS_SetStop(SiS_Pr);
8727 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8729 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8730 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8731 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8732 if(temp) continue; /* (ERROR: no ack) */
8733 tempah = *mydataptr++;
8734 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8735 if(temp) continue; /* (ERROR: no ack) */
8736 for(j=0; j<num; j++) {
8737 tempah = *mydataptr++;
8738 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8742 if(SiS_SetStop(SiS_Pr)) continue;
8749 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8751 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8752 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8753 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8754 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8755 SiS_SetupDDCN(SiS_Pr);
8757 SiS_SetSwitchDDC2(SiS_Pr);
8760 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8761 if(!dataptr) return false;
8767 /* The Chrontel 700x is connected to the 630/730 via
8768 * the 630/730's DDC/I2C port.
8770 * On 630(S)T chipset, the index changed from 0x11 to
8771 * 0x0a, possibly for working around the DDC problems
8775 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8777 unsigned short temp, i;
8779 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8781 SiS_SetStop(SiS_Pr);
8782 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8784 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8785 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8786 if(temp) continue; /* (ERROR: no ack) */
8787 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
8788 if(temp) continue; /* (ERROR: no ack) */
8789 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
8790 if(temp) continue; /* (ERROR: no ack) */
8791 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
8792 SiS_Pr->SiS_ChrontelInit = 1;
8798 /* Write to Chrontel 700x */
8800 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8802 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8804 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8806 if(!(SiS_Pr->SiS_ChrontelInit)) {
8807 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8808 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8809 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8810 SiS_SetupDDCN(SiS_Pr);
8813 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
8814 (!(SiS_Pr->SiS_ChrontelInit)) ) {
8815 SiS_Pr->SiS_DDC_Index = 0x0a;
8816 SiS_Pr->SiS_DDC_Data = 0x80;
8817 SiS_Pr->SiS_DDC_Clk = 0x40;
8818 SiS_SetupDDCN(SiS_Pr);
8820 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
8824 /* Write to Chrontel 701x */
8825 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
8827 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8829 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8830 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8831 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8832 SiS_SetupDDCN(SiS_Pr);
8833 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8834 SiS_SetChReg(SiS_Pr, reg, val, 0);
8839 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8841 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8842 SiS_SetCH700x(SiS_Pr, reg, val);
8844 SiS_SetCH701x(SiS_Pr, reg, val);
8847 static unsigned short
8848 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
8850 unsigned short tempah, temp, i;
8852 for(i=0; i<20; i++) { /* Do 20 attempts to read */
8854 SiS_SetStop(SiS_Pr);
8855 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8857 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8858 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8859 if(temp) continue; /* (ERROR: no ack) */
8860 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
8861 if(temp) continue; /* (ERROR: no ack) */
8862 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
8863 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
8864 if(temp) continue; /* (ERROR: no ack) */
8865 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
8866 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
8867 SiS_Pr->SiS_ChrontelInit = 1;
8873 /* Read from Chrontel 700x */
8874 /* Parameter is [Register no (S7-S0)] */
8876 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8878 unsigned short result;
8880 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8882 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8884 if(!(SiS_Pr->SiS_ChrontelInit)) {
8885 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8886 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8887 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8888 SiS_SetupDDCN(SiS_Pr);
8891 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8893 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
8894 (!SiS_Pr->SiS_ChrontelInit) ) {
8896 SiS_Pr->SiS_DDC_Index = 0x0a;
8897 SiS_Pr->SiS_DDC_Data = 0x80;
8898 SiS_Pr->SiS_DDC_Clk = 0x40;
8899 SiS_SetupDDCN(SiS_Pr);
8901 result = SiS_GetChReg(SiS_Pr,0x80);
8906 /* Read from Chrontel 701x */
8907 /* Parameter is [Register no (S7-S0)] */
8909 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8911 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8912 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8913 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8914 SiS_SetupDDCN(SiS_Pr);
8915 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8917 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8919 return SiS_GetChReg(SiS_Pr,0);
8922 /* Read from Chrontel 70xx */
8923 /* Parameter is [Register no (S7-S0)] */
8926 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8928 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8929 return SiS_GetCH700x(SiS_Pr, tempbx);
8931 return SiS_GetCH701x(SiS_Pr, tempbx);
8935 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
8936 unsigned char myor, unsigned short myand)
8938 unsigned short tempbl;
8940 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
8941 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
8944 /* Our own DDC functions */
8947 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
8948 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
8949 unsigned int VBFlags2)
8951 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
8952 unsigned char flag, cr32;
8953 unsigned short temp = 0, myadaptnum = adaptnum;
8956 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
8957 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
8960 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
8962 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
8964 SiS_Pr->SiS_DDC_SecAddr = 0;
8965 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
8966 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
8967 SiS_Pr->SiS_DDC_Index = 0x11;
8970 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
8973 if(VBFlags2 & VB2_SISBRIDGE) {
8974 if(myadaptnum == 0) {
8975 if(!(cr32 & 0x20)) {
8977 if(!(cr32 & 0x10)) {
8979 if(!(cr32 & 0x08)) {
8988 if(VGAEngine == SIS_300_VGA) { /* 300 series */
8990 if(myadaptnum != 0) {
8992 if(VBFlags2 & VB2_SISBRIDGE) {
8993 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
8994 SiS_Pr->SiS_DDC_Index = 0x0f;
8998 if(!(VBFlags2 & VB2_301)) {
8999 if((cr32 & 0x80) && (checkcr32)) {
9000 if(myadaptnum >= 1) {
9001 if(!(cr32 & 0x08)) {
9003 if(!(cr32 & 0x10)) return 0xFFFF;
9009 temp = 4 - (myadaptnum * 2);
9012 } else { /* 315/330 series */
9014 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9016 if(VBFlags2 & VB2_SISBRIDGE) {
9017 if(myadaptnum == 2) {
9022 if(myadaptnum == 1) {
9024 if(VBFlags2 & VB2_SISBRIDGE) {
9025 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9026 SiS_Pr->SiS_DDC_Index = 0x0f;
9030 if((cr32 & 0x80) && (checkcr32)) {
9031 if(myadaptnum >= 1) {
9032 if(!(cr32 & 0x08)) {
9034 if(!(cr32 & 0x10)) return 0xFFFF;
9040 if(myadaptnum == 1) {
9042 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9048 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9049 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9051 SiS_SetupDDCN(SiS_Pr);
9056 static unsigned short
9057 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9059 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9060 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9063 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9069 static unsigned short
9070 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9072 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9073 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9079 static unsigned short
9080 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9082 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9083 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9088 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9090 SiS_SetSCLKLow(SiS_Pr);
9092 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9093 SiS_Pr->SiS_DDC_Index,
9094 SiS_Pr->SiS_DDC_NData,
9095 SiS_Pr->SiS_DDC_Data);
9097 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9098 SiS_Pr->SiS_DDC_Index,
9099 SiS_Pr->SiS_DDC_NData,
9102 SiS_SetSCLKHigh(SiS_Pr);
9105 static unsigned short
9106 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9108 unsigned char mask, value;
9109 unsigned short temp, ret=0;
9110 bool failed = false;
9112 SiS_SetSwitchDDC2(SiS_Pr);
9113 if(SiS_PrepareDDC(SiS_Pr)) {
9114 SiS_SetStop(SiS_Pr);
9119 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9120 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9121 SiS_SendACK(SiS_Pr, 0);
9131 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9132 SiS_SendACK(SiS_Pr, 1);
9134 if(temp == value) ret = 0;
9137 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9138 if(temp == 0x30) ret = 0;
9142 SiS_SetStop(SiS_Pr);
9148 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9150 unsigned short flag;
9153 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9154 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9155 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9156 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9157 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9158 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9159 if(!(flag & 0x1a)) flag = 0;
9165 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9167 unsigned short flag, length, i;
9168 unsigned char chksum,gotcha;
9170 if(DDCdatatype > 4) return 0xFFFF;
9173 SiS_SetSwitchDDC2(SiS_Pr);
9174 if(!(SiS_PrepareDDC(SiS_Pr))) {
9176 if(DDCdatatype != 1) length = 255;
9179 for(i=0; i<length; i++) {
9180 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9181 chksum += buffer[i];
9182 gotcha |= buffer[i];
9183 SiS_SendACK(SiS_Pr, 0);
9185 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9186 chksum += buffer[i];
9187 SiS_SendACK(SiS_Pr, 1);
9188 if(gotcha) flag = (unsigned short)chksum;
9193 SiS_SetStop(SiS_Pr);
9197 /* Our private DDC functions
9199 It complies somewhat with the corresponding VESA function
9200 in arguments and return values.
9202 Since this is probably called before the mode is changed,
9203 we use our pre-detected pSiS-values instead of SiS_Pr as
9204 regards chipset and video bridge type.
9207 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9208 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9209 LCDA is CRT1, but DDC is read from CRT2 port.
9210 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9211 buffer: ptr to 256 data bytes which will be filled with read data.
9213 Returns 0xFFFF if error, otherwise
9214 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9215 if DDCdatatype = 0: Returns supported DDC modes
9219 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9220 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9221 unsigned int VBFlags2)
9223 unsigned char sr1f, cr17=1;
9224 unsigned short result;
9232 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9235 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9238 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9239 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9240 if(VGAEngine == SIS_300_VGA) {
9241 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9243 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9244 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9245 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9248 if((sr1f) || (!cr17)) {
9249 SiS_WaitRetrace1(SiS_Pr);
9250 SiS_WaitRetrace1(SiS_Pr);
9251 SiS_WaitRetrace1(SiS_Pr);
9252 SiS_WaitRetrace1(SiS_Pr);
9255 if(DDCdatatype == 0) {
9256 result = SiS_ProbeDDC(SiS_Pr);
9258 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9259 if((!result) && (DDCdatatype == 1)) {
9260 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9261 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9262 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9263 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9264 (buffer[0x12] == 1)) {
9265 if(!SiS_Pr->DDCPortMixup) {
9267 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9269 if(buffer[0x14] & 0x80) result = 0xFFFE;
9275 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9276 if(VGAEngine == SIS_300_VGA) {
9277 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9282 /* Generic I2C functions for Chrontel & DDC --------- */
9285 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9287 SiS_SetSCLKHigh(SiS_Pr);
9288 SiS_WaitRetrace1(SiS_Pr);
9290 SiS_SetSCLKLow(SiS_Pr);
9291 SiS_WaitRetrace1(SiS_Pr);
9295 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9297 SiS_WaitRetrace1(SiS_Pr);
9298 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9301 /* Set I2C start condition */
9302 /* This is done by a SD high-to-low transition while SC is high */
9303 static unsigned short
9304 SiS_SetStart(struct SiS_Private *SiS_Pr)
9306 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9307 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9308 SiS_Pr->SiS_DDC_Index,
9309 SiS_Pr->SiS_DDC_NData,
9310 SiS_Pr->SiS_DDC_Data); /* SD->high */
9311 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9312 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9313 SiS_Pr->SiS_DDC_Index,
9314 SiS_Pr->SiS_DDC_NData,
9315 0x00); /* SD->low = start condition */
9316 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9320 /* Set I2C stop condition */
9321 /* This is done by a SD low-to-high transition while SC is high */
9322 static unsigned short
9323 SiS_SetStop(struct SiS_Private *SiS_Pr)
9325 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9326 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9327 SiS_Pr->SiS_DDC_Index,
9328 SiS_Pr->SiS_DDC_NData,
9329 0x00); /* SD->low */
9330 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9331 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9332 SiS_Pr->SiS_DDC_Index,
9333 SiS_Pr->SiS_DDC_NData,
9334 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9335 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9339 /* Write 8 bits of data */
9340 static unsigned short
9341 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9343 unsigned short i,flag,temp;
9346 for(i = 0; i < 8; i++) {
9347 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9349 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9350 SiS_Pr->SiS_DDC_Index,
9351 SiS_Pr->SiS_DDC_NData,
9352 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9354 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9355 SiS_Pr->SiS_DDC_Index,
9356 SiS_Pr->SiS_DDC_NData,
9357 0x00); /* Write bit (0) to SD */
9359 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9362 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9366 static unsigned short
9367 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9369 unsigned short i, temp, getdata;
9372 for(i = 0; i < 8; i++) {
9374 SiS_SetSCLKLow(SiS_Pr);
9375 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9376 SiS_Pr->SiS_DDC_Index,
9377 SiS_Pr->SiS_DDC_NData,
9378 SiS_Pr->SiS_DDC_Data);
9379 SiS_SetSCLKHigh(SiS_Pr);
9380 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9381 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9386 static unsigned short
9387 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9389 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9390 SiS_Pr->SiS_DDC_Index,
9391 SiS_Pr->SiS_DDC_NClk,
9392 0x00); /* SetSCLKLow() */
9393 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9397 static unsigned short
9398 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9400 unsigned short temp, watchdog=1000;
9402 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9403 SiS_Pr->SiS_DDC_Index,
9404 SiS_Pr->SiS_DDC_NClk,
9405 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9407 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9408 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9412 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9416 /* Check I2C acknowledge */
9417 /* Returns 0 if ack ok, non-0 if ack not ok */
9418 static unsigned short
9419 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9421 unsigned short tempah;
9423 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9424 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9425 SiS_Pr->SiS_DDC_Index,
9426 SiS_Pr->SiS_DDC_NData,
9427 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9428 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9429 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9430 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9431 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9435 /* End of I2C functions ----------------------- */
9438 /* =============== SiS 315/330 O.E.M. ================= */
9440 #ifdef CONFIG_FB_SIS_315
9442 static unsigned short
9443 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9445 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9446 unsigned short romptr;
9448 if(SiS_Pr->ChipType < SIS_330) {
9449 romptr = SISGETROMW(0x128);
9450 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9451 romptr = SISGETROMW(0x12a);
9453 romptr = SISGETROMW(0x1a8);
9454 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9455 romptr = SISGETROMW(0x1aa);
9460 static unsigned short
9461 GetLCDromptr(struct SiS_Private *SiS_Pr)
9463 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9464 unsigned short romptr;
9466 if(SiS_Pr->ChipType < SIS_330) {
9467 romptr = SISGETROMW(0x120);
9468 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9469 romptr = SISGETROMW(0x122);
9471 romptr = SISGETROMW(0x1a0);
9472 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9473 romptr = SISGETROMW(0x1a2);
9478 static unsigned short
9479 GetTVromptr(struct SiS_Private *SiS_Pr)
9481 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9482 unsigned short romptr;
9484 if(SiS_Pr->ChipType < SIS_330) {
9485 romptr = SISGETROMW(0x114);
9486 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9487 romptr = SISGETROMW(0x11a);
9489 romptr = SISGETROMW(0x194);
9490 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9491 romptr = SISGETROMW(0x19a);
9496 static unsigned short
9497 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9499 unsigned short index;
9501 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9502 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9503 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9506 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9507 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9513 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9514 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9515 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9516 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9517 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9519 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9523 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9524 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9528 static unsigned short
9529 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9531 unsigned short index;
9533 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9534 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9535 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9539 static unsigned short
9540 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9542 unsigned short index;
9545 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9546 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9548 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9552 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9553 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9561 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9563 unsigned short index = 0, temp = 0;
9565 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9566 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9567 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9568 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9569 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9571 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9572 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9575 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9576 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9577 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9583 return (unsigned int)(index | (temp << 16));
9587 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9589 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9594 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9596 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9601 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9605 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9606 if(SiS_Pr->SiS_ROMNew) {
9607 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9608 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9609 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9610 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9612 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9613 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9614 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9615 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9618 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9624 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9626 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9627 unsigned short delay=0,index,myindex,temp,romptr=0;
9628 bool dochiptest = true;
9630 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9631 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9633 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9636 /* Find delay (from ROM, internal tables, PCI subsystem) */
9638 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9640 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9641 romptr = GetRAMDACromptr(SiS_Pr);
9643 if(romptr) delay = ROMAddr[romptr];
9646 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9649 } else if(IS_SIS740) {
9654 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9659 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9661 bool gotitfrompci = false;
9663 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9665 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9666 if(SiS_Pr->PDC != -1) {
9667 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9668 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9672 if(SiS_Pr->PDCA != -1) {
9673 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9674 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9681 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9682 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9684 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9687 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9690 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9692 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9695 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9696 if(IS_SIS740) delay = 0x01;
9699 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9704 /* This is a piece of typical SiS crap: They code the OEM LCD
9705 * delay into the code, at no defined place in the BIOS.
9706 * We now have to start doing a PCI subsystem check here.
9709 switch(SiS_Pr->SiS_CustomT) {
9710 case CUT_COMPAQ1280:
9711 case CUT_COMPAQ12802:
9712 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9713 gotitfrompci = true;
9719 case CUT_CLEVO14002:
9720 gotitfrompci = true;
9725 case CUT_CLEVO10242:
9726 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9727 gotitfrompci = true;
9730 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9736 /* Could we find it through the PCI ID? If no, use ROM or table */
9740 index = GetLCDPtrIndexBIOS(SiS_Pr);
9741 myindex = GetLCDPtrIndex(SiS_Pr);
9743 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9745 if(SiS_IsNotM650orLater(SiS_Pr)) {
9747 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9748 /* Always use the second pointer on 650; some BIOSes */
9749 /* still carry old 301 data at the first location */
9750 /* romptr = SISGETROMW(0x120); */
9751 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9752 romptr = SISGETROMW(0x122);
9754 delay = ROMAddr[(romptr + index)];
9756 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9761 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
9762 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
9763 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
9767 } else if(SiS_Pr->SiS_UseROM &&
9768 (!(SiS_Pr->SiS_ROMNew)) &&
9769 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
9770 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
9771 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
9772 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
9773 ((romptr = GetLCDromptr(SiS_Pr)))) {
9775 /* Data for 1280x1024 wrong in 301B BIOS */
9776 /* Data for 1600x1200 wrong in 301C BIOS */
9777 delay = ROMAddr[(romptr + index)];
9779 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9781 if(IS_SIS740) delay = 0x03;
9786 delay = SiS310_LCDDelayCompensation_301[myindex];
9787 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9788 if(IS_SIS740) delay = 0x01;
9789 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
9790 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9791 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9792 if(IS_SIS740) delay = 0x01; /* ? */
9794 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
9795 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9796 if(IS_SIS740) delay = 0x01;
9797 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
9802 } /* got it from PCI */
9804 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9805 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
9809 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
9811 index = GetTVPtrIndex(SiS_Pr);
9813 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9815 if(SiS_IsNotM650orLater(SiS_Pr)) {
9817 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9818 /* Always use the second pointer on 650; some BIOSes */
9819 /* still carry old 301 data at the first location */
9820 /* romptr = SISGETROMW(0x114); */
9821 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9822 romptr = SISGETROMW(0x11a);
9824 delay = ROMAddr[romptr + index];
9828 delay = SiS310_TVDelayCompensation_301B[index];
9834 switch(SiS_Pr->SiS_CustomT) {
9835 case CUT_COMPAQ1280:
9836 case CUT_COMPAQ12802:
9838 case CUT_CLEVO14002:
9843 case CUT_CLEVO10242:
9848 delay = SiS310_TVDelayCompensation_651301LV[index];
9849 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
9850 delay = SiS310_TVDelayCompensation_651302LV[index];
9855 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9857 romptr = GetTVromptr(SiS_Pr);
9859 delay = ROMAddr[romptr + index];
9861 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9863 delay = SiS310_TVDelayCompensation_LVDS[index];
9867 delay = SiS310_TVDelayCompensation_301[index];
9868 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9870 delay = SiS310_TVDelayCompensation_740301B[index];
9871 /* LV: use 301 data? BIOS bug? */
9873 delay = SiS310_TVDelayCompensation_301B[index];
9874 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
9880 if(SiS_LCDAEnabled(SiS_Pr)) {
9889 if(SiS_Pr->SiS_VBType & VB_SISVB) {
9891 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
9893 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
9894 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
9897 } else if(temp == 6) {
9900 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
9903 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9907 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9913 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9914 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9916 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
9918 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
9920 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9929 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
9931 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9932 unsigned short index,temp,temp1,romptr=0;
9934 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
9937 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
9939 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
9941 temp = GetTVPtrIndex(SiS_Pr);
9942 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9945 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
9946 if(SiS_Pr->ChipType >= SIS_661) {
9947 temp1 = GetOEMTVPtr661(SiS_Pr);
9949 romptr = SISGETROMW(0x260);
9950 if(SiS_Pr->ChipType >= SIS_760) {
9951 romptr = SISGETROMW(0x360);
9953 } else if(SiS_Pr->ChipType >= SIS_330) {
9954 romptr = SISGETROMW(0x192);
9956 romptr = SISGETROMW(0x112);
9962 temp = ROMAddr[romptr + temp1 + index];
9964 temp = SiS310_TVAntiFlick1[temp][index];
9968 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
9972 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
9974 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9975 unsigned short index,temp,temp1,romptr=0;
9977 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9980 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
9982 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
9984 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
9985 if(SiS_Pr->ChipType >= SIS_661) {
9986 romptr = SISGETROMW(0x26c);
9987 if(SiS_Pr->ChipType >= SIS_760) {
9988 romptr = SISGETROMW(0x36c);
9990 temp1 = GetOEMTVPtr661(SiS_Pr);
9992 } else if(SiS_Pr->ChipType >= SIS_330) {
9993 romptr = SISGETROMW(0x1a4);
9995 romptr = SISGETROMW(0x124);
10001 temp = ROMAddr[romptr + temp1 + index];
10003 temp = SiS310_TVEdge1[temp][index];
10006 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10010 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10012 unsigned short index, temp, i, j;
10014 if(ModeNo <= 0x13) {
10015 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10017 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10020 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10022 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10023 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10024 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10025 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10027 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10028 for(i=0x35, j=0; i<=0x38; i++, j++) {
10029 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10031 for(i=0x48; i<=0x4A; i++, j++) {
10032 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10035 for(i=0x35, j=0; i<=0x38; i++, j++) {
10036 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10042 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10044 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10045 unsigned short index,temp,i,j,resinfo,romptr=0;
10046 unsigned int lindex;
10048 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10050 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10051 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10053 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10054 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10056 for(j=0, i=0x31; i<=0x34; i++, j++) {
10057 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10062 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10063 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10066 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10068 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10071 temp = GetTVPtrIndex(SiS_Pr);
10072 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10073 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10075 if(SiS_Pr->SiS_UseROM) {
10076 romptr = SISGETROMW(0x116);
10077 if(SiS_Pr->ChipType >= SIS_330) {
10078 romptr = SISGETROMW(0x196);
10080 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10081 romptr = SISGETROMW(0x11c);
10082 if(SiS_Pr->ChipType >= SIS_330) {
10083 romptr = SISGETROMW(0x19c);
10085 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10086 romptr = SISGETROMW(0x116);
10087 if(SiS_Pr->ChipType >= SIS_330) {
10088 romptr = SISGETROMW(0x196);
10094 romptr += (temp << 2);
10095 for(j=0, i=0x31; i<=0x34; i++, j++) {
10096 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10100 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10101 for(j=0, i=0x31; i<=0x34; i++, j++) {
10102 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10103 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10104 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10105 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10107 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10111 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10112 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10113 if((resinfo == SIS_RI_640x480) ||
10114 (resinfo == SIS_RI_800x600)) {
10115 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10116 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10117 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10118 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10119 } else if(resinfo == SIS_RI_1024x768) {
10120 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10121 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10122 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10123 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10130 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10131 unsigned short ModeIdIndex, unsigned short RTI)
10133 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10134 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10136 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10139 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10140 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10142 if(SiS_Pr->SiS_ROMNew) {
10143 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10144 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10145 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10147 if(SiS_Pr->UseCustomMode) {
10148 index = SiS_Pr->CSRClock;
10149 } else if(ModeNo > 0x13) {
10150 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10151 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10153 if(index < 25) index = 25;
10154 index = ((index / 25) - 1) << 1;
10155 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10158 romptr = SISGETROMW(0x104);
10159 delay = ROMAddr[romptr + index];
10160 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10161 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10162 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10164 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10165 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10171 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10173 if(SiS_Pr->UseCustomMode) delay = 0x04;
10174 else if(ModeNo <= 0x13) delay = 0x04;
10175 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10176 delay |= (delay << 8);
10178 if(SiS_Pr->ChipType >= XGI_20) {
10181 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10184 if(SiS_Pr->SiS_XGIROM) {
10185 index = GetTVPtrIndex(SiS_Pr);
10186 if((romptr = SISGETROMW(0x35e))) {
10187 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10188 delay |= (delay << 8);
10192 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10193 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10199 } else if(SiS_Pr->ChipType >= SIS_340) {
10202 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10205 /* TODO (eventually) */
10207 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10211 index = GetOEMTVPtr661(SiS_Pr);
10212 if(SiS_Pr->SiS_ROMNew) {
10213 romptr = SISGETROMW(0x106);
10214 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10215 delay = ROMAddr[romptr + index];
10218 if(index > 3) delay = 0;
10221 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10223 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10225 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10226 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10228 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10230 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10231 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10232 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10236 /* TMDS: Set our own, since BIOS has no idea */
10237 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10238 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10239 switch(SiS_Pr->SiS_LCDResInfo) {
10240 case Panel_1024x768: delay = 0x0008; break;
10241 case Panel_1280x720: delay = 0x0004; break;
10242 case Panel_1280x768:
10243 case Panel_1280x768_2:delay = 0x0004; break;
10244 case Panel_1280x800:
10245 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10246 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10247 case Panel_1280x1024: delay = 0x1e04; break;
10248 case Panel_1400x1050: delay = 0x0004; break;
10249 case Panel_1600x1200: delay = 0x0400; break;
10250 case Panel_1680x1050: delay = 0x0e04; break;
10252 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10254 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10256 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10258 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10266 /* Override by detected or user-set values */
10267 /* (but only if, for some reason, we can't read value from BIOS) */
10268 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10269 delay = SiS_Pr->PDC & 0x1f;
10271 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10272 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10279 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10281 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10282 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10284 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10285 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10290 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10292 unsigned short infoflag;
10293 unsigned char temp;
10295 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10297 if(ModeNo <= 0x13) {
10298 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10299 } else if(SiS_Pr->UseCustomMode) {
10300 infoflag = SiS_Pr->CInfoFlag;
10302 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10305 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10306 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10311 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10312 temp = (infoflag >> 6) | 0x0c;
10313 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10315 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10317 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10320 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10322 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10324 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10325 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10327 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10334 SetPanelParms661(struct SiS_Private *SiS_Pr)
10336 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10337 unsigned short romptr, temp1, temp2;
10339 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10340 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10343 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10344 if(SiS_Pr->LVDSHL != -1) {
10345 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10349 if(SiS_Pr->SiS_ROMNew) {
10351 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10352 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10353 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10355 if(SiS_Pr->LVDSHL != -1) {
10359 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10361 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10362 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10363 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10371 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10373 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10374 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10375 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10376 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10377 SetPanelParms661(SiS_Pr);
10380 SetDelayComp(SiS_Pr,ModeNo);
10383 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10384 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10385 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10386 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10387 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10388 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10394 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10395 unsigned short ModeIdIndex, unsigned short RRTI)
10397 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10399 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10401 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10402 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10403 SetPanelParms661(SiS_Pr);
10406 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10407 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10408 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10409 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10410 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10411 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10418 * This finalizes some CRT2 registers for the very panel used.
10419 * If we have a backup if these registers, we use it; otherwise
10420 * we set the register according to most BIOSes. However, this
10421 * function looks quite different in every BIOS, so you better
10422 * pray that we have a backup...
10425 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10427 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10428 unsigned short resinfo,modeflag;
10430 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10431 if(SiS_Pr->SiS_ROMNew) return;
10433 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10434 if(SiS_Pr->LVDSHL != -1) {
10435 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10439 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10440 if(SiS_Pr->UseCustomMode) return;
10442 switch(SiS_Pr->SiS_CustomT) {
10443 case CUT_COMPAQ1280:
10444 case CUT_COMPAQ12802:
10445 case CUT_CLEVO1400:
10446 case CUT_CLEVO14002:
10450 if(ModeNo <= 0x13) {
10451 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10452 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10454 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10455 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10459 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10460 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10461 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10463 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10468 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10469 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10470 /* Maybe all panels? */
10471 if(SiS_Pr->LVDSHL == -1) {
10472 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10478 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10479 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10480 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10481 if(SiS_Pr->LVDSHL == -1) {
10482 /* Maybe all panels? */
10483 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10485 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10486 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10488 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10489 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10490 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10491 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10499 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10500 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10501 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10502 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10504 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10506 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10508 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10509 if(SiS_Pr->LVDSHL == -1) {
10510 /* Maybe ACER only? */
10511 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10514 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10515 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10516 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10517 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10518 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10519 if(tempch == 0x03) {
10520 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10521 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10522 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10523 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10525 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10526 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10527 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10528 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10529 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10530 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10531 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10532 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10533 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10534 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10535 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10536 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10537 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10538 if(ModeNo <= 0x13) {
10539 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10540 if((resinfo == 0) || (resinfo == 2)) return;
10541 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10542 if((resinfo == 1) || (resinfo == 3)) return;
10544 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10545 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10546 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10548 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10550 temp = tempbx & 0xff;
10551 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10552 temp = (tempbx >> 8) & 0x03;
10553 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10556 } else if(ModeNo <= 0x13) {
10558 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10559 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10560 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10561 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10563 if(!(modeflag & HalfDCLK)) {
10564 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10565 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10566 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10567 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10568 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10569 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10570 if(ModeNo == 0x12) {
10573 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10574 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10575 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10576 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10577 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10578 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10581 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10582 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10585 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10593 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10597 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10598 tempbx = (tempbh << 8) | tempbl;
10599 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10600 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10601 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10604 if(tempbx > 770) tempbx = 770;
10605 if(SiS_Pr->SiS_VGAVDE < 600) {
10606 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10607 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10608 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10614 temp = tempbx & 0xff;
10615 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10616 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10617 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10624 /* ================= SiS 300 O.E.M. ================== */
10626 #ifdef CONFIG_FB_SIS_300
10629 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10630 unsigned short RefTabIndex)
10632 unsigned short crt2crtc=0, modeflag, myindex=0;
10633 unsigned char temp;
10636 if(ModeNo <= 0x13) {
10637 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10638 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10640 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10641 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10646 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10647 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10650 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10651 if(modeflag & HalfDCLK) myindex = 1;
10653 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10654 for(i=0; i<7; i++) {
10655 if(barco_p1[myindex][crt2crtc][i][0]) {
10656 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10657 barco_p1[myindex][crt2crtc][i][0],
10658 barco_p1[myindex][crt2crtc][i][2],
10659 barco_p1[myindex][crt2crtc][i][1]);
10663 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10665 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10667 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10672 static unsigned short
10673 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10675 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10676 unsigned short tempbx=0,romptr=0;
10677 static const unsigned char customtable300[] = {
10678 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10679 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10681 static const unsigned char customtable630[] = {
10682 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10683 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10686 if(SiS_Pr->ChipType == SIS_300) {
10688 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10689 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10691 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10692 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10693 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10695 if(SiS_Pr->SiS_UseROM) {
10696 if(ROMAddr[0x235] & 0x80) {
10697 tempbx = SiS_Pr->SiS_LCDTypeInfo;
10699 romptr = SISGETROMW(0x255);
10700 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10701 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10702 if(tempbx == 0xFF) return 0xFFFF;
10705 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10712 if(SiS_Pr->SiS_UseROM) {
10713 romptr = SISGETROMW(0x255);
10714 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10715 else tempbx = 0xff;
10717 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10719 if(tempbx == 0xFF) return 0xFFFF;
10721 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10722 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10725 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10726 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10727 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10735 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10737 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10738 unsigned short index,temp,romptr=0;
10740 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10742 if(SiS_Pr->SiS_UseROM) {
10743 if(!(ROMAddr[0x237] & 0x01)) return;
10744 if(!(ROMAddr[0x237] & 0x02)) return;
10745 romptr = SISGETROMW(0x24b);
10748 /* The Panel Compensation Delay should be set according to tables
10749 * here. Unfortunately, various BIOS versions don't care about
10750 * a uniform way using eg. ROM byte 0x220, but use different
10751 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10752 * Thus we don't set this if the user selected a custom pdc or if
10753 * we otherwise detected a valid pdc.
10755 if(SiS_Pr->PDC != -1) return;
10757 temp = GetOEMLCDPtr(SiS_Pr, 0);
10759 if(SiS_Pr->UseCustomMode)
10762 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
10764 if(SiS_Pr->ChipType != SIS_300) {
10766 romptr += (temp * 2);
10767 romptr = SISGETROMW(romptr);
10769 temp = ROMAddr[romptr];
10771 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10772 temp = SiS300_OEMLCDDelay2[temp][index];
10774 temp = SiS300_OEMLCDDelay3[temp][index];
10778 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
10780 romptr += (temp * 2);
10781 romptr = SISGETROMW(romptr);
10783 temp = ROMAddr[romptr];
10785 temp = SiS300_OEMLCDDelay5[temp][index];
10788 if(SiS_Pr->SiS_UseROM) {
10789 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
10791 romptr += (temp * 2);
10792 romptr = SISGETROMW(romptr);
10794 temp = ROMAddr[romptr];
10796 temp = SiS300_OEMLCDDelay4[temp][index];
10799 temp = SiS300_OEMLCDDelay4[temp][index];
10804 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
10808 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10810 #if 0 /* Unfinished; Data table missing */
10811 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10812 unsigned short index,temp;
10814 if((SiS_Pr->SiS_UseROM) {
10815 if(!(ROMAddr[0x237] & 0x01)) return;
10816 if(!(ROMAddr[0x237] & 0x04)) return;
10817 /* No rom pointer in BIOS header! */
10820 temp = GetOEMLCDPtr(SiS_Pr, 1);
10821 if(temp == 0xFFFF) return;
10823 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
10824 for(i=0x14, j=0; i<=0x17; i++, j++) {
10825 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
10827 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
10829 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
10830 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
10831 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
10832 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
10833 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
10834 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
10839 static unsigned short
10840 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
10842 unsigned short index;
10845 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
10846 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10847 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
10848 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
10849 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10851 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
10852 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10858 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10860 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10861 unsigned short index,temp,romptr=0;
10863 if(SiS_Pr->SiS_UseROM) {
10864 if(!(ROMAddr[0x238] & 0x01)) return;
10865 if(!(ROMAddr[0x238] & 0x02)) return;
10866 romptr = SISGETROMW(0x241);
10869 temp = GetOEMTVPtr(SiS_Pr);
10871 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
10874 romptr += (temp * 2);
10875 romptr = SISGETROMW(romptr);
10877 temp = ROMAddr[romptr];
10879 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10880 temp = SiS300_OEMTVDelay301[temp][index];
10882 temp = SiS300_OEMTVDelayLVDS[temp][index];
10886 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
10890 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10892 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10893 unsigned short index,temp,romptr=0;
10895 if(SiS_Pr->SiS_UseROM) {
10896 if(!(ROMAddr[0x238] & 0x01)) return;
10897 if(!(ROMAddr[0x238] & 0x04)) return;
10898 romptr = SISGETROMW(0x243);
10901 temp = GetOEMTVPtr(SiS_Pr);
10903 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
10906 romptr += (temp * 2);
10907 romptr = SISGETROMW(romptr);
10909 temp = ROMAddr[romptr];
10911 temp = SiS300_OEMTVFlicker[temp][index];
10914 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
10918 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10920 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10921 unsigned short index,i,j,temp,romptr=0;
10923 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
10925 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
10927 if(SiS_Pr->SiS_UseROM) {
10928 if(!(ROMAddr[0x238] & 0x01)) return;
10929 if(!(ROMAddr[0x238] & 0x08)) return;
10930 romptr = SISGETROMW(0x245);
10933 temp = GetOEMTVPtr(SiS_Pr);
10935 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
10937 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10938 for(i=0x31, j=0; i<=0x34; i++, j++) {
10939 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
10943 romptr += (temp * 2);
10944 romptr = SISGETROMW(romptr);
10945 romptr += (index * 4);
10946 for(i=0x31, j=0; i<=0x34; i++, j++) {
10947 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10950 for(i=0x31, j=0; i<=0x34; i++, j++) {
10951 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
10958 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10960 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10961 unsigned short index,temp,i,j,romptr=0;
10963 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
10965 if(SiS_Pr->SiS_UseROM) {
10966 if(!(ROMAddr[0x238] & 0x01)) return;
10967 if(!(ROMAddr[0x238] & 0x10)) return;
10968 romptr = SISGETROMW(0x247);
10971 temp = GetOEMTVPtr(SiS_Pr);
10973 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
10974 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
10975 /* NTSCJ uses NTSC filters */
10977 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
10979 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10980 for(i=0x35, j=0; i<=0x38; i++, j++) {
10981 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
10983 for(i=0x48; i<=0x4A; i++, j++) {
10984 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
10987 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
10988 romptr += (temp * 2);
10989 romptr = SISGETROMW(romptr);
10990 romptr += (index * 4);
10991 for(i=0x35, j=0; i<=0x38; i++, j++) {
10992 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10995 for(i=0x35, j=0; i<=0x38; i++, j++) {
10996 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11002 static unsigned short
11003 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11005 unsigned short ModeIdIndex;
11006 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11008 if(*ModeNo <= 5) *ModeNo |= 1;
11010 for(ModeIdIndex=0; ; ModeIdIndex++) {
11011 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11012 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11015 if(*ModeNo != 0x07) {
11016 if(*ModeNo > 0x03) return ModeIdIndex;
11017 if(VGAINFO & 0x80) return ModeIdIndex;
11021 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11022 /* else 350 lines */
11023 return ModeIdIndex;
11027 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11028 unsigned short RefTableIndex)
11030 unsigned short OEMModeIdIndex = 0;
11032 if(!SiS_Pr->UseCustomMode) {
11033 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11034 if(!(OEMModeIdIndex)) return;
11037 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11038 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11039 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11040 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11043 if(SiS_Pr->UseCustomMode) return;
11044 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11045 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11046 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11047 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11048 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11049 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);