1/* 2 * Mode initializing code (CRT2 section) 3 * for SiS 300/305/540/630/730, 4 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX], 5 * XGI V3XT/V5/V8, Z7 6 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x) 7 * 8 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 9 * 10 * If distributed as part of the Linux kernel, the following license terms 11 * apply: 12 * 13 * * This program is free software; you can redistribute it and/or modify 14 * * it under the terms of the GNU General Public License as published by 15 * * the Free Software Foundation; either version 2 of the named License, 16 * * or any later version. 17 * * 18 * * This program is distributed in the hope that it will be useful, 19 * * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * * GNU General Public License for more details. 22 * * 23 * * You should have received a copy of the GNU General Public License 24 * * along with this program; if not, write to the Free Software 25 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA 26 * 27 * Otherwise, the following license terms apply: 28 * 29 * * Redistribution and use in source and binary forms, with or without 30 * * modification, are permitted provided that the following conditions 31 * * are met: 32 * * 1) Redistributions of source code must retain the above copyright 33 * * notice, this list of conditions and the following disclaimer. 34 * * 2) Redistributions in binary form must reproduce the above copyright 35 * * notice, this list of conditions and the following disclaimer in the 36 * * documentation and/or other materials provided with the distribution. 37 * * 3) The name of the author may not be used to endorse or promote products 38 * * derived from this software without specific prior written permission. 39 * * 40 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 41 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 42 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 43 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 44 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 46 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 47 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 48 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 49 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 50 * 51 * Author: Thomas Winischhofer <thomas@winischhofer.net> 52 * 53 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc. 54 * Used by permission. 55 * 56 */ 57 58#ifdef HAVE_CONFIG_H 59#include "config.h" 60#endif 61 62#if 1 63#define SET_EMI /* 302LV/ELV: Set EMI values */ 64#endif 65 66#if 1 67#define SET_PWD /* 301/302LV: Set PWD */ 68#endif 69 70#define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */ 71#define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */ 72#define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */ 73 74#include "init301.h" 75 76#ifdef SIS300 77#include "oem300.h" 78#endif 79 80#ifdef SIS315H 81#include "oem310.h" 82#endif 83 84#define SiS_I2CDELAY 1000 85#define SiS_I2CDELAYSHORT 150 86 87static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr); 88#ifdef SIS_LINUX_KERNEL 89static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val); 90#endif 91 92/*********************************************/ 93/* HELPER: Lock/Unlock CRT2 */ 94/*********************************************/ 95 96void 97SiS_UnLockCRT2(struct SiS_Private *SiS_Pr) 98{ 99 if(SiS_Pr->ChipType == XGI_20) 100 return; 101 else if(SiS_Pr->ChipType >= SIS_315H) 102 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01); 103 else 104 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01); 105} 106 107#ifdef SIS_LINUX_KERNEL 108static 109#endif 110void 111SiS_LockCRT2(struct SiS_Private *SiS_Pr) 112{ 113 if(SiS_Pr->ChipType == XGI_20) 114 return; 115 else if(SiS_Pr->ChipType >= SIS_315H) 116 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE); 117 else 118 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE); 119} 120 121/*********************************************/ 122/* HELPER: Write SR11 */ 123/*********************************************/ 124 125static void 126SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, 127 unsigned short DataOR) 128{ 129 if(SiS_Pr->ChipType >= SIS_661) { 130 DataAND &= 0x0f; 131 DataOR &= 0x0f; 132 } 133 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR); 134} 135 136/*********************************************/ 137/* HELPER: Get Pointer to LCD structure */ 138/*********************************************/ 139 140#ifdef SIS315H 141static unsigned char * 142GetLCDStructPtr661(struct SiS_Private *SiS_Pr) 143{ 144 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 145 unsigned char *myptr = NULL; 146 unsigned short romindex = 0, reg = 0, idx = 0; 147 148 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable 149 * due to the variaty of panels the BIOS doesn't know about. 150 * Exception: If the BIOS has better knowledge (such as in case 151 * of machines with a 301C and a panel that does not support DDC) 152 * use the BIOS data as well. 153 */ 154 155 if((SiS_Pr->SiS_ROMNew) && 156 ( (SiS_Pr->SiS_VBType & VB_SISLVDS) || 157 (!SiS_Pr->PanelSelfDetected) )) { 158 159 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c; 160 else reg = 0x7d; 161 162 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26; 163 164 if(idx < (8*26)) { 165 myptr = (unsigned char *)&SiS_LCDStruct661[idx]; 166 } 167 romindex = SISGETROMW(0x100); 168 if(romindex) { 169 romindex += idx; 170 myptr = &ROMAddr[romindex]; 171 } 172 } 173 return myptr; 174} 175 176static unsigned short 177GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr) 178{ 179 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 180 unsigned short romptr = 0; 181 182 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable 183 * due to the variaty of panels the BIOS doesn't know about. 184 * Exception: If the BIOS has better knowledge (such as in case 185 * of machines with a 301C and a panel that does not support DDC) 186 * use the BIOS data as well. 187 */ 188 189 if((SiS_Pr->SiS_ROMNew) && 190 ( (SiS_Pr->SiS_VBType & VB_SISLVDS) || 191 (!SiS_Pr->PanelSelfDetected) )) { 192 romptr = SISGETROMW(0x102); 193 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize); 194 } 195 196 return romptr; 197} 198#endif 199 200/*********************************************/ 201/* Adjust Rate for CRT2 */ 202/*********************************************/ 203 204static BOOLEAN 205SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 206 unsigned short RRTI, unsigned short *i) 207{ 208 unsigned short checkmask=0, modeid, infoflag; 209 210 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID; 211 212 if(SiS_Pr->SiS_VBType & VB_SISVB) { 213 214 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 215 216 checkmask |= SupportRAMDAC2; 217 if(SiS_Pr->ChipType >= SIS_315H) { 218 checkmask |= SupportRAMDAC2_135; 219 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 220 checkmask |= SupportRAMDAC2_162; 221 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) { 222 checkmask |= SupportRAMDAC2_202; 223 } 224 } 225 } 226 227 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 228 229 checkmask |= SupportLCD; 230 if(SiS_Pr->ChipType >= SIS_315H) { 231 if(SiS_Pr->SiS_VBType & VB_SISVB) { 232 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 233 if(modeid == 0x2e) checkmask |= Support64048060Hz; 234 } 235 } 236 } 237 238 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 239 240 checkmask |= SupportHiVision; 241 242 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) { 243 244 checkmask |= SupportTV; 245 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 246 checkmask |= SupportTV1024; 247 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 248 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 249 checkmask |= SupportYPbPr750p; 250 } 251 } 252 } 253 254 } 255 256 } else { /* LVDS */ 257 258 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 259 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 260 checkmask |= SupportCHTV; 261 } 262 } 263 264 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 265 checkmask |= SupportLCD; 266 } 267 268 } 269 270 /* Look backwards in table for matching CRT2 mode */ 271 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) { 272 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag; 273 if(infoflag & checkmask) return TRUE; 274 if((*i) == 0) break; 275 } 276 277 /* Look through the whole mode-section of the table from the beginning 278 * for a matching CRT2 mode if no mode was found yet. 279 */ 280 for((*i) = 0; ; (*i)++) { 281 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break; 282 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag; 283 if(infoflag & checkmask) return TRUE; 284 } 285 return FALSE; 286} 287 288/*********************************************/ 289/* Get rate index */ 290/*********************************************/ 291 292unsigned short 293SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 294{ 295 unsigned short RRTI,i,backup_i; 296 unsigned short modeflag,index,temp,backupindex; 297 static const unsigned short LCDRefreshIndex[] = { 298 0x00, 0x00, 0x01, 0x01, 299 0x01, 0x01, 0x01, 0x01, 300 0x01, 0x01, 0x01, 0x01, 301 0x01, 0x01, 0x01, 0x01, 302 0x00, 0x00, 0x00, 0x00 303 }; 304 305 /* Do NOT check for UseCustomMode here, will skrew up FIFO */ 306 if(ModeNo == 0xfe) return 0; 307 308 if(ModeNo <= 0x13) { 309 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 310 } else { 311 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 312 } 313 314 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 315 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 316 if(modeflag & HalfDCLK) return 0; 317 } 318 } 319 320 if(ModeNo < 0x14) return 0xFFFF; 321 322 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F; 323 backupindex = index; 324 325 if(index > 0) index--; 326 327 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 328 if(SiS_Pr->SiS_VBType & VB_SISVB) { 329 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 330 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0; 331 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0; 332 } 333 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 334 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) { 335 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)]; 336 if(index > temp) index = temp; 337 } 338 } 339 } else { 340 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0; 341 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 342 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0; 343 } 344 } 345 } 346 347 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; 348 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID; 349 350 if(SiS_Pr->ChipType >= SIS_315H) { 351 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) { 352 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) || 353 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) { 354 if(backupindex <= 1) RRTI++; 355 } 356 } 357 } 358 359 i = 0; 360 do { 361 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break; 362 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag; 363 temp &= ModeTypeMask; 364 if(temp < SiS_Pr->SiS_ModeType) break; 365 i++; 366 index--; 367 } while(index != 0xFFFF); 368 369 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 370 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 371 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag; 372 if(temp & InterlaceMode) i++; 373 } 374 } 375 376 i--; 377 378 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) { 379 backup_i = i; 380 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) { 381 i = backup_i; 382 } 383 } 384 385 return (RRTI + i); 386} 387 388/*********************************************/ 389/* STORE CRT2 INFO in CR34 */ 390/*********************************************/ 391 392static void 393SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 394{ 395 unsigned short temp1, temp2; 396 397 /* Store CRT1 ModeNo in CR34 */ 398 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo); 399 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8; 400 temp2 = ~(SetInSlaveMode >> 8); 401 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1); 402} 403 404/*********************************************/ 405/* HELPER: GET SOME DATA FROM BIOS ROM */ 406/*********************************************/ 407 408#ifdef SIS300 409static BOOLEAN 410SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr) 411{ 412 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 413 unsigned short temp,temp1; 414 415 if(SiS_Pr->SiS_UseROM) { 416 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 417 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f); 418 temp1 = SISGETROMW(0x23b); 419 if(temp1 & temp) return TRUE; 420 } 421 } 422 return FALSE; 423} 424 425static BOOLEAN 426SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr) 427{ 428 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 429 unsigned short temp,temp1; 430 431 if(SiS_Pr->SiS_UseROM) { 432 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 433 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f); 434 temp1 = SISGETROMW(0x23d); 435 if(temp1 & temp) return TRUE; 436 } 437 } 438 return FALSE; 439} 440#endif 441 442/*********************************************/ 443/* HELPER: DELAY FUNCTIONS */ 444/*********************************************/ 445 446void 447SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime) 448{ 449 unsigned int i, j; 450 451 for(i = 0; i < delaytime; i++) { 452 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); 453 } 454} 455 456#if defined(SIS300) || defined(SIS315H) 457static void 458SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay) 459{ 460 SiS_DDC2Delay(SiS_Pr, delay * 36); 461} 462#endif 463 464#ifdef SIS315H 465static void 466SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay) 467{ 468 while(delay--) { 469 SiS_GenericDelay(SiS_Pr, 6623); 470 } 471} 472#endif 473 474#if defined(SIS300) || defined(SIS315H) 475static void 476SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay) 477{ 478 while(delay--) { 479 SiS_GenericDelay(SiS_Pr, 66); 480 } 481} 482#endif 483 484static void 485SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime) 486{ 487#if defined(SIS300) || defined(SIS315H) 488 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 489 unsigned short PanelID, DelayIndex, Delay=0; 490#endif 491 492 if(SiS_Pr->ChipType < SIS_315H) { 493 494#ifdef SIS300 495 496 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 497 if(SiS_Pr->SiS_VBType & VB_SISVB) { 498 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7; 499 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12; 500 } 501 DelayIndex = PanelID >> 4; 502 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { 503 Delay = 3; 504 } else { 505 if(DelayTime >= 2) DelayTime -= 2; 506 if(!(DelayTime & 0x01)) { 507 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; 508 } else { 509 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; 510 } 511 if(SiS_Pr->SiS_UseROM) { 512 if(ROMAddr[0x220] & 0x40) { 513 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225]; 514 else Delay = (unsigned short)ROMAddr[0x226]; 515 } 516 } 517 } 518 SiS_ShortDelay(SiS_Pr, Delay); 519 520#endif /* SIS300 */ 521 522 } else { 523 524#ifdef SIS315H 525 526 if((SiS_Pr->ChipType >= SIS_661) || 527 (SiS_Pr->ChipType <= SIS_315PRO) || 528 (SiS_Pr->ChipType == SIS_330) || 529 (SiS_Pr->SiS_ROMNew)) { 530 531 if(!(DelayTime & 0x01)) { 532 SiS_DDC2Delay(SiS_Pr, 0x1000); 533 } else { 534 SiS_DDC2Delay(SiS_Pr, 0x4000); 535 } 536 537 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* || 538 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) || 539 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */ 540 541 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 542 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 543 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) { 544 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12; 545 } 546 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 547 DelayIndex = PanelID & 0x0f; 548 } else { 549 DelayIndex = PanelID >> 4; 550 } 551 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { 552 Delay = 3; 553 } else { 554 if(DelayTime >= 2) DelayTime -= 2; 555 if(!(DelayTime & 0x01)) { 556 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0]; 557 } else { 558 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1]; 559 } 560 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 561 if(ROMAddr[0x13c] & 0x40) { 562 if(!(DelayTime & 0x01)) { 563 Delay = (unsigned short)ROMAddr[0x17e]; 564 } else { 565 Delay = (unsigned short)ROMAddr[0x17f]; 566 } 567 } 568 } 569 } 570 SiS_ShortDelay(SiS_Pr, Delay); 571 } 572 573 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */ 574 575 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 576 if(!(DelayTime & 0x01)) { 577 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; 578 } else { 579 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; 580 } 581 Delay <<= 8; 582 SiS_DDC2Delay(SiS_Pr, Delay); 583 584 } 585 586#endif /* SIS315H */ 587 588 } 589} 590 591#ifdef SIS315H 592static void 593SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop) 594{ 595 int i; 596 for(i = 0; i < DelayLoop; i++) { 597 SiS_PanelDelay(SiS_Pr, DelayTime); 598 } 599} 600#endif 601 602/*********************************************/ 603/* HELPER: WAIT-FOR-RETRACE FUNCTIONS */ 604/*********************************************/ 605 606void 607SiS_WaitRetrace1(struct SiS_Private *SiS_Pr) 608{ 609 unsigned short watchdog; 610 611 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return; 612 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return; 613 614 watchdog = 65535; 615 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog); 616 watchdog = 65535; 617 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog); 618} 619 620#if defined(SIS300) || defined(SIS315H) 621static void 622SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg) 623{ 624 unsigned short watchdog; 625 626 watchdog = 65535; 627 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog); 628 watchdog = 65535; 629 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog); 630} 631#endif 632 633static void 634SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr) 635{ 636 if(SiS_Pr->ChipType < SIS_315H) { 637#ifdef SIS300 638 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 639 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return; 640 } 641 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) { 642 SiS_WaitRetrace1(SiS_Pr); 643 } else { 644 SiS_WaitRetrace2(SiS_Pr, 0x25); 645 } 646#endif 647 } else { 648#ifdef SIS315H 649 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) { 650 SiS_WaitRetrace1(SiS_Pr); 651 } else { 652 SiS_WaitRetrace2(SiS_Pr, 0x30); 653 } 654#endif 655 } 656} 657 658static void 659SiS_VBWait(struct SiS_Private *SiS_Pr) 660{ 661 unsigned short tempal,temp,i,j; 662 663 temp = 0; 664 for(i = 0; i < 3; i++) { 665 for(j = 0; j < 100; j++) { 666 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da); 667 if(temp & 0x01) { 668 if((tempal & 0x08)) continue; 669 else break; 670 } else { 671 if(!(tempal & 0x08)) continue; 672 else break; 673 } 674 } 675 temp ^= 0x01; 676 } 677} 678 679static void 680SiS_VBLongWait(struct SiS_Private *SiS_Pr) 681{ 682 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 683 SiS_VBWait(SiS_Pr); 684 } else { 685 SiS_WaitRetrace1(SiS_Pr); 686 } 687} 688 689/*********************************************/ 690/* HELPER: MISC */ 691/*********************************************/ 692 693#ifdef SIS300 694static BOOLEAN 695SiS_Is301B(struct SiS_Private *SiS_Pr) 696{ 697 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE; 698 return FALSE; 699} 700#endif 701 702static BOOLEAN 703SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr) 704{ 705 if(SiS_Pr->ChipType == SIS_730) { 706 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return TRUE; 707 } 708 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return TRUE; 709 return FALSE; 710} 711 712BOOLEAN 713SiS_IsDualEdge(struct SiS_Private *SiS_Pr) 714{ 715#ifdef SIS315H 716 if(SiS_Pr->ChipType >= SIS_315H) { 717 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) { 718 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return TRUE; 719 } 720 } 721#endif 722 return FALSE; 723} 724 725BOOLEAN 726SiS_IsVAMode(struct SiS_Private *SiS_Pr) 727{ 728#ifdef SIS315H 729 unsigned short flag; 730 731 if(SiS_Pr->ChipType >= SIS_315H) { 732 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 733 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE; 734 } 735#endif 736 return FALSE; 737} 738 739#ifdef SIS315H 740static BOOLEAN 741SiS_IsVAorLCD(struct SiS_Private *SiS_Pr) 742{ 743 if(SiS_IsVAMode(SiS_Pr)) return TRUE; 744 if(SiS_CRT2IsLCD(SiS_Pr)) return TRUE; 745 return FALSE; 746} 747#endif 748 749static BOOLEAN 750SiS_IsDualLink(struct SiS_Private *SiS_Pr) 751{ 752#ifdef SIS315H 753 if(SiS_Pr->ChipType >= SIS_315H) { 754 if((SiS_CRT2IsLCD(SiS_Pr)) || 755 (SiS_IsVAMode(SiS_Pr))) { 756 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE; 757 } 758 } 759#endif 760 return FALSE; 761} 762 763#ifdef SIS315H 764static BOOLEAN 765SiS_TVEnabled(struct SiS_Private *SiS_Pr) 766{ 767 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE; 768 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 769 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE; 770 } 771 return FALSE; 772} 773#endif 774 775#ifdef SIS315H 776static BOOLEAN 777SiS_LCDAEnabled(struct SiS_Private *SiS_Pr) 778{ 779 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE; 780 return FALSE; 781} 782#endif 783 784#ifdef SIS315H 785static BOOLEAN 786SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr) 787{ 788 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) { 789 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE; 790 } 791 return FALSE; 792} 793#endif 794 795#ifdef SIS315H 796static BOOLEAN 797SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr) 798{ 799 unsigned short flag; 800 801 if(SiS_Pr->ChipType == SIS_650) { 802 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0; 803 /* Check for revision != A0 only */ 804 if((flag == 0xe0) || (flag == 0xc0) || 805 (flag == 0xb0) || (flag == 0x90)) return FALSE; 806 } else if(SiS_Pr->ChipType >= SIS_661) return FALSE; 807 return TRUE; 808} 809#endif 810 811#ifdef SIS315H 812static BOOLEAN 813SiS_IsYPbPr(struct SiS_Private *SiS_Pr) 814{ 815 if(SiS_Pr->ChipType >= SIS_315H) { 816 /* YPrPb = 0x08 */ 817 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return TRUE; 818 } 819 return FALSE; 820} 821#endif 822 823#ifdef SIS315H 824static BOOLEAN 825SiS_IsChScart(struct SiS_Private *SiS_Pr) 826{ 827 if(SiS_Pr->ChipType >= SIS_315H) { 828 /* Scart = 0x04 */ 829 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return TRUE; 830 } 831 return FALSE; 832} 833#endif 834 835#ifdef SIS315H 836static BOOLEAN 837SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr) 838{ 839 unsigned short flag; 840 841 if(SiS_Pr->ChipType >= SIS_315H) { 842 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 843 if(flag & SetCRT2ToTV) return TRUE; 844 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 845 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */ 846 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */ 847 } else { 848 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 849 if(flag & SetCRT2ToTV) return TRUE; 850 } 851 return FALSE; 852} 853#endif 854 855#ifdef SIS315H 856static BOOLEAN 857SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr) 858{ 859 unsigned short flag; 860 861 if(SiS_Pr->ChipType >= SIS_315H) { 862 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 863 if(flag & SetCRT2ToLCD) return TRUE; 864 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 865 if(flag & SetToLCDA) return TRUE; 866 } else { 867 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 868 if(flag & SetCRT2ToLCD) return TRUE; 869 } 870 return FALSE; 871} 872#endif 873 874static BOOLEAN 875SiS_HaveBridge(struct SiS_Private *SiS_Pr) 876{ 877 unsigned short flag; 878 879 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 880 return TRUE; 881 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 882 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 883 if((flag == 1) || (flag == 2)) return TRUE; 884 } 885 return FALSE; 886} 887 888static BOOLEAN 889SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr) 890{ 891 unsigned short flag; 892 893 if(SiS_HaveBridge(SiS_Pr)) { 894 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 895 if(SiS_Pr->ChipType < SIS_315H) { 896 flag &= 0xa0; 897 if((flag == 0x80) || (flag == 0x20)) return TRUE; 898 } else { 899 flag &= 0x50; 900 if((flag == 0x40) || (flag == 0x10)) return TRUE; 901 } 902 } 903 return FALSE; 904} 905 906static BOOLEAN 907SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr) 908{ 909 unsigned short flag1; 910 911 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); 912 if(flag1 & (SetInSlaveMode >> 8)) return TRUE; 913 return FALSE; 914} 915 916/*********************************************/ 917/* GET VIDEO BRIDGE CONFIG INFO */ 918/*********************************************/ 919 920/* Setup general purpose IO for Chrontel communication */ 921#ifdef SIS300 922void 923SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo) 924{ 925 unsigned int acpibase; 926 unsigned short temp; 927 928 if(!(SiS_Pr->SiS_ChSW)) return; 929 930#ifdef SIS_LINUX_KERNEL 931 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74); 932#else 933 acpibase = sis_pci_read_device_u32(1, 0x74); 934#endif 935 acpibase &= 0xFFFF; 936 if(!acpibase) return; 937 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */ 938 temp &= 0xFEFF; 939 SiS_SetRegShort((acpibase + 0x3c), temp); 940 temp = SiS_GetRegShort((acpibase + 0x3c)); 941 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */ 942 temp &= 0xFEFF; 943 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100; 944 SiS_SetRegShort((acpibase + 0x3a), temp); 945 temp = SiS_GetRegShort((acpibase + 0x3a)); 946} 947#endif 948 949void 950SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 951 unsigned short ModeIdIndex, int checkcrt2mode) 952{ 953 unsigned short tempax, tempbx, temp; 954 unsigned short modeflag, resinfo = 0; 955 956 SiS_Pr->SiS_SetFlag = 0; 957 958 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 959 960 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask; 961 962 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) { 963 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 964 } 965 966 tempbx = 0; 967 968 if(SiS_HaveBridge(SiS_Pr)) { 969 970 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 971 tempbx |= temp; 972 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8; 973 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV); 974 tempbx |= tempax; 975 976#ifdef SIS315H 977 if(SiS_Pr->ChipType >= SIS_315H) { 978 if(SiS_Pr->SiS_VBType & VB_SISLCDA) { 979 if(ModeNo == 0x03) { 980 /* Mode 0x03 is never in driver mode */ 981 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf); 982 } 983 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) { 984 /* Reset LCDA setting if not driver mode */ 985 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); 986 } 987 if(IS_SIS650) { 988 if(SiS_Pr->SiS_UseLCDA) { 989 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) { 990 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) { 991 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA)); 992 } 993 } 994 } 995 } 996 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 997 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) { 998 tempbx |= SetCRT2ToLCDA; 999 } 1000 } 1001 1002 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */ 1003 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision); 1004 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) { 1005 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0; 1006 if(temp == 0x60) tempbx |= SetCRT2ToHiVision; 1007 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 1008 tempbx |= SetCRT2ToYPbPr525750; 1009 } 1010 } 1011 } 1012 1013 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1014 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1015 if(temp & SetToLCDA) { 1016 tempbx |= SetCRT2ToLCDA; 1017 } 1018 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1019 if(temp & EnableCHYPbPr) { 1020 tempbx |= SetCRT2ToCHYPbPr; 1021 } 1022 } 1023 } 1024 } 1025 1026#endif /* SIS315H */ 1027 1028 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) { 1029 tempbx &= ~(SetCRT2ToRAMDAC); 1030 } 1031 1032 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1033 temp = SetCRT2ToSVIDEO | 1034 SetCRT2ToAVIDEO | 1035 SetCRT2ToSCART | 1036 SetCRT2ToLCDA | 1037 SetCRT2ToLCD | 1038 SetCRT2ToRAMDAC | 1039 SetCRT2ToHiVision | 1040 SetCRT2ToYPbPr525750; 1041 } else { 1042 if(SiS_Pr->ChipType >= SIS_315H) { 1043 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1044 temp = SetCRT2ToAVIDEO | 1045 SetCRT2ToSVIDEO | 1046 SetCRT2ToSCART | 1047 SetCRT2ToLCDA | 1048 SetCRT2ToLCD | 1049 SetCRT2ToCHYPbPr; 1050 } else { 1051 temp = SetCRT2ToLCDA | 1052 SetCRT2ToLCD; 1053 } 1054 } else { 1055 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1056 temp = SetCRT2ToTV | SetCRT2ToLCD; 1057 } else { 1058 temp = SetCRT2ToLCD; 1059 } 1060 } 1061 } 1062 1063 if(!(tempbx & temp)) { 1064 tempax = DisableCRT2Display; 1065 tempbx = 0; 1066 } 1067 1068 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1069 1070 unsigned short clearmask = ( DriverMode | 1071 DisableCRT2Display | 1072 LoadDACFlag | 1073 SetNotSimuMode | 1074 SetInSlaveMode | 1075 SetPALTV | 1076 SwitchCRT2 | 1077 SetSimuScanMode ); 1078 1079 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA); 1080 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC); 1081 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD); 1082 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART); 1083 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision); 1084 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750); 1085 1086 } else { 1087 1088 if(SiS_Pr->ChipType >= SIS_315H) { 1089 if(tempbx & SetCRT2ToLCDA) { 1090 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode); 1091 } 1092 } 1093 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1094 if(tempbx & SetCRT2ToTV) { 1095 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode); 1096 } 1097 } 1098 if(tempbx & SetCRT2ToLCD) { 1099 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode); 1100 } 1101 if(SiS_Pr->ChipType >= SIS_315H) { 1102 if(tempbx & SetCRT2ToLCDA) { 1103 tempbx |= SetCRT2ToLCD; 1104 } 1105 } 1106 1107 } 1108 1109 if(tempax & DisableCRT2Display) { 1110 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) { 1111 tempbx = SetSimuScanMode | DisableCRT2Display; 1112 } 1113 } 1114 1115 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode; 1116 1117 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */ 1118 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 1119 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 1120 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) { 1121 modeflag &= (~CRT2Mode); 1122 } 1123 } 1124 1125 if(!(tempbx & SetSimuScanMode)) { 1126 if(tempbx & SwitchCRT2) { 1127 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) { 1128 if(resinfo != SIS_RI_1600x1200) { 1129 tempbx |= SetSimuScanMode; 1130 } 1131 } 1132 } else { 1133 if(SiS_BridgeIsEnabled(SiS_Pr)) { 1134 if(!(tempbx & DriverMode)) { 1135 if(SiS_BridgeInSlavemode(SiS_Pr)) { 1136 tempbx |= SetSimuScanMode; 1137 } 1138 } 1139 } 1140 } 1141 } 1142 1143 if(!(tempbx & DisableCRT2Display)) { 1144 if(tempbx & DriverMode) { 1145 if(tempbx & SetSimuScanMode) { 1146 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) { 1147 if(resinfo != SIS_RI_1600x1200) { 1148 tempbx |= SetInSlaveMode; 1149 } 1150 } 1151 } 1152 } else { 1153 tempbx |= SetInSlaveMode; 1154 } 1155 } 1156 1157 } 1158 1159 SiS_Pr->SiS_VBInfo = tempbx; 1160 1161#ifdef SIS300 1162 if(SiS_Pr->ChipType == SIS_630) { 1163 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo); 1164 } 1165#endif 1166 1167#ifdef SIS_LINUX_KERNEL 1168#if 0 1169 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n", 1170 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); 1171#endif 1172#endif 1173#ifdef SIS_XORG_XF86 1174#ifdef TWDEBUG 1175 xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n", 1176 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); 1177#endif 1178#endif 1179} 1180 1181/*********************************************/ 1182/* DETERMINE YPbPr MODE */ 1183/*********************************************/ 1184 1185void 1186SiS_SetYPbPr(struct SiS_Private *SiS_Pr) 1187{ 1188 1189 unsigned char temp; 1190 1191 /* Note: This variable is only used on 30xLV systems. 1192 * CR38 has a different meaning on LVDS/CH7019 systems. 1193 * On 661 and later, these bits moved to CR35. 1194 * 1195 * On 301, 301B, only HiVision 1080i is supported. 1196 * On 30xLV, 301C, only YPbPr 1080i is supported. 1197 */ 1198 1199 SiS_Pr->SiS_YPbPr = 0; 1200 if(SiS_Pr->ChipType >= SIS_661) return; 1201 1202 if(SiS_Pr->SiS_VBType) { 1203 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1204 SiS_Pr->SiS_YPbPr = YPbPrHiVision; 1205 } 1206 } 1207 1208 if(SiS_Pr->ChipType >= SIS_315H) { 1209 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 1210 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1211 if(temp & 0x08) { 1212 switch((temp >> 4)) { 1213 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break; 1214 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break; 1215 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break; 1216 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break; 1217 } 1218 } 1219 } 1220 } 1221 1222} 1223 1224/*********************************************/ 1225/* DETERMINE TVMode flag */ 1226/*********************************************/ 1227 1228void 1229SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 1230{ 1231 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 1232 unsigned short temp, temp1, resinfo = 0, romindex = 0; 1233 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect; 1234 1235 SiS_Pr->SiS_TVMode = 0; 1236 1237 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; 1238 if(SiS_Pr->UseCustomMode) return; 1239 1240 if(ModeNo > 0x13) { 1241 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1242 } 1243 1244 if(SiS_Pr->ChipType < SIS_661) { 1245 1246 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL; 1247 1248 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1249 temp = 0; 1250 if((SiS_Pr->ChipType == SIS_630) || 1251 (SiS_Pr->ChipType == SIS_730)) { 1252 temp = 0x35; 1253 romindex = 0xfe; 1254 } else if(SiS_Pr->ChipType >= SIS_315H) { 1255 temp = 0x38; 1256 if(SiS_Pr->ChipType < XGI_20) { 1257 romindex = 0xf3; 1258 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b; 1259 } 1260 } 1261 if(temp) { 1262 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 1263 OutputSelect = ROMAddr[romindex]; 1264 if(!(OutputSelect & EnablePALMN)) { 1265 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F); 1266 } 1267 } 1268 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp); 1269 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1270 if(temp1 & EnablePALM) { /* 0x40 */ 1271 SiS_Pr->SiS_TVMode |= TVSetPALM; 1272 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1273 } else if(temp1 & EnablePALN) { /* 0x80 */ 1274 SiS_Pr->SiS_TVMode |= TVSetPALN; 1275 } 1276 } else { 1277 if(temp1 & EnableNTSCJ) { /* 0x40 */ 1278 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1279 } 1280 } 1281 } 1282 /* Translate HiVision/YPbPr to our new flags */ 1283 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1284 if(SiS_Pr->SiS_YPbPr == YPbPr750p) { 1285 SiS_Pr->SiS_TVMode |= TVSetYPbPr750p; 1286 } else if(SiS_Pr->SiS_YPbPr == YPbPr525p) { 1287 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1288 SiS_Pr->SiS_TVMode |= TVSetYPbPr625p; 1289 } else { 1290 SiS_Pr->SiS_TVMode |= TVSetYPbPr525p; 1291 } 1292 } else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) { 1293 SiS_Pr->SiS_TVMode |= TVSetHiVision; 1294 } else { 1295 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1296 SiS_Pr->SiS_TVMode |= TVSetYPbPr625i; 1297 } else { 1298 SiS_Pr->SiS_TVMode |= TVSetYPbPr525i; 1299 } 1300 } 1301 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | 1302 TVSetYPbPr525p | 1303 TVSetYPbPr625p | 1304 TVSetYPbPr525i | 1305 TVSetYPbPr625i)) { 1306 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision; 1307 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750; 1308 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1309 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) { 1310 SiS_Pr->SiS_TVMode |= TVSetPAL; 1311 } 1312 } 1313 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1314 if(SiS_Pr->SiS_CHOverScan) { 1315 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 1316 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1317 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) { 1318 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1319 } 1320 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1321 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79); 1322 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) { 1323 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1324 } 1325 } 1326 if(SiS_Pr->SiS_CHSOverScan) { 1327 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1328 } 1329 } 1330 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1331 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1332 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1333 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM; 1334 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN; 1335 } else { 1336 if(temp & EnableNTSCJ) { 1337 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1338 } 1339 } 1340 } 1341 } 1342 1343 } else { /* 661 and later */ 1344 1345 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1346 if(temp1 & 0x01) { 1347 SiS_Pr->SiS_TVMode |= TVSetPAL; 1348 if(temp1 & 0x08) { 1349 SiS_Pr->SiS_TVMode |= TVSetPALN; 1350 } else if(temp1 & 0x04) { 1351 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1352 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1353 } 1354 SiS_Pr->SiS_TVMode |= TVSetPALM; 1355 } 1356 } else { 1357 if(temp1 & 0x02) { 1358 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1359 } 1360 } 1361 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1362 if(SiS_Pr->SiS_CHOverScan) { 1363 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) { 1364 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1365 } 1366 } 1367 } 1368 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1369 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 1370 temp1 &= 0xe0; 1371 if(temp1 == 0x00) { 1372 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1373 SiS_Pr->SiS_TVMode |= TVSetYPbPr625i; 1374 } else { 1375 SiS_Pr->SiS_TVMode |= TVSetYPbPr525i; 1376 } 1377 } else if(temp1 == 0x20) { 1378 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1379 SiS_Pr->SiS_TVMode |= TVSetYPbPr625p; 1380 } else { 1381 SiS_Pr->SiS_TVMode |= TVSetYPbPr525p; 1382 } 1383 } else if(temp1 == 0x40) { 1384 SiS_Pr->SiS_TVMode |= TVSetYPbPr750p; 1385 } 1386 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1387 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1388 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL); 1389 } 1390 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) { 1391 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) { 1392 SiS_Pr->SiS_TVMode |= TVAspect169; 1393 } else { 1394 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39); 1395 if(temp1 & 0x02) { 1396 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) { 1397 SiS_Pr->SiS_TVMode |= TVAspect169; 1398 } else { 1399 SiS_Pr->SiS_TVMode |= TVAspect43LB; 1400 } 1401 } else { 1402 SiS_Pr->SiS_TVMode |= TVAspect43; 1403 } 1404 } 1405 } 1406 } 1407 } 1408 1409 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL; 1410 1411 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1412 1413 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1414 SiS_Pr->SiS_TVMode |= TVSetPAL; 1415 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ); 1416 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 1417 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | 1418 TVSetYPbPr625i | 1419 TVSetYPbPr525p | 1420 TVSetYPbPr625p | 1421 TVSetYPbPr750p)) { 1422 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN); 1423 } 1424 } 1425 1426 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 1427 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 1428 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode; 1429 } 1430 } 1431 1432 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 1433 if(resinfo == SIS_RI_1024x768) { 1434 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 1435 SiS_Pr->SiS_TVMode |= TVSet525p1024; 1436 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | 1437 TVSetYPbPr750p | 1438 TVSetYPbPr625p | 1439 TVSetYPbPr625i))) { 1440 SiS_Pr->SiS_TVMode |= TVSetNTSC1024; 1441 } 1442 } 1443 } 1444 1445 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1446 if(resinfo == SIS_RI_960x540) { 1447 SiS_Pr->SiS_TVMode |= TVSetHiVi960540; 1448 } 1449 } 1450 1451 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO; 1452 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && 1453 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 1454 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1455 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPrProg) { 1456 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1457 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) { 1458 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 1459 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1460 } 1461 } 1462 1463 } 1464 1465 SiS_Pr->SiS_VBInfo &= ~SetPALTV; 1466 1467#ifdef SIS_XORG_XF86 1468#ifdef TWDEBUG 1469 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo); 1470#endif 1471#endif 1472} 1473 1474/*********************************************/ 1475/* GET LCD INFO */ 1476/*********************************************/ 1477 1478static unsigned short 1479SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr) 1480{ 1481 unsigned short temp = SiS_Pr->SiS_LCDResInfo; 1482 /* Translate my LCDResInfo to BIOS value */ 1483 switch(temp) { 1484 case Panel_1280x768_2: temp = Panel_1280x768; break; 1485 case Panel_1280x800_2: temp = Panel_1280x800; break; 1486 case Panel_1280x854: temp = Panel661_1280x854; break; 1487 } 1488 return temp; 1489} 1490 1491static void 1492SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr) 1493{ 1494#ifdef SIS315H 1495 unsigned char *ROMAddr; 1496 unsigned short temp; 1497 1498#ifdef SIS_XORG_XF86 1499#ifdef TWDEBUG 1500 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n", 1501 SiS_Pr->PanelHT, SiS_Pr->PanelVT, 1502 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE, 1503 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE, 1504 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK, 1505 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A, 1506 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B); 1507#endif 1508#endif 1509 1510 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) { 1511 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) { 1512 SiS_Pr->SiS_NeedRomModeData = TRUE; 1513 SiS_Pr->PanelHT = temp; 1514 } 1515 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) { 1516 SiS_Pr->SiS_NeedRomModeData = TRUE; 1517 SiS_Pr->PanelVT = temp; 1518 } 1519 SiS_Pr->PanelHRS = SISGETROMW(10); 1520 SiS_Pr->PanelHRE = SISGETROMW(12); 1521 SiS_Pr->PanelVRS = SISGETROMW(14); 1522 SiS_Pr->PanelVRE = SISGETROMW(16); 1523 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315; 1524 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK = 1525 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]); 1526 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B = 1527 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19]; 1528 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C = 1529 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20]; 1530 1531#ifdef SIS_XORG_XF86 1532#ifdef TWDEBUG 1533 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n", 1534 SiS_Pr->PanelHT, SiS_Pr->PanelVT, 1535 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE, 1536 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE, 1537 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK, 1538 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A, 1539 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B); 1540#endif 1541#endif 1542 1543 } 1544#endif 1545} 1546 1547static void 1548SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo, 1549 const unsigned char *nonscalingmodes) 1550{ 1551 int i = 0; 1552 while(nonscalingmodes[i] != 0xff) { 1553 if(nonscalingmodes[i++] == resinfo) { 1554 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || 1555 (SiS_Pr->UsePanelScaler == -1)) { 1556 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1557 } 1558 break; 1559 } 1560 } 1561} 1562 1563void 1564SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 1565{ 1566 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0; 1567 BOOLEAN panelcanscale = FALSE; 1568#ifdef SIS300 1569 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 1570 static const unsigned char SiS300SeriesLCDRes[] = 1571 { 0, 1, 2, 3, 7, 4, 5, 8, 1572 0, 0, 10, 0, 0, 0, 0, 15 }; 1573#endif 1574#ifdef SIS315H 1575 unsigned char *myptr = NULL; 1576#endif 1577 1578 SiS_Pr->SiS_LCDResInfo = 0; 1579 SiS_Pr->SiS_LCDTypeInfo = 0; 1580 SiS_Pr->SiS_LCDInfo = 0; 1581 SiS_Pr->PanelHRS = 999; /* HSync start */ 1582 SiS_Pr->PanelHRE = 999; /* HSync end */ 1583 SiS_Pr->PanelVRS = 999; /* VSync start */ 1584 SiS_Pr->PanelVRE = 999; /* VSync end */ 1585 SiS_Pr->SiS_NeedRomModeData = FALSE; 1586 1587 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */ 1588 SiS_Pr->Alternate1600x1200 = FALSE; 1589 1590 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return; 1591 1592 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 1593 1594 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) { 1595 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1596 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal; 1597 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal; 1598 } 1599 1600 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 1601 1602 /* For broken BIOSes: Assume 1024x768 */ 1603 if(temp == 0) temp = 0x02; 1604 1605 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 1606 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2; 1607 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) { 1608 SiS_Pr->SiS_LCDTypeInfo = temp >> 4; 1609 } else { 1610 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1; 1611 } 1612 temp &= 0x0f; 1613#ifdef SIS300 1614 if(SiS_Pr->ChipType < SIS_315H) { 1615 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */ 1616 if(SiS_Pr->SiS_VBType & VB_SIS301) { 1617 if(temp < 0x0f) temp &= 0x07; 1618 } 1619 /* Translate 300 series LCDRes to 315 series for unified usage */ 1620 temp = SiS300SeriesLCDRes[temp]; 1621 } 1622#endif 1623 1624 /* Translate to our internal types */ 1625#ifdef SIS315H 1626 if(SiS_Pr->ChipType == SIS_550) { 1627 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */ 1628 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2; 1629 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3; 1630 } else if(SiS_Pr->ChipType >= SIS_661) { 1631 if(temp == Panel661_1280x854) temp = Panel_1280x854; 1632 } 1633#endif 1634 1635 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */ 1636 if(temp == Panel310_1280x768) { 1637 temp = Panel_1280x768_2; 1638 } 1639 if(SiS_Pr->SiS_ROMNew) { 1640 if(temp == Panel661_1280x800) { 1641 temp = Panel_1280x800_2; 1642 } 1643 } 1644 } 1645 1646 SiS_Pr->SiS_LCDResInfo = temp; 1647 1648#ifdef SIS300 1649 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1650 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 1651 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366; 1652 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { 1653 SiS_Pr->SiS_LCDResInfo = Panel_848x480; 1654 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) { 1655 SiS_Pr->SiS_LCDResInfo = Panel_856x480; 1656 } 1657 } 1658#endif 1659 1660 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1661 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301) 1662 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301; 1663 } else { 1664 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS) 1665 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS; 1666 } 1667 1668 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); 1669 SiS_Pr->SiS_LCDInfo = temp & ~0x000e; 1670 /* Need temp below! */ 1671 1672 /* These must/can't scale no matter what */ 1673 switch(SiS_Pr->SiS_LCDResInfo) { 1674 case Panel_320x240_1: 1675 case Panel_320x240_2: 1676 case Panel_320x240_3: 1677 case Panel_1280x960: 1678 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD; 1679 break; 1680 case Panel_640x480: 1681 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1682 } 1683 1684 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE; 1685 1686 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD; 1687 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1688 1689 /* Dual link, Pass 1:1 BIOS default, etc. */ 1690#ifdef SIS315H 1691 if(SiS_Pr->ChipType >= SIS_661) { 1692 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 1693 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1694 } 1695 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 1696 if(SiS_Pr->SiS_ROMNew) { 1697 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1698 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) { 1699 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1700 } 1701 } 1702 } else if(SiS_Pr->ChipType >= SIS_315H) { 1703 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 1704 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1705 } 1706 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) { 1707 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit); 1708 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1709 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit; 1710 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 1711 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1712 } 1713 } else if(!(SiS_Pr->SiS_ROMNew)) { 1714 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 1715 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) && 1716 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) { 1717 SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1718 } 1719 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 1720 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 1721 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) || 1722 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) { 1723 SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1724 } 1725 } 1726 } 1727 } 1728#endif 1729 1730 /* Pass 1:1 */ 1731 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 1732 /* Always center screen on LVDS (if scaling is disabled) */ 1733 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1734 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 1735 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 1736 /* Always center screen on SiS LVDS (if scaling is disabled) */ 1737 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1738 } else { 1739 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */ 1740 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1741 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1742 } 1743 } 1744 1745 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1746 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 1747 1748 switch(SiS_Pr->SiS_LCDResInfo) { 1749 case Panel_320x240_1: 1750 case Panel_320x240_2: 1751 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; 1752 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3; 1753 SiS_Pr->PanelVCLKIdx300 = VCLK28; 1754 SiS_Pr->PanelVCLKIdx315 = VCLK28; 1755 break; 1756 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; 1757 SiS_Pr->PanelVRE = 3; 1758 SiS_Pr->PanelVCLKIdx300 = VCLK28; 1759 SiS_Pr->PanelVCLKIdx315 = VCLK28; 1760 break; 1761 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600; 1762 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628; 1763 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128; 1764 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4; 1765 SiS_Pr->PanelVCLKIdx300 = VCLK40; 1766 SiS_Pr->PanelVCLKIdx315 = VCLK40; 1767 break; 1768 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600; 1769 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800; 1770 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 1771 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6; 1772 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1773 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 1774 break; 1775 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; 1776 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 1777 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 1778 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1779 if(SiS_Pr->ChipType < SIS_315H) { 1780 SiS_Pr->PanelHRS = 23; 1781 SiS_Pr->PanelVRE = 5; 1782 } 1783 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1784 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 1785 SiS_GetLCDInfoBIOS(SiS_Pr); 1786 break; 1787 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768; 1788 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 1789 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 1790 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1791 if(SiS_Pr->ChipType < SIS_315H) { 1792 SiS_Pr->PanelHRS = 23; 1793 SiS_Pr->PanelVRE = 5; 1794 } 1795 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1796 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 1797 break; 1798 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864; 1799 break; 1800 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720; 1801 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750; 1802 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40; 1803 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5; 1804 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720; 1805 /* Data above for TMDS (projector); get from BIOS for LVDS */ 1806 SiS_GetLCDInfoBIOS(SiS_Pr); 1807 break; 1808 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; 1809 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1810 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806; 1811 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */ 1812 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */ 1813 } else { 1814 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802; 1815 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112; 1816 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1817 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; 1818 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; 1819 } 1820 break; 1821 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; 1822 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806; 1823 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 1824 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1825 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2; 1826 SiS_GetLCDInfoBIOS(SiS_Pr); 1827 break; 1828 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800; 1829 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816; 1830 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24; 1831 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3; 1832 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315; 1833 SiS_GetLCDInfoBIOS(SiS_Pr); 1834 break; 1835 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800; 1836 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812; 1837 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 1838 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3; 1839 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2; 1840 SiS_GetLCDInfoBIOS(SiS_Pr); 1841 break; 1842 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854; 1843 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861; 1844 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112; 1845 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 1846 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854; 1847 SiS_GetLCDInfoBIOS(SiS_Pr); 1848 break; 1849 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960; 1850 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000; 1851 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300; 1852 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315; 1853 if(resinfo == SIS_RI_1280x1024) { 1854 SiS_Pr->PanelVCLKIdx300 = VCLK100_300; 1855 SiS_Pr->PanelVCLKIdx315 = VCLK100_315; 1856 } 1857 break; 1858 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; 1859 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 1860 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 1861 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 1862 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300; 1863 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 1864 SiS_GetLCDInfoBIOS(SiS_Pr); 1865 break; 1866 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; 1867 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 1868 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 1869 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 1870 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 1871 SiS_GetLCDInfoBIOS(SiS_Pr); 1872 break; 1873 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; 1874 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250; 1875 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192; 1876 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 1877 SiS_Pr->PanelVCLKIdx315 = VCLK162_315; 1878 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) { 1879 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 1880 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235; 1881 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32; 1882 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4; 1883 SiS_Pr->PanelVCLKIdx315 = VCLK130_315; 1884 SiS_Pr->Alternate1600x1200 = TRUE; 1885 } 1886 } else if(SiS_Pr->SiS_IF_DEF_LVDS) { 1887 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320; 1888 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999; 1889 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999; 1890 } 1891 SiS_GetLCDInfoBIOS(SiS_Pr); 1892 break; 1893 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050; 1894 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066; 1895 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76; 1896 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1897 SiS_Pr->PanelVCLKIdx315 = VCLK121_315; 1898 SiS_GetLCDInfoBIOS(SiS_Pr); 1899 break; 1900 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; 1901 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 1902 break; 1903 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480; 1904 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525; 1905 break; 1906 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480; 1907 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525; 1908 break; 1909 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX; 1910 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY; 1911 SiS_Pr->PanelHT = SiS_Pr->CHTotal; 1912 SiS_Pr->PanelVT = SiS_Pr->CVTotal; 1913 if(SiS_Pr->CP_PreferredIndex != -1) { 1914 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex]; 1915 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex]; 1916 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex]; 1917 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex]; 1918 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex]; 1919 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex]; 1920 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex]; 1921 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex]; 1922 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes; 1923 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS; 1924 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes; 1925 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS; 1926 if(SiS_Pr->CP_PrefClock) { 1927 int idx; 1928 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315; 1929 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300; 1930 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300; 1931 else idx = VCLK_CUSTOM_315; 1932 SiS_Pr->SiS_VCLKData[idx].CLOCK = 1933 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock; 1934 SiS_Pr->SiS_VCLKData[idx].SR2B = 1935 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B; 1936 SiS_Pr->SiS_VCLKData[idx].SR2C = 1937 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C; 1938 } 1939 } 1940 break; 1941 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; 1942 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 1943 break; 1944 } 1945 1946 /* Special cases */ 1947 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 1948 (SiS_Pr->SiS_IF_DEF_DSTN) || 1949 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 1950 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 1951 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 1952 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) { 1953 SiS_Pr->PanelHRS = 999; 1954 SiS_Pr->PanelHRE = 999; 1955 } 1956 1957 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 1958 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 1959 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 1960 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) { 1961 SiS_Pr->PanelVRS = 999; 1962 SiS_Pr->PanelVRE = 999; 1963 } 1964 1965 /* DontExpand overrule */ 1966 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 1967 1968 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) { 1969 /* No scaling for this mode on any panel (LCD=CRT2)*/ 1970 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1971 } 1972 1973 switch(SiS_Pr->SiS_LCDResInfo) { 1974 1975 case Panel_Custom: 1976 case Panel_1152x864: 1977 case Panel_1280x768: /* TMDS only */ 1978 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1979 break; 1980 1981 case Panel_800x600: { 1982 static const unsigned char nonscalingmodes[] = { 1983 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff 1984 }; 1985 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 1986 break; 1987 } 1988 case Panel_1024x768: { 1989 static const unsigned char nonscalingmodes[] = { 1990 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 1991 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 1992 0xff 1993 }; 1994 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 1995 break; 1996 } 1997 case Panel_1280x720: { 1998 static const unsigned char nonscalingmodes[] = { 1999 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2000 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2001 0xff 2002 }; 2003 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2004 if(SiS_Pr->PanelHT == 1650) { 2005 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2006 } 2007 break; 2008 } 2009 case Panel_1280x768_2: { /* LVDS only */ 2010 static const unsigned char nonscalingmodes[] = { 2011 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2012 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2013 SIS_RI_1152x768,0xff 2014 }; 2015 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2016 switch(resinfo) { 2017 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) { 2018 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2019 } 2020 break; 2021 } 2022 break; 2023 } 2024 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */ 2025 static const unsigned char nonscalingmodes[] = { 2026 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2027 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2028 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff 2029 }; 2030 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2031 break; 2032 } 2033 case Panel_1280x800_2: { /* SiS LVDS */ 2034 static const unsigned char nonscalingmodes[] = { 2035 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2036 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2037 SIS_RI_1152x768,0xff 2038 }; 2039 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2040 switch(resinfo) { 2041 case SIS_RI_1280x720: 2042 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) { 2043 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2044 } 2045 break; 2046 } 2047 break; 2048 } 2049 case Panel_1280x854: { /* SiS LVDS */ 2050 static const unsigned char nonscalingmodes[] = { 2051 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2052 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2053 SIS_RI_1152x768,0xff 2054 }; 2055 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2056 switch(resinfo) { 2057 case SIS_RI_1280x720: 2058 case SIS_RI_1280x768: 2059 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) { 2060 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2061 } 2062 break; 2063 } 2064 break; 2065 } 2066 case Panel_1280x960: { 2067 static const unsigned char nonscalingmodes[] = { 2068 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2069 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2070 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2071 SIS_RI_1280x854,0xff 2072 }; 2073 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2074 break; 2075 } 2076 case Panel_1280x1024: { 2077 static const unsigned char nonscalingmodes[] = { 2078 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2079 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2080 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2081 SIS_RI_1280x854,SIS_RI_1280x960,0xff 2082 }; 2083 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2084 break; 2085 } 2086 case Panel_1400x1050: { 2087 static const unsigned char nonscalingmodes[] = { 2088 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2089 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2090 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854, 2091 SIS_RI_1280x960,0xff 2092 }; 2093 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2094 switch(resinfo) { 2095 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) { 2096 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2097 } 2098 break; 2099 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2100 break; 2101 } 2102 break; 2103 } 2104 case Panel_1600x1200: { 2105 static const unsigned char nonscalingmodes[] = { 2106 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2107 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2108 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2109 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff 2110 }; 2111 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2112 break; 2113 } 2114 case Panel_1680x1050: { 2115 static const unsigned char nonscalingmodes[] = { 2116 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2117 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2118 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768, 2119 SIS_RI_1360x1024,0xff 2120 }; 2121 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2122 break; 2123 } 2124 } 2125 } 2126 2127#ifdef SIS300 2128 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2129 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { 2130 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */ 2131 } 2132 } 2133 2134 if(SiS_Pr->ChipType < SIS_315H) { 2135 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2136 if(SiS_Pr->SiS_UseROM) { 2137 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 2138 if(!(ROMAddr[0x235] & 0x02)) { 2139 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD); 2140 } 2141 } 2142 } 2143 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 2144 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) { 2145 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD); 2146 } 2147 } 2148 } 2149#endif 2150 2151 /* Special cases */ 2152 2153 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) { 2154 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2155 } 2156 2157 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 2158 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2159 } 2160 2161 switch(SiS_Pr->SiS_LCDResInfo) { 2162 case Panel_640x480: 2163 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2164 break; 2165 case Panel_1280x800: 2166 /* Don't pass 1:1 by default (TMDS special) */ 2167 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2168 break; 2169 case Panel_1280x960: 2170 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2171 break; 2172 case Panel_Custom: 2173 if((!SiS_Pr->CP_PrefClock) || 2174 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) { 2175 SiS_Pr->SiS_LCDInfo |= LCDPass11; 2176 } 2177 break; 2178 } 2179 2180 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) { 2181 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2182 } 2183 2184 /* (In)validate LCDPass11 flag */ 2185 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2186 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2187 } 2188 2189 /* LVDS DDA */ 2190 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) { 2191 2192 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 2193 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) { 2194 if(ModeNo == 0x12) { 2195 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 2196 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2197 } 2198 } else if(ModeNo > 0x13) { 2199 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) { 2200 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2201 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) { 2202 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2203 } 2204 } 2205 } 2206 } 2207 } 2208 } 2209 2210 if(modeflag & HalfDCLK) { 2211 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) { 2212 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2213 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 2214 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2215 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) { 2216 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2217 } else if(ModeNo > 0x13) { 2218 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 2219 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2220 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) { 2221 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2222 } 2223 } 2224 } 2225 2226 } 2227 2228 /* VESA timing */ 2229 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2230 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) { 2231 SiS_Pr->SiS_SetFlag |= LCDVESATiming; 2232 } 2233 } else { 2234 SiS_Pr->SiS_SetFlag |= LCDVESATiming; 2235 } 2236 2237#ifdef SIS_LINUX_KERNEL 2238#if 0 2239 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n", 2240 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo); 2241#endif 2242#endif 2243#ifdef SIS_XORG_XF86 2244 xf86DrvMsgVerb(0, X_PROBED, 4, 2245 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n", 2246 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag); 2247#endif 2248} 2249 2250/*********************************************/ 2251/* GET VCLK */ 2252/*********************************************/ 2253 2254unsigned short 2255SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 2256 unsigned short RefreshRateTableIndex) 2257{ 2258 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0; 2259 unsigned short resinfo, tempbx; 2260 const unsigned char *CHTVVCLKPtr = NULL; 2261 2262 if(ModeNo <= 0x13) { 2263 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 2264 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 2265 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03; 2266 VCLKIndexGENCRT = VCLKIndexGEN; 2267 } else { 2268 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2269 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 2270 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 2271 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, 2272 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide); 2273 } 2274 2275 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */ 2276 2277 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 2278 2279 CRT2Index >>= 6; 2280 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */ 2281 2282 if(SiS_Pr->ChipType < SIS_315H) { 2283 VCLKIndex = SiS_Pr->PanelVCLKIdx300; 2284 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 2285 VCLKIndex = VCLKIndexGEN; 2286 } 2287 } else { 2288 VCLKIndex = SiS_Pr->PanelVCLKIdx315; 2289 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 2290 switch(resinfo) { 2291 /* Correct those whose IndexGEN doesn't match VBVCLK array */ 2292 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break; 2293 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break; 2294 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break; 2295 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break; 2296 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break; 2297 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break; 2298 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break; 2299 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break; 2300 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break; 2301 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break; 2302 default: VCLKIndex = VCLKIndexGEN; 2303 } 2304 2305 if(ModeNo <= 0x13) { 2306 if(SiS_Pr->ChipType <= SIS_315PRO) { 2307 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42; 2308 } else { 2309 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00; 2310 } 2311 } 2312 if(SiS_Pr->ChipType <= SIS_315PRO) { 2313 if(VCLKIndex == 0) VCLKIndex = 0x41; 2314 if(VCLKIndex == 1) VCLKIndex = 0x43; 2315 if(VCLKIndex == 4) VCLKIndex = 0x44; 2316 } 2317 } 2318 } 2319 2320 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */ 2321 2322 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 2323 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2; 2324 else VCLKIndex = HiTVVCLK; 2325 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK; 2326 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) 2327 VCLKIndex = YPbPr750pVCLK; 2328 else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr625p | TVRPLLDIV2XO)) 2329 VCLKIndex = TVVCLKDIV2; 2330 else 2331 VCLKIndex = TVVCLK; 2332 2333 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300; 2334 else VCLKIndex += TVCLKBASE_315; 2335 2336 } else { /* VGA2 */ 2337 2338 VCLKIndex = VCLKIndexGENCRT; 2339 if(SiS_Pr->ChipType < SIS_315H) { 2340 if(ModeNo > 0x13) { 2341 if( (SiS_Pr->ChipType == SIS_630) && 2342 (SiS_Pr->ChipRevision >= 0x30)) { 2343 if(VCLKIndex == 0x14) VCLKIndex = 0x34; 2344 } 2345 /* Better VGA2 clock for 1280x1024@75 */ 2346 if(VCLKIndex == 0x17) VCLKIndex = 0x45; 2347 } 2348 } 2349 } 2350 2351 } else { /* If not programming CRT2 */ 2352 2353 VCLKIndex = VCLKIndexGENCRT; 2354 if(SiS_Pr->ChipType < SIS_315H) { 2355 if(ModeNo > 0x13) { 2356 if( (SiS_Pr->ChipType != SIS_630) && 2357 (SiS_Pr->ChipType != SIS_300) ) { 2358 if(VCLKIndex == 0x1b) VCLKIndex = 0x48; 2359 } 2360 } 2361 } 2362 } 2363 2364 } else { /* LVDS */ 2365 2366 VCLKIndex = CRT2Index; 2367 2368 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 2369 2370 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) { 2371 2372 VCLKIndex &= 0x1f; 2373 tempbx = 0; 2374 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2375 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 2376 tempbx += 2; 2377 if(SiS_Pr->SiS_ModeType > ModeVGA) { 2378 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8; 2379 } 2380 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 2381 tempbx = 4; 2382 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2383 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) { 2384 tempbx = 6; 2385 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2386 } 2387 } 2388 switch(tempbx) { 2389 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break; 2390 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break; 2391 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break; 2392 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; 2393 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break; 2394 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break; 2395 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break; 2396 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break; 2397 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break; 2398 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; 2399 } 2400 VCLKIndex = CHTVVCLKPtr[VCLKIndex]; 2401 2402 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 2403 2404 if(SiS_Pr->ChipType < SIS_315H) { 2405 VCLKIndex = SiS_Pr->PanelVCLKIdx300; 2406 } else { 2407 VCLKIndex = SiS_Pr->PanelVCLKIdx315; 2408 } 2409 2410#ifdef SIS300 2411 /* Special Timing: Barco iQ Pro R series */ 2412 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44; 2413 2414 /* Special Timing: 848x480 and 856x480 parallel lvds panels */ 2415 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { 2416 if(SiS_Pr->ChipType < SIS_315H) { 2417 VCLKIndex = VCLK34_300; 2418 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ 2419 } else { 2420 VCLKIndex = VCLK34_315; 2421 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ 2422 } 2423 } 2424#endif 2425 2426 } else { 2427 2428 VCLKIndex = VCLKIndexGENCRT; 2429 if(SiS_Pr->ChipType < SIS_315H) { 2430 if(ModeNo > 0x13) { 2431 if( (SiS_Pr->ChipType == SIS_630) && 2432 (SiS_Pr->ChipRevision >= 0x30) ) { 2433 if(VCLKIndex == 0x14) VCLKIndex = 0x2e; 2434 } 2435 } 2436 } 2437 } 2438 2439 } else { /* if not programming CRT2 */ 2440 2441 VCLKIndex = VCLKIndexGENCRT; 2442 if(SiS_Pr->ChipType < SIS_315H) { 2443 if(ModeNo > 0x13) { 2444 if( (SiS_Pr->ChipType != SIS_630) && 2445 (SiS_Pr->ChipType != SIS_300) ) { 2446 if(VCLKIndex == 0x1b) VCLKIndex = 0x48; 2447 } 2448#if 0 2449 if(SiS_Pr->ChipType == SIS_730) { 2450 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */ 2451 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */ 2452 } 2453#endif 2454 } 2455 } 2456 2457 } 2458 2459 } 2460 2461#ifdef SIS_XORG_XF86 2462#ifdef TWDEBUG 2463 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex); 2464#endif 2465#endif 2466 2467 return VCLKIndex; 2468} 2469 2470/*********************************************/ 2471/* SET CRT2 MODE TYPE REGISTERS */ 2472/*********************************************/ 2473 2474static void 2475SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 2476{ 2477 unsigned short i, j, modeflag, tempah=0; 2478 short tempcl; 2479#if defined(SIS300) || defined(SIS315H) 2480 unsigned short tempbl; 2481#endif 2482#ifdef SIS315H 2483 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 2484 unsigned short tempah2, tempbl2; 2485#endif 2486 2487 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 2488 2489 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 2490 2491 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); 2492 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7); 2493 2494 } else { 2495 2496 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0); 2497 if(SiS_Pr->ChipType >= SIS_315H) { 2498 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F); 2499 } 2500 2501 tempcl = SiS_Pr->SiS_ModeType; 2502 2503 if(SiS_Pr->ChipType < SIS_315H) { 2504 2505#ifdef SIS300 /* ---- 300 series ---- */ 2506 2507 /* For 301BDH: (with LCD via LVDS) */ 2508 if(SiS_Pr->SiS_VBType & VB_NoLCD) { 2509 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32); 2510 tempbl &= 0xef; 2511 tempbl |= 0x02; 2512 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 2513 tempbl |= 0x10; 2514 tempbl &= 0xfd; 2515 } 2516 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl); 2517 } 2518 2519 if(ModeNo > 0x13) { 2520 tempcl -= ModeVGA; 2521 if(tempcl >= 0) { 2522 tempah = ((0x10 >> tempcl) | 0x80); 2523 } 2524 } else tempah = 0x80; 2525 2526 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0; 2527 2528#endif /* SIS300 */ 2529 2530 } else { 2531 2532#ifdef SIS315H /* ------- 315/330 series ------ */ 2533 2534 if(ModeNo > 0x13) { 2535 tempcl -= ModeVGA; 2536 if(tempcl >= 0) { 2537 tempah = (0x08 >> tempcl); 2538 if (tempah == 0) tempah = 1; 2539 tempah |= 0x40; 2540 } 2541 } else tempah = 0x40; 2542 2543 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50; 2544 2545#endif /* SIS315H */ 2546 2547 } 2548 2549 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2550 2551 if(SiS_Pr->ChipType < SIS_315H) { 2552 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); 2553 } else { 2554#ifdef SIS315H 2555 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2556 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); 2557 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 2558 if(IS_SIS740) { 2559 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); 2560 } else { 2561 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); 2562 } 2563 } 2564#endif 2565 } 2566 2567 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2568 2569 tempah = 0x01; 2570 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 2571 tempah |= 0x02; 2572 } 2573 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 2574 tempah ^= 0x05; 2575 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 2576 tempah ^= 0x01; 2577 } 2578 } 2579 2580 if(SiS_Pr->ChipType < SIS_315H) { 2581 2582 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2583 2584 tempah = (tempah << 5) & 0xFF; 2585 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah); 2586 tempah = (tempah >> 5) & 0xFF; 2587 2588 } else { 2589 2590 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08; 2591 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08; 2592 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah); 2593 tempah &= ~0x08; 2594 2595 } 2596 2597 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) { 2598 tempah |= 0x10; 2599 } 2600 2601 tempah |= 0x80; 2602 if(SiS_Pr->SiS_VBType & VB_SIS301) { 2603 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80; 2604 } 2605 2606 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 2607 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) { 2608 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2609 tempah |= 0x20; 2610 } 2611 } 2612 } 2613 2614 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah); 2615 2616 tempah = 0x80; 2617 if(SiS_Pr->SiS_VBType & VB_SIS301) { 2618 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0; 2619 } 2620 2621 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40; 2622 2623 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 2624 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) { 2625 tempah |= 0x40; 2626 } 2627 } 2628 2629 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah); 2630 2631 } else { /* LVDS */ 2632 2633 if(SiS_Pr->ChipType >= SIS_315H) { 2634 2635#ifdef SIS315H 2636 /* LVDS can only be slave in 8bpp modes */ 2637 tempah = 0x80; 2638 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) { 2639 if(SiS_Pr->SiS_VBInfo & DriverMode) { 2640 tempah |= 0x02; 2641 } 2642 } 2643 2644 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02; 2645 2646 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01; 2647 2648 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1; 2649 2650 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah); 2651#endif 2652 2653 } else { 2654 2655#ifdef SIS300 2656 tempah = 0; 2657 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) { 2658 tempah |= 0x02; 2659 } 2660 tempah <<= 5; 2661 2662 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2663 2664 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah); 2665#endif 2666 2667 } 2668 2669 } 2670 2671 } /* LCDA */ 2672 2673 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2674 2675 if(SiS_Pr->ChipType >= SIS_315H) { 2676 2677#ifdef SIS315H 2678 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */ 2679 2680 /* The following is nearly unpreditable and varies from machine 2681 * to machine. Especially the 301DH seems to be a real trouble 2682 * maker. Some BIOSes simply set the registers (like in the 2683 * NoLCD-if-statements here), some set them according to the 2684 * LCDA stuff. It is very likely that some machines are not 2685 * treated correctly in the following, very case-orientated 2686 * code. What do I do then...? 2687 */ 2688 2689 /* 740 variants match for 30xB, 301B-DH, 30xLV */ 2690 2691 if(!(IS_SIS740)) { 2692 tempah = 0x04; /* For all bridges */ 2693 tempbl = 0xfb; 2694 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2695 tempah = 0x00; 2696 if(SiS_IsDualEdge(SiS_Pr)) { 2697 tempbl = 0xff; 2698 } 2699 } 2700 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); 2701 } 2702 2703 /* The following two are responsible for eventually wrong colors 2704 * in TV output. The DH (VB_NoLCD) conditions are unknown; the 2705 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version 2706 * in a 650 box (Jake). What is the criteria? 2707 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same 2708 * treatment like the 651+301B-DH(b0) case. Seems more to be the 2709 * chipset than the bridge revision. 2710 */ 2711 2712 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 2713 tempah = 0x30; 2714 tempbl = 0xc0; 2715 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || 2716 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) { 2717 tempah = 0x00; 2718 tempbl = 0x00; 2719 } 2720 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah); 2721 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl); 2722 } else if(SiS_Pr->SiS_VBType & VB_SIS301) { 2723 /* Fixes "TV-blue-bug" on 315+301 */ 2724 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */ 2725 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); 2726 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 2727 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */ 2728 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0); 2729 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */ 2730 tempah = 0x30; tempah2 = 0xc0; 2731 tempbl = 0xcf; tempbl2 = 0x3f; 2732 if(SiS_Pr->SiS_TVBlue == 0) { 2733 tempah = tempah2 = 0x00; 2734 } else if(SiS_Pr->SiS_TVBlue == -1) { 2735 /* Set on 651/M650, clear on 315/650 */ 2736 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ { 2737 tempah = tempah2 = 0x00; 2738 } 2739 } 2740 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah); 2741 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2); 2742 } else { 2743 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */ 2744 tempbl = 0xcf; tempbl2 = 0x3f; 2745 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2746 tempah = tempah2 = 0x00; 2747 if(SiS_IsDualEdge(SiS_Pr)) { 2748 tempbl = tempbl2 = 0xff; 2749 } 2750 } 2751 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah); 2752 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2); 2753 } 2754 2755 if(IS_SIS740) { 2756 tempah = 0x80; 2757 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00; 2758 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah); 2759 } else { 2760 tempah = 0x00; 2761 tempbl = 0x7f; 2762 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2763 tempbl = 0xff; 2764 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80; 2765 } 2766 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah); 2767 } 2768 2769#endif /* SIS315H */ 2770 2771 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 2772 2773#ifdef SIS300 2774 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); 2775 2776 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || 2777 ((SiS_Pr->SiS_VBType & VB_NoLCD) && 2778 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) { 2779 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F); 2780 } else { 2781 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80); 2782 } 2783#endif 2784 2785 } 2786 2787 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 2788 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80); 2789 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) { 2790 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0); 2791 } 2792 } 2793 2794 } else { /* LVDS */ 2795 2796#ifdef SIS315H 2797 if(SiS_Pr->ChipType >= SIS_315H) { 2798 2799 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 2800 2801 tempah = 0x04; 2802 tempbl = 0xfb; 2803 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2804 tempah = 0x00; 2805 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff; 2806 } 2807 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); 2808 2809 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 2810 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 2811 } 2812 2813 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); 2814 2815 } else if(SiS_Pr->ChipType == SIS_550) { 2816 2817 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 2818 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); 2819 2820 } 2821 2822 } 2823#endif 2824 2825 } 2826 2827} 2828 2829/*********************************************/ 2830/* GET RESOLUTION DATA */ 2831/*********************************************/ 2832 2833unsigned short 2834SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 2835{ 2836 if(ModeNo <= 0x13) 2837 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo); 2838 else 2839 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO); 2840} 2841 2842static void 2843SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 2844{ 2845 unsigned short xres, yres, modeflag=0, resindex; 2846 2847 if(SiS_Pr->UseCustomMode) { 2848 xres = SiS_Pr->CHDisplay; 2849 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1; 2850 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres; 2851 /* DoubleScanMode-check done in CheckCalcCustomMode()! */ 2852 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay; 2853 return; 2854 } 2855 2856 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex); 2857 2858 if(ModeNo <= 0x13) { 2859 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal; 2860 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal; 2861 } else { 2862 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal; 2863 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal; 2864 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2865 } 2866 2867 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) { 2868 2869 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) { 2870 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) { 2871 if(yres == 350) yres = 400; 2872 } 2873 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) { 2874 if(ModeNo == 0x12) yres = 400; 2875 } 2876 } 2877 2878 if(modeflag & HalfDCLK) xres <<= 1; 2879 if(modeflag & DoubleScanMode) yres <<= 1; 2880 2881 } 2882 2883 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 2884 2885 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 2886 switch(SiS_Pr->SiS_LCDResInfo) { 2887 case Panel_1024x768: 2888 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 2889 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2890 if(yres == 350) yres = 357; 2891 if(yres == 400) yres = 420; 2892 if(yres == 480) yres = 525; 2893 } 2894 } 2895 break; 2896 case Panel_1280x1024: 2897 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2898 /* BIOS bug - does this regardless of scaling */ 2899 if(yres == 400) yres = 405; 2900 } 2901 if(yres == 350) yres = 360; 2902 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 2903 if(yres == 360) yres = 375; 2904 } 2905 break; 2906 case Panel_1600x1200: 2907 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 2908 if(yres == 1024) yres = 1056; 2909 } 2910 break; 2911 } 2912 } 2913 2914 } else { 2915 2916 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2917 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) { 2918 if(xres == 720) xres = 640; 2919 } 2920 } else if(xres == 720) xres = 640; 2921 2922 if(SiS_Pr->SiS_SetFlag & SetDOSMode) { 2923 yres = 400; 2924 if(SiS_Pr->ChipType >= SIS_315H) { 2925 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480; 2926 } else { 2927 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480; 2928 } 2929 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480; 2930 } 2931 2932 } 2933 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres; 2934 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres; 2935} 2936 2937/*********************************************/ 2938/* GET CRT2 TIMING DATA */ 2939/*********************************************/ 2940 2941static void 2942SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 2943 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index, 2944 unsigned short *ResIndex) 2945{ 2946 unsigned short tempbx=0, tempal=0, resinfo=0; 2947 2948 if(ModeNo <= 0x13) { 2949 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 2950 } else { 2951 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 2952 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2953 } 2954 2955 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) { 2956 2957 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */ 2958 2959 tempbx = SiS_Pr->SiS_LCDResInfo; 2960 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32; 2961 2962 /* patch index */ 2963 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) { 2964 if (resinfo == SIS_RI_1280x800) tempal = 9; 2965 else if(resinfo == SIS_RI_1400x1050) tempal = 11; 2966 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) || 2967 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) || 2968 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) { 2969 if (resinfo == SIS_RI_1280x768) tempal = 9; 2970 } 2971 2972 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 2973 /* Pass 1:1 only (center-screen handled outside) */ 2974 /* This is never called for the panel's native resolution */ 2975 /* since Pass1:1 will not be set in this case */ 2976 tempbx = 100; 2977 if(ModeNo >= 0x13) { 2978 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS; 2979 } 2980 } 2981 2982#ifdef SIS315H 2983 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 2984 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 2985 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2986 tempbx = 200; 2987 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++; 2988 } 2989 } 2990 } 2991#endif 2992 2993 } else { /* TV */ 2994 2995 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 2996 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */ 2997 tempbx = 2; 2998 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2999 tempbx = 13; 3000 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14; 3001 } 3002 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3003 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7; 3004 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6; 3005 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625i) tempbx = 15; 3006 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625p) tempbx = 16; 3007 else tempbx = 5; 3008 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5; 3009 } else { 3010 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3; 3011 else tempbx = 4; 3012 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5; 3013 } 3014 3015 } 3016 3017 tempal &= 0x3F; 3018 3019 if(ModeNo > 0x13) { 3020 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) { 3021 switch(resinfo) { 3022 case SIS_RI_720x480: 3023 tempal = 9; 3024 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 6; 3025 break; 3026 case SIS_RI_720x576: 3027 case SIS_RI_768x576: 3028 case SIS_RI_1024x576: 3029 tempal = 6; 3030 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 3031 tempal = 8; 3032 if(resinfo == SIS_RI_1024x576) tempal = 10; 3033 } 3034 break; 3035 case SIS_RI_800x480: 3036 tempal = 4; 3037 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9; 3038 break; 3039 case SIS_RI_512x384: 3040 case SIS_RI_1024x768: 3041 tempal = 7; 3042 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr625p)) { 3043 tempal = 8; 3044 } 3045 break; 3046 case SIS_RI_1280x720: 3047 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 11; 3048 break; 3049 } 3050 } 3051 } 3052 3053 *CRT2Index = tempbx; 3054 *ResIndex = tempal; 3055 3056 } else { /* LVDS, 301B-DH (if running on LCD) */ 3057 3058 tempbx = 0; 3059 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 3060 3061 tempbx = 90; 3062 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 3063 tempbx = 92; 3064 if(SiS_Pr->SiS_ModeType > ModeVGA) { 3065 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99; 3066 } 3067 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94; 3068 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96; 3069 } 3070 if(tempbx != 99) { 3071 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++; 3072 } 3073 3074 } else { 3075 3076 switch(SiS_Pr->SiS_LCDResInfo) { 3077 case Panel_640x480: tempbx = 12; break; 3078 case Panel_320x240_1: tempbx = 10; break; 3079 case Panel_320x240_2: 3080 case Panel_320x240_3: tempbx = 14; break; 3081 case Panel_800x600: tempbx = 16; break; 3082 case Panel_1024x600: tempbx = 18; break; 3083 case Panel_1152x768: 3084 case Panel_1024x768: tempbx = 20; break; 3085 case Panel_1280x768: tempbx = 22; break; 3086 case Panel_1280x1024: tempbx = 24; break; 3087 case Panel_1400x1050: tempbx = 26; break; 3088 case Panel_1600x1200: tempbx = 28; break; 3089#ifdef SIS300 3090 case Panel_Barco1366: tempbx = 80; break; 3091#endif 3092 } 3093 3094 switch(SiS_Pr->SiS_LCDResInfo) { 3095 case Panel_320x240_1: 3096 case Panel_320x240_2: 3097 case Panel_320x240_3: 3098 case Panel_640x480: 3099 break; 3100 default: 3101 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3102 } 3103 3104 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30; 3105 3106#ifdef SIS300 3107 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 3108 tempbx = 82; 3109 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3110 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { 3111 tempbx = 84; 3112 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3113 } 3114#endif 3115 3116 } 3117 3118 (*CRT2Index) = tempbx; 3119 (*ResIndex) = tempal & 0x1F; 3120 } 3121} 3122 3123static void 3124SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3125 unsigned short RefreshRateTableIndex) 3126{ 3127 unsigned short tempax=0, tempbx=0, index, dotclock; 3128 unsigned short temp1=0, modeflag=0, tempcx=0; 3129 3130 SiS_Pr->SiS_RVBHCMAX = 1; 3131 SiS_Pr->SiS_RVBHCFACT = 1; 3132 3133 if(ModeNo <= 0x13) { 3134 3135 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 3136 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex); 3137 3138 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0]; 3139 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6]; 3140 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7]; 3141 3142 dotclock = (modeflag & Charx8Dot) ? 8 : 9; 3143 3144 } else { 3145 3146 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3147 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2); 3148 3149 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0]; 3150 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8); 3151 tempax &= 0x03FF; 3152 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6]; 3153 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8; 3154 tempcx &= 0x0100; 3155 tempcx <<= 2; 3156 tempbx |= tempcx; 3157 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7]; 3158 3159 dotclock = 8; 3160 3161 } 3162 3163 if(temp1 & 0x01) tempbx |= 0x0100; 3164 if(temp1 & 0x20) tempbx |= 0x0200; 3165 3166 tempax += 5; 3167 tempax *= dotclock; 3168 if(modeflag & HalfDCLK) tempax <<= 1; 3169 3170 tempbx++; 3171 3172 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; 3173 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx; 3174} 3175 3176static void 3177SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 3178 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex) 3179{ 3180 unsigned short ResIndex; 3181 3182 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3183 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 3184 if(SiS_Pr->UseCustomMode) { 3185 ResIndex = SiS_Pr->CHTotal; 3186 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1; 3187 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex; 3188 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal; 3189 } else { 3190 if(ModeNo < 0x13) { 3191 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 3192 } else { 3193 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS; 3194 } 3195 if(ResIndex == 0x09) { 3196 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */ 3197 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */ 3198 } 3199 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT; 3200 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT; 3201 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT; 3202 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT; 3203 } 3204 } else { 3205 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3206 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3207 } 3208 } else { 3209 /* This handles custom modes and custom panels */ 3210 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; 3211 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; 3212 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3213 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3214 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE); 3215 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE); 3216 } 3217} 3218 3219static void 3220SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3221 unsigned short RefreshRateTableIndex) 3222{ 3223 unsigned short CRT2Index, ResIndex, backup; 3224 const struct SiS_LVDSData *LVDSData = NULL; 3225 3226 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex); 3227 3228 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3229 SiS_Pr->SiS_RVBHCMAX = 1; 3230 SiS_Pr->SiS_RVBHCFACT = 1; 3231 SiS_Pr->SiS_NewFlickerMode = 0; 3232 SiS_Pr->SiS_RVBHRS = 50; 3233 SiS_Pr->SiS_RY1COE = 0; 3234 SiS_Pr->SiS_RY2COE = 0; 3235 SiS_Pr->SiS_RY3COE = 0; 3236 SiS_Pr->SiS_RY4COE = 0; 3237 SiS_Pr->SiS_RVBHRS2 = 0; 3238 } 3239 3240 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3241 3242#ifdef SIS315H 3243 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3244 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex); 3245#endif 3246 3247 } else { 3248 3249 /* 301BDH needs LVDS Data */ 3250 backup = SiS_Pr->SiS_IF_DEF_LVDS; 3251 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 3252 SiS_Pr->SiS_IF_DEF_LVDS = 1; 3253 } 3254 3255 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 3256 &CRT2Index, &ResIndex); 3257 3258 SiS_Pr->SiS_IF_DEF_LVDS = backup; 3259 3260 switch(CRT2Index) { 3261 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break; 3262 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break; 3263 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break; 3264 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break; 3265 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break; 3266 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; 3267#ifdef SIS300 3268 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break; 3269 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break; 3270 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break; 3271 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break; 3272 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break; 3273#endif 3274 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break; 3275 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break; 3276 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break; 3277 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break; 3278 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break; 3279 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break; 3280 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break; 3281 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break; 3282 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; 3283 } 3284 3285 if(LVDSData) { 3286 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT; 3287 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT; 3288 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT; 3289 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT; 3290 } else { 3291 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3292 } 3293 3294 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) && 3295 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && 3296 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) { 3297 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || 3298 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) { 3299 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; 3300 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; 3301#ifdef SIS300 3302 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 3303 if(ResIndex < 0x08) { 3304 SiS_Pr->SiS_HDE = 1280; 3305 SiS_Pr->SiS_VDE = 1024; 3306 } 3307 } 3308#endif 3309 } 3310 } 3311 } 3312} 3313 3314static void 3315SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3316 unsigned short RefreshRateTableIndex) 3317{ 3318 unsigned char *ROMAddr = NULL; 3319 unsigned short tempax, tempbx, modeflag, romptr=0; 3320 unsigned short resinfo, CRT2Index, ResIndex; 3321 const struct SiS_LCDData *LCDPtr = NULL; 3322 const struct SiS_TVData *TVPtr = NULL; 3323#ifdef SIS315H 3324 short resinfo661; 3325#endif 3326 3327 if(ModeNo <= 0x13) { 3328 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 3329 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 3330 } else if(SiS_Pr->UseCustomMode) { 3331 modeflag = SiS_Pr->CModeFlag; 3332 resinfo = 0; 3333 } else { 3334 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3335 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 3336#ifdef SIS315H 3337 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661; 3338 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && 3339 (SiS_Pr->SiS_SetFlag & LCDVESATiming) && 3340 (resinfo661 >= 0) && 3341 (SiS_Pr->SiS_NeedRomModeData) ) { 3342 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) { 3343 if((romptr = (SISGETROMW(21)))) { 3344 romptr += (resinfo661 * 10); 3345 ROMAddr = SiS_Pr->VirtualRomBase; 3346 } 3347 } 3348 } 3349#endif 3350 } 3351 3352 SiS_Pr->SiS_NewFlickerMode = 0; 3353 SiS_Pr->SiS_RVBHRS = 50; 3354 SiS_Pr->SiS_RY1COE = 0; 3355 SiS_Pr->SiS_RY2COE = 0; 3356 SiS_Pr->SiS_RY3COE = 0; 3357 SiS_Pr->SiS_RY4COE = 0; 3358 SiS_Pr->SiS_RVBHRS2 = 0; 3359 3360 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex); 3361 3362 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 3363 3364 if(SiS_Pr->UseCustomMode) { 3365 3366 SiS_Pr->SiS_RVBHCMAX = 1; 3367 SiS_Pr->SiS_RVBHCFACT = 1; 3368 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; 3369 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; 3370 3371 tempax = SiS_Pr->CHTotal; 3372 if(modeflag & HalfDCLK) tempax <<= 1; 3373 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; 3374 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal; 3375 3376 } else { 3377 3378 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3379 3380 } 3381 3382 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 3383 3384 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex, 3385 &CRT2Index,&ResIndex); 3386 3387 switch(CRT2Index) { 3388 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break; 3389 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break; 3390 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break; 3391 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break; 3392 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break; 3393 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break; 3394 case 8: TVPtr = SiS_Pr->SiS_StPALData; break; 3395 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break; 3396 case 10: TVPtr = SiS_Pr->SiS_St525iData; break; 3397 case 11: TVPtr = SiS_Pr->SiS_St525pData; break; 3398 case 12: TVPtr = SiS_Pr->SiS_St750pData; break; 3399 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break; 3400 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break; 3401 case 15: TVPtr = SiS_Pr->SiS_Ext625iData; break; 3402 case 16: TVPtr = SiS_Pr->SiS_Ext625pData; break; 3403 case 20: TVPtr = SiS_Pr->SiS_St625iData; break; 3404 case 21: TVPtr = SiS_Pr->SiS_St625pData; break; 3405 default: TVPtr = SiS_Pr->SiS_StPALData; break; 3406 } 3407 3408 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX; 3409 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT; 3410 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT; 3411 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT; 3412 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE; 3413 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE; 3414 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff; 3415 if(modeflag & HalfDCLK) { 3416 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS; 3417 if(SiS_Pr->SiS_RVBHRS2) { 3418 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3; 3419 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07; 3420 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax; 3421 else SiS_Pr->SiS_RVBHRS2 += tempax; 3422 } 3423 } else { 3424 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS; 3425 } 3426 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7; 3427 3428 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 3429 3430 if((resinfo == SIS_RI_960x540) || 3431 (resinfo == SIS_RI_960x600) || 3432 (resinfo == SIS_RI_1024x768) || 3433 (resinfo == SIS_RI_1280x1024) || 3434 (resinfo == SIS_RI_1280x720)) { 3435 SiS_Pr->SiS_NewFlickerMode = 0x40; 3436 } 3437 3438 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode; 3439 3440 SiS_Pr->SiS_HT = ExtHiTVHT; 3441 SiS_Pr->SiS_VT = ExtHiTVVT; 3442 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 3443 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 3444 SiS_Pr->SiS_HT = StHiTVHT; 3445 SiS_Pr->SiS_VT = StHiTVVT; 3446 } 3447 } 3448 3449 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3450 3451 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 3452 SiS_Pr->SiS_HT = 1650; 3453 SiS_Pr->SiS_VT = 750; 3454 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 3455 SiS_Pr->SiS_HT = NTSCHT; 3456 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT; 3457 SiS_Pr->SiS_VT = NTSCVT; 3458 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) { 3459 SiS_Pr->SiS_HT = NTSCHT; 3460 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT; 3461 SiS_Pr->SiS_VT = NTSCVT; 3462 } else { 3463 SiS_Pr->SiS_HT = PALHT; 3464 SiS_Pr->SiS_VT = PALVT; 3465 } 3466 3467 } else { 3468 3469 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE; 3470 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE; 3471 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE; 3472 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE; 3473 3474 if(modeflag & HalfDCLK) { 3475 SiS_Pr->SiS_RY1COE = 0x00; 3476 SiS_Pr->SiS_RY2COE = 0xf4; 3477 SiS_Pr->SiS_RY3COE = 0x10; 3478 SiS_Pr->SiS_RY4COE = 0x38; 3479 } 3480 3481 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 3482 SiS_Pr->SiS_HT = NTSCHT; 3483 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT; 3484 SiS_Pr->SiS_VT = NTSCVT; 3485 } else { 3486 SiS_Pr->SiS_HT = PALHT; 3487 SiS_Pr->SiS_VT = PALVT; 3488 } 3489 3490 } 3491 3492 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3493 3494 SiS_Pr->SiS_RVBHCMAX = 1; 3495 SiS_Pr->SiS_RVBHCFACT = 1; 3496 3497 if(SiS_Pr->UseCustomMode) { 3498 3499 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; 3500 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; 3501 3502 tempax = SiS_Pr->CHTotal; 3503 if(modeflag & HalfDCLK) tempax <<= 1; 3504 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; 3505 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal; 3506 3507 } else { 3508 3509 BOOLEAN gotit = FALSE; 3510 3511 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 3512 3513 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT; 3514 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT; 3515 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3516 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3517 gotit = TRUE; 3518 3519 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) { 3520 3521#ifdef SIS315H 3522 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr]; 3523 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1]; 3524 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8); 3525 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4); 3526 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8); 3527 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4); 3528 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8); 3529 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) { 3530 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3; 3531 tempax = (ROMAddr[romptr+9] >> 4) & 0x07; 3532 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax; 3533 else SiS_Pr->SiS_RVBHRS2 += tempax; 3534 } 3535 if(SiS_Pr->SiS_VGAHT) gotit = TRUE; 3536 else { 3537 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 3538 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 3539 SiS_Pr->SiS_RVBHCMAX = 1; 3540 SiS_Pr->SiS_RVBHCFACT = 1; 3541 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT; 3542 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT; 3543 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3544 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3545 SiS_Pr->SiS_RVBHRS2 = 0; 3546 gotit = TRUE; 3547 } 3548#endif 3549 3550 } 3551 3552 if(!gotit) { 3553 3554 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex, 3555 &CRT2Index,&ResIndex); 3556 3557 switch(CRT2Index) { 3558 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; 3559 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break; 3560 case Panel_1280x720 : 3561 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break; 3562 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break; 3563 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break; 3564 case Panel_1280x800 : 3565 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break; 3566 case Panel_1280x800_2 : 3567 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break; 3568 case Panel_1280x854 : 3569 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break; 3570 case Panel_1280x960 : 3571 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break; 3572 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break; 3573 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; 3574 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break; 3575 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break; 3576 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break; 3577 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break; 3578 case Panel_1680x1050 : 3579 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break; 3580 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break; 3581#ifdef SIS315H 3582 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break; 3583 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; 3584#endif 3585 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; 3586 } 3587 3588#ifdef SIS_XORG_XF86 3589#ifdef TWDEBUG 3590 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex); 3591#endif 3592#endif 3593 3594 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX; 3595 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT; 3596 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT; 3597 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT; 3598 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT; 3599 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT; 3600 3601 } 3602 3603 tempax = SiS_Pr->PanelXRes; 3604 tempbx = SiS_Pr->PanelYRes; 3605 3606 switch(SiS_Pr->SiS_LCDResInfo) { 3607 case Panel_1024x768: 3608 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 3609 if(SiS_Pr->ChipType < SIS_315H) { 3610 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; 3611 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; 3612 } 3613 } else { 3614 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527; 3615 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620; 3616 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775; 3617 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775; 3618 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; 3619 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; 3620 } 3621 break; 3622 case Panel_1280x960: 3623 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700; 3624 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800; 3625 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960; 3626 break; 3627 case Panel_1280x1024: 3628 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768; 3629 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800; 3630 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864; 3631 break; 3632 case Panel_1600x1200: 3633 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 3634 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875; 3635 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000; 3636 } 3637 break; 3638 } 3639 3640 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3641 tempax = SiS_Pr->SiS_VGAHDE; 3642 tempbx = SiS_Pr->SiS_VGAVDE; 3643 } 3644 3645 SiS_Pr->SiS_HDE = tempax; 3646 SiS_Pr->SiS_VDE = tempbx; 3647 } 3648 } 3649} 3650 3651static void 3652SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3653 unsigned short RefreshRateTableIndex) 3654{ 3655 3656 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3657 3658 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 3659 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3660 } else { 3661 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 3662 /* Need LVDS Data for LCD on 301B-DH */ 3663 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3664 } else { 3665 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3666 } 3667 } 3668 3669 } else { 3670 3671 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3672 3673 } 3674} 3675 3676/*********************************************/ 3677/* GET LVDS DES (SKEW) DATA */ 3678/*********************************************/ 3679 3680static const struct SiS_LVDSDes * 3681SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr) 3682{ 3683 const struct SiS_LVDSDes *PanelDesPtr = NULL; 3684 3685#ifdef SIS300 3686 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3687 3688 if(SiS_Pr->ChipType < SIS_315H) { 3689 if(SiS_Pr->SiS_LCDTypeInfo == 4) { 3690 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 3691 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a; 3692 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3693 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a; 3694 } 3695 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 3696 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b; 3697 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3698 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b; 3699 } 3700 } 3701 } 3702 } 3703 } 3704#endif 3705 return PanelDesPtr; 3706} 3707 3708static void 3709SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3710 unsigned short RefreshRateTableIndex) 3711{ 3712 unsigned short modeflag, ResIndex; 3713 const struct SiS_LVDSDes *PanelDesPtr = NULL; 3714 3715 SiS_Pr->SiS_LCDHDES = 0; 3716 SiS_Pr->SiS_LCDVDES = 0; 3717 3718 /* Some special cases */ 3719 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3720 3721 /* Trumpion */ 3722 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 3723 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 3724 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3725 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3726 } 3727 } 3728 return; 3729 } 3730 3731 /* 640x480 on LVDS */ 3732 if(SiS_Pr->ChipType < SIS_315H) { 3733 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) { 3734 SiS_Pr->SiS_LCDHDES = 8; 3735 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512; 3736 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436; 3737 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440; 3738 return; 3739 } 3740 } 3741 3742 } /* LCD */ 3743 3744 if( (SiS_Pr->UseCustomMode) || 3745 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) || 3746 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 3747 (SiS_Pr->SiS_CustomT == CUT_PANEL856) || 3748 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) { 3749 return; 3750 } 3751 3752 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 3753 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 3754 3755 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3756 3757#ifdef SIS315H 3758 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3759 /* non-pass 1:1 only, see above */ 3760 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) { 3761 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2); 3762 } 3763 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) { 3764 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2); 3765 } 3766 } 3767 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3768 switch(SiS_Pr->SiS_CustomT) { 3769 case CUT_UNIWILL1024: 3770 case CUT_UNIWILL10242: 3771 case CUT_CLEVO1400: 3772 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 3773 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3774 } 3775 break; 3776 } 3777 switch(SiS_Pr->SiS_LCDResInfo) { 3778 case Panel_1280x1024: 3779 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { 3780 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3781 } 3782 break; 3783 case Panel_1280x800: /* Verified for Averatec 6240 */ 3784 case Panel_1280x800_2: /* Verified for Asus A4L */ 3785 case Panel_1280x854: /* Not verified yet FIXME */ 3786 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3787 break; 3788 } 3789 } 3790#endif 3791 3792 } else { 3793 3794 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 3795 3796 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) { 3797 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256; 3798 } 3799 3800 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) { 3801 3802 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES; 3803 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES; 3804 3805 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3806 3807 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) { 3808 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2); 3809 } 3810 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) { 3811 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2); 3812 } else { 3813 if(SiS_Pr->ChipType < SIS_315H) { 3814 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3815 } else { 3816 switch(SiS_Pr->SiS_LCDResInfo) { 3817 case Panel_800x600: 3818 case Panel_1024x768: 3819 case Panel_1280x1024: 3820 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT; 3821 break; 3822 case Panel_1400x1050: 3823 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3824 break; 3825 } 3826 } 3827 } 3828 3829 } else { 3830 3831 if(SiS_Pr->ChipType < SIS_315H) { 3832#ifdef SIS300 3833 switch(SiS_Pr->SiS_LCDResInfo) { 3834 case Panel_800x600: 3835 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3836 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3837 } else { 3838 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3; 3839 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT; 3840 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2; 3841 else SiS_Pr->SiS_LCDVDES -= 4; 3842 } 3843 break; 3844 case Panel_1024x768: 3845 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3846 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3847 } else { 3848 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1; 3849 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8; 3850 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12; 3851 } 3852 break; 3853 case Panel_1024x600: 3854 default: 3855 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) && 3856 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) { 3857 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3858 } else { 3859 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1; 3860 } 3861 break; 3862 } 3863 3864 switch(SiS_Pr->SiS_LCDTypeInfo) { 3865 case 1: 3866 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0; 3867 break; 3868 case 3: /* 640x480 only? */ 3869 SiS_Pr->SiS_LCDHDES = 8; 3870 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512; 3871 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436; 3872 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440; 3873 break; 3874 } 3875#endif 3876 } else { 3877#ifdef SIS315H 3878 switch(SiS_Pr->SiS_LCDResInfo) { 3879 case Panel_1024x768: 3880 case Panel_1280x1024: 3881 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3882 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3883 } 3884 break; 3885 case Panel_320x240_1: 3886 case Panel_320x240_2: 3887 case Panel_320x240_3: 3888 SiS_Pr->SiS_LCDVDES = 524; 3889 break; 3890 } 3891#endif 3892 } 3893 } 3894 3895 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 3896 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 3897 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3898 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632; 3899 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) { 3900 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) { 3901 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) { 3902 if(SiS_Pr->ChipType < SIS_315H) { 3903 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320; 3904 } else { 3905#ifdef SIS315H 3906 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480; 3907 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804; 3908 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704; 3909 if(!(modeflag & HalfDCLK)) { 3910 SiS_Pr->SiS_LCDHDES = 320; 3911 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632; 3912 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542; 3913 } 3914#endif 3915 } 3916 } 3917 } 3918 } 3919 } 3920 } 3921} 3922 3923/*********************************************/ 3924/* DISABLE VIDEO BRIDGE */ 3925/*********************************************/ 3926 3927#ifdef SIS315H 3928static int 3929SiS_HandlePWD(struct SiS_Private *SiS_Pr) 3930{ 3931 int ret = 0; 3932#ifdef SET_PWD 3933 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 3934 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr); 3935 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40; 3936 unsigned short temp; 3937 3938 if( (SiS_Pr->SiS_VBType & VB_SISPWD) && 3939 (romptr) && 3940 (SiS_Pr->SiS_PWDOffset) ) { 3941 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]); 3942 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]); 3943 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]); 3944 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]); 3945 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]); 3946 temp = 0x00; 3947 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) { 3948 temp = 0x80; 3949 ret = 1; 3950 } 3951 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp); 3952#ifdef SIS_XORG_XF86 3953#ifdef TWDEBUG 3954 xf86DrvMsg(0, 0, "Setting PWD %x\n", temp); 3955#endif 3956#endif 3957 } 3958#endif 3959 return ret; 3960} 3961#endif 3962 3963/* NEVER use any variables (VBInfo), this will be called 3964 * from outside the context of modeswitch! 3965 * MUST call getVBType before calling this 3966 */ 3967void 3968SiS_DisableBridge(struct SiS_Private *SiS_Pr) 3969{ 3970#ifdef SIS315H 3971 unsigned short tempah, pushax=0, modenum; 3972#endif 3973 unsigned short temp=0; 3974 3975 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3976 3977 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */ 3978 3979 if(SiS_Pr->ChipType < SIS_315H) { 3980 3981#ifdef SIS300 /* 300 series */ 3982 3983 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 3984 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 3985 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); 3986 } else { 3987 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 3988 } 3989 SiS_PanelDelay(SiS_Pr, 3); 3990 } 3991 if(SiS_Is301B(SiS_Pr)) { 3992 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f); 3993 SiS_ShortDelay(SiS_Pr,1); 3994 } 3995 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); 3996 SiS_DisplayOff(SiS_Pr); 3997 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 3998 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 3999 SiS_UnLockCRT2(SiS_Pr); 4000 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) { 4001 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); 4002 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 4003 } 4004 if( (!(SiS_CRT2IsLCD(SiS_Pr))) || 4005 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { 4006 SiS_PanelDelay(SiS_Pr, 2); 4007 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4008 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); 4009 } else { 4010 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4011 } 4012 } 4013 4014#endif /* SIS300 */ 4015 4016 } else { 4017 4018#ifdef SIS315H /* 315 series */ 4019 4020 int didpwd = 0; 4021 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) || 4022 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE; 4023 4024 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f; 4025 4026 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4027 4028#ifdef SET_EMI 4029 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4030 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) { 4031 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4032 } 4033 } 4034#endif 4035 4036 didpwd = SiS_HandlePWD(SiS_Pr); 4037 4038 if( (modenum <= 0x13) || 4039 (SiS_IsVAMode(SiS_Pr)) || 4040 (!(SiS_IsDualEdge(SiS_Pr))) ) { 4041 if(!didpwd) { 4042 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe); 4043 if(custom1) SiS_PanelDelay(SiS_Pr, 3); 4044 } else { 4045 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc); 4046 } 4047 } 4048 4049 if(!custom1) { 4050 SiS_DDC2Delay(SiS_Pr,0xff00); 4051 SiS_DDC2Delay(SiS_Pr,0xe000); 4052 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00); 4053 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06); 4054 if(IS_SIS740) { 4055 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); 4056 } 4057 SiS_PanelDelay(SiS_Pr, 3); 4058 } 4059 4060 } 4061 4062 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4063 /* if(SiS_Pr->ChipType < SIS_340) {*/ 4064 tempah = 0xef; 4065 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7; 4066 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah); 4067 /*}*/ 4068 } 4069 4070 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4071 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10); 4072 } 4073 4074 tempah = 0x3f; 4075 if(SiS_IsDualEdge(SiS_Pr)) { 4076 tempah = 0x7f; 4077 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf; 4078 } 4079 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah); 4080 4081 if((SiS_IsVAMode(SiS_Pr)) || 4082 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) { 4083 4084 SiS_DisplayOff(SiS_Pr); 4085 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4086 SiS_PanelDelay(SiS_Pr, 2); 4087 } 4088 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4089 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF); 4090 4091 } 4092 4093 if((!(SiS_IsVAMode(SiS_Pr))) || 4094 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) { 4095 4096 if(!(SiS_IsDualEdge(SiS_Pr))) { 4097 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf); 4098 SiS_DisplayOff(SiS_Pr); 4099 } 4100 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4101 4102 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4103 SiS_PanelDelay(SiS_Pr, 2); 4104 } 4105 4106 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4107 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 4108 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); 4109 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4110 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); 4111 4112 } 4113 4114 if(SiS_IsNotM650orLater(SiS_Pr)) { 4115 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4116 } 4117 4118 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4119 4120 if( (!(SiS_IsVAMode(SiS_Pr))) && 4121 (!(SiS_CRT2IsLCD(SiS_Pr))) && 4122 (!(SiS_IsDualEdge(SiS_Pr))) ) { 4123 4124 if(custom1) SiS_PanelDelay(SiS_Pr, 2); 4125 if(!didpwd) { 4126 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); 4127 } 4128 if(custom1) SiS_PanelDelay(SiS_Pr, 4); 4129 } 4130 4131 if(!custom1) { 4132 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax); 4133 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4134 if(SiS_IsVAorLCD(SiS_Pr)) { 4135 SiS_PanelDelayLoop(SiS_Pr, 3, 20); 4136 } 4137 } 4138 } 4139 4140 } 4141 4142#endif /* SIS315H */ 4143 4144 } 4145 4146 } else { /* ============ For 301 ================ */ 4147 4148 if(SiS_Pr->ChipType < SIS_315H) { 4149#ifdef SIS300 4150 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4151 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4152 SiS_PanelDelay(SiS_Pr, 3); 4153 } 4154#endif 4155 } 4156 4157 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */ 4158 SiS_DisplayOff(SiS_Pr); 4159 4160 if(SiS_Pr->ChipType >= SIS_315H) { 4161 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4162 } 4163 4164 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */ 4165 4166 if(SiS_Pr->ChipType >= SIS_315H) { 4167 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 4168 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); 4169 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4170 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); 4171 } else { 4172#ifdef SIS300 4173 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */ 4174 if( (!(SiS_CRT2IsLCD(SiS_Pr))) || 4175 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { 4176 SiS_PanelDelay(SiS_Pr, 2); 4177 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4178 } 4179#endif 4180 } 4181 4182 } 4183 4184 } else { /* ============ For LVDS =============*/ 4185 4186 if(SiS_Pr->ChipType < SIS_315H) { 4187 4188#ifdef SIS300 /* 300 series */ 4189 4190 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 4191 SiS_SetCH700x(SiS_Pr,0x0E,0x09); 4192 } 4193 4194 if(SiS_Pr->ChipType == SIS_730) { 4195 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { 4196 SiS_WaitVBRetrace(SiS_Pr); 4197 } 4198 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4199 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4200 SiS_PanelDelay(SiS_Pr, 3); 4201 } 4202 } else { 4203 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { 4204 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4205 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4206 SiS_WaitVBRetrace(SiS_Pr); 4207 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) { 4208 SiS_DisplayOff(SiS_Pr); 4209 } 4210 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4211 SiS_PanelDelay(SiS_Pr, 3); 4212 } 4213 } 4214 } 4215 } 4216 4217 SiS_DisplayOff(SiS_Pr); 4218 4219 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4220 4221 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4222 SiS_UnLockCRT2(SiS_Pr); 4223 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); 4224 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 4225 4226 if( (!(SiS_CRT2IsLCD(SiS_Pr))) || 4227 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { 4228 SiS_PanelDelay(SiS_Pr, 2); 4229 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4230 } 4231 4232#endif /* SIS300 */ 4233 4234 } else { 4235 4236#ifdef SIS315H /* 315 series */ 4237 4238 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4239 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */ 4240 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18); 4241 /* } */ 4242 } 4243 4244 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 4245 4246 if(SiS_Pr->ChipType == SIS_740) { 4247 temp = SiS_GetCH701x(SiS_Pr,0x61); 4248 if(temp < 1) { 4249 SiS_SetCH701x(SiS_Pr,0x76,0xac); 4250 SiS_SetCH701x(SiS_Pr,0x66,0x00); 4251 } 4252 4253 if( (!(SiS_IsDualEdge(SiS_Pr))) || 4254 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) { 4255 SiS_SetCH701x(SiS_Pr,0x49,0x3e); 4256 } 4257 } 4258 4259 if( (!(SiS_IsDualEdge(SiS_Pr))) || 4260 (SiS_IsVAMode(SiS_Pr)) ) { 4261 SiS_Chrontel701xBLOff(SiS_Pr); 4262 SiS_Chrontel701xOff(SiS_Pr); 4263 } 4264 4265 if(SiS_Pr->ChipType != SIS_740) { 4266 if( (!(SiS_IsDualEdge(SiS_Pr))) || 4267 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) { 4268 SiS_SetCH701x(SiS_Pr,0x49,0x01); 4269 } 4270 } 4271 4272 } 4273 4274 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4275 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4276 SiS_PanelDelay(SiS_Pr, 3); 4277 } 4278 4279 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4280 (!(SiS_IsDualEdge(SiS_Pr))) || 4281 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) { 4282 SiS_DisplayOff(SiS_Pr); 4283 } 4284 4285 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4286 (!(SiS_IsDualEdge(SiS_Pr))) || 4287 (!(SiS_IsVAMode(SiS_Pr))) ) { 4288 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4289 } 4290 4291 if(SiS_Pr->ChipType == SIS_740) { 4292 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4293 } 4294 4295 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4296 4297 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4298 (!(SiS_IsDualEdge(SiS_Pr))) || 4299 (!(SiS_IsVAMode(SiS_Pr))) ) { 4300 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4301 } 4302 4303 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4304 if(SiS_CRT2IsLCD(SiS_Pr)) { 4305 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4306 if(SiS_Pr->ChipType == SIS_550) { 4307 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf); 4308 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef); 4309 } 4310 } 4311 } else { 4312 if(SiS_Pr->ChipType == SIS_740) { 4313 if(SiS_IsLCDOrLCDA(SiS_Pr)) { 4314 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4315 } 4316 } else if(SiS_IsVAMode(SiS_Pr)) { 4317 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4318 } 4319 } 4320 4321 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 4322 if(SiS_IsDualEdge(SiS_Pr)) { 4323 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */ 4324 } else { 4325 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 4326 } 4327 } 4328 4329 SiS_UnLockCRT2(SiS_Pr); 4330 4331 if(SiS_Pr->ChipType == SIS_550) { 4332 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/ 4333 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */ 4334 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4335 (!(SiS_IsDualEdge(SiS_Pr))) || 4336 (!(SiS_IsVAMode(SiS_Pr))) ) { 4337 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); 4338 } 4339 4340 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4341 if(SiS_CRT2IsLCD(SiS_Pr)) { 4342 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4343 SiS_PanelDelay(SiS_Pr, 2); 4344 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4345 } 4346 } 4347 } 4348 4349#endif /* SIS315H */ 4350 4351 } /* 315 series */ 4352 4353 } /* LVDS */ 4354 4355} 4356 4357/*********************************************/ 4358/* ENABLE VIDEO BRIDGE */ 4359/*********************************************/ 4360 4361/* NEVER use any variables (VBInfo), this will be called 4362 * from outside the context of a mode switch! 4363 * MUST call getVBType before calling this 4364 */ 4365#ifdef SIS_LINUX_KERNEL 4366static 4367#endif 4368void 4369SiS_EnableBridge(struct SiS_Private *SiS_Pr) 4370{ 4371 unsigned short temp=0, tempah; 4372#ifdef SIS315H 4373 unsigned short temp1, pushax=0; 4374 BOOLEAN delaylong = FALSE; 4375#endif 4376 4377 if(SiS_Pr->SiS_VBType & VB_SISVB) { 4378 4379 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */ 4380 4381 if(SiS_Pr->ChipType < SIS_315H) { 4382 4383#ifdef SIS300 /* 300 series */ 4384 4385 if(SiS_CRT2IsLCD(SiS_Pr)) { 4386 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4387 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 4388 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { 4389 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4390 } 4391 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) { 4392 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) { 4393 SiS_PanelDelay(SiS_Pr, 0); 4394 } 4395 } 4396 } 4397 4398 if((SiS_Pr->SiS_VBType & VB_NoLCD) && 4399 (SiS_CRT2IsLCD(SiS_Pr))) { 4400 4401 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */ 4402 SiS_DisplayOn(SiS_Pr); 4403 SiS_UnLockCRT2(SiS_Pr); 4404 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); 4405 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4406 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); 4407 } else { 4408 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); 4409 } 4410 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4411 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4412 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4413 SiS_PanelDelay(SiS_Pr, 1); 4414 } 4415 SiS_WaitVBRetrace(SiS_Pr); 4416 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 4417 } 4418 } 4419 4420 } else { 4421 4422 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ 4423 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4424 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4425 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; 4426 } 4427 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4428 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4429 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ 4430 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0); 4431 SiS_DisplayOn(SiS_Pr); 4432 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4433 if(SiS_CRT2IsLCD(SiS_Pr)) { 4434 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4435 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4436 SiS_PanelDelay(SiS_Pr, 1); 4437 } 4438 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 4439 } 4440 } 4441 } 4442 4443 } 4444 4445 4446#endif /* SIS300 */ 4447 4448 } else { 4449 4450#ifdef SIS315H /* 315 series */ 4451 4452#ifdef SET_EMI 4453 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0; 4454 int didpwd = 0; 4455 /* unsigned short emidelay=0; */ 4456#endif 4457 4458 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4459 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef); 4460#ifdef SET_EMI 4461 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4462 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4463 } 4464#endif 4465 } 4466 4467 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4468 /*if(SiS_Pr->ChipType < SIS_340) { */ 4469 tempah = 0x10; 4470 if(SiS_LCDAEnabled(SiS_Pr)) { 4471 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18; 4472 else tempah = 0x08; 4473 } 4474 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah); 4475 /*}*/ 4476 } 4477 4478 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4479 4480 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00); 4481 SiS_DisplayOff(SiS_Pr); 4482 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06); 4483 if(IS_SIS740) { 4484 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); 4485 } 4486 4487 didpwd = SiS_HandlePWD(SiS_Pr); 4488 4489 if(SiS_IsVAorLCD(SiS_Pr)) { 4490 if(!didpwd) { 4491 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { 4492 SiS_PanelDelayLoop(SiS_Pr, 3, 2); 4493 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 4494 SiS_PanelDelayLoop(SiS_Pr, 3, 2); 4495 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4496 SiS_GenericDelay(SiS_Pr, 17664); 4497 } 4498 } 4499 } else { 4500 SiS_PanelDelayLoop(SiS_Pr, 3, 2); 4501 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4502 SiS_GenericDelay(SiS_Pr, 17664); 4503 } 4504 } 4505 } 4506 4507 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) { 4508 SiS_PanelDelayLoop(SiS_Pr, 3, 10); 4509 delaylong = TRUE; 4510 } 4511 4512 } 4513 4514 if(!(SiS_IsVAMode(SiS_Pr))) { 4515 4516 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; 4517 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4518 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4519 if(!(tempah & SetCRT2ToRAMDAC)) { 4520 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20; 4521 } 4522 } 4523 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4524 4525 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ 4526 4527 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4528 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4529 4530 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4531 SiS_PanelDelay(SiS_Pr, 2); 4532 } 4533 4534 } else { 4535 4536 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20); 4537 4538 } 4539 4540 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20); 4541 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4542 4543 if(SiS_Pr->SiS_VBType & VB_SISPOWER) { 4544 if( (SiS_LCDAEnabled(SiS_Pr)) || 4545 (SiS_CRT2IsLCD(SiS_Pr)) ) { 4546 /* Enable "LVDS PLL power on" (even on 301C) */ 4547 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f); 4548 /* Enable "LVDS Driver Power on" (even on 301C) */ 4549 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f); 4550 } 4551 } 4552 4553 tempah = 0xc0; 4554 if(SiS_IsDualEdge(SiS_Pr)) { 4555 tempah = 0x80; 4556 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40; 4557 } 4558 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah); 4559 4560 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4561 4562 SiS_PanelDelay(SiS_Pr, 2); 4563 4564 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10); 4565 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4566 4567 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) { 4568#ifdef SET_EMI 4569 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4570 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4571 SiS_GenericDelay(SiS_Pr, 2048); 4572 } 4573#endif 4574 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c); 4575 4576 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4577#ifdef SET_EMI 4578 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 4579 4580 if(SiS_Pr->SiS_ROMNew) { 4581 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 4582 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr); 4583 if(romptr) { 4584 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */ 4585 SiS_Pr->EMI_30 = 0; 4586 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0]; 4587 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1]; 4588 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2]; 4589 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40; 4590 /* emidelay = SISGETROMW((romptr + 0x22)); */ 4591 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE; 4592 } 4593 } 4594 4595 /* (P4_30|0x40) */ 4596 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */ 4597 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */ 4598 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */ 4599 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */ 4600 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */ 4601 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */ 4602 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */ 4603 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */ 4604 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */ 4605 4606 if(SiS_Pr->HaveEMI) { 4607 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31; 4608 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33; 4609 } else { 4610 r30 = 0; 4611 } 4612 4613 /* EMI_30 is read at driver start; however, the BIOS sets this 4614 * (if it is used) only if the LCD is in use. In case we caught 4615 * the machine while on TV output, this bit is not set and we 4616 * don't know if it should be set - hence our detection is wrong. 4617 * Work-around this here: 4618 */ 4619 4620 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) { 4621 switch((cr36 & 0x0f)) { 4622 case 2: 4623 r30 |= 0x40; 4624 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40; 4625 if(!SiS_Pr->HaveEMI) { 4626 r31 = 0x05; r32 = 0x60; r33 = 0x33; 4627 if((cr36 & 0xf0) == 0x30) { 4628 r31 = 0x0d; r32 = 0x70; r33 = 0x40; 4629 } 4630 } 4631 break; 4632 case 3: /* 1280x1024 */ 4633 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40; 4634 if(!SiS_Pr->HaveEMI) { 4635 r31 = 0x12; r32 = 0xd0; r33 = 0x6b; 4636 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 4637 r31 = 0x0d; r32 = 0x70; r33 = 0x6b; 4638 } 4639 } 4640 break; 4641 case 9: /* 1400x1050 */ 4642 r30 |= 0x40; 4643 if(!SiS_Pr->HaveEMI) { 4644 r31 = 0x05; r32 = 0x60; r33 = 0x00; 4645 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) { 4646 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */ 4647 } 4648 } 4649 break; 4650 case 11: /* 1600x1200 - unknown */ 4651 r30 |= 0x40; 4652 if(!SiS_Pr->HaveEMI) { 4653 r31 = 0x05; r32 = 0x60; r33 = 0x00; 4654 } 4655 } 4656 } 4657 4658 /* BIOS values don't work so well sometimes */ 4659 if(!SiS_Pr->OverruleEMI) { 4660#ifdef COMPAL_HACK 4661 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) { 4662 if((cr36 & 0x0f) == 0x09) { 4663 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00; 4664 } 4665 } 4666#endif 4667#ifdef COMPAQ_HACK 4668 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 4669 if((cr36 & 0x0f) == 0x03) { 4670 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b; 4671 } 4672 } 4673#endif 4674#ifdef ASUS_HACK 4675 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 4676 if((cr36 & 0x0f) == 0x02) { 4677 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */ 4678 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */ 4679 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */ 4680 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */ 4681 } 4682 } 4683#endif 4684 } 4685 4686 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) { 4687 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */ 4688 SiS_GenericDelay(SiS_Pr, 2048); 4689 } 4690 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31); 4691 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32); 4692 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33); 4693#endif /* SET_EMI */ 4694 4695 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 4696 4697#ifdef SET_EMI 4698 if( (SiS_LCDAEnabled(SiS_Pr)) || 4699 (SiS_CRT2IsLCD(SiS_Pr)) ) { 4700 if(r30 & 0x40) { 4701 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/ 4702 SiS_PanelDelayLoop(SiS_Pr, 3, 5); 4703 if(delaylong) { 4704 SiS_PanelDelayLoop(SiS_Pr, 3, 5); 4705 delaylong = FALSE; 4706 } 4707 SiS_WaitVBRetrace(SiS_Pr); 4708 SiS_WaitVBRetrace(SiS_Pr); 4709 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 4710 SiS_GenericDelay(SiS_Pr, 1280); 4711 } 4712 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */ 4713 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/ 4714 } 4715 } 4716#endif 4717 } 4718 } 4719 4720 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4721 if(SiS_IsVAorLCD(SiS_Pr)) { 4722 SiS_PanelDelayLoop(SiS_Pr, 3, 10); 4723 if(delaylong) { 4724 SiS_PanelDelayLoop(SiS_Pr, 3, 10); 4725 } 4726 SiS_WaitVBRetrace(SiS_Pr); 4727 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4728 SiS_GenericDelay(SiS_Pr, 2048); 4729 SiS_WaitVBRetrace(SiS_Pr); 4730 } 4731 if(!didpwd) { 4732 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 4733 } else { 4734 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03); 4735 } 4736 } 4737 } 4738 4739 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax); 4740 SiS_DisplayOn(SiS_Pr); 4741 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff); 4742 4743 } 4744 4745 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4746 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4747 } 4748 4749#endif /* SIS315H */ 4750 4751 } 4752 4753 } else { /* ============ For 301 ================ */ 4754 4755 if(SiS_Pr->ChipType < SIS_315H) { 4756 if(SiS_CRT2IsLCD(SiS_Pr)) { 4757 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4758 SiS_PanelDelay(SiS_Pr, 0); 4759 } 4760 } 4761 4762 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ 4763 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4764 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4765 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; 4766 } 4767 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4768 4769 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ 4770 4771 if(SiS_Pr->ChipType >= SIS_315H) { 4772 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E); 4773 if(!(temp & 0x80)) { 4774 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */ 4775 } 4776 } 4777 4778 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ 4779 4780 SiS_VBLongWait(SiS_Pr); 4781 SiS_DisplayOn(SiS_Pr); 4782 if(SiS_Pr->ChipType >= SIS_315H) { 4783 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4784 } 4785 SiS_VBLongWait(SiS_Pr); 4786 4787 if(SiS_Pr->ChipType < SIS_315H) { 4788 if(SiS_CRT2IsLCD(SiS_Pr)) { 4789 SiS_PanelDelay(SiS_Pr, 1); 4790 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 4791 } 4792 } 4793 4794 } 4795 4796 } else { /* =================== For LVDS ================== */ 4797 4798 if(SiS_Pr->ChipType < SIS_315H) { 4799 4800#ifdef SIS300 /* 300 series */ 4801 4802 if(SiS_CRT2IsLCD(SiS_Pr)) { 4803 if(SiS_Pr->ChipType == SIS_730) { 4804 SiS_PanelDelay(SiS_Pr, 1); 4805 SiS_PanelDelay(SiS_Pr, 1); 4806 SiS_PanelDelay(SiS_Pr, 1); 4807 } 4808 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4809 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) { 4810 SiS_PanelDelay(SiS_Pr, 0); 4811 } 4812 } 4813 4814 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4815 SiS_DisplayOn(SiS_Pr); 4816 SiS_UnLockCRT2(SiS_Pr); 4817 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); 4818 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4819 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); 4820 } else { 4821 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); 4822 } 4823 4824 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 4825 if(!(SiS_CRT2IsLCD(SiS_Pr))) { 4826 SiS_WaitVBRetrace(SiS_Pr); 4827 SiS_SetCH700x(SiS_Pr,0x0E,0x0B); 4828 } 4829 } 4830 4831 if(SiS_CRT2IsLCD(SiS_Pr)) { 4832 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4833 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4834 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4835 SiS_PanelDelay(SiS_Pr, 1); 4836 SiS_PanelDelay(SiS_Pr, 1); 4837 } 4838 SiS_WaitVBRetrace(SiS_Pr); 4839 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 4840 } 4841 } 4842 } 4843 4844#endif /* SIS300 */ 4845 4846 } else { 4847 4848#ifdef SIS315H /* 315 series */ 4849 4850 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4851 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */ 4852 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18); 4853 /*}*/ 4854 } 4855 4856 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4857 if(SiS_CRT2IsLCD(SiS_Pr)) { 4858 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4859 SiS_PanelDelay(SiS_Pr, 0); 4860 } 4861 } 4862 4863 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4864 SiS_UnLockCRT2(SiS_Pr); 4865 4866 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); 4867 4868 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4869 temp = SiS_GetCH701x(SiS_Pr,0x66); 4870 temp &= 0x20; 4871 SiS_Chrontel701xBLOff(SiS_Pr); 4872 } 4873 4874 if(SiS_Pr->ChipType != SIS_550) { 4875 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4876 } 4877 4878 if(SiS_Pr->ChipType == SIS_740) { 4879 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4880 if(SiS_IsLCDOrLCDA(SiS_Pr)) { 4881 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 4882 } 4883 } 4884 } 4885 4886 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E); 4887 if(!(temp1 & 0x80)) { 4888 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); 4889 } 4890 4891 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4892 if(temp) { 4893 SiS_Chrontel701xBLOn(SiS_Pr); 4894 } 4895 } 4896 4897 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4898 if(SiS_CRT2IsLCD(SiS_Pr)) { 4899 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 4900 if(SiS_Pr->ChipType == SIS_550) { 4901 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40); 4902 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10); 4903 } 4904 } 4905 } else if(SiS_IsVAMode(SiS_Pr)) { 4906 if(SiS_Pr->ChipType != SIS_740) { 4907 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 4908 } 4909 } 4910 4911 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4912 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4913 } 4914 4915 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4916 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) { 4917 SiS_Chrontel701xOn(SiS_Pr); 4918 } 4919 if( (SiS_IsVAMode(SiS_Pr)) || 4920 (SiS_IsLCDOrLCDA(SiS_Pr)) ) { 4921 SiS_ChrontelDoSomething1(SiS_Pr); 4922 } 4923 } 4924 4925 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4926 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4927 if( (SiS_IsVAMode(SiS_Pr)) || 4928 (SiS_IsLCDOrLCDA(SiS_Pr)) ) { 4929 SiS_Chrontel701xBLOn(SiS_Pr); 4930 SiS_ChrontelInitTVVSync(SiS_Pr); 4931 } 4932 } 4933 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4934 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4935 if(SiS_CRT2IsLCD(SiS_Pr)) { 4936 SiS_PanelDelay(SiS_Pr, 1); 4937 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 4938 } 4939 } 4940 } 4941 4942#endif /* SIS315H */ 4943 4944 } /* 310 series */ 4945 4946 } /* LVDS */ 4947 4948} 4949 4950/*********************************************/ 4951/* SET PART 1 REGISTER GROUP */ 4952/*********************************************/ 4953 4954/* Set CRT2 OFFSET / PITCH */ 4955static void 4956SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 4957 unsigned short RRTI) 4958{ 4959 unsigned short offset; 4960 unsigned char temp; 4961 4962 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return; 4963 4964 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI); 4965 4966 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF)); 4967 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8)); 4968 4969 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1); 4970 if(offset & 0x07) temp++; 4971 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp); 4972} 4973 4974/* Set CRT2 sync and PanelLink mode */ 4975static void 4976SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex) 4977{ 4978 unsigned short tempah=0, tempbl, infoflag; 4979 4980 tempbl = 0xC0; 4981 4982 if(SiS_Pr->UseCustomMode) { 4983 infoflag = SiS_Pr->CInfoFlag; 4984 } else { 4985 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 4986 } 4987 4988 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */ 4989 4990 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 4991 tempah = 0; 4992 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) { 4993 tempah = SiS_Pr->SiS_LCDInfo; 4994 } else tempah = infoflag >> 8; 4995 tempah &= 0xC0; 4996 tempah |= 0x20; 4997 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 4998 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 4999 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 5000 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 5001 tempah |= 0xf0; 5002 } 5003 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 5004 (SiS_Pr->SiS_IF_DEF_DSTN) || 5005 (SiS_Pr->SiS_IF_DEF_TRUMPION) || 5006 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 5007 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) { 5008 tempah |= 0x30; 5009 } 5010 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 5011 (SiS_Pr->SiS_IF_DEF_DSTN) ) { 5012 tempah &= ~0xc0; 5013 } 5014 } 5015 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 5016 if(SiS_Pr->ChipType >= SIS_315H) { 5017 tempah >>= 3; 5018 tempah &= 0x18; 5019 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah); 5020 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */ 5021 } else { 5022 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0); 5023 } 5024 } else { 5025 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5026 } 5027 5028 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5029 5030 if(SiS_Pr->ChipType < SIS_315H) { 5031 5032#ifdef SIS300 /* ---- 300 series --- */ 5033 5034 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */ 5035 5036 tempah = infoflag >> 8; 5037 tempbl = 0; 5038 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5039 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5040 tempah = SiS_Pr->SiS_LCDInfo; 5041 tempbl = (tempah >> 6) & 0x03; 5042 } 5043 } 5044 tempah &= 0xC0; 5045 tempah |= 0x20; 5046 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5047 tempah |= 0xc0; 5048 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5049 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 5050 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5051 } 5052 5053 } else { /* 630 - 301 */ 5054 5055 tempah = ((infoflag >> 8) & 0xc0) | 0x20; 5056 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5057 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5058 5059 } 5060 5061#endif /* SIS300 */ 5062 5063 } else { 5064 5065#ifdef SIS315H /* ------- 315 series ------ */ 5066 5067 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */ 5068 5069 tempbl = 0; 5070 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) && 5071 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 5072 tempah = infoflag >> 8; 5073 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5074 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6); 5075 } 5076 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) && 5077 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) { 5078 tempah = infoflag >> 8; 5079 tempbl = 0x03; 5080 } else { 5081 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); 5082 tempbl = (tempah >> 6) & 0x03; 5083 tempbl |= 0x08; 5084 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04; 5085 } 5086 tempah &= 0xC0; 5087 tempah |= 0x20; 5088 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5089 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0; 5090 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5091 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 5092 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5093 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5094 } 5095 } 5096 5097 } else { /* 315 - TMDS */ 5098 5099 tempah = tempbl = infoflag >> 8; 5100 if(!SiS_Pr->UseCustomMode) { 5101 tempbl = 0; 5102 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 5103 if(ModeNo <= 0x13) { 5104 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); 5105 } 5106 } 5107 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5108 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5109 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5110 tempah = SiS_Pr->SiS_LCDInfo; 5111 tempbl = (tempah >> 6) & 0x03; 5112 } 5113 } 5114 } 5115 } 5116 tempah &= 0xC0; 5117 tempah |= 0x20; 5118 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5119 if(SiS_Pr->SiS_VBType & VB_NoLCD) { 5120 /* Imitate BIOS bug */ 5121 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0; 5122 } 5123 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 5124 tempah >>= 3; 5125 tempah &= 0x18; 5126 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah); 5127 } else { 5128 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5129 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 5130 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5131 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5132 } 5133 } 5134 } 5135 5136 } 5137#endif /* SIS315H */ 5138 } 5139 } 5140} 5141 5142/* Set CRT2 FIFO on 300/540/630/730 */ 5143#ifdef SIS300 5144static void 5145SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo) 5146{ 5147 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 5148 unsigned short temp, index, modeidindex, refreshratetableindex; 5149 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0; 5150 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup; 5151 unsigned int data, pci50, pciA0; 5152 static const unsigned char colortharray[] = { 5153 1, 1, 2, 2, 3, 4 5154 }; 5155 5156 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate; 5157 5158 if(!SiS_Pr->CRT1UsesCustomMode) { 5159 5160 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */ 5161 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex); 5162 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 5163 SiS_Pr->SiS_SelectCRT2Rate = 0; 5164 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex); 5165 5166 if(CRT1ModeNo >= 0x13) { 5167 /* Get VCLK */ 5168 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide); 5169 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 5170 5171 /* Get colordepth */ 5172 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1; 5173 if(!colorth) colorth++; 5174 } 5175 5176 } else { 5177 5178 CRT1ModeNo = 0xfe; 5179 5180 /* Get VCLK */ 5181 VCLK = SiS_Pr->CSRClock_CRT1; 5182 5183 /* Get color depth */ 5184 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)]; 5185 5186 } 5187 5188 if(CRT1ModeNo >= 0x13) { 5189 /* Get MCLK */ 5190 if(SiS_Pr->ChipType == SIS_300) { 5191 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A); 5192 } else { 5193 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A); 5194 } 5195 index &= 0x07; 5196 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; 5197 5198 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1; 5199 if(!temp) temp++; 5200 temp <<= 2; 5201 5202 data2 = temp - ((colorth * VCLK) / MCLK); 5203 5204 temp = (28 * 16) % data2; 5205 data2 = (28 * 16) / data2; 5206 if(temp) data2++; 5207 5208 if(SiS_Pr->ChipType == SIS_300) { 5209 5210 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl); 5211 data = SiS_GetFIFOThresholdB300(tempbx, tempcl); 5212 5213 } else { 5214 5215#ifdef SIS_LINUX_KERNEL 5216 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); 5217 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0); 5218#else 5219 pci50 = sis_pci_read_host_bridge_u32(0x50); 5220 pciA0 = sis_pci_read_host_bridge_u32(0xA0); 5221#endif 5222 5223 if(SiS_Pr->ChipType == SIS_730) { 5224 5225 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3); 5226 index += (unsigned short)(((pci50 >> 9)) & 0x03); 5227 5228 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */ 5229 index = 0; /* -- do it like the BIOS anyway... */ 5230 5231 } else { 5232 5233 pci50 >>= 24; 5234 pciA0 >>= 24; 5235 5236 index = (pci50 >> 1) & 0x07; 5237 5238 if(pci50 & 0x01) index += 6; 5239 if(!(pciA0 & 0x01)) index += 24; 5240 5241 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12; 5242 5243 } 5244 5245 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15; 5246 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5; 5247 5248 } 5249 5250 data += data2; /* CRT1 Request Period */ 5251 5252 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 5253 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; 5254 5255 if(!SiS_Pr->UseCustomMode) { 5256 5257 CRT2ModeNo = ModeNo; 5258 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex); 5259 5260 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex); 5261 5262 /* Get VCLK */ 5263 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex); 5264 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 5265 5266 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 5267 if(SiS_Pr->SiS_UseROM) { 5268 if(ROMAddr[0x220] & 0x01) { 5269 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8); 5270 } 5271 } 5272 } 5273 5274 } else { 5275 5276 /* Get VCLK */ 5277 CRT2ModeNo = 0xfe; 5278 VCLK = SiS_Pr->CSRClock; 5279 5280 } 5281 5282 /* Get colordepth */ 5283 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1; 5284 if(!colorth) colorth++; 5285 5286 data = data * VCLK * colorth; 5287 temp = data % (MCLK << 4); 5288 data = data / (MCLK << 4); 5289 if(temp) data++; 5290 5291 if(data < 6) data = 6; 5292 else if(data > 0x14) data = 0x14; 5293 5294 if(SiS_Pr->ChipType == SIS_300) { 5295 temp = 0x16; 5296 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) 5297 temp = 0x13; 5298 } else { 5299 temp = 0x16; 5300 if(( (SiS_Pr->ChipType == SIS_630) || 5301 (SiS_Pr->ChipType == SIS_730) ) && 5302 (SiS_Pr->ChipRevision >= 0x30)) 5303 temp = 0x1b; 5304 } 5305 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp); 5306 5307 if((SiS_Pr->ChipType == SIS_630) && 5308 (SiS_Pr->ChipRevision >= 0x30)) { 5309 if(data > 0x13) data = 0x13; 5310 } 5311 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data); 5312 5313 } else { /* If mode <= 0x13, we just restore everything */ 5314 5315 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 5316 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; 5317 5318 } 5319} 5320#endif 5321 5322/* Set CRT2 FIFO on 315/330 series */ 5323#ifdef SIS315H 5324static void 5325SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr) 5326{ 5327 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B); 5328 if( (SiS_Pr->ChipType == SIS_760) && 5329 (SiS_Pr->SiS_SysFlags & SF_760LFB) && 5330 (SiS_Pr->SiS_ModeType == Mode32Bpp) && 5331 (SiS_Pr->SiS_VGAHDE >= 1280) && 5332 (SiS_Pr->SiS_VGAVDE >= 1024) ) { 5333 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03); 5334 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b); 5335 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0); 5336 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01); 5337 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0); 5338 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e); 5339 } else { 5340 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04); 5341 } 5342 5343} 5344#endif 5345 5346static unsigned short 5347SiS_GetVGAHT2(struct SiS_Private *SiS_Pr) 5348{ 5349 unsigned int tempax,tempbx; 5350 5351 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX; 5352 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT; 5353 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx; 5354 return (unsigned short)tempax; 5355} 5356 5357/* Set Part 1 / SiS bridge slave mode */ 5358static void 5359SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex, 5360 unsigned short RefreshRateTableIndex) 5361{ 5362 unsigned short temp, modeflag, i, j, xres=0, VGAVDE; 5363 static const unsigned short CRTranslation[] = { 5364 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */ 5365 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 5366 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */ 5367 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00, 5368 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */ 5369 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00 5370 }; 5371 5372 if(ModeNo <= 0x13) { 5373 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 5374 } else if(SiS_Pr->UseCustomMode) { 5375 modeflag = SiS_Pr->CModeFlag; 5376 xres = SiS_Pr->CHDisplay; 5377 } else { 5378 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 5379 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes; 5380 } 5381 5382 /* The following is only done if bridge is in slave mode: */ 5383 5384 if(SiS_Pr->ChipType >= SIS_315H) { 5385 if(xres >= 1600) { /* BIOS: == 1600 */ 5386 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04); 5387 } 5388 } 5389 5390 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */ 5391 5392 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE; 5393 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1; 5394 5395 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay; 5396 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 5397 SiS_Pr->CHBlankStart += 16; 5398 } 5399 5400 SiS_Pr->CHBlankEnd = 32; 5401 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5402 if(xres == 1600) SiS_Pr->CHBlankEnd += 80; 5403 } 5404 5405 temp = SiS_Pr->SiS_VGAHT - 96; 5406 if(!(modeflag & HalfDCLK)) temp -= 32; 5407 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 5408 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04); 5409 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2); 5410 temp -= 3; 5411 temp <<= 3; 5412 } else { 5413 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2; 5414 } 5415 SiS_Pr->CHSyncStart = temp; 5416 5417 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */ 5418 5419 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */ 5420 5421 VGAVDE = SiS_Pr->SiS_VGAVDE; 5422 if (VGAVDE == 357) VGAVDE = 350; 5423 else if(VGAVDE == 360) VGAVDE = 350; 5424 else if(VGAVDE == 375) VGAVDE = 350; 5425 else if(VGAVDE == 405) VGAVDE = 400; 5426 else if(VGAVDE == 420) VGAVDE = 400; 5427 else if(VGAVDE == 525) VGAVDE = 480; 5428 else if(VGAVDE == 1056) VGAVDE = 1024; 5429 SiS_Pr->CVDisplay = VGAVDE; 5430 5431 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay; 5432 5433 SiS_Pr->CVBlankEnd = 1; 5434 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226; 5435 5436 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1; 5437 SiS_Pr->CVSyncStart = VGAVDE + temp; 5438 5439 temp >>= 3; 5440 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp; 5441 5442 SiS_CalcCRRegisters(SiS_Pr, 0); 5443 SiS_Pr->CCRT1CRTC[16] &= ~0xE0; 5444 5445 for(i = 0; i <= 7; i++) { 5446 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]); 5447 } 5448 for(i = 0x10, j = 8; i <= 0x12; i++, j++) { 5449 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]); 5450 } 5451 for(i = 0x15, j = 11; i <= 0x16; i++, j++) { 5452 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]); 5453 } 5454 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) { 5455 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]); 5456 } 5457 5458 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0; 5459 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp); 5460 5461 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5; 5462 if(modeflag & DoubleScanMode) temp |= 0x80; 5463 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp); 5464 5465 temp = 0; 5466 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01); 5467 if(modeflag & HalfDCLK) temp |= 0x08; 5468 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */ 5469 5470 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */ 5471 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */ 5472 5473 temp = 0; 5474 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 5475 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7; 5476 } 5477 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */ 5478 5479 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); 5480 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */ 5481 5482#ifdef SIS_XORG_XF86 5483#ifdef TWDEBUG 5484 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n", 5485 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal, 5486 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal, 5487 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd); 5488 5489 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", 5490 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1], 5491 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3], 5492 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5], 5493 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]); 5494 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", 5495 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9], 5496 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11], 5497 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13], 5498 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]); 5499 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]); 5500#endif 5501#endif 5502} 5503 5504/* Setup panel link 5505 * This is used for LVDS, LCDA and Chrontel TV output 5506 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA 5507 */ 5508static void 5509SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 5510 unsigned short RefreshRateTableIndex) 5511{ 5512 unsigned short modeflag, resinfo = 0; 5513 unsigned short push2, tempax, tempbx, tempcx, temp; 5514 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0; 5515 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE; 5516 BOOLEAN lvds550 = FALSE; 5517#ifdef SIS300 5518 unsigned short crt2crtc = 0; 5519#endif 5520#ifdef SIS315H 5521 unsigned short pushcx; 5522#endif 5523 5524 if(ModeNo <= 0x13) { 5525 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 5526 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 5527#ifdef SIS300 5528 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 5529#endif 5530 } else if(SiS_Pr->UseCustomMode) { 5531 modeflag = SiS_Pr->CModeFlag; 5532 } else { 5533 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 5534 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 5535#ifdef SIS300 5536 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 5537#endif 5538 } 5539 5540 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */ 5541 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 5542 islvds = TRUE; 5543 } 5544 5545 if(SiS_Pr->ChipType == SIS_550 && 5546 SiS_Pr->SiS_IF_DEF_LVDS && 5547 !SiS_Pr->SiS_IF_DEF_FSTN && 5548 !SiS_Pr->SiS_IF_DEF_DSTN) { 5549 lvds550 = TRUE; 5550 } 5551 5552 /* is really sis if sis bridge, but not 301B-DH */ 5553 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 5554 issis = TRUE; 5555 } 5556 5557 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) { 5558 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN && !lvds550) { 5559 chkdclkfirst = TRUE; 5560 } 5561 } 5562 5563#ifdef SIS315H 5564 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 5565 if(IS_SIS330) { 5566 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); 5567 } else if(IS_SIS740) { 5568 if(islvds) { 5569 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); 5570 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03); 5571 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5572 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); 5573 } 5574 } else { 5575 if(islvds) { 5576 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); 5577 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00); 5578 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5579 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f); 5580 if(SiS_Pr->SiS_VBType & VB_SIS30xC) { 5581 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) || 5582 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 5583 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20); 5584 } 5585 } 5586 } 5587 } 5588 } 5589#endif 5590 5591 /* Horizontal */ 5592 5593 tempax = SiS_Pr->SiS_LCDHDES; 5594 if(islvds) { 5595 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5596 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN && !lvds550) { 5597 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) && 5598 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) { 5599 tempax -= 8; 5600 } 5601 } 5602 } 5603 } 5604 5605 temp = (tempax & 0x0007); 5606 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */ 5607 temp = (tempax >> 3) & 0x00FF; 5608 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */ 5609 5610 tempbx = SiS_Pr->SiS_HDE; 5611 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5612 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5613 tempbx = SiS_Pr->PanelXRes; 5614 } 5615 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) || 5616 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) || 5617 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) { 5618 tempbx >>= 1; 5619 } 5620 } 5621 5622 tempax += tempbx; 5623 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT; 5624 5625 temp = tempax; 5626 if(temp & 0x07) temp += 8; 5627 temp >>= 3; 5628 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */ 5629 5630 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2; 5631 5632 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5633 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5634 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS; 5635 } 5636 } 5637 5638 tempcx += tempax; 5639 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT; 5640 5641 temp = (tempcx >> 3) & 0x00FF; 5642 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5643 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5644 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5645 switch(ModeNo) { 5646 case 0x04: 5647 case 0x05: 5648 case 0x0d: temp = 0x56; break; 5649 case 0x10: temp = 0x60; break; 5650 case 0x13: temp = 0x5f; break; 5651 case 0x40: 5652 case 0x41: 5653 case 0x4f: 5654 case 0x43: 5655 case 0x44: 5656 case 0x62: 5657 case 0x56: 5658 case 0x53: 5659 case 0x5d: 5660 case 0x5e: temp = 0x54; break; 5661 } 5662 } 5663 } 5664 } 5665 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */ 5666 5667 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5668 temp += 2; 5669 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5670 temp += 8; 5671 if(SiS_Pr->PanelHRE != 999) { 5672 temp = tempcx + SiS_Pr->PanelHRE; 5673 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT; 5674 temp >>= 3; 5675 } 5676 } 5677 } else { 5678 temp += 10; 5679 } 5680 5681 temp &= 0x1F; 5682 temp |= ((tempcx & 0x07) << 5); 5683 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */ 5684 5685 /* Vertical */ 5686 5687 tempax = SiS_Pr->SiS_VGAVDE; 5688 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5689 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5690 tempax = SiS_Pr->PanelYRes; 5691 } 5692 } 5693 5694 tempbx = SiS_Pr->SiS_LCDVDES + tempax; 5695 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; 5696 5697 push2 = tempbx; 5698 5699 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE; 5700 if((SiS_Pr->ChipType < SIS_315H) || lvds550) { 5701 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5702 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5703 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes; 5704 } 5705 } 5706 } 5707 if(islvds) tempcx >>= 1; 5708 else tempcx >>= 2; 5709 5710 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && 5711 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) && 5712 (SiS_Pr->PanelVRS != 999) ) { 5713 tempcx = SiS_Pr->PanelVRS; 5714 tempbx += tempcx; 5715 if(issis || lvds550) tempbx++; 5716 } else { 5717 tempbx += tempcx; 5718 if(SiS_Pr->ChipType < SIS_315H) tempbx++; 5719 else if(issis || lvds550) tempbx++; 5720 } 5721 5722 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; 5723 5724 temp = tempbx & 0x00FF; 5725 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5726 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5727 if(ModeNo == 0x10) temp = 0xa9; 5728 } 5729 } 5730 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */ 5731 5732 tempcx >>= 3; 5733 tempcx++; 5734 5735 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5736 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5737 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE; 5738 } 5739 } 5740 5741 tempcx += tempbx; 5742 temp = tempcx & 0x000F; 5743 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */ 5744 5745 temp = ((tempbx >> 8) & 0x07) << 3; 5746 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN || lvds550) { 5747 if(SiS_Pr->SiS_HDE != 640) { 5748 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40; 5749 } 5750 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40; 5751 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40; 5752 tempbx = 0x87; 5753 if((SiS_Pr->ChipType >= SIS_315H) || 5754 (SiS_Pr->ChipRevision >= 0x30)) { 5755 tempbx = 0x07; 5756 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 5757 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80; 5758 } 5759 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */ 5760 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 5761 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 5762 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80; 5763 } else { 5764 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80; 5765 } 5766 } 5767 } 5768 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp); 5769 5770 tempbx = push2; /* BPLVDEE */ 5771 5772 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */ 5773 5774 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5775 switch(SiS_Pr->SiS_LCDResInfo) { 5776 case Panel_640x480: 5777 tempbx = SiS_Pr->SiS_VGAVDE - 1; 5778 tempcx = SiS_Pr->SiS_VGAVDE; 5779 break; 5780 case Panel_800x600: 5781 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5782 if(resinfo == SIS_RI_800x600) tempcx++; 5783 } 5784 break; 5785 case Panel_1024x600: 5786 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5787 if(resinfo == SIS_RI_1024x600) tempcx++; 5788 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 5789 if(resinfo == SIS_RI_800x600) tempcx++; 5790 } 5791 } 5792 break; 5793 case Panel_1024x768: 5794 if(SiS_Pr->ChipType < SIS_315H) { 5795 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5796 if(resinfo == SIS_RI_1024x768) tempcx++; 5797 } 5798 } 5799 break; 5800 } 5801 } 5802 5803 temp = ((tempbx >> 8) & 0x07) << 3; 5804 temp |= ((tempcx >> 8) & 0x07); 5805 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp); 5806 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx); 5807 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx); 5808 5809 /* Vertical scaling */ 5810 5811 if(SiS_Pr->ChipType < SIS_315H) { 5812 5813#ifdef SIS300 /* 300 series */ 5814 tempeax = SiS_Pr->SiS_VGAVDE << 6; 5815 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE); 5816 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE; 5817 if(temp) tempeax++; 5818 5819 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F; 5820 5821 temp = (unsigned short)(tempeax & 0x00FF); 5822 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */ 5823 tempvcfact = temp; 5824#endif /* SIS300 */ 5825 5826 } else { 5827 5828#ifdef SIS315H /* 315 series */ 5829 tempeax = SiS_Pr->SiS_VGAVDE << 18; 5830 tempebx = SiS_Pr->SiS_VDE; 5831 temp = (tempeax % tempebx); 5832 tempeax = tempeax / tempebx; 5833 if(temp) tempeax++; 5834 tempvcfact = tempeax; 5835 5836 temp = (unsigned short)(tempeax & 0x00FF); 5837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp); 5838 temp = (unsigned short)((tempeax & 0x00FF00) >> 8); 5839 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp); 5840 temp = (unsigned short)((tempeax & 0x00030000) >> 16); 5841 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04; 5842 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp); 5843 5844 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) { 5845 temp = (unsigned short)(tempeax & 0x00FF); 5846 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp); 5847 temp = (unsigned short)((tempeax & 0x00FF00) >> 8); 5848 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp); 5849 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6); 5850 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp); 5851 temp = 0; 5852 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08; 5853 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp); 5854 } 5855#endif 5856 5857 } 5858 5859 /* Horizontal scaling */ 5860 5861 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/ 5862 if(chkdclkfirst) { 5863 if(modeflag & HalfDCLK) tempeax >>= 1; 5864 } 5865 tempebx = tempeax << 16; 5866 if(SiS_Pr->SiS_HDE == tempeax) { 5867 tempecx = 0xFFFF; 5868 } else { 5869 tempecx = tempebx / SiS_Pr->SiS_HDE; 5870 if(SiS_Pr->ChipType >= SIS_315H) { 5871 if(tempebx % SiS_Pr->SiS_HDE) tempecx++; 5872 } 5873 } 5874 5875 if(SiS_Pr->ChipType >= SIS_315H) { 5876 tempeax = (tempebx / tempecx) - 1; 5877 } else { 5878 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1; 5879 } 5880 tempecx = (tempecx << 16) | (tempeax & 0xFFFF); 5881 temp = (unsigned short)(tempecx & 0x00FF); 5882 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp); 5883 5884 if(SiS_Pr->ChipType >= SIS_315H) { 5885 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact; 5886 tempbx = (unsigned short)(tempeax & 0xFFFF); 5887 } else { 5888 tempeax = SiS_Pr->SiS_VGAVDE << 6; 5889 tempbx = tempvcfact & 0x3f; 5890 if(tempbx == 0) tempbx = 64; 5891 tempeax /= tempbx; 5892 tempbx = (unsigned short)(tempeax & 0xFFFF); 5893 } 5894 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--; 5895 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) { 5896 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1; 5897 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1; 5898 } 5899 5900 temp = ((tempbx >> 8) & 0x07) << 3; 5901 temp = temp | ((tempecx >> 8) & 0x07); 5902 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp); 5903 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx); 5904 5905 tempecx >>= 16; /* BPLHCFACT */ 5906 if(!chkdclkfirst) { 5907 if(modeflag & HalfDCLK) tempecx >>= 1; 5908 } 5909 temp = (unsigned short)((tempecx & 0xFF00) >> 8); 5910 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp); 5911 temp = (unsigned short)(tempecx & 0x00FF); 5912 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp); 5913 5914#ifdef SIS315H 5915 if(SiS_Pr->ChipType >= SIS_315H) { 5916 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 5917 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) { 5918 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20); 5919 } 5920 } else { 5921 if(islvds) { 5922 if(SiS_Pr->ChipType == SIS_740) { 5923 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03); 5924 } else { 5925 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23); 5926 } 5927 } 5928 } 5929 } 5930#endif 5931 5932#ifdef SIS300 5933 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5934 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 5935 unsigned char *trumpdata; 5936 int i, j = crt2crtc; 5937 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 }; 5938 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 }; 5939 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 }; 5940 5941 if(SiS_Pr->SiS_UseROM) { 5942 trumpdata = &ROMAddr[0x8001 + (j * 80)]; 5943 } else { 5944 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7; 5945 trumpdata = &SiS300_TrumpionData[j][0]; 5946 } 5947 5948 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf); 5949 for(i=0; i<5; i++) { 5950 SiS_SetTrumpionBlock(SiS_Pr, trumpdata); 5951 } 5952 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5953 if(ModeNo == 0x13) { 5954 for(i=0; i<4; i++) { 5955 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]); 5956 } 5957 } else if(ModeNo == 0x10) { 5958 for(i=0; i<4; i++) { 5959 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]); 5960 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]); 5961 } 5962 } 5963 } 5964 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 5965 } 5966#endif 5967 5968#ifdef SIS315H 5969 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { 5970 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00); 5971 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00); 5972 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00); 5973 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87); 5974 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A); 5975 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B); 5976 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03); 5977 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */ 5978 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 5979 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 5980 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 5981 tempax += 64; 5982 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff); 5983 temp = (tempax >> 8) << 3; 5984 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp); 5985 tempax += 32; /* Blpe = lBlps+32 */ 5986 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff); 5987 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */ 5988 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007); 5989 5990 tempax = SiS_Pr->SiS_VDE; 5991 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 5992 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 5993 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 5994 tempax >>= 1; 5995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff); 5996 temp = (tempax >> 8) << 3; 5997 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp); 5998 5999 tempeax = SiS_Pr->SiS_HDE; 6000 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6001 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6002 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1; 6003 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */ 6004 temp = tempeax & 0x7f; 6005 tempeax >>= 7; 6006 if(temp) tempeax++; 6007 temp = tempeax & 0x3f; 6008 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp); 6009 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */ 6010 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00); 6011 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10); 6012 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040); 6013 6014 tempax = SiS_Pr->SiS_HDE; 6015 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6016 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6017 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6018 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */ 6019 pushcx = tempax; 6020 temp = tempax & 0x00FF; 6021 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp); 6022 temp = ((tempax & 0xFF00) >> 8) << 3; 6023 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp); 6024 6025 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */ 6026 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6027 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6028 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6029 tempeax = tempax * pushcx; 6030 temp = tempeax & 0xFF; 6031 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp); 6032 temp = (tempeax & 0xFF00) >> 8; 6033 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp); 6034 temp = ((tempeax & 0xFF0000) >> 16) | 0x10; 6035 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp); 6036 temp = ((tempeax & 0x01000000) >> 24) << 7; 6037 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp); 6038 6039 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03); 6040 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50); 6041 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00); 6042 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01); 6043 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38); 6044 6045 if(SiS_Pr->SiS_IF_DEF_FSTN) { 6046 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02); 6047 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00); 6048 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00); 6049 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c); 6050 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00); 6051 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00); 6052 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80); 6053 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0); 6054 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00); 6055 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0); 6056 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00); 6057 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10); 6058 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00); 6059 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00); 6060 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10); 6061 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25); 6062 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80); 6063 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14); 6064 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03); 6065 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a); 6066 } 6067 } 6068#endif /* SIS315H */ 6069} 6070 6071/* Set Part 1 */ 6072static void 6073SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 6074 unsigned short RefreshRateTableIndex) 6075{ 6076#if defined(SIS300) || defined(SIS315H) 6077 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 6078#endif 6079 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0; 6080 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0, lvds550=0; 6081#ifdef SIS315H 6082 unsigned short tempbl=0; 6083#endif 6084 6085 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 6086 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6087 return; 6088 } 6089 6090 if(ModeNo <= 0x13) { 6091 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 6092 } else if(SiS_Pr->UseCustomMode) { 6093 modeflag = SiS_Pr->CModeFlag; 6094 } else { 6095 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2); 6096 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 6097 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 6098 } 6099 6100 if(SiS_Pr->ChipType == SIS_550 && 6101 SiS_Pr->SiS_IF_DEF_LVDS && 6102 !SiS_Pr->SiS_IF_DEF_DSTN && 6103 !SiS_Pr->SiS_IF_DEF_FSTN) { 6104 lvds550 = 1; 6105 } 6106 6107 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6108 6109 if( ! ((SiS_Pr->ChipType >= SIS_315H) && 6110 (!lvds550) && 6111 (SiS_Pr->SiS_IF_DEF_LVDS == 1) && 6112 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) { 6113 6114 if(SiS_Pr->ChipType < SIS_315H ) { 6115#ifdef SIS300 6116 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo); 6117#endif 6118 } else { 6119#ifdef SIS315H 6120 SiS_SetCRT2FIFO_310(SiS_Pr); 6121#endif 6122 } 6123 6124 /* 1. Horizontal setup */ 6125 6126 if(SiS_Pr->ChipType < SIS_315H) { 6127 6128#ifdef SIS300 /* ------------- 300 series --------------*/ 6129 6130 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ 6131 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */ 6132 6133 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4; 6134 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */ 6135 6136 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ 6137 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */ 6138 6139 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */ 6140 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2; 6141 tempbx = pushbx + tempcx; 6142 tempcx <<= 1; 6143 tempcx += tempbx; 6144 6145 bridgeadd = 12; 6146 6147#endif /* SIS300 */ 6148 6149 } else { 6150 6151#ifdef SIS315H /* ------------------- 315/330 series --------------- */ 6152 6153 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */ 6154 if(modeflag & HalfDCLK) { 6155 if((SiS_Pr->SiS_VBType & VB_SISVB) || lvds550) { 6156 tempcx >>= 1; 6157 } else { 6158 tempax = SiS_Pr->SiS_VGAHDE >> 1; 6159 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax; 6160 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 6161 tempcx = SiS_Pr->SiS_HT - tempax; 6162 } 6163 } 6164 } 6165 tempcx--; 6166 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */ 6167 temp = (tempcx >> 4) & 0xF0; 6168 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */ 6169 6170 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */ 6171 tempbx = SiS_Pr->SiS_VGAHDE; 6172 tempcx -= tempbx; 6173 tempcx >>= 2; 6174 if(modeflag & HalfDCLK) { 6175 tempbx >>= 1; 6176 tempcx >>= 1; 6177 } 6178 tempbx += 16; 6179 6180 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */ 6181 6182 pushbx = tempbx; 6183 if(!lvds550) tempcx >>= 1; 6184 tempbx += tempcx; 6185 tempcx += tempbx; 6186 if(lvds550) tempcx += 20; 6187 6188 bridgeadd = 16; 6189 6190 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6191 if(SiS_Pr->ChipType >= SIS_661) { 6192 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) || 6193 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 6194 if(resinfo == SIS_RI_1280x1024) { 6195 tempcx = (tempcx & 0xff00) | 0x30; 6196 } else if(resinfo == SIS_RI_1600x1200) { 6197 tempcx = (tempcx & 0xff00) | 0xff; 6198 } 6199 } 6200 } 6201 } 6202 6203#endif /* SIS315H */ 6204 6205 } /* 315/330 series */ 6206 6207 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6208 6209 if(SiS_Pr->UseCustomMode) { 6210 tempbx = SiS_Pr->CHSyncStart + bridgeadd; 6211 tempcx = SiS_Pr->CHSyncEnd + bridgeadd; 6212 tempax = SiS_Pr->SiS_VGAHT; 6213 if(modeflag & HalfDCLK) tempax >>= 1; 6214 tempax--; 6215 if(tempcx > tempax) tempcx = tempax; 6216 } 6217 6218 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 6219 unsigned char cr4, cr14, cr5, cr15; 6220 if(SiS_Pr->UseCustomMode) { 6221 cr4 = SiS_Pr->CCRT1CRTC[4]; 6222 cr14 = SiS_Pr->CCRT1CRTC[14]; 6223 cr5 = SiS_Pr->CCRT1CRTC[5]; 6224 cr15 = SiS_Pr->CCRT1CRTC[15]; 6225 } else { 6226 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4]; 6227 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14]; 6228 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5]; 6229 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15]; 6230 } 6231 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */ 6232 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */ 6233 tempcx &= 0x00FF; 6234 tempcx |= (tempbx & 0xFF00); 6235 tempbx += bridgeadd; 6236 tempcx += bridgeadd; 6237 tempax = SiS_Pr->SiS_VGAHT; 6238 if(modeflag & HalfDCLK) tempax >>= 1; 6239 tempax--; 6240 if(tempcx > tempax) tempcx = tempax; 6241 } 6242 6243 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) { 6244 tempbx = 1040; 6245 tempcx = 1044; /* HWCursor bug! */ 6246 } 6247 6248 } 6249 6250 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */ 6251 6252 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */ 6253 6254 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0); 6255 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */ 6256 6257 /* 2. Vertical setup */ 6258 6259 tempcx = SiS_Pr->SiS_VGAVT - 1; 6260 temp = tempcx & 0x00FF; 6261 if((SiS_Pr->ChipType < SIS_661) && !lvds550) { 6262 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 6263 if(SiS_Pr->ChipType < SIS_315H) { 6264 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6265 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) { 6266 temp--; 6267 } 6268 } 6269 } else { 6270 temp--; 6271 } 6272 } else if(SiS_Pr->ChipType >= SIS_315H) { 6273 temp--; 6274 } 6275 } 6276 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */ 6277 6278 tempbx = SiS_Pr->SiS_VGAVDE - 1; 6279 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */ 6280 6281 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07); 6282 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */ 6283 6284 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661) && !lvds550) { 6285 tempcx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 2; 6286 tempbx = SiS_Pr->SiS_VGAVDE + tempcx; 6287 if(tempcx < 4) tempcx = 4; 6288 tempcx = (tempcx >> 2) + tempbx + 1; 6289 } else { 6290 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */ 6291 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */ 6292 } 6293 6294 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6295 if(SiS_Pr->UseCustomMode) { 6296 tempbx = SiS_Pr->CVSyncStart; 6297 tempcx = SiS_Pr->CVSyncEnd; 6298 } 6299 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 6300 unsigned char cr8, cr7, cr13; 6301 if(SiS_Pr->UseCustomMode) { 6302 cr8 = SiS_Pr->CCRT1CRTC[8]; 6303 cr7 = SiS_Pr->CCRT1CRTC[7]; 6304 cr13 = SiS_Pr->CCRT1CRTC[13]; 6305 tempcx = SiS_Pr->CCRT1CRTC[9]; 6306 } else { 6307 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8]; 6308 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7]; 6309 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13]; 6310 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9]; 6311 } 6312 tempbx = cr8; 6313 if(cr7 & 0x04) tempbx |= 0x0100; 6314 if(cr7 & 0x80) tempbx |= 0x0200; 6315 if(cr13 & 0x08) tempbx |= 0x0400; 6316 } 6317 } 6318 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */ 6319 6320 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F); 6321 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */ 6322 6323 /* 3. Panel delay compensation */ 6324 6325 if(SiS_Pr->ChipType < SIS_315H) { 6326 6327#ifdef SIS300 /* ---------- 300 series -------------- */ 6328 6329 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6330 temp = 0x20; 6331 if(SiS_Pr->ChipType == SIS_300) { 6332 temp = 0x10; 6333 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c; 6334 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20; 6335 } 6336 if(SiS_Pr->SiS_VBType & VB_SIS301) { 6337 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20; 6338 } 6339 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24; 6340 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c; 6341 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08; 6342 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6343 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c; 6344 else temp = 0x20; 6345 } 6346 if(SiS_Pr->SiS_UseROM) { 6347 if(ROMAddr[0x220] & 0x80) { 6348 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) 6349 temp = ROMAddr[0x221]; 6350 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) 6351 temp = ROMAddr[0x222]; 6352 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) 6353 temp = ROMAddr[0x223]; 6354 else 6355 temp = ROMAddr[0x224]; 6356 } 6357 } 6358 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6359 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC; 6360 } 6361 6362 } else { 6363 temp = 0x20; 6364 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 6365 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04; 6366 } 6367 if(SiS_Pr->SiS_UseROM) { 6368 if(ROMAddr[0x220] & 0x80) { 6369 temp = ROMAddr[0x220]; 6370 } 6371 } 6372 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6373 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC; 6374 } 6375 } 6376 6377 temp &= 0x3c; 6378 6379 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */ 6380 6381#endif /* SIS300 */ 6382 6383 } else { 6384 6385#ifdef SIS315H /* --------------- 315/330 series ---------------*/ 6386 6387 if(SiS_Pr->ChipType < SIS_661) { 6388 6389 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 6390 6391 if(SiS_Pr->ChipType == SIS_740) temp = 0x03; 6392 else temp = 0x00; 6393 6394 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a; 6395 tempbl = 0xF0; 6396 if(SiS_Pr->ChipType == SIS_650) { 6397 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6398 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F; 6399 } 6400 } 6401 6402 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN || lvds550) { 6403 temp = 0x08; 6404 tempbl = 0; 6405 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 6406 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0; 6407 } 6408 } 6409 6410 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */ 6411 } 6412 6413 } /* < 661 */ 6414 6415 tempax = 0; 6416 if(modeflag & DoubleScanMode) tempax |= 0x80; 6417 if(modeflag & HalfDCLK) tempax |= 0x40; 6418 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax); 6419 6420#endif /* SIS315H */ 6421 6422 } 6423 6424 } /* Slavemode */ 6425 6426 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6427 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 6428 /* For 301BDH with LCD, we set up the Panel Link */ 6429 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6430 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6431 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6432 } 6433 } else { 6434 if(SiS_Pr->ChipType < SIS_315H) { 6435 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6436 } else { 6437 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6438 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 6439 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6440 } 6441 } else { 6442 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6443 } 6444 } 6445 } 6446} 6447 6448/*********************************************/ 6449/* SET PART 2 REGISTER GROUP */ 6450/*********************************************/ 6451 6452#ifdef SIS315H 6453static BOOLEAN 6454SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex, 6455 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index, 6456 unsigned short *ResIndex) 6457{ 6458 6459 if(SiS_Pr->ChipType < SIS_315H) return FALSE; 6460 6461 if(ModeNo <= 0x13) 6462 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6463 else 6464 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 6465 6466 (*ResIndex) &= 0x3f; 6467 (*CRT2Index) = 0; 6468 6469 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 6470 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 6471 (*CRT2Index) = 200; 6472 } 6473 } 6474 6475 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 6476 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 6477 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206; 6478 } 6479 } 6480 return (((*CRT2Index) != 0)); 6481} 6482#endif 6483 6484#ifdef SIS300 6485static void 6486SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc) 6487{ 6488 unsigned short tempcx; 6489 static const unsigned char atable[] = { 6490 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02, 6491 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02 6492 }; 6493 6494 if(!SiS_Pr->UseCustomMode) { 6495 if( ( ( (SiS_Pr->ChipType == SIS_630) || 6496 (SiS_Pr->ChipType == SIS_730) ) && 6497 (SiS_Pr->ChipRevision > 2) ) && 6498 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) && 6499 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) && 6500 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) { 6501 if(ModeNo == 0x13) { 6502 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9); 6503 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC); 6504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6); 6505 } else if((crt2crtc & 0x3F) == 4) { 6506 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B); 6507 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13); 6508 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5); 6509 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08); 6510 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2); 6511 } 6512 } 6513 6514 if(SiS_Pr->ChipType < SIS_315H) { 6515 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) { 6516 crt2crtc &= 0x1f; 6517 tempcx = 0; 6518 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 6519 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6520 tempcx += 7; 6521 } 6522 } 6523 tempcx += crt2crtc; 6524 if(crt2crtc >= 4) { 6525 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff); 6526 } 6527 6528 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 6529 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6530 if(crt2crtc == 4) { 6531 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28); 6532 } 6533 } 6534 } 6535 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18); 6536 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]); 6537 } 6538 } 6539 } 6540} 6541 6542/* For ECS A907. Highly preliminary. */ 6543static void 6544SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, 6545 unsigned short ModeNo) 6546{ 6547 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL; 6548 unsigned short crt2crtc, resindex; 6549 int i, j; 6550 6551 if(SiS_Pr->ChipType != SIS_300) return; 6552 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return; 6553 if(SiS_Pr->UseCustomMode) return; 6554 6555 if(ModeNo <= 0x13) { 6556 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6557 } else { 6558 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 6559 } 6560 6561 resindex = crt2crtc & 0x3F; 6562 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; 6563 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2; 6564 6565 /* The BIOS code (1.16.51,56) is obviously a fragment! */ 6566 if(ModeNo > 0x13) { 6567 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; 6568 resindex = 4; 6569 } 6570 6571 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); 6572 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]); 6573 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) { 6574 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6575 } 6576 for(j = 0x1c; j <= 0x1d; i++, j++ ) { 6577 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6578 } 6579 for(j = 0x1f; j <= 0x21; i++, j++ ) { 6580 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6581 } 6582 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]); 6583 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]); 6584} 6585#endif 6586 6587static void 6588SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 6589{ 6590 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return; 6591 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; 6592 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr625i | TVSetYPbPr625p)) return; 6593 6594 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6595 if(SiS_Pr->SiS_TVMode & TVSetHiVi960540) { 6596 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); 6597 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x47); 6598 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0xea); 6599 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,0x00); 6600 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,0x0e); 6601 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,0x00); 6602 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0xe6); 6603 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,0x90); 6604 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xc0,0x09); 6605 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xf8,0x03); 6606 } 6607 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 6608#ifndef OLD1280720P 6609 if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) { 6610 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x19); 6611 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x23); 6612 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0x1c); 6613 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,0x10); 6614 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,0x0b); 6615 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,0x10); 6616 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x2c); 6617 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,0x68); 6618 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xc0,0x01); 6619 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xf8,0x05); 6620 } 6621#endif 6622 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 6623 if(SiS_Pr->SiS_TVMode & TVSet525p1024) { 6624 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0x77); 6625 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x20,0x13); 6626 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2b,0x78); 6627 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2c,0x04); 6628 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x42,0x14); 6629 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x73); 6630 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1c,0xaf); 6631 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1e,0x71); 6632 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,0xbb); 6633 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,0xb5); 6634 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x26,0xdc); 6635 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,0x3c); 6636 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x45,0x11); 6637 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,0x00); 6638 } 6639 } else if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 6640 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 6641 static const unsigned char specialtv[] = { 6642 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53, 6643 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a, 6644 0x58,0xe4,0x73,0xda,0x13 6645 }; 6646 int i, j; 6647 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) { 6648 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]); 6649 } 6650 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72); 6651 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) { 6652 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 6653 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); 6654 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b); 6655 } else { 6656 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */ 6657 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */ 6658 } 6659 } 6660 } 6661 } else { 6662 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) || 6663 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) { 6664 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */ 6665 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */ 6666 } else { 6667 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */ 6668 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */ 6669 } 6670 } 6671} 6672 6673static void 6674SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 6675{ 6676 unsigned short temp; 6677 6678 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 6679 if(SiS_Pr->SiS_VGAVDE == 525) { 6680 temp = 0xc3; 6681 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 6682 temp++; 6683 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2; 6684 } 6685 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp); 6686 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3); 6687 } else if(SiS_Pr->SiS_VGAVDE == 420) { 6688 temp = 0x4d; 6689 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 6690 temp++; 6691 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++; 6692 } 6693 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp); 6694 } 6695 } 6696 6697 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6698 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) { 6699 if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 6700 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03); 6701 /* Not always for LV, see SetGrp2 */ 6702 } 6703 temp = 1; 6704 if(ModeNo <= 0x13) temp = 3; 6705 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp); 6706 } 6707 } 6708} 6709 6710static void 6711SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 6712 unsigned short RefreshRateTableIndex) 6713{ 6714 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp; 6715 unsigned short push2, modeflag, crt2crtc, bridgeoffset; 6716 unsigned int longtemp, PhaseIndex; 6717 BOOLEAN newtvphase; 6718 const unsigned char *TimingPoint; 6719#ifdef SIS315H 6720 unsigned short resindex, CRT2Index; 6721 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL; 6722 6723 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 6724#endif 6725 6726 if(ModeNo <= 0x13) { 6727 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 6728 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6729 } else if(SiS_Pr->UseCustomMode) { 6730 modeflag = SiS_Pr->CModeFlag; 6731 crt2crtc = 0; 6732 } else { 6733 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 6734 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 6735 } 6736 6737 temp = 0; 6738 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08; 6739 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04; 6740 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02; 6741 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01; 6742 6743 if(!(SiS_Pr->SiS_TVMode & TVSetPALTiming)) temp |= 0x10; 6744 6745 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp); 6746 6747 PhaseIndex = 0x01; /* SiS_PALPhase */ 6748 TimingPoint = SiS_Pr->SiS_PALTiming; 6749 6750 newtvphase = FALSE; 6751 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) && 6752 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || 6753 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) { 6754 newtvphase = TRUE; 6755 } 6756 6757 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6758 6759 TimingPoint = SiS_Pr->SiS_HiTVExtTiming; 6760 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6761 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing; 6762 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 6763 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing; 6764 } 6765 } 6766 6767 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 6768 6769 i = 0; 6770 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2; 6771 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1; 6772 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625i) i = 3; 6773 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625p) i = 4; 6774 6775 TimingPoint = &SiS_YPbPrTable[i][0]; 6776 6777 PhaseIndex = 0x00; /* SiS_NTSCPhase */ 6778 6779 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) { 6780 6781 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */ 6782 6783 } else { 6784 6785 TimingPoint = SiS_Pr->SiS_NTSCTiming; 6786 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */ 6787 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */ 6788 6789 } 6790 6791 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) { 6792 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */ 6793 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */ 6794 } 6795 6796 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 6797 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 6798 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */ 6799 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) { 6800 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */ 6801 } else { 6802 PhaseIndex = 0x10; /* SiS_SpecialPhase */ 6803 } 6804 } 6805 6806 for(i = 0x31, j = 0; i <= 0x34; i++, j++) { 6807 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]); 6808 } 6809 6810 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) { 6811 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); 6812 } 6813 for(i = 0x39; i <= 0x45; i++, j++) { 6814 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); 6815 } 6816 6817 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 6818 if(SiS_Pr->SiS_ModeType != ModeText) { 6819 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F); 6820 } 6821 } 6822 6823 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode); 6824 6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE); 6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE); 6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE); 6828 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE); 6829 6830 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950; 6831 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680; 6832 else if(SiS_Pr->SiS_TVMode & TVSetPALTiming) tempax = 520; 6833 else tempax = 440; /* NTSC, YPbPr 525 */ 6834 6835 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (SiS_Pr->SiS_VDE <= tempax)) { 6836 6837 tempax -= SiS_Pr->SiS_VDE; 6838 tempax >>= 1; 6839 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) { 6840 tempax >>= 1; 6841 } 6842 tempax &= 0x00ff; 6843 6844 temp = tempax + (unsigned short)TimingPoint[0]; 6845 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); 6846 6847 temp = tempax + (unsigned short)TimingPoint[1]; 6848 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp); 6849 } 6850 6851 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) { 6852 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 6853 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); 6854 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); 6855 } else { 6856 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17); 6857 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d); 6858 } 6859 } 6860 6861 tempcx = SiS_Pr->SiS_HT; 6862 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1; 6863 tempcx--; 6864 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--; 6865 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx); 6866 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f)); 6867 6868 tempcx = SiS_Pr->SiS_HT >> 1; 6869 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1; 6870 tempcx += 7; 6871 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4; 6872 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0)); 6873 6874 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8); 6875 tempbx += tempcx; 6876 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx); 6877 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0)); 6878 6879 tempbx += 8; 6880 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6881 tempbx -= 4; 6882 tempcx = tempbx; 6883 } 6884 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0)); 6885 6886 j += 2; 6887 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8)); 6888 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx); 6889 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0)); 6890 6891 tempcx += 8; 6892 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4; 6893 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0)); 6894 6895 tempcx = SiS_Pr->SiS_HT >> 1; 6896 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1; 6897 j += 2; 6898 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8)); 6899 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0)); 6900 6901 tempcx -= 11; 6902 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 6903 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1; 6904 } 6905 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx); 6906 6907 tempbx = SiS_Pr->SiS_VDE; 6908 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6909 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746; 6910 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746; 6911 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853; 6912 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && 6913 (!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) ) { 6914 tempbx >>= 1; 6915 if(SiS_Pr->ChipType >= SIS_315H) { 6916 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 6917 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++; 6918 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6919 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 6920 if(crt2crtc == 4) tempbx++; 6921 } 6922 } 6923 } 6924 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6925 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6926 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++; 6927 } 6928 if(!(SiS_Pr->SiS_TVMode & TVSetPALTiming)) { 6929 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */ 6930 } 6931 } 6932 } 6933 tempbx -= 2; 6934 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx); 6935 6936 temp = (tempcx >> 8) & 0x0F; 6937 temp |= ((tempbx >> 2) & 0xC0); 6938 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) { 6939 temp |= 0x10; 6940 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20; 6941 } 6942 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp); 6943 6944 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) { 6945 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5)); 6946 } 6947 6948 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 6949 tempbx = SiS_Pr->SiS_VDE; 6950 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && 6951 (!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) ) { 6952 tempbx >>= 1; 6953 } 6954 tempbx -= 3; 6955 temp = ((tempbx >> 3) & 0x60) | 0x18; 6956 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp); 6957 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx); 6958 6959 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) { 6960 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4)); 6961 } 6962 } 6963 6964 tempax = tempbx = tempcx = 0; 6965 if(!(modeflag & HalfDCLK)) { 6966 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) { 6967 tempbx |= 0x20; 6968 } 6969 } 6970 6971 tempch = tempcl = 1; 6972 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 6973 if(SiS_Pr->SiS_VGAHDE >= 960) { 6974 if(!(modeflag & HalfDCLK)) { 6975 tempcl = 32; 6976 if(SiS_Pr->SiS_VGAHDE >= 1280) { 6977 tempch = 20; 6978 tempbx &= ~0x20; 6979 } else if(SiS_Pr->SiS_VGAHDE >= 1024) { 6980 tempch = 25; 6981 } else { 6982 tempch = 25; /* OK */ 6983 } 6984 } 6985 } 6986 } 6987 6988 if(!(tempbx & 0x20)) { 6989 if(modeflag & HalfDCLK) tempcl <<= 1; 6990 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13; 6991 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3; 6992 tempax = longtemp / SiS_Pr->SiS_HDE; 6993 if(longtemp % SiS_Pr->SiS_HDE) tempax++; 6994 tempbx |= ((tempax >> 8) & 0x1F); 6995 tempcx = tempax >> 13; 6996 } 6997 6998 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax); 6999 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx); 7000 7001 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7002 7003 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,(tempcx & 0x07)); 7004 7005 if(SiS_Pr->SiS_TVMode & TVSetPALTiming) { 7006 tempbx = 0x0382; 7007 tempcx = 0x007e; 7008 } else { 7009 tempbx = 0x0369; 7010 tempcx = 0x0061; 7011 } 7012 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx); 7013 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx); 7014 temp = (tempcx & 0x0300) >> 6; 7015 temp |= ((tempbx >> 8) & 0x03); 7016 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 7017 temp |= 0x10; 7018 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr625p)) temp |= 0x20; 7019 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40; 7020 } 7021 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp); 7022 7023 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43); 7024 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3)); 7025 7026 SiS_SetTVSpecial(SiS_Pr, ModeNo); 7027 7028 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) { 7029 temp = 0; 7030 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8; 7031 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp); 7032 } 7033 7034 } 7035 7036 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 7037 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) { 7038 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01); 7039 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1)); 7040 } 7041 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF); 7042 } 7043 7044 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7045 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 7046 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00); 7047 } 7048 } 7049 7050 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return; 7051 7052 /* From here: Part2 LCD setup */ 7053 7054 tempbx = SiS_Pr->SiS_HDE; 7055 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7056 tempbx--; /* RHACTE = HDE - 1 */ 7057 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx); 7058 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0)); 7059 7060 temp = 0x01; 7061 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 7062 if(SiS_Pr->SiS_ModeType == ModeEGA) { 7063 if(SiS_Pr->SiS_VGAHDE >= 1024) { 7064 temp = 0x02; 7065 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 7066 temp = 0x01; 7067 } 7068 } 7069 } 7070 } 7071 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp); 7072 7073 tempbx = SiS_Pr->SiS_VDE - 1; 7074 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx); 7075 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07)); 7076 7077 tempcx = SiS_Pr->SiS_VT - 1; 7078 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx); 7079 temp = (tempcx >> 3) & 0xE0; 7080 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 7081 /* Enable dithering; only do this for 32bpp mode */ 7082 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { 7083 temp |= 0x10; 7084 } 7085 } 7086 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp); 7087 7088 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0); 7089 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0); 7090 7091 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB); 7092 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF); 7093 7094#ifdef SIS315H 7095 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 7096 &CRT2Index, &resindex)) { 7097 switch(CRT2Index) { 7098 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break; 7099 default: 7100 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break; 7101 } 7102 7103 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); 7104 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]); 7105 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) { 7106 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 7107 } 7108 for(j = 0x1c; j <= 0x1d; i++, j++ ) { 7109 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 7110 } 7111 for(j = 0x1f; j <= 0x21; i++, j++ ) { 7112 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 7113 } 7114 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]); 7115 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]); 7116 7117 SiS_SetGroup2_Tail(SiS_Pr, ModeNo); 7118 7119 } else { 7120#endif 7121 7122 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */ 7123 /* Clevo dual-link 1024x768 */ 7124 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */ 7125 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */ 7126 7127 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 7128 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) { 7129 tempbx = SiS_Pr->SiS_VDE - 1; 7130 tempcx = SiS_Pr->SiS_VT - 1; 7131 } else { 7132 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2); 7133 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2); 7134 } 7135 } else { 7136 tempbx = SiS_Pr->PanelYRes; 7137 tempcx = SiS_Pr->SiS_VT; 7138 tempax = 1; 7139 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) { 7140 tempax = SiS_Pr->PanelYRes; 7141 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */ 7142 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) { 7143 tempax = tempcx = 0; 7144 } else { 7145 tempax -= SiS_Pr->SiS_VDE; 7146 } 7147 tempax >>= 1; 7148 } 7149 tempcx -= tempax; /* lcdvdes */ 7150 tempbx -= tempax; /* lcdvdee */ 7151 } 7152 7153 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */ 7154 7155#ifdef SIS_XORG_XF86 7156#ifdef TWDEBUG 7157 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx); 7158#endif 7159#endif 7160 7161 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */ 7162 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */ 7163 7164 temp = (tempbx >> 5) & 0x38; 7165 temp |= ((tempcx >> 8) & 0x07); 7166 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp); 7167 7168 tempax = SiS_Pr->SiS_VDE; 7169 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7170 tempax = SiS_Pr->PanelYRes; 7171 } 7172 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4; 7173 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7174 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) { 7175 tempcx = (SiS_Pr->SiS_VT - tempax) / 10; 7176 } 7177 } 7178 7179 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1; 7180 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 7181 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) { 7182 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */ 7183 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes; 7184 if(tempax % 4) { tempax >>= 2; tempax++; } 7185 else { tempax >>= 2; } 7186 tempbx -= (tempax - 1); 7187 } else { 7188 tempbx -= 10; 7189 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1; 7190 } 7191 } 7192 } 7193 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 7194 tempbx++; 7195 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) { 7196 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 7197 tempbx = 770; 7198 tempcx = 3; 7199 } 7200 } 7201 } 7202 7203 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */ 7204 7205 if(SiS_Pr->UseCustomMode) { 7206 tempbx = SiS_Pr->CVSyncStart; 7207 } 7208 7209#ifdef SIS_XORG_XF86 7210#ifdef TWDEBUG 7211 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx); 7212#endif 7213#endif 7214 7215 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */ 7216 7217 temp = (tempbx >> 4) & 0xF0; 7218 tempbx += (tempcx + 1); 7219 temp |= (tempbx & 0x0F); 7220 7221 if(SiS_Pr->UseCustomMode) { 7222 temp &= 0xf0; 7223 temp |= (SiS_Pr->CVSyncEnd & 0x0f); 7224 } 7225 7226#ifdef SIS_XORG_XF86 7227#ifdef TWDEBUG 7228 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f)); 7229#endif 7230#endif 7231 7232 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); 7233 7234#ifdef SIS300 7235 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc); 7236#endif 7237 7238 bridgeoffset = 7; 7239 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2; 7240 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */ 7241 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++; 7242 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */ 7243 /* Higher bridgeoffset shifts to the LEFT */ 7244 7245 temp = 0; 7246 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7247 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) { 7248 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2); 7249 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1; 7250 } 7251 } 7252 temp += bridgeoffset; 7253 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */ 7254 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0)); 7255 7256 tempcx = SiS_Pr->SiS_HT; 7257 tempax = tempbx = SiS_Pr->SiS_HDE; 7258 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7259 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) { 7260 tempax = SiS_Pr->PanelXRes; 7261 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2); 7262 } 7263 } 7264 if(SiS_IsDualLink(SiS_Pr)) { 7265 tempcx >>= 1; 7266 tempbx >>= 1; 7267 tempax >>= 1; 7268 } 7269 7270#ifdef SIS_XORG_XF86 7271#ifdef TWDEBUG 7272 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx); 7273#endif 7274#endif 7275 7276 tempbx += bridgeoffset; 7277 7278 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */ 7279 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f)); 7280 7281 tempcx = (tempcx - tempax) >> 2; 7282 7283 tempbx += tempcx; 7284 push2 = tempbx; 7285 7286 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 7287 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 7288 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 7289 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47; 7290 } 7291 } 7292 } 7293 7294 if(SiS_Pr->UseCustomMode) { 7295 tempbx = SiS_Pr->CHSyncStart; 7296 if(modeflag & HalfDCLK) tempbx <<= 1; 7297 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7298 tempbx += bridgeoffset; 7299 } 7300 7301#ifdef SIS_XORG_XF86 7302#ifdef TWDEBUG 7303 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx); 7304#endif 7305#endif 7306 7307 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */ 7308 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0)); 7309 7310 tempbx = push2; 7311 7312 tempcx <<= 1; 7313 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7314 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2; 7315 } 7316 tempbx += tempcx; 7317 7318 if(SiS_Pr->UseCustomMode) { 7319 tempbx = SiS_Pr->CHSyncEnd; 7320 if(modeflag & HalfDCLK) tempbx <<= 1; 7321 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7322 tempbx += bridgeoffset; 7323 } 7324 7325#ifdef SIS_XORG_XF86 7326#ifdef TWDEBUG 7327 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx); 7328#endif 7329#endif 7330 7331 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */ 7332 7333 SiS_SetGroup2_Tail(SiS_Pr, ModeNo); 7334 7335#ifdef SIS300 7336 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo); 7337#endif 7338#ifdef SIS315H 7339 } /* CRT2-LCD from table */ 7340#endif 7341} 7342 7343/*********************************************/ 7344/* SET PART 3 REGISTER GROUP */ 7345/*********************************************/ 7346 7347static void 7348SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 7349{ 7350 unsigned short i; 7351 const unsigned char *tempdi; 7352 7353 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 7354 7355#ifndef SIS_CP 7356 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00); 7357#else 7358 SIS_CP_INIT301_CP 7359#endif 7360 7361 if(SiS_Pr->SiS_TVMode & TVSetPALTiming) { 7362 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA); 7363 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8); 7364 } else { 7365 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5); 7366 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7); 7367 } 7368 7369 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 7370 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA); 7371 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8); 7372 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8); 7373 } 7374 7375 tempdi = NULL; 7376 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7377 tempdi = SiS_Pr->SiS_HiTVGroup3Data; 7378 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 7379 tempdi = SiS_Pr->SiS_HiTVGroup3Simu; 7380 } 7381 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 7382 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr625i))) { 7383 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) 7384 tempdi = SiS_HiTVGroup3_2; 7385 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) 7386 tempdi = SiS_HiTVGroup3_1; 7387 } 7388 } 7389 if(tempdi) { 7390 for(i=0; i<=0x3E; i++) { 7391 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]); 7392 } 7393 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) { 7394 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 7395 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f); 7396 } 7397 } 7398 } 7399 7400#ifdef SIS_CP 7401 SIS_CP_INIT301_CP2 7402#endif 7403} 7404 7405/*********************************************/ 7406/* SET PART 4 REGISTER GROUP */ 7407/*********************************************/ 7408 7409#ifdef SIS315H 7410#if 0 7411static void 7412SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift) 7413{ 7414 unsigned short temp, temp1, temp2; 7415 7416 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f); 7417 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20); 7418 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift); 7419 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp); 7420 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0)); 7421 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f; 7422 temp = (unsigned short)((int)(temp) + shift); 7423 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f)); 7424 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43); 7425 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42); 7426 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift); 7427 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp); 7428 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0)); 7429} 7430#endif 7431 7432static void 7433SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 7434{ 7435 unsigned short temp, temp1; 7436 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 7437 7438 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return; 7439 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return; 7440 7441 if(SiS_Pr->ChipType >= XGI_20) return; 7442 7443 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) { 7444 if(!(ROMAddr[0x61] & 0x04)) return; 7445 } 7446 7447 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08); 7448 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a); 7449 if(!(temp & 0x01)) { 7450 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf); 7451 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc); 7452 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) { 7453 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8); 7454 } 7455 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb); 7456 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000; 7457 else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr625p)) temp = 0x0002; 7458 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400; 7459 else temp = 0x0402; 7460 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 7461 temp1 = 0; 7462 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4; 7463 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1); 7464 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01; 7465 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff)); 7466 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8)); 7467 if(ModeNo > 0x13) { 7468 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd); 7469 } 7470 } else { 7471 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03; 7472 if(temp1 == 0x01) temp |= 0x01; 7473 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */ 7474 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff)); 7475 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8)); 7476 if(ModeNo > 0x13) { 7477 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd); 7478 } 7479 } 7480 7481#if 0 7482 if(SiS_Pr->ChipType >= SIS_661) { /* ? */ 7483 if(SiS_Pr->SiS_TVMode & TVAspect43) { 7484 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 7485 if(resinfo == SIS_RI_1024x768) { 7486 SiS_ShiftXPos(SiS_Pr, 97); 7487 } else { 7488 SiS_ShiftXPos(SiS_Pr, 111); 7489 } 7490 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) { 7491 SiS_ShiftXPos(SiS_Pr, 136); 7492 } 7493 } 7494 } 7495#endif 7496 7497 } 7498 7499} 7500#endif 7501 7502static void 7503SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7504 unsigned short RefreshRateTableIndex) 7505{ 7506 unsigned short vclkindex, temp, reg1, reg2; 7507 7508 if(SiS_Pr->UseCustomMode) { 7509 reg1 = SiS_Pr->CSR2B; 7510 reg2 = SiS_Pr->CSR2C; 7511 } else { 7512 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 7513 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A; 7514 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B; 7515 } 7516 7517 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7518 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) { 7519 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57); 7520 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46); 7521 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6); 7522 } else { 7523 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1); 7524 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2); 7525 } 7526 } else { 7527 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01); 7528 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2); 7529 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1); 7530 } 7531 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00); 7532 temp = 0x08; 7533 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20; 7534 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp); 7535} 7536 7537static void 7538SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr) 7539{ 7540 if(SiS_Pr->ChipType >= SIS_315H) { 7541 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 7542 if((SiS_CRT2IsLCD(SiS_Pr)) || 7543 (SiS_IsVAMode(SiS_Pr))) { 7544 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) { 7545 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c); 7546 } else { 7547 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20); 7548 } 7549 } 7550 } 7551 } 7552 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 7553 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00); 7554#ifdef SET_EMI 7555 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 7556#endif 7557 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 7558 } 7559} 7560 7561static void 7562SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7563 unsigned short RefreshRateTableIndex) 7564{ 7565 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo; 7566 unsigned int tempebx, tempeax, templong; 7567 7568 if(ModeNo <= 0x13) { 7569 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 7570 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 7571 } else if(SiS_Pr->UseCustomMode) { 7572 modeflag = SiS_Pr->CModeFlag; 7573 resinfo = 0; 7574 } else { 7575 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 7576 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 7577 } 7578 7579 if(SiS_Pr->ChipType >= SIS_315H) { 7580 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 7581 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 7582 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e); 7583 } 7584 } 7585 } 7586 7587 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) { 7588 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7589 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f); 7590 } 7591 } 7592 7593 if(SiS_Pr->ChipType >= SIS_315H) { 7594 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 7595 SiS_SetDualLinkEtc(SiS_Pr); 7596 return; 7597 } 7598 } 7599 7600 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT); 7601 7602 tempbx = SiS_Pr->SiS_RVBHCMAX; 7603 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx); 7604 7605 temp = (tempbx >> 1) & 0x80; 7606 7607 tempcx = SiS_Pr->SiS_VGAHT - 1; 7608 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx); 7609 7610 temp |= ((tempcx >> 5) & 0x78); 7611 7612 tempcx = SiS_Pr->SiS_VGAVT - 1; 7613 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5; 7614 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx); 7615 7616 temp |= ((tempcx >> 8) & 0x07); 7617 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp); 7618 7619 tempbx = SiS_Pr->SiS_VGAHDE; 7620 if(modeflag & HalfDCLK) tempbx >>= 1; 7621 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7622 7623 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7624 temp = 0; 7625 if(tempbx > 800) temp = 0x60; 7626 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7627 temp = 0; 7628 if(tempbx > 1024) temp = 0xC0; 7629 else if(tempbx >= 960) temp = 0xA0; 7630 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPrProg) { 7631 temp = 0; 7632 if(tempbx >= 1280) temp = 0x40; 7633 else if(tempbx >= 1024) temp = 0x20; 7634 } else { 7635 temp = 0x80; 7636 if(tempbx >= 1024) temp = 0xA0; 7637 } 7638 7639 temp |= SiS_Pr->Init_P4_0E; 7640 7641 if(SiS_Pr->SiS_VBType & VB_SIS301) { 7642 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) { 7643 temp &= 0xf0; 7644 temp |= 0x0A; 7645 } 7646 } 7647 7648 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp); 7649 7650 tempeax = SiS_Pr->SiS_VGAVDE; 7651 tempebx = SiS_Pr->SiS_VDE; 7652 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7653 if(!(temp & 0xE0)) tempebx >>= 1; 7654 } 7655 7656 tempcx = SiS_Pr->SiS_RVBHRS; 7657 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx); 7658 tempcx >>= 8; 7659 tempcx |= 0x40; 7660 7661 if(tempeax <= tempebx) { 7662 tempcx ^= 0x40; 7663 } else { 7664 tempeax -= tempebx; 7665 } 7666 7667 tempeax *= (256 * 1024); 7668 templong = tempeax % tempebx; 7669 tempeax /= tempebx; 7670 if(templong) tempeax++; 7671 7672 temp = (unsigned short)(tempeax & 0x000000FF); 7673 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp); 7674 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8); 7675 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp); 7676 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */ 7677 temp |= (tempcx & 0x4F); 7678 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp); 7679 7680 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7681 7682 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28); 7683 7684 /* Calc Linebuffer max address and set/clear decimode */ 7685 tempbx = 0; 7686 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08; 7687 tempax = SiS_Pr->SiS_VGAHDE; 7688 if(modeflag & HalfDCLK) tempax >>= 1; 7689 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1; 7690 if(tempax > 800) { 7691 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7692 tempax -= 800; 7693 } else { 7694 tempbx = 0x08; 7695 if(tempax == 960) tempax *= 25; /* Correct */ 7696 else if(tempax == 1024) tempax *= 25; 7697 else tempax *= 20; 7698 temp = tempax % 32; 7699 tempax /= 32; 7700 if(temp) tempax++; 7701 tempax++; 7702 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7703 if(resinfo == SIS_RI_1024x768 || 7704 resinfo == SIS_RI_1024x576 || 7705 resinfo == SIS_RI_1280x1024 || 7706 resinfo == SIS_RI_1280x720) { 7707 /* Otherwise white line or garbage at right edge */ 7708 tempax = (tempax & 0xff00) | 0x20; 7709 } else if(resinfo == SIS_RI_960x540) { 7710 tempax = (tempax & 0xff00) | 0xed; 7711 } 7712 } 7713 } 7714 } 7715 tempax--; 7716 temp = ((tempax >> 4) & 0x30) | tempbx; 7717 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax); 7718 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp); 7719 7720 temp = 0x0036; tempbx = 0xD0; 7721 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 7722 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */ 7723 } 7724 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7725 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | 7726 TVSetHiVision | 7727 TVSetYPbPrProg))) { 7728 temp |= 0x01; 7729 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 7730 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 7731 temp &= ~0x01; 7732 } 7733 } 7734 } 7735 } 7736 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp); 7737 7738 tempbx = SiS_Pr->SiS_HT >> 1; 7739 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7740 tempbx -= 2; 7741 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx); 7742 temp = (tempbx >> 5) & 0x38; 7743 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp); 7744 7745 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 7746 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7747 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e); 7748 /* LCD-too-dark-error-source, see FinalizeLCD() */ 7749 } 7750 } 7751 7752 SiS_SetDualLinkEtc(SiS_Pr); 7753 7754 } /* 301B */ 7755 7756 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 7757} 7758 7759/*********************************************/ 7760/* SET PART 5 REGISTER GROUP */ 7761/*********************************************/ 7762 7763static void 7764SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 7765{ 7766 7767 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 7768 7769 if(SiS_Pr->SiS_ModeType == ModeVGA) { 7770 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) { 7771 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 7772 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); 7773 } 7774 } 7775} 7776 7777/*********************************************/ 7778/* MODIFY CRT1 GROUP FOR SLAVE MODE */ 7779/*********************************************/ 7780 7781static BOOLEAN 7782SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7783 unsigned short RefreshRateTableIndex, unsigned short *ResIndex, 7784 unsigned short *DisplayType) 7785 { 7786 unsigned short modeflag = 0; 7787 BOOLEAN checkhd = TRUE; 7788 7789 /* Pass 1:1 not supported here */ 7790 7791 if(ModeNo <= 0x13) { 7792 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 7793 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 7794 } else { 7795 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 7796 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 7797 } 7798 7799 (*ResIndex) &= 0x3F; 7800 7801 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 7802 7803 (*DisplayType) = 80; 7804 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) { 7805 (*DisplayType) = 82; 7806 if(SiS_Pr->SiS_ModeType > ModeVGA) { 7807 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84; 7808 } 7809 } 7810 if((*DisplayType) != 84) { 7811 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++; 7812 } 7813 7814 } else { 7815 7816 (*DisplayType = 0); 7817 switch(SiS_Pr->SiS_LCDResInfo) { 7818 case Panel_320x240_1: (*DisplayType) = 50; 7819 checkhd = FALSE; 7820 break; 7821 case Panel_320x240_2: (*DisplayType) = 14; 7822 break; 7823 case Panel_320x240_3: (*DisplayType) = 18; 7824 break; 7825 case Panel_640x480: (*DisplayType) = 10; 7826 break; 7827 case Panel_1024x600: (*DisplayType) = 26; 7828 break; 7829 default: return TRUE; 7830 } 7831 7832 if(checkhd) { 7833 if(modeflag & HalfDCLK) (*DisplayType)++; 7834 } 7835 7836 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) { 7837 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2; 7838 } 7839 7840 } 7841 7842 return TRUE; 7843} 7844 7845static void 7846SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7847 unsigned short RefreshRateTableIndex) 7848{ 7849 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType; 7850 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr = NULL; 7851 static const unsigned short CRIdx[] = { 7852 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 7853 0x07, 0x10, 0x11, 0x15, 0x16 7854 }; 7855 7856 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 7857 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 7858 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 7859 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) 7860 return; 7861 7862 if(SiS_Pr->SiS_IF_DEF_LVDS) { 7863 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 7864 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return; 7865 } 7866 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 7867 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return; 7868 } else return; 7869 7870 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return; 7871 7872 if(SiS_Pr->ChipType < SIS_315H) { 7873 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return; 7874 } 7875 7876 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 7877 &ResIndex, &DisplayType))) { 7878 return; 7879 } 7880 7881 switch(DisplayType) { 7882 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */ 7883 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */ 7884 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */ 7885 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */ 7886 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */ 7887 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break; 7888 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break; 7889#if 0 /* Works better with calculated numbers */ 7890 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break; 7891 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break; 7892 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break; 7893 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break; 7894#endif 7895 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break; 7896 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break; 7897 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break; 7898 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break; 7899 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break; 7900 } 7901 7902 if(LVDSCRT1Ptr) { 7903 7904 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 7905 7906 for(i = 0; i <= 10; i++) { 7907 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i]; 7908 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah); 7909 } 7910 7911 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) { 7912 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j]; 7913 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah); 7914 } 7915 7916 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0; 7917 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah); 7918 7919 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 7920 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 7921 7922 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5; 7923 if(modeflag & DoubleScanMode) tempah |= 0x80; 7924 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah); 7925 7926 } else { 7927 7928 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex); 7929 7930 } 7931} 7932 7933/*********************************************/ 7934/* SET CRT2 ECLK */ 7935/*********************************************/ 7936 7937static void 7938SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7939 unsigned short RefreshRateTableIndex) 7940{ 7941 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 7942 unsigned short clkbase, vclkindex = 0; 7943 unsigned char sr2b, sr2c; 7944 7945 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 7946 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 7947 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) { 7948 RefreshRateTableIndex--; 7949 } 7950 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, 7951 RefreshRateTableIndex); 7952 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 7953 } else { 7954 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, 7955 RefreshRateTableIndex); 7956 } 7957 7958 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B; 7959 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C; 7960 7961 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 7962 if(SiS_Pr->SiS_UseROM) { 7963 if(ROMAddr[0x220] & 0x01) { 7964 sr2b = ROMAddr[0x227]; 7965 sr2c = ROMAddr[0x228]; 7966 } 7967 } 7968 } 7969 7970 clkbase = 0x02B; 7971 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 7972 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 7973 clkbase += 3; 7974 } 7975 } 7976 7977 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20); 7978 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b); 7979 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); 7980 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10); 7981 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b); 7982 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); 7983 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00); 7984 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b); 7985 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); 7986} 7987 7988/*********************************************/ 7989/* SET UP CHRONTEL CHIPS */ 7990/*********************************************/ 7991 7992static void 7993SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7994 unsigned short RefreshRateTableIndex) 7995{ 7996 unsigned short TVType, resindex; 7997 const struct SiS_CHTVRegData *CHTVRegData = NULL; 7998 7999 if(ModeNo <= 0x13) 8000 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 8001 else 8002 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 8003 8004 resindex &= 0x3F; 8005 8006 TVType = 0; 8007 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 8008 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 8009 TVType += 2; 8010 if(SiS_Pr->SiS_ModeType > ModeVGA) { 8011 if(SiS_Pr->SiS_CHSOverScan) TVType = 8; 8012 } 8013 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 8014 TVType = 4; 8015 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 8016 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) { 8017 TVType = 6; 8018 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 8019 } 8020 } 8021 8022 switch(TVType) { 8023 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break; 8024 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break; 8025 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break; 8026 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; 8027 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break; 8028 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break; 8029 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break; 8030 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break; 8031 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break; 8032 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; 8033 } 8034 8035 8036 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 8037 8038#ifdef SIS300 8039 8040 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */ 8041 8042 /* We don't support modes >800x600 */ 8043 if (resindex > 5) return; 8044 8045 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 8046 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/ 8047 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/ 8048 } else { 8049 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/ 8050 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/ 8051 } 8052 8053 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */ 8054 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */ 8055 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */ 8056 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */ 8057 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */ 8058 8059 /* Set minimum flicker filter for Luma channel (SR1-0=00), 8060 minimum text enhancement (S3-2=10), 8061 maximum flicker filter for Chroma channel (S5-4=10) 8062 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!) 8063 */ 8064 SiS_SetCH700x(SiS_Pr,0x01,0x28); 8065 8066 /* Set video bandwidth 8067 High bandwith Luma composite video filter(S0=1) 8068 low bandwith Luma S-video filter (S2-1=00) 8069 disable peak filter in S-video channel (S3=0) 8070 high bandwidth Chroma Filter (S5-4=11) 8071 =00110001=0x31 8072 */ 8073 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */ 8074 8075 /* Register 0x3D does not exist in non-macrovision register map 8076 (Maybe this is a macrovision register?) 8077 */ 8078#ifndef SIS_CP 8079 SiS_SetCH70xx(SiS_Pr,0x3d,0x00); 8080#endif 8081 8082 /* Register 0x10 only contains 1 writable bit (S0) for sensing, 8083 all other bits a read-only. Macrovision? 8084 */ 8085 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F); 8086 8087 /* Register 0x11 only contains 3 writable bits (S0-S2) for 8088 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) ) 8089 */ 8090 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8); 8091 8092 /* Clear DSEN 8093 */ 8094 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF); 8095 8096 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */ 8097 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) { 8098 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */ 8099 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8100 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */ 8101 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */ 8102 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */ 8103 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0); 8104 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0); 8105 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0); 8106 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0); 8107 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0); 8108 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0); 8109 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0); 8110 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */ 8111 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */ 8112 } 8113 } else { 8114 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */ 8115 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8116 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); 8117 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */ 8118#if 0 8119 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */ 8120 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */ 8121 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */ 8122 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0); 8123 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0); 8124 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0); 8125 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0); 8126 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0); 8127 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */ 8128 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */ 8129#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */ 8130 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8131 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); 8132 } 8133 } 8134 } else { /* ---- PAL ---- */ 8135 /* We don't play around with FSCI in PAL mode */ 8136 if(resindex == 0x04) { 8137 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8138 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */ 8139 } else { 8140 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8141 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */ 8142 } 8143 } 8144 8145#endif /* 300 */ 8146 8147 } else { 8148 8149 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */ 8150 8151#ifdef SIS315H 8152 8153 unsigned short temp; 8154 8155 /* We don't support modes >1024x768 */ 8156 if (resindex > 6) return; 8157 8158 temp = CHTVRegData[resindex].Reg[0]; 8159 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10; 8160 SiS_SetCH701x(SiS_Pr,0x00,temp); 8161 8162 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]); 8163 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]); 8164 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]); 8165 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]); 8166 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]); 8167 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]); 8168 8169 temp = CHTVRegData[resindex].Reg[7]; 8170 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66; 8171 SiS_SetCH701x(SiS_Pr,0x07,temp); 8172 8173 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]); 8174 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]); 8175 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]); 8176 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]); 8177 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]); 8178 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]); 8179 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]); 8180 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]); 8181 8182 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02; 8183 /* D1 should be set for PAL, PAL-N and NTSC-J, 8184 but I won't do that for PAL unless somebody 8185 tells me to do so. Since the BIOS uses 8186 non-default CIV values and blacklevels, 8187 this might be compensated anyway. 8188 */ 8189 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02; 8190 SiS_SetCH701x(SiS_Pr,0x21,temp); 8191 8192#endif /* 315 */ 8193 8194 } 8195 8196#ifdef SIS_CP 8197 SIS_CP_INIT301_CP3 8198#endif 8199 8200} 8201 8202#ifdef SIS315H /* ----------- 315 series only ---------- */ 8203 8204void 8205SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr) 8206{ 8207 unsigned short temp; 8208 8209 /* Enable Chrontel 7019 LCD panel backlight */ 8210 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8211 if(SiS_Pr->ChipType == SIS_740) { 8212 SiS_SetCH701x(SiS_Pr,0x66,0x65); 8213 } else { 8214 temp = SiS_GetCH701x(SiS_Pr,0x66); 8215 temp |= 0x20; 8216 SiS_SetCH701x(SiS_Pr,0x66,temp); 8217 } 8218 } 8219} 8220 8221void 8222SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr) 8223{ 8224 unsigned short temp; 8225 8226 /* Disable Chrontel 7019 LCD panel backlight */ 8227 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8228 temp = SiS_GetCH701x(SiS_Pr,0x66); 8229 temp &= 0xDF; 8230 SiS_SetCH701x(SiS_Pr,0x66,temp); 8231 } 8232} 8233 8234static void 8235SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr) 8236{ 8237 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b }; 8238 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 }; 8239 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 }; 8240 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 }; 8241 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 }; 8242 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; 8243 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; 8244 const unsigned char *tableptr = NULL; 8245 int i; 8246 8247 /* Set up Power up/down timing */ 8248 8249 if(SiS_Pr->ChipType == SIS_740) { 8250 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 8251 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740; 8252 else tableptr = table1024_740; 8253 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 8254 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 8255 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) { 8256 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740; 8257 else tableptr = table1400_740; 8258 } else return; 8259 } else { 8260 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 8261 tableptr = table1024_650; 8262 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 8263 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 8264 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) { 8265 tableptr = table1400_650; 8266 } else return; 8267 } 8268 8269 for(i=0; i<5; i++) { 8270 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]); 8271 } 8272} 8273 8274static void 8275SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr) 8276{ 8277 const unsigned char *tableptr = NULL; 8278 unsigned short tempbh; 8279 int i; 8280 static const unsigned char regtable[] = { 8281 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71, 8282 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 8283 }; 8284 static const unsigned char table1024_740[] = { 8285 0x60, 0x02, 0x00, 0x07, 0x40, 0xed, 8286 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 8287 }; 8288 static const unsigned char table1280_740[] = { 8289 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, 8290 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 8291 }; 8292 static const unsigned char table1400_740[] = { 8293 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, 8294 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 8295 }; 8296 static const unsigned char table1600_740[] = { 8297 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3, 8298 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 8299 }; 8300 static const unsigned char table1024_650[] = { 8301 0x60, 0x02, 0x00, 0x07, 0x40, 0xed, 8302 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 8303 }; 8304 static const unsigned char table1280_650[] = { 8305 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, 8306 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 8307 }; 8308 static const unsigned char table1400_650[] = { 8309 0x60, 0x03, 0x11, 0x00, 0x40, 0xef, 8310 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 8311 }; 8312 static const unsigned char table1600_650[] = { 8313 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3, 8314 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a 8315 }; 8316 8317 if(SiS_Pr->ChipType == SIS_740) { 8318 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740; 8319 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740; 8320 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740; 8321 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740; 8322 else return; 8323 } else { 8324 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650; 8325 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650; 8326 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650; 8327 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650; 8328 else return; 8329 } 8330 8331 tempbh = SiS_GetCH701x(SiS_Pr,0x74); 8332 if((tempbh == 0xf6) || (tempbh == 0xc7)) { 8333 tempbh = SiS_GetCH701x(SiS_Pr,0x73); 8334 if(tempbh == 0xc8) { 8335 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return; 8336 } else if(tempbh == 0xdb) { 8337 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return; 8338 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return; 8339 } else if(tempbh == 0xde) { 8340 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return; 8341 } 8342 } 8343 8344 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d; 8345 else tempbh = 0x0c; 8346 8347 for(i = 0; i < tempbh; i++) { 8348 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]); 8349 } 8350 SiS_ChrontelPowerSequencing(SiS_Pr); 8351 tempbh = SiS_GetCH701x(SiS_Pr,0x1e); 8352 tempbh |= 0xc0; 8353 SiS_SetCH701x(SiS_Pr,0x1e,tempbh); 8354 8355 if(SiS_Pr->ChipType == SIS_740) { 8356 tempbh = SiS_GetCH701x(SiS_Pr,0x1c); 8357 tempbh &= 0xfb; 8358 SiS_SetCH701x(SiS_Pr,0x1c,tempbh); 8359 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03); 8360 tempbh = SiS_GetCH701x(SiS_Pr,0x64); 8361 tempbh |= 0x40; 8362 SiS_SetCH701x(SiS_Pr,0x64,tempbh); 8363 tempbh = SiS_GetCH701x(SiS_Pr,0x03); 8364 tempbh &= 0x3f; 8365 SiS_SetCH701x(SiS_Pr,0x03,tempbh); 8366 } 8367} 8368 8369static void 8370SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr) 8371{ 8372 unsigned char temp, temp1; 8373 8374 temp1 = SiS_GetCH701x(SiS_Pr,0x49); 8375 SiS_SetCH701x(SiS_Pr,0x49,0x3e); 8376 temp = SiS_GetCH701x(SiS_Pr,0x47); 8377 temp &= 0x7f; /* Use external VSYNC */ 8378 SiS_SetCH701x(SiS_Pr,0x47,temp); 8379 SiS_LongDelay(SiS_Pr, 3); 8380 temp = SiS_GetCH701x(SiS_Pr,0x47); 8381 temp |= 0x80; /* Use internal VSYNC */ 8382 SiS_SetCH701x(SiS_Pr,0x47,temp); 8383 SiS_SetCH701x(SiS_Pr,0x49,temp1); 8384} 8385 8386static void 8387SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr) 8388{ 8389 unsigned short temp; 8390 8391 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8392 if(SiS_Pr->ChipType == SIS_740) { 8393 temp = SiS_GetCH701x(SiS_Pr,0x1c); 8394 temp |= 0x04; /* Invert XCLK phase */ 8395 SiS_SetCH701x(SiS_Pr,0x1c,temp); 8396 } 8397 if(SiS_IsYPbPr(SiS_Pr)) { 8398 temp = SiS_GetCH701x(SiS_Pr,0x01); 8399 temp &= 0x3f; 8400 temp |= 0x80; /* Enable YPrPb (HDTV) */ 8401 SiS_SetCH701x(SiS_Pr,0x01,temp); 8402 } 8403 if(SiS_IsChScart(SiS_Pr)) { 8404 temp = SiS_GetCH701x(SiS_Pr,0x01); 8405 temp &= 0x3f; 8406 temp |= 0xc0; /* Enable SCART + CVBS */ 8407 SiS_SetCH701x(SiS_Pr,0x01,temp); 8408 } 8409 if(SiS_Pr->ChipType == SIS_740) { 8410 SiS_ChrontelResetVSync(SiS_Pr); 8411 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */ 8412 } else { 8413 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */ 8414 temp = SiS_GetCH701x(SiS_Pr,0x49); 8415 if(SiS_IsYPbPr(SiS_Pr)) { 8416 temp = SiS_GetCH701x(SiS_Pr,0x73); 8417 temp |= 0x60; 8418 SiS_SetCH701x(SiS_Pr,0x73,temp); 8419 } 8420 temp = SiS_GetCH701x(SiS_Pr,0x47); 8421 temp &= 0x7f; 8422 SiS_SetCH701x(SiS_Pr,0x47,temp); 8423 SiS_LongDelay(SiS_Pr, 2); 8424 temp = SiS_GetCH701x(SiS_Pr,0x47); 8425 temp |= 0x80; 8426 SiS_SetCH701x(SiS_Pr,0x47,temp); 8427 } 8428 } 8429} 8430 8431static void 8432SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr) 8433{ 8434 unsigned short temp; 8435 8436 /* Complete power down of LVDS */ 8437 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8438 if(SiS_Pr->ChipType == SIS_740) { 8439 SiS_LongDelay(SiS_Pr, 1); 8440 SiS_GenericDelay(SiS_Pr, 5887); 8441 SiS_SetCH701x(SiS_Pr,0x76,0xac); 8442 SiS_SetCH701x(SiS_Pr,0x66,0x00); 8443 } else { 8444 SiS_LongDelay(SiS_Pr, 2); 8445 temp = SiS_GetCH701x(SiS_Pr,0x76); 8446 temp &= 0xfc; 8447 SiS_SetCH701x(SiS_Pr,0x76,temp); 8448 SiS_SetCH701x(SiS_Pr,0x66,0x00); 8449 } 8450 } 8451} 8452 8453static void 8454SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr) 8455{ 8456 unsigned short temp; 8457 8458 if(SiS_Pr->ChipType == SIS_740) { 8459 8460 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */ 8461 temp &= 0x01; 8462 if(!temp) { 8463 8464 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8465 temp = SiS_GetCH701x(SiS_Pr,0x49); 8466 SiS_SetCH701x(SiS_Pr,0x49,0x3e); 8467 } 8468 8469 /* Reset Chrontel 7019 datapath */ 8470 SiS_SetCH701x(SiS_Pr,0x48,0x10); 8471 SiS_LongDelay(SiS_Pr, 1); 8472 SiS_SetCH701x(SiS_Pr,0x48,0x18); 8473 8474 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8475 SiS_ChrontelResetVSync(SiS_Pr); 8476 SiS_SetCH701x(SiS_Pr,0x49,temp); 8477 } 8478 8479 } else { 8480 8481 /* Clear/set/clear GPIO */ 8482 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8483 temp &= 0xef; 8484 SiS_SetCH701x(SiS_Pr,0x5c,temp); 8485 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8486 temp |= 0x10; 8487 SiS_SetCH701x(SiS_Pr,0x5c,temp); 8488 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8489 temp &= 0xef; 8490 SiS_SetCH701x(SiS_Pr,0x5c,temp); 8491 temp = SiS_GetCH701x(SiS_Pr,0x61); 8492 if(!temp) { 8493 SiS_SetCH701xForLCD(SiS_Pr); 8494 } 8495 } 8496 8497 } else { /* 650 */ 8498 /* Reset Chrontel 7019 datapath */ 8499 SiS_SetCH701x(SiS_Pr,0x48,0x10); 8500 SiS_LongDelay(SiS_Pr, 1); 8501 SiS_SetCH701x(SiS_Pr,0x48,0x18); 8502 } 8503} 8504 8505static void 8506SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr) 8507{ 8508 unsigned short temp; 8509 8510 if(SiS_Pr->ChipType == SIS_740) { 8511 8512 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8513 SiS_ChrontelResetVSync(SiS_Pr); 8514 } 8515 8516 } else { 8517 8518 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */ 8519 temp = SiS_GetCH701x(SiS_Pr,0x49); 8520 temp &= 1; 8521 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */ 8522 temp = SiS_GetCH701x(SiS_Pr,0x47); 8523 temp &= 0x70; 8524 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */ 8525 SiS_LongDelay(SiS_Pr, 3); 8526 temp = SiS_GetCH701x(SiS_Pr,0x47); 8527 temp |= 0x80; 8528 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */ 8529 } 8530 8531 } 8532} 8533 8534static void 8535SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 8536{ 8537 unsigned short temp,temp1; 8538 8539 if(SiS_Pr->ChipType == SIS_740) { 8540 8541 temp = SiS_GetCH701x(SiS_Pr,0x61); 8542 if(temp < 1) { 8543 temp++; 8544 SiS_SetCH701x(SiS_Pr,0x61,temp); 8545 } 8546 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */ 8547 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */ 8548 SiS_LongDelay(SiS_Pr, 1); 8549 SiS_GenericDelay(SiS_Pr, 5887); 8550 8551 } else { /* 650 */ 8552 8553 temp1 = 0; 8554 temp = SiS_GetCH701x(SiS_Pr,0x61); 8555 if(temp < 2) { 8556 temp++; 8557 SiS_SetCH701x(SiS_Pr,0x61,temp); 8558 temp1 = 1; 8559 } 8560 SiS_SetCH701x(SiS_Pr,0x76,0xac); 8561 temp = SiS_GetCH701x(SiS_Pr,0x66); 8562 temp |= 0x5f; 8563 SiS_SetCH701x(SiS_Pr,0x66,temp); 8564 if(ModeNo > 0x13) { 8565 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8566 SiS_GenericDelay(SiS_Pr, 1023); 8567 } else { 8568 SiS_GenericDelay(SiS_Pr, 767); 8569 } 8570 } else { 8571 if(!temp1) 8572 SiS_GenericDelay(SiS_Pr, 767); 8573 } 8574 temp = SiS_GetCH701x(SiS_Pr,0x76); 8575 temp |= 0x03; 8576 SiS_SetCH701x(SiS_Pr,0x76,temp); 8577 temp = SiS_GetCH701x(SiS_Pr,0x66); 8578 temp &= 0x7f; 8579 SiS_SetCH701x(SiS_Pr,0x66,temp); 8580 SiS_LongDelay(SiS_Pr, 1); 8581 8582 } 8583} 8584 8585static void 8586SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr) 8587{ 8588 unsigned short temp,tempcl,tempch; 8589 8590 SiS_LongDelay(SiS_Pr, 1); 8591 tempcl = 3; 8592 tempch = 0; 8593 8594 do { 8595 temp = SiS_GetCH701x(SiS_Pr,0x66); 8596 temp &= 0x04; /* PLL stable? -> bail out */ 8597 if(temp == 0x04) break; 8598 8599 if(SiS_Pr->ChipType == SIS_740) { 8600 /* Power down LVDS output, PLL normal operation */ 8601 SiS_SetCH701x(SiS_Pr,0x76,0xac); 8602 } 8603 8604 SiS_SetCH701xForLCD(SiS_Pr); 8605 8606 if(tempcl == 0) { 8607 if(tempch == 3) break; 8608 SiS_ChrontelResetDB(SiS_Pr); 8609 tempcl = 3; 8610 tempch++; 8611 } 8612 tempcl--; 8613 temp = SiS_GetCH701x(SiS_Pr,0x76); 8614 temp &= 0xfb; /* Reset PLL */ 8615 SiS_SetCH701x(SiS_Pr,0x76,temp); 8616 SiS_LongDelay(SiS_Pr, 2); 8617 temp = SiS_GetCH701x(SiS_Pr,0x76); 8618 temp |= 0x04; /* PLL normal operation */ 8619 SiS_SetCH701x(SiS_Pr,0x76,temp); 8620 if(SiS_Pr->ChipType == SIS_740) { 8621 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */ 8622 } else { 8623 SiS_SetCH701x(SiS_Pr,0x78,0x60); 8624 } 8625 SiS_LongDelay(SiS_Pr, 2); 8626 } while(0); 8627 8628 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */ 8629} 8630 8631static void 8632SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr) 8633{ 8634 unsigned short temp; 8635 8636 temp = SiS_GetCH701x(SiS_Pr,0x03); 8637 temp |= 0x80; /* Set datapath 1 to TV */ 8638 temp &= 0xbf; /* Set datapath 2 to LVDS */ 8639 SiS_SetCH701x(SiS_Pr,0x03,temp); 8640 8641 if(SiS_Pr->ChipType == SIS_740) { 8642 8643 temp = SiS_GetCH701x(SiS_Pr,0x1c); 8644 temp &= 0xfb; /* Normal XCLK phase */ 8645 SiS_SetCH701x(SiS_Pr,0x1c,temp); 8646 8647 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03); 8648 8649 temp = SiS_GetCH701x(SiS_Pr,0x64); 8650 temp |= 0x40; /* ? Bit not defined */ 8651 SiS_SetCH701x(SiS_Pr,0x64,temp); 8652 8653 temp = SiS_GetCH701x(SiS_Pr,0x03); 8654 temp &= 0x3f; /* D1 input to both LVDS and TV */ 8655 SiS_SetCH701x(SiS_Pr,0x03,temp); 8656 8657 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) { 8658 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */ 8659 SiS_LongDelay(SiS_Pr, 1); 8660 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */ 8661 SiS_ChrontelResetDB(SiS_Pr); 8662 SiS_ChrontelDoSomething2(SiS_Pr); 8663 SiS_ChrontelDoSomething3(SiS_Pr, 0); 8664 } else { 8665 temp = SiS_GetCH701x(SiS_Pr,0x66); 8666 if(temp != 0x45) { 8667 SiS_ChrontelResetDB(SiS_Pr); 8668 SiS_ChrontelDoSomething2(SiS_Pr); 8669 SiS_ChrontelDoSomething3(SiS_Pr, 0); 8670 } 8671 } 8672 8673 } else { /* 650 */ 8674 8675 SiS_ChrontelResetDB(SiS_Pr); 8676 SiS_ChrontelDoSomething2(SiS_Pr); 8677 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34); 8678 SiS_ChrontelDoSomething3(SiS_Pr,temp); 8679 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */ 8680 8681 } 8682 8683} 8684#endif /* 315 series */ 8685 8686/*********************************************/ 8687/* MAIN: SET CRT2 REGISTER GROUP */ 8688/*********************************************/ 8689 8690BOOLEAN 8691SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 8692{ 8693#ifdef SIS300 8694 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 8695#endif 8696 unsigned short ModeIdIndex, RefreshRateTableIndex; 8697 8698 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 8699 8700 if(!SiS_Pr->UseCustomMode) { 8701 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex); 8702 } else { 8703 ModeIdIndex = 0; 8704 } 8705 8706 /* Used for shifting CR33 */ 8707 SiS_Pr->SiS_SelectCRT2Rate = 4; 8708 8709 SiS_UnLockCRT2(SiS_Pr); 8710 8711 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex); 8712 8713 SiS_SaveCRT2Info(SiS_Pr,ModeNo); 8714 8715 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8716 SiS_DisableBridge(SiS_Pr); 8717 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) { 8718 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80); 8719 } 8720 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex); 8721 } 8722 8723 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 8724 SiS_LockCRT2(SiS_Pr); 8725 SiS_DisplayOn(SiS_Pr); 8726 return TRUE; 8727 } 8728 8729 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8730 8731 /* Set up Panel Link for LVDS and LCDA */ 8732 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0; 8733 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 8734 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) || 8735 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) { 8736 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8737 } 8738 8739#ifdef SIS_XORG_XF86 8740#ifdef TWDEBUG 8741 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES); 8742 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE); 8743 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE); 8744 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT); 8745 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT); 8746#endif 8747#endif 8748 8749 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8750 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8751 } 8752 8753 if(SiS_Pr->SiS_VBType & VB_SISVB) { 8754 8755 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8756 8757 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8758#ifdef SIS315H 8759 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8760#endif 8761 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex); 8762 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8763#ifdef SIS315H 8764 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex); 8765#endif 8766 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex); 8767 8768 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex); 8769 8770 /* For 301BDH (Panel link initialization): */ 8771 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 8772 8773 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) { 8774 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 8775 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8776 } 8777 } 8778 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8779 } 8780 } 8781 8782 } else { 8783 8784 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex); 8785 8786 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8787 8788 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8789 8790 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8791 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 8792 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 8793 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8794#ifdef SIS315H 8795 SiS_SetCH701xForLCD(SiS_Pr); 8796#endif 8797 } 8798 } 8799 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 8800 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8801 } 8802 } 8803 } 8804 8805 } 8806 8807#ifdef SIS300 8808 if(SiS_Pr->ChipType < SIS_315H) { 8809 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8810 if(SiS_Pr->SiS_UseOEM) { 8811 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) { 8812 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 8813 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8814 } 8815 } else { 8816 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8817 } 8818 } 8819 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 8820 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 8821 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 8822 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex); 8823 } 8824 SiS_DisplayOn(SiS_Pr); 8825 } 8826 } 8827 } 8828#endif 8829 8830#ifdef SIS315H 8831 if(SiS_Pr->ChipType >= SIS_315H) { 8832 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8833 if(SiS_Pr->ChipType < SIS_661) { 8834 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex); 8835 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8836 } else { 8837 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8838 } 8839 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40); 8840 } 8841 } 8842#endif 8843 8844 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8845 SiS_EnableBridge(SiS_Pr); 8846 } 8847 8848 SiS_DisplayOn(SiS_Pr); 8849 8850 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 8851 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 8852 /* Disable LCD panel when using TV */ 8853 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C); 8854 } else { 8855 /* Disable TV when using LCD */ 8856 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8); 8857 } 8858 } 8859 8860 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8861 SiS_LockCRT2(SiS_Pr); 8862 } 8863 8864 return TRUE; 8865} 8866 8867 8868/*********************************************/ 8869/* ENABLE/DISABLE LCD BACKLIGHT (SIS) */ 8870/*********************************************/ 8871 8872void 8873SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr) 8874{ 8875 /* Switch on LCD backlight on SiS30xLV */ 8876 SiS_DDC2Delay(SiS_Pr,0xff00); 8877 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { 8878 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 8879 SiS_WaitVBRetrace(SiS_Pr); 8880 } 8881 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) { 8882 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 8883 } 8884} 8885 8886void 8887SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr) 8888{ 8889 /* Switch off LCD backlight on SiS30xLV */ 8890 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); 8891 SiS_DDC2Delay(SiS_Pr,0xff00); 8892} 8893 8894/*********************************************/ 8895/* DDC RELATED FUNCTIONS */ 8896/*********************************************/ 8897 8898static void 8899SiS_SetupDDCN(struct SiS_Private *SiS_Pr) 8900{ 8901 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data; 8902 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk; 8903 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) { 8904 SiS_Pr->SiS_DDC_NData &= 0x0f; 8905 SiS_Pr->SiS_DDC_NClk &= 0x0f; 8906 } 8907} 8908 8909#ifdef SIS300 8910static unsigned char * 8911SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr) 8912{ 8913 int i, j, num; 8914 unsigned short tempah,temp; 8915 unsigned char *mydataptr; 8916 8917 for(i=0; i<20; i++) { /* Do 20 attempts to write */ 8918 mydataptr = dataptr; 8919 num = *mydataptr++; 8920 if(!num) return mydataptr; 8921 if(i) { 8922 SiS_SetStop(SiS_Pr); 8923 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2); 8924 } 8925 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 8926 tempah = SiS_Pr->SiS_DDC_DeviceAddr; 8927 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ 8928 if(temp) continue; /* (ERROR: no ack) */ 8929 tempah = *mydataptr++; 8930 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */ 8931 if(temp) continue; /* (ERROR: no ack) */ 8932 for(j=0; j<num; j++) { 8933 tempah = *mydataptr++; 8934 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */ 8935 if(temp) break; 8936 } 8937 if(temp) continue; 8938 if(SiS_SetStop(SiS_Pr)) continue; 8939 return mydataptr; 8940 } 8941 return NULL; 8942} 8943 8944static BOOLEAN 8945SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr) 8946{ 8947 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */ 8948 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 8949 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 8950 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 8951 SiS_SetupDDCN(SiS_Pr); 8952 8953 SiS_SetSwitchDDC2(SiS_Pr); 8954 8955 while(*dataptr) { 8956 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr); 8957 if(!dataptr) return FALSE; 8958 } 8959#ifdef SIS_XORG_XF86 8960#ifdef TWDEBUG 8961 xf86DrvMsg(0, X_INFO, "Trumpion block success\n"); 8962#endif 8963#endif 8964 return TRUE; 8965} 8966#endif 8967 8968/* The Chrontel 700x is connected to the 630/730 via 8969 * the 630/730's DDC/I2C port. 8970 * 8971 * On 630(S)T chipset, the index changed from 0x11 to 8972 * 0x0a, possibly for working around the DDC problems 8973 */ 8974 8975static BOOLEAN 8976SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor) 8977{ 8978 unsigned short temp, i; 8979 8980 for(i=0; i<20; i++) { /* Do 20 attempts to write */ 8981 if(i) { 8982 SiS_SetStop(SiS_Pr); 8983 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4); 8984 } 8985 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 8986 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */ 8987 if(temp) continue; /* (ERROR: no ack) */ 8988 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */ 8989 if(temp) continue; /* (ERROR: no ack) */ 8990 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */ 8991 if(temp) continue; /* (ERROR: no ack) */ 8992 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */ 8993 SiS_Pr->SiS_ChrontelInit = 1; 8994 return TRUE; 8995 } 8996 return FALSE; 8997} 8998 8999/* Write to Chrontel 700x */ 9000void 9001SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) 9002{ 9003 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ 9004 9005 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9006 9007 if(!(SiS_Pr->SiS_ChrontelInit)) { 9008 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9009 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 9010 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 9011 SiS_SetupDDCN(SiS_Pr); 9012 } 9013 9014 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) && 9015 (!(SiS_Pr->SiS_ChrontelInit)) ) { 9016 SiS_Pr->SiS_DDC_Index = 0x0a; 9017 SiS_Pr->SiS_DDC_Data = 0x80; 9018 SiS_Pr->SiS_DDC_Clk = 0x40; 9019 SiS_SetupDDCN(SiS_Pr); 9020 9021 SiS_SetChReg(SiS_Pr, reg, val, 0x80); 9022 } 9023} 9024 9025/* Write to Chrontel 701x */ 9026/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */ 9027void 9028SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) 9029{ 9030 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9031 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ 9032 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ 9033 SiS_SetupDDCN(SiS_Pr); 9034 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ 9035 SiS_SetChReg(SiS_Pr, reg, val, 0); 9036} 9037 9038#ifdef SIS_LINUX_KERNEL 9039static 9040#endif 9041void 9042SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) 9043{ 9044 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) 9045 SiS_SetCH700x(SiS_Pr, reg, val); 9046 else 9047 SiS_SetCH701x(SiS_Pr, reg, val); 9048} 9049 9050static unsigned short 9051SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor) 9052{ 9053 unsigned short tempah, temp, i; 9054 9055 for(i=0; i<20; i++) { /* Do 20 attempts to read */ 9056 if(i) { 9057 SiS_SetStop(SiS_Pr); 9058 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4); 9059 } 9060 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 9061 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */ 9062 if(temp) continue; /* (ERROR: no ack) */ 9063 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */ 9064 if(temp) continue; /* (ERROR: no ack) */ 9065 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */ 9066 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */ 9067 if(temp) continue; /* (ERROR: no ack) */ 9068 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */ 9069 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */ 9070 SiS_Pr->SiS_ChrontelInit = 1; 9071 return tempah; 9072 } 9073 return 0xFFFF; 9074} 9075 9076/* Read from Chrontel 700x */ 9077/* Parameter is [Register no (S7-S0)] */ 9078unsigned short 9079SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx) 9080{ 9081 unsigned short result; 9082 9083 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ 9084 9085 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9086 9087 if(!(SiS_Pr->SiS_ChrontelInit)) { 9088 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9089 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 9090 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 9091 SiS_SetupDDCN(SiS_Pr); 9092 } 9093 9094 SiS_Pr->SiS_DDC_ReadAddr = tempbx; 9095 9096 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) && 9097 (!SiS_Pr->SiS_ChrontelInit) ) { 9098 9099 SiS_Pr->SiS_DDC_Index = 0x0a; 9100 SiS_Pr->SiS_DDC_Data = 0x80; 9101 SiS_Pr->SiS_DDC_Clk = 0x40; 9102 SiS_SetupDDCN(SiS_Pr); 9103 9104 result = SiS_GetChReg(SiS_Pr,0x80); 9105 } 9106 return result; 9107} 9108 9109/* Read from Chrontel 701x */ 9110/* Parameter is [Register no (S7-S0)] */ 9111unsigned short 9112SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx) 9113{ 9114 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9115 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ 9116 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ 9117 SiS_SetupDDCN(SiS_Pr); 9118 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ 9119 9120 SiS_Pr->SiS_DDC_ReadAddr = tempbx; 9121 9122 return SiS_GetChReg(SiS_Pr,0); 9123} 9124 9125/* Read from Chrontel 70xx */ 9126/* Parameter is [Register no (S7-S0)] */ 9127#ifdef SIS_LINUX_KERNEL 9128static 9129#endif 9130unsigned short 9131SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx) 9132{ 9133 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) 9134 return SiS_GetCH700x(SiS_Pr, tempbx); 9135 else 9136 return SiS_GetCH701x(SiS_Pr, tempbx); 9137} 9138 9139void 9140SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg, 9141 unsigned char myor, unsigned short myand) 9142{ 9143 unsigned short tempbl; 9144 9145 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor; 9146 SiS_SetCH70xx(SiS_Pr, reg, tempbl); 9147} 9148 9149/* Our own DDC functions */ 9150#ifndef SIS_XORG_XF86 9151static 9152#endif 9153unsigned short 9154SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, 9155 unsigned short adaptnum, unsigned short DDCdatatype, BOOLEAN checkcr32, 9156 unsigned int VBFlags2) 9157{ 9158 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 }; 9159 unsigned char flag, cr32; 9160 unsigned short temp = 0, myadaptnum = adaptnum; 9161 9162 if(adaptnum != 0) { 9163 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF; 9164 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF; 9165 } 9166 9167 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */ 9168 9169 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */ 9170 9171 SiS_Pr->SiS_DDC_SecAddr = 0; 9172 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype]; 9173 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4; 9174 SiS_Pr->SiS_DDC_Index = 0x11; 9175 flag = 0xff; 9176 9177 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32); 9178 9179#if 0 9180 if(VBFlags2 & VB2_SISBRIDGE) { 9181 if(myadaptnum == 0) { 9182 if(!(cr32 & 0x20)) { 9183 myadaptnum = 2; 9184 if(!(cr32 & 0x10)) { 9185 myadaptnum = 1; 9186 if(!(cr32 & 0x08)) { 9187 myadaptnum = 0; 9188 } 9189 } 9190 } 9191 } 9192 } 9193#endif 9194 9195 if(VGAEngine == SIS_300_VGA) { /* 300 series */ 9196 9197 if(myadaptnum != 0) { 9198 flag = 0; 9199 if(VBFlags2 & VB2_SISBRIDGE) { 9200 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; 9201 SiS_Pr->SiS_DDC_Index = 0x0f; 9202 } 9203 } 9204 9205 if(!(VBFlags2 & VB2_301)) { 9206 if((cr32 & 0x80) && (checkcr32)) { 9207 if(myadaptnum >= 1) { 9208 if(!(cr32 & 0x08)) { 9209 myadaptnum = 1; 9210 if(!(cr32 & 0x10)) return 0xFFFF; 9211 } 9212 } 9213 } 9214 } 9215 9216 temp = 4 - (myadaptnum * 2); 9217 if(flag) temp = 0; 9218 9219 } else { /* 315/330 series */ 9220 9221 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */ 9222 9223 if(VBFlags2 & VB2_SISBRIDGE) { 9224 if(myadaptnum == 2) { 9225 myadaptnum = 1; 9226 } 9227 } 9228 9229 if(myadaptnum == 1) { 9230 flag = 0; 9231 if(VBFlags2 & VB2_SISBRIDGE) { 9232 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; 9233 SiS_Pr->SiS_DDC_Index = 0x0f; 9234 } 9235 } 9236 9237 if((cr32 & 0x80) && (checkcr32)) { 9238 if(myadaptnum >= 1) { 9239 if(!(cr32 & 0x08)) { 9240 myadaptnum = 1; 9241 if(!(cr32 & 0x10)) return 0xFFFF; 9242 } 9243 } 9244 } 9245 9246 temp = myadaptnum; 9247 if(myadaptnum == 1) { 9248 temp = 0; 9249 if(VBFlags2 & VB2_LVDS) flag = 0xff; 9250 } 9251 9252 if(flag) temp = 0; 9253 } 9254 9255 SiS_Pr->SiS_DDC_Data = 0x02 << temp; 9256 SiS_Pr->SiS_DDC_Clk = 0x01 << temp; 9257 9258 SiS_SetupDDCN(SiS_Pr); 9259 9260#ifdef SIS_XORG_XF86 9261#ifdef TWDEBUG 9262 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n", 9263 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp); 9264#endif 9265#endif 9266 return 0; 9267} 9268 9269static unsigned short 9270SiS_WriteDABDDC(struct SiS_Private *SiS_Pr) 9271{ 9272 if(SiS_SetStart(SiS_Pr)) return 0xFFFF; 9273 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) { 9274 return 0xFFFF; 9275 } 9276 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) { 9277 return 0xFFFF; 9278 } 9279 return 0; 9280} 9281 9282static unsigned short 9283SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr) 9284{ 9285 if(SiS_SetStart(SiS_Pr)) return 0xFFFF; 9286 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) { 9287 return 0xFFFF; 9288 } 9289 return 0; 9290} 9291 9292static unsigned short 9293SiS_PrepareDDC(struct SiS_Private *SiS_Pr) 9294{ 9295 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr); 9296 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr)); 9297 return 0; 9298} 9299 9300static void 9301SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno) 9302{ 9303 SiS_SetSCLKLow(SiS_Pr); 9304 if(yesno) { 9305 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9306 SiS_Pr->SiS_DDC_Index, 9307 SiS_Pr->SiS_DDC_NData, 9308 SiS_Pr->SiS_DDC_Data); 9309 } else { 9310 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9311 SiS_Pr->SiS_DDC_Index, 9312 SiS_Pr->SiS_DDC_NData, 9313 0); 9314 } 9315 SiS_SetSCLKHigh(SiS_Pr); 9316} 9317 9318static unsigned short 9319SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) 9320{ 9321 unsigned char mask, value; 9322 unsigned short temp, ret=0; 9323 BOOLEAN failed = FALSE; 9324 9325 SiS_SetSwitchDDC2(SiS_Pr); 9326 if(SiS_PrepareDDC(SiS_Pr)) { 9327 SiS_SetStop(SiS_Pr); 9328#ifdef SIS_XORG_XF86 9329#ifdef TWDEBUG 9330 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n"); 9331#endif 9332#endif 9333 return 0xFFFF; 9334 } 9335 mask = 0xf0; 9336 value = 0x20; 9337 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { 9338 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9339 SiS_SendACK(SiS_Pr, 0); 9340 if(temp == 0) { 9341 mask = 0xff; 9342 value = 0xff; 9343 } else { 9344 failed = TRUE; 9345 ret = 0xFFFF; 9346#ifdef SIS_XORG_XF86 9347#ifdef TWDEBUG 9348 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n"); 9349#endif 9350#endif 9351 } 9352 } 9353 if(failed == FALSE) { 9354 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9355 SiS_SendACK(SiS_Pr, 1); 9356 temp &= mask; 9357 if(temp == value) ret = 0; 9358 else { 9359 ret = 0xFFFF; 9360#ifdef SIS_XORG_XF86 9361#ifdef TWDEBUG 9362 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n"); 9363#endif 9364#endif 9365 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { 9366 if(temp == 0x30) ret = 0; 9367 } 9368 } 9369 } 9370 SiS_SetStop(SiS_Pr); 9371 return ret; 9372} 9373 9374#ifndef SIS_XORG_XF86 9375static 9376#endif 9377unsigned short 9378SiS_ProbeDDC(struct SiS_Private *SiS_Pr) 9379{ 9380 unsigned short flag; 9381 9382 flag = 0x180; 9383 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; 9384 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02; 9385 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; 9386 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08; 9387 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; 9388 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10; 9389 if(!(flag & 0x1a)) flag = 0; 9390 return flag; 9391} 9392 9393#ifndef SIS_XORG_XF86 9394static 9395#endif 9396unsigned short 9397SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer) 9398{ 9399 unsigned short flag, length, i; 9400 unsigned char chksum,gotcha; 9401 9402 if(DDCdatatype > 4) return 0xFFFF; 9403 9404 flag = 0; 9405 SiS_SetSwitchDDC2(SiS_Pr); 9406 if(!(SiS_PrepareDDC(SiS_Pr))) { 9407 length = 127; 9408 if(DDCdatatype != 1) length = 255; 9409 chksum = 0; 9410 gotcha = 0; 9411 for(i=0; i<length; i++) { 9412 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9413 chksum += buffer[i]; 9414 gotcha |= buffer[i]; 9415 SiS_SendACK(SiS_Pr, 0); 9416 } 9417 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9418 chksum += buffer[i]; 9419 SiS_SendACK(SiS_Pr, 1); 9420 if(gotcha) flag = (unsigned short)chksum; 9421 else flag = 0xFFFF; 9422 } else { 9423 flag = 0xFFFF; 9424 } 9425 SiS_SetStop(SiS_Pr); 9426 return flag; 9427} 9428 9429/* Our private DDC functions 9430 9431 It complies somewhat with the corresponding VESA function 9432 in arguments and return values. 9433 9434 Since this is probably called before the mode is changed, 9435 we use our pre-detected pSiS-values instead of SiS_Pr as 9436 regards chipset and video bridge type. 9437 9438 Arguments: 9439 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog) 9440 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B. 9441 LCDA is CRT1, but DDC is read from CRT2 port. 9442 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2) 9443 buffer: ptr to 256 data bytes which will be filled with read data. 9444 9445 Returns 0xFFFF if error, otherwise 9446 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum) 9447 if DDCdatatype = 0: Returns supported DDC modes 9448 9449 */ 9450unsigned short 9451SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, 9452 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer, 9453 unsigned int VBFlags2) 9454{ 9455 unsigned char sr1f, cr17=1; 9456 unsigned short result; 9457 9458 if(adaptnum > 2) 9459 return 0xFFFF; 9460 9461 if(DDCdatatype > 4) 9462 return 0xFFFF; 9463 9464 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0)) 9465 return 0xFFFF; 9466 9467 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE, VBFlags2) == 0xFFFF) 9468 return 0xFFFF; 9469 9470 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f); 9471 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04); 9472 if(VGAEngine == SIS_300_VGA) { 9473 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80; 9474 if(!cr17) { 9475 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80); 9476 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01); 9477 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03); 9478 } 9479 } 9480 if((sr1f) || (!cr17)) { 9481 SiS_WaitRetrace1(SiS_Pr); 9482 SiS_WaitRetrace1(SiS_Pr); 9483 SiS_WaitRetrace1(SiS_Pr); 9484 SiS_WaitRetrace1(SiS_Pr); 9485 } 9486 9487 if(DDCdatatype == 0) { 9488 result = SiS_ProbeDDC(SiS_Pr); 9489 } else { 9490 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer); 9491 if((!result) && (DDCdatatype == 1)) { 9492 if((buffer[0] == 0x00) && (buffer[1] == 0xff) && 9493 (buffer[2] == 0xff) && (buffer[3] == 0xff) && 9494 (buffer[4] == 0xff) && (buffer[5] == 0xff) && 9495 (buffer[6] == 0xff) && (buffer[7] == 0x00) && 9496 (buffer[0x12] == 1)) { 9497 if(!SiS_Pr->DDCPortMixup) { 9498 if(adaptnum == 1) { 9499 if(!(buffer[0x14] & 0x80)) result = 0xFFFE; 9500 } else { 9501 if(buffer[0x14] & 0x80) result = 0xFFFE; 9502 } 9503 } 9504 } 9505 } 9506 } 9507 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f); 9508 if(VGAEngine == SIS_300_VGA) { 9509 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17); 9510 } 9511 return result; 9512} 9513 9514/* Generic I2C functions for Chrontel & DDC --------- */ 9515 9516static void 9517SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr) 9518{ 9519 SiS_SetSCLKHigh(SiS_Pr); 9520 SiS_WaitRetrace1(SiS_Pr); 9521 9522 SiS_SetSCLKLow(SiS_Pr); 9523 SiS_WaitRetrace1(SiS_Pr); 9524} 9525 9526unsigned short 9527SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr) 9528{ 9529 SiS_WaitRetrace1(SiS_Pr); 9530 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1); 9531} 9532 9533/* Set I2C start condition */ 9534/* This is done by a SD high-to-low transition while SC is high */ 9535static unsigned short 9536SiS_SetStart(struct SiS_Private *SiS_Pr) 9537{ 9538 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9539 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9540 SiS_Pr->SiS_DDC_Index, 9541 SiS_Pr->SiS_DDC_NData, 9542 SiS_Pr->SiS_DDC_Data); /* SD->high */ 9543 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ 9544 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9545 SiS_Pr->SiS_DDC_Index, 9546 SiS_Pr->SiS_DDC_NData, 9547 0x00); /* SD->low = start condition */ 9548 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9549 return 0; 9550} 9551 9552/* Set I2C stop condition */ 9553/* This is done by a SD low-to-high transition while SC is high */ 9554static unsigned short 9555SiS_SetStop(struct SiS_Private *SiS_Pr) 9556{ 9557 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9558 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9559 SiS_Pr->SiS_DDC_Index, 9560 SiS_Pr->SiS_DDC_NData, 9561 0x00); /* SD->low */ 9562 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ 9563 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9564 SiS_Pr->SiS_DDC_Index, 9565 SiS_Pr->SiS_DDC_NData, 9566 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */ 9567 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */ 9568 return 0; 9569} 9570 9571/* Write 8 bits of data */ 9572static unsigned short 9573SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax) 9574{ 9575 unsigned short i,flag,temp; 9576 9577 flag = 0x80; 9578 for(i = 0; i < 8; i++) { 9579 SiS_SetSCLKLow(SiS_Pr); /* SC->low */ 9580 if(tempax & flag) { 9581 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9582 SiS_Pr->SiS_DDC_Index, 9583 SiS_Pr->SiS_DDC_NData, 9584 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */ 9585 } else { 9586 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9587 SiS_Pr->SiS_DDC_Index, 9588 SiS_Pr->SiS_DDC_NData, 9589 0x00); /* Write bit (0) to SD */ 9590 } 9591 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */ 9592 flag >>= 1; 9593 } 9594 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */ 9595 return temp; 9596} 9597 9598static unsigned short 9599SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr) 9600{ 9601 unsigned short i, temp, getdata; 9602 9603 getdata = 0; 9604 for(i = 0; i < 8; i++) { 9605 getdata <<= 1; 9606 SiS_SetSCLKLow(SiS_Pr); 9607 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9608 SiS_Pr->SiS_DDC_Index, 9609 SiS_Pr->SiS_DDC_NData, 9610 SiS_Pr->SiS_DDC_Data); 9611 SiS_SetSCLKHigh(SiS_Pr); 9612 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); 9613 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01; 9614 } 9615 return getdata; 9616} 9617 9618static unsigned short 9619SiS_SetSCLKLow(struct SiS_Private *SiS_Pr) 9620{ 9621 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9622 SiS_Pr->SiS_DDC_Index, 9623 SiS_Pr->SiS_DDC_NClk, 9624 0x00); /* SetSCLKLow() */ 9625 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9626 return 0; 9627} 9628 9629static unsigned short 9630SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr) 9631{ 9632 unsigned short temp, watchdog=1000; 9633 9634 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9635 SiS_Pr->SiS_DDC_Index, 9636 SiS_Pr->SiS_DDC_NClk, 9637 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */ 9638 do { 9639 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); 9640 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog); 9641 if (!watchdog) { 9642#ifdef SIS_XORG_XF86 9643#ifdef TWDEBUG 9644 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n"); 9645#endif 9646#endif 9647 return 0xFFFF; 9648 } 9649 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9650 return 0; 9651} 9652 9653/* Check I2C acknowledge */ 9654/* Returns 0 if ack ok, non-0 if ack not ok */ 9655static unsigned short 9656SiS_CheckACK(struct SiS_Private *SiS_Pr) 9657{ 9658 unsigned short tempah; 9659 9660 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */ 9661 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9662 SiS_Pr->SiS_DDC_Index, 9663 SiS_Pr->SiS_DDC_NData, 9664 SiS_Pr->SiS_DDC_Data); /* (SD->high) */ 9665 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */ 9666 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */ 9667 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */ 9668 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */ 9669 return 0; 9670} 9671 9672/* End of I2C functions ----------------------- */ 9673 9674 9675/* =============== SiS 315/330 O.E.M. ================= */ 9676 9677#ifdef SIS315H 9678 9679static unsigned short 9680GetRAMDACromptr(struct SiS_Private *SiS_Pr) 9681{ 9682 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9683 unsigned short romptr; 9684 9685 if(SiS_Pr->ChipType < SIS_330) { 9686 romptr = SISGETROMW(0x128); 9687 if(SiS_Pr->SiS_VBType & VB_SIS30xB) 9688 romptr = SISGETROMW(0x12a); 9689 } else { 9690 romptr = SISGETROMW(0x1a8); 9691 if(SiS_Pr->SiS_VBType & VB_SIS30xB) 9692 romptr = SISGETROMW(0x1aa); 9693 } 9694 return romptr; 9695} 9696 9697static unsigned short 9698GetLCDromptr(struct SiS_Private *SiS_Pr) 9699{ 9700 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9701 unsigned short romptr; 9702 9703 if(SiS_Pr->ChipType < SIS_330) { 9704 romptr = SISGETROMW(0x120); 9705 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9706 romptr = SISGETROMW(0x122); 9707 } else { 9708 romptr = SISGETROMW(0x1a0); 9709 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9710 romptr = SISGETROMW(0x1a2); 9711 } 9712 return romptr; 9713} 9714 9715static unsigned short 9716GetTVromptr(struct SiS_Private *SiS_Pr) 9717{ 9718 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9719 unsigned short romptr; 9720 9721 if(SiS_Pr->ChipType < SIS_330) { 9722 romptr = SISGETROMW(0x114); 9723 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9724 romptr = SISGETROMW(0x11a); 9725 } else { 9726 romptr = SISGETROMW(0x194); 9727 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9728 romptr = SISGETROMW(0x19a); 9729 } 9730 return romptr; 9731} 9732 9733static unsigned short 9734GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr) 9735{ 9736 unsigned short index; 9737 9738 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 9739 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 9740 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) { 9741 index >>= 4; 9742 index *= 3; 9743 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9744 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; 9745 return index; 9746 } 9747 } 9748 } 9749 9750 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F; 9751 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5; 9752 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */ 9753 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5; 9754 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5; 9755 } else { 9756 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6; 9757 } 9758 index--; 9759 index *= 3; 9760 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9761 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; 9762 return index; 9763} 9764 9765static unsigned short 9766GetLCDPtrIndex(struct SiS_Private *SiS_Pr) 9767{ 9768 unsigned short index; 9769 9770 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3; 9771 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9772 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; 9773 return index; 9774} 9775 9776static unsigned short 9777GetTVPtrIndex(struct SiS_Private *SiS_Pr) 9778{ 9779 unsigned short index; 9780 9781 index = 0; 9782 if(SiS_Pr->SiS_TVMode & TVSetPALTiming) index = 1; 9783 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2; 9784 9785 index <<= 1; 9786 9787 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && 9788 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 9789 index++; 9790 } 9791 9792 return index; 9793} 9794 9795static unsigned int 9796GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme) 9797{ 9798 unsigned short index = 0, temp = 0; 9799 9800 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1; 9801 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2; 9802 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3; 9803 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6; 9804 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 9805 index = 4; 9806 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++; 9807 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7; 9808 } 9809 9810 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 9811 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || 9812 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 9813 index += addme; 9814 temp++; 9815 } 9816 temp += 0x0100; 9817 } 9818 return (unsigned int)(index | (temp << 16)); 9819} 9820 9821static unsigned int 9822GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr) 9823{ 9824 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8)); 9825} 9826 9827#if 0 9828static unsigned int 9829GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr) 9830{ 9831 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6)); 9832} 9833#endif 9834 9835static int 9836GetOEMTVPtr661(struct SiS_Private *SiS_Pr) 9837{ 9838 int index = 0; 9839 9840 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr625i | TVSetYPbPr625p)) 9841 return 0xffff; 9842 9843 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2; 9844 if(SiS_Pr->SiS_ROMNew) { 9845 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4; 9846 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6; 9847 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8; 9848 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10; 9849 } else { 9850 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4; 9851 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6; 9852 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8; 9853 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10; 9854 } 9855 9856 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++; 9857 9858 return index; 9859} 9860 9861static void 9862SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 9863{ 9864 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9865 unsigned short delay=0,index,myindex,temp,romptr=0; 9866 BOOLEAN dochiptest = TRUE; 9867 9868 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 9869 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf); 9870 } else { 9871 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f); 9872 } 9873 9874 /* Find delay (from ROM, internal tables, PCI subsystem) */ 9875 9876 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */ 9877 9878 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 9879 romptr = GetRAMDACromptr(SiS_Pr); 9880 } 9881 if(romptr) delay = ROMAddr[romptr]; 9882 else { 9883 delay = 0x04; 9884 if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 9885 if(IS_SIS650) { 9886 delay = 0x0a; 9887 } else if(IS_SIS740) { 9888 delay = 0x00; 9889 } else if(SiS_Pr->ChipType < SIS_330) { 9890 delay = 0x0c; 9891 } else { 9892 delay = 0x0c; 9893 } 9894 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 9895 delay = 0x00; 9896 } 9897 } 9898 9899 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */ 9900 9901 BOOLEAN gotitfrompci = FALSE; 9902 9903 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */ 9904 9905 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 9906 if(SiS_Pr->PDC != -1) { 9907 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f)); 9908 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7)); 9909 return; 9910 } 9911 } else { 9912 if(SiS_Pr->PDCA != -1) { 9913 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0)); 9914 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6)); 9915 return; 9916 } 9917 } 9918 9919 /* Custom Panel? */ 9920 9921 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) { 9922 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 9923 delay = 0x00; 9924 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) { 9925 delay = 0x20; 9926 } 9927 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay); 9928 } else { 9929 delay = 0x0c; 9930 if(SiS_Pr->SiS_VBType & VB_SIS301C) { 9931 delay = 0x03; 9932 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) { 9933 delay = 0x00; 9934 } 9935 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 9936 if(IS_SIS740) delay = 0x01; 9937 else delay = 0x03; 9938 } 9939 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay); 9940 } 9941 return; 9942 } 9943 9944 /* This is a piece of typical SiS crap: They code the OEM LCD 9945 * delay into the code, at no defined place in the BIOS. 9946 * We now have to start doing a PCI subsystem check here. 9947 */ 9948 9949 switch(SiS_Pr->SiS_CustomT) { 9950 case CUT_COMPAQ1280: 9951 case CUT_COMPAQ12802: 9952 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 9953 gotitfrompci = TRUE; 9954 dochiptest = FALSE; 9955 delay = 0x03; 9956 } 9957 break; 9958 case CUT_CLEVO1400: 9959 case CUT_CLEVO14002: 9960 gotitfrompci = TRUE; 9961 dochiptest = FALSE; 9962 delay = 0x02; 9963 break; 9964 case CUT_CLEVO1024: 9965 case CUT_CLEVO10242: 9966 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 9967 gotitfrompci = TRUE; 9968 dochiptest = FALSE; 9969 delay = 0x33; 9970 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay); 9971 delay &= 0x0f; 9972 } 9973 break; 9974 } 9975 9976 /* Could we find it through the PCI ID? If no, use ROM or table */ 9977 9978 if(!gotitfrompci) { 9979 9980 index = GetLCDPtrIndexBIOS(SiS_Pr); 9981 myindex = GetLCDPtrIndex(SiS_Pr); 9982 9983 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 9984 9985 if(SiS_IsNotM650orLater(SiS_Pr)) { 9986 9987 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 9988 /* Always use the second pointer on 650; some BIOSes */ 9989 /* still carry old 301 data at the first location */ 9990 /* romptr = SISGETROMW(0x120); */ 9991 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */ 9992 romptr = SISGETROMW(0x122); 9993 if(!romptr) return; 9994 delay = ROMAddr[(romptr + index)]; 9995 } else { 9996 delay = SiS310_LCDDelayCompensation_650301LV[myindex]; 9997 } 9998 9999 } else { 10000 10001 delay = SiS310_LCDDelayCompensation_651301LV[myindex]; 10002 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) 10003 delay = SiS310_LCDDelayCompensation_651302LV[myindex]; 10004 10005 } 10006 10007 } else if(SiS_Pr->SiS_UseROM && 10008 (!(SiS_Pr->SiS_ROMNew)) && 10009 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) && 10010 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) && 10011 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) && 10012 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) && 10013 ((romptr = GetLCDromptr(SiS_Pr)))) { 10014 10015 /* Data for 1280x1024 wrong in 301B BIOS */ 10016 /* Data for 1600x1200 wrong in 301C BIOS */ 10017 delay = ROMAddr[(romptr + index)]; 10018 10019 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 10020 10021 if(IS_SIS740) delay = 0x03; 10022 else delay = 0x00; 10023 10024 } else { 10025 10026 delay = SiS310_LCDDelayCompensation_301[myindex]; 10027 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10028 if(IS_SIS740) delay = 0x01; 10029 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex]; 10030 else delay = SiS310_LCDDelayCompensation_650301LV[myindex]; 10031 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) { 10032 if(IS_SIS740) delay = 0x01; /* ? */ 10033 else delay = 0x03; 10034 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */ 10035 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 10036 if(IS_SIS740) delay = 0x01; 10037 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex]; 10038 } 10039 10040 } 10041 10042 } /* got it from PCI */ 10043 10044 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10045 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0)); 10046 dochiptest = FALSE; 10047 } 10048 10049 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */ 10050 10051 index = GetTVPtrIndex(SiS_Pr); 10052 10053 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 10054 10055 if(SiS_IsNotM650orLater(SiS_Pr)) { 10056 10057 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10058 /* Always use the second pointer on 650; some BIOSes */ 10059 /* still carry old 301 data at the first location */ 10060 /* romptr = SISGETROMW(0x114); */ 10061 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */ 10062 romptr = SISGETROMW(0x11a); 10063 if(!romptr) return; 10064 delay = ROMAddr[romptr + index]; 10065 10066 } else { 10067 10068 delay = SiS310_TVDelayCompensation_301B[index]; 10069 10070 } 10071 10072 } else { 10073 10074 switch(SiS_Pr->SiS_CustomT) { 10075 case CUT_COMPAQ1280: 10076 case CUT_COMPAQ12802: 10077 case CUT_CLEVO1400: 10078 case CUT_CLEVO14002: 10079 delay = 0x02; 10080 dochiptest = FALSE; 10081 break; 10082 case CUT_CLEVO1024: 10083 case CUT_CLEVO10242: 10084 delay = 0x03; 10085 dochiptest = FALSE; 10086 break; 10087 default: 10088 delay = SiS310_TVDelayCompensation_651301LV[index]; 10089 if(SiS_Pr->SiS_VBType & VB_SIS302LV) { 10090 delay = SiS310_TVDelayCompensation_651302LV[index]; 10091 } 10092 } 10093 } 10094 10095 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10096 10097 romptr = GetTVromptr(SiS_Pr); 10098 if(!romptr) return; 10099 delay = ROMAddr[romptr + index]; 10100 10101 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 10102 10103 delay = SiS310_TVDelayCompensation_LVDS[index]; 10104 10105 } else { 10106 10107 delay = SiS310_TVDelayCompensation_301[index]; 10108 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 10109 if(IS_SIS740) { 10110 delay = SiS310_TVDelayCompensation_740301B[index]; 10111 /* LV: use 301 data? BIOS bug? */ 10112 } else { 10113 delay = SiS310_TVDelayCompensation_301B[index]; 10114 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02; 10115 } 10116 } 10117 10118 } 10119 10120 if(SiS_LCDAEnabled(SiS_Pr)) { 10121 delay &= 0x0f; 10122 dochiptest = FALSE; 10123 } 10124 10125 } else return; 10126 10127 /* Write delay */ 10128 10129 if(SiS_Pr->SiS_VBType & VB_SISVB) { 10130 10131 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) { 10132 10133 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4; 10134 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */ 10135 delay &= 0x0f; 10136 delay |= 0xb0; 10137 } else if(temp == 6) { 10138 delay &= 0x0f; 10139 delay |= 0xc0; 10140 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */ 10141 delay = 0x35; 10142 } 10143 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay); 10144 10145 } else { 10146 10147 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); 10148 10149 } 10150 10151 } else { /* LVDS */ 10152 10153 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10154 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); 10155 } else { 10156 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) { 10157 delay <<= 4; 10158 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay); 10159 } else { 10160 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); 10161 } 10162 } 10163 10164 } 10165 10166} 10167 10168static void 10169SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 10170{ 10171 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10172 unsigned short index,temp,temp1,romptr=0; 10173 10174 if(SiS_Pr->SiS_TVMode & TVSetYPbPrProg) return; 10175 10176 if(ModeNo<=0x13) 10177 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex; 10178 else 10179 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; 10180 10181 temp = GetTVPtrIndex(SiS_Pr); 10182 temp >>= 1; /* 0: NTSC/YPbPr525, 1: PAL/YPbPr625, 2: HiTV */ 10183 temp1 = temp; 10184 10185 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 10186 if(SiS_Pr->ChipType >= SIS_661) { 10187 temp1 = GetOEMTVPtr661(SiS_Pr); 10188 if(temp1 != 0xffff) { 10189 temp1 >>= 1; 10190 romptr = SISGETROMW(0x260); 10191 if(SiS_Pr->ChipType >= SIS_760) { 10192 romptr = SISGETROMW(0x360); 10193 } 10194 } 10195 } else if(SiS_Pr->ChipType >= SIS_330) { 10196 romptr = SISGETROMW(0x192); 10197 } else { 10198 romptr = SISGETROMW(0x112); 10199 } 10200 } 10201 10202 if(romptr) { 10203 temp1 <<= 1; 10204 temp = ROMAddr[romptr + temp1 + index]; 10205 } else { 10206 temp = SiS310_TVAntiFlick1[temp][index]; 10207 } 10208 temp <<= 4; 10209 10210 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */ 10211} 10212 10213static void 10214SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 10215{ 10216 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10217 unsigned short index,temp,temp1,romptr=0; 10218 10219 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr525, 1: PAL/YPbPr625, 2: HiTV */ 10220 10221 if(ModeNo <= 0x13) 10222 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex; 10223 else 10224 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; 10225 10226 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 10227 if(SiS_Pr->ChipType >= SIS_661) { 10228 temp1 = GetOEMTVPtr661(SiS_Pr); 10229 if(temp1 != 0xffff) { 10230 temp1 >>= 1; 10231 romptr = SISGETROMW(0x26c); 10232 if(SiS_Pr->ChipType >= SIS_760) { 10233 romptr = SISGETROMW(0x36c); 10234 } 10235 } 10236 } else if(SiS_Pr->ChipType >= SIS_330) { 10237 romptr = SISGETROMW(0x1a4); 10238 } else { 10239 romptr = SISGETROMW(0x124); 10240 } 10241 } 10242 10243 if(romptr) { 10244 temp1 <<= 1; 10245 temp = ROMAddr[romptr + temp1 + index]; 10246 } else { 10247 temp = SiS310_TVEdge1[temp][index]; 10248 } 10249 temp <<= 5; 10250 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */ 10251} 10252 10253static void 10254SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 10255{ 10256 unsigned short index, temp, i, j; 10257 10258 if(ModeNo <= 0x13) { 10259 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex; 10260 } else { 10261 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; 10262 } 10263 10264 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */ 10265 10266 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */ 10267 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */ 10268 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */ 10269 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */ 10270 10271 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 10272 for(i=0x35, j=0; i<=0x38; i++, j++) { 10273 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]); 10274 } 10275 for(i=0x48; i<=0x4A; i++, j++) { 10276 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]); 10277 } 10278 } else { 10279 for(i=0x35, j=0; i<=0x38; i++, j++) { 10280 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]); 10281 } 10282 } 10283} 10284 10285static void 10286SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 10287{ 10288 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10289 unsigned short index,temp,i,j,resinfo,romptr=0; 10290 unsigned int lindex; 10291 10292 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; 10293 10294 /* NTSC-J data not in BIOS, and already set in SetGroup2 */ 10295 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return; 10296 10297 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) { 10298 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff; 10299 lindex <<= 2; 10300 for(j=0, i=0x31; i<=0x34; i++, j++) { 10301 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]); 10302 } 10303 return; 10304 } 10305 10306 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */ 10307 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return; 10308 10309 if(ModeNo<=0x13) { 10310 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 10311 } else { 10312 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 10313 } 10314 10315 temp = GetTVPtrIndex(SiS_Pr); 10316 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics, 10317 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text 10318 */ 10319 if(SiS_Pr->SiS_UseROM) { 10320 romptr = SISGETROMW(0x116); 10321 if(SiS_Pr->ChipType >= SIS_330) { 10322 romptr = SISGETROMW(0x196); 10323 } 10324 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 10325 romptr = SISGETROMW(0x11c); 10326 if(SiS_Pr->ChipType >= SIS_330) { 10327 romptr = SISGETROMW(0x19c); 10328 } 10329 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) { 10330 romptr = SISGETROMW(0x116); 10331 if(SiS_Pr->ChipType >= SIS_330) { 10332 romptr = SISGETROMW(0x196); 10333 } 10334 } 10335 } 10336 } 10337 if(romptr) { 10338 romptr += (temp << 2); 10339 for(j=0, i=0x31; i<=0x34; i++, j++) { 10340 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); 10341 } 10342 } else { 10343 index = temp % 2; 10344 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */ 10345 for(j=0, i=0x31; i<=0x34; i++, j++) { 10346 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) 10347 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]); 10348 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) 10349 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]); 10350 else 10351 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]); 10352 } 10353 } 10354 10355 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) { 10356 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPrProg))) && (ModeNo > 0x13)) { 10357 if((resinfo == SIS_RI_640x480) || 10358 (resinfo == SIS_RI_800x600)) { 10359 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21); 10360 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0); 10361 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5); 10362 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f); 10363 } else if(resinfo == SIS_RI_1024x768) { 10364 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e); 10365 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b); 10366 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb); 10367 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b); 10368 } 10369 } 10370 } 10371} 10372 10373static void 10374SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 10375 unsigned short ModeIdIndex, unsigned short RTI) 10376{ 10377 unsigned short delay = 0, romptr = 0, index, lcdpdcindex; 10378 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10379 10380 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC))) 10381 return; 10382 10383 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */ 10384 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */ 10385 10386 if(SiS_Pr->SiS_ROMNew) { 10387 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) || 10388 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && 10389 (SiS_Pr->SiS_LCDInfo & LCDPass11))) { 10390 index = 25; 10391 if(SiS_Pr->UseCustomMode) { 10392 index = SiS_Pr->CSRClock; 10393 } else if(ModeNo > 0x13) { 10394 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI); 10395 index = SiS_Pr->SiS_VCLKData[index].CLOCK; 10396 } 10397 if(index < 25) index = 25; 10398 index = ((index / 25) - 1) << 1; 10399 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) { 10400 index++; 10401 } 10402 romptr = SISGETROMW(0x104); 10403 delay = ROMAddr[romptr + index]; 10404 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) { 10405 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f)); 10406 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7)); 10407 } else { 10408 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0)); 10409 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6)); 10410 } 10411 return; 10412 } 10413 } 10414 10415 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */ 10416 10417 if(SiS_Pr->UseCustomMode) delay = 0x04; 10418 else if(ModeNo <= 0x13) delay = 0x04; 10419 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4); 10420 delay |= (delay << 8); 10421 10422 if(SiS_Pr->ChipType >= XGI_20) { 10423 10424 delay = 0x0606; 10425 10426 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10427 delay = 0x0404; 10428 if(SiS_Pr->SiS_XGIROM) { 10429 index = GetTVPtrIndex(SiS_Pr); 10430 if((romptr = SISGETROMW(0x35e))) { 10431 delay = (ROMAddr[romptr + index] & 0x0f) << 1; 10432 delay |= (delay << 8); 10433 } 10434 } 10435 10436 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 10437 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) { 10438 delay -= 0x0404; 10439 } 10440 } 10441 } 10442 10443 } else if(SiS_Pr->ChipType >= SIS_340) { 10444 10445 delay = 0x0606; 10446 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10447 delay = 0x0404; 10448 } 10449 /* TODO (eventually) */ 10450 10451 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10452 10453 /* 3. TV */ 10454 10455 index = GetOEMTVPtr661(SiS_Pr); 10456 if((SiS_Pr->SiS_ROMNew) && (index != 0xffff)) { 10457 romptr = SISGETROMW(0x106); 10458 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12; 10459 delay = ROMAddr[romptr + index]; 10460 } else { 10461 delay = 0x04; 10462 if(index > 3 || index == 0xffff) delay = 0; 10463 } 10464 10465 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10466 10467 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */ 10468 10469 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) && 10470 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) { 10471 10472 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12; 10473 10474 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */ 10475 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */ 10476 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */ 10477 10478 } else { 10479 10480 /* TMDS: Set our own, since BIOS has no idea */ 10481 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */ 10482 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 10483 switch(SiS_Pr->SiS_LCDResInfo) { 10484 case Panel_1024x768: delay = 0x0008; break; 10485 case Panel_1280x720: delay = 0x0004; break; 10486 case Panel_1280x768: 10487 case Panel_1280x768_2:delay = 0x0004; break; 10488 case Panel_1280x800: 10489 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */ 10490 case Panel_1280x854: delay = 0x0004; break; /* FIXME */ 10491 case Panel_1280x1024: delay = 0x1e04; break; 10492 case Panel_1400x1050: delay = 0x0004; break; 10493 case Panel_1600x1200: delay = 0x0400; break; 10494 case Panel_1680x1050: delay = 0x0e04; break; 10495 default: 10496 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) { 10497 delay = 0x0008; 10498 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) { 10499 delay = 0x1e04; 10500 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) { 10501 delay = 0x0004; 10502 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) { 10503 delay = 0x0400; 10504 } else 10505 delay = 0x0e04; 10506 break; 10507 } 10508 } 10509 10510 /* Override by detected or user-set values */ 10511 /* (but only if, for some reason, we can't read value from BIOS) */ 10512 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) { 10513 delay = SiS_Pr->PDC & 0x1f; 10514 } 10515 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) { 10516 delay = (SiS_Pr->PDCA & 0x1f) << 8; 10517 } 10518 10519 } 10520 10521 } 10522 10523 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10524 delay >>= 8; 10525 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0)); 10526 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6)); 10527 } else { 10528 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f)); 10529 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7)); 10530 } 10531} 10532 10533static void 10534SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI) 10535{ 10536 unsigned short infoflag; 10537 unsigned char temp; 10538 10539 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10540 10541 if(ModeNo <= 0x13) { 10542 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2); 10543 } else if(SiS_Pr->UseCustomMode) { 10544 infoflag = SiS_Pr->CInfoFlag; 10545 } else { 10546 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag; 10547 } 10548 10549 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 10550 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */ 10551 } 10552 10553 infoflag &= 0xc0; 10554 10555 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 10556 temp = (infoflag >> 6) | 0x0c; 10557 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 10558 temp ^= 0x04; 10559 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10; 10560 } 10561 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp); 10562 } else { 10563 temp = 0x30; 10564 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20; 10565 temp |= infoflag; 10566 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp); 10567 temp = 0; 10568 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 10569 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80; 10570 } 10571 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp); 10572 } 10573 10574 } 10575} 10576 10577static void 10578SetPanelParms661(struct SiS_Private *SiS_Pr) 10579{ 10580 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10581 unsigned short romptr, temp1, temp2; 10582 10583 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) { 10584 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f); 10585 } 10586 10587 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10588 if(SiS_Pr->LVDSHL != -1) { 10589 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL); 10590 } 10591 } 10592 10593 if(SiS_Pr->SiS_ROMNew) { 10594 10595 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) { 10596 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10597 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c; 10598 temp2 = 0xfc; 10599 if(SiS_Pr->LVDSHL != -1) { 10600 temp1 &= 0xfc; 10601 temp2 = 0xf3; 10602 } 10603 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1); 10604 } 10605 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 10606 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1; 10607 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1); 10608 } 10609 } 10610 10611 } 10612} 10613 10614static void 10615SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI) 10616{ 10617 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 10618 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 10619 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10620 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI); 10621 SetPanelParms661(SiS_Pr); 10622 } 10623 } else { 10624 SetDelayComp(SiS_Pr,ModeNo); 10625 } 10626 10627 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 10628 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex); 10629 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex); 10630 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex); 10631 if(SiS_Pr->SiS_VBType & VB_SIS301) { 10632 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex); 10633 } 10634 } 10635} 10636 10637static void 10638SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 10639 unsigned short ModeIdIndex, unsigned short RRTI) 10640{ 10641 if(SiS_Pr->SiS_VBType & VB_SISVB) { 10642 10643 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 10644 10645 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10646 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI); 10647 SetPanelParms661(SiS_Pr); 10648 } 10649 10650 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10651 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex); 10652 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex); 10653 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex); 10654 if(SiS_Pr->SiS_VBType & VB_SIS301) { 10655 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex); 10656 } 10657 } 10658 } 10659} 10660 10661/* FinalizeLCD 10662 * This finalizes some CRT2 registers for the very panel used. 10663 * If we have a backup if these registers, we use it; otherwise 10664 * we set the register according to most BIOSes. However, this 10665 * function looks quite different in every BIOS, so you better 10666 * pray that we have a backup... 10667 */ 10668static void 10669SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 10670{ 10671 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp; 10672 unsigned short resinfo,modeflag; 10673 10674 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return; 10675 if(SiS_Pr->SiS_ROMNew) return; 10676 10677 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10678 if(SiS_Pr->LVDSHL != -1) { 10679 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL); 10680 } 10681 } 10682 10683 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return; 10684 if(SiS_Pr->UseCustomMode) return; 10685 10686 switch(SiS_Pr->SiS_CustomT) { 10687 case CUT_COMPAQ1280: 10688 case CUT_COMPAQ12802: 10689 case CUT_CLEVO1400: 10690 case CUT_CLEVO14002: 10691 return; 10692 } 10693 10694 if(ModeNo <= 0x13) { 10695 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 10696 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 10697 } else { 10698 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 10699 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 10700 } 10701 10702 if(IS_SIS650) { 10703 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) { 10704 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { 10705 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02); 10706 } else { 10707 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03); 10708 } 10709 } 10710 } 10711 10712 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { 10713 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10714 /* Maybe all panels? */ 10715 if(SiS_Pr->LVDSHL == -1) { 10716 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); 10717 } 10718 return; 10719 } 10720 } 10721 10722 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) { 10723 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10724 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10725 if(SiS_Pr->LVDSHL == -1) { 10726 /* Maybe all panels? */ 10727 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); 10728 } 10729 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10730 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 10731 if(tempch == 3) { 10732 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); 10733 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25); 10734 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00); 10735 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b); 10736 } 10737 } 10738 return; 10739 } 10740 } 10741 } 10742 10743 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10744 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10745 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 10746 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00); 10747#ifdef SET_EMI 10748 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 10749#endif 10750 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 10751 } 10752 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 10753 if(SiS_Pr->LVDSHL == -1) { 10754 /* Maybe ACER only? */ 10755 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); 10756 } 10757 } 10758 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 10759 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10760 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) { 10761 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76); 10762 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10763 if(tempch == 0x03) { 10764 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); 10765 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25); 10766 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00); 10767 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b); 10768 } 10769 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) { 10770 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14); 10771 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15); 10772 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16); 10773 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17); 10774 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18); 10775 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19); 10776 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a); 10777 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b); 10778 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c); 10779 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d); 10780 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */ 10781 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90); 10782 if(ModeNo <= 0x13) { 10783 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11); 10784 if((resinfo == 0) || (resinfo == 2)) return; 10785 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18); 10786 if((resinfo == 1) || (resinfo == 3)) return; 10787 } 10788 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); 10789 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) { 10790 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */ 10791#if 0 10792 tempbx = 806; /* 0x326 */ /* other older BIOSes */ 10793 tempbx--; 10794 temp = tempbx & 0xff; 10795 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); 10796 temp = (tempbx >> 8) & 0x03; 10797 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp); 10798#endif 10799 } 10800 } else if(ModeNo <= 0x13) { 10801 if(ModeNo <= 1) { 10802 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70); 10803 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff); 10804 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48); 10805 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12); 10806 } 10807 if(!(modeflag & HalfDCLK)) { 10808 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20); 10809 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a); 10810 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28); 10811 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00); 10812 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c); 10813 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc); 10814 if(ModeNo == 0x12) { 10815 switch(tempch) { 10816 case 0: 10817 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95); 10818 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc); 10819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10); 10820 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95); 10821 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48); 10822 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12); 10823 break; 10824 case 2: 10825 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95); 10826 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48); 10827 break; 10828 case 3: 10829 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95); 10830 break; 10831 } 10832 } 10833 } 10834 } 10835 } 10836 } else { 10837 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01); 10838 tempcl &= 0x0f; 10839 tempbh &= 0x70; 10840 tempbh >>= 4; 10841 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04); 10842 tempbx = (tempbh << 8) | tempbl; 10843 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10844 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) { 10845 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 10846 tempbx = 770; 10847 } else { 10848 if(tempbx > 770) tempbx = 770; 10849 if(SiS_Pr->SiS_VGAVDE < 600) { 10850 tempax = 768 - SiS_Pr->SiS_VGAVDE; 10851 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */ 10852 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */ 10853 tempbx -= tempax; 10854 } 10855 } 10856 } else return; 10857 } 10858 temp = tempbx & 0xff; 10859 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp); 10860 temp = ((tempbx & 0xff00) >> 4) | tempcl; 10861 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp); 10862 } 10863 } 10864} 10865 10866#endif 10867 10868/* ================= SiS 300 O.E.M. ================== */ 10869 10870#ifdef SIS300 10871 10872static void 10873SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex, 10874 unsigned short RefTabIndex) 10875{ 10876 unsigned short crt2crtc=0, modeflag, myindex=0; 10877 unsigned char temp; 10878 int i; 10879 10880 if(ModeNo <= 0x13) { 10881 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 10882 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 10883 } else { 10884 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 10885 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC; 10886 } 10887 10888 crt2crtc &= 0x3f; 10889 10890 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 10891 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf); 10892 } 10893 10894 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 10895 if(modeflag & HalfDCLK) myindex = 1; 10896 10897 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 10898 for(i=0; i<7; i++) { 10899 if(barco_p1[myindex][crt2crtc][i][0]) { 10900 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 10901 barco_p1[myindex][crt2crtc][i][0], 10902 barco_p1[myindex][crt2crtc][i][2], 10903 barco_p1[myindex][crt2crtc][i][1]); 10904 } 10905 } 10906 } 10907 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 10908 if(temp & 0x80) { 10909 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18); 10910 temp++; 10911 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); 10912 } 10913 } 10914} 10915 10916static unsigned short 10917GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag) 10918{ 10919 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10920 unsigned short tempbx=0,romptr=0; 10921 static const unsigned char customtable300[] = { 10922 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 10923 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 10924 }; 10925 static const unsigned char customtable630[] = { 10926 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 10927 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 10928 }; 10929 10930 if(SiS_Pr->ChipType == SIS_300) { 10931 10932 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f; 10933 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07; 10934 tempbx -= 2; 10935 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4; 10936 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10937 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3; 10938 } 10939 if(SiS_Pr->SiS_UseROM) { 10940 if(ROMAddr[0x235] & 0x80) { 10941 tempbx = SiS_Pr->SiS_LCDTypeInfo; 10942 if(Flag) { 10943 romptr = SISGETROMW(0x255); 10944 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo]; 10945 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo]; 10946 if(tempbx == 0xFF) return 0xFFFF; 10947 } 10948 tempbx <<= 1; 10949 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++; 10950 } 10951 } 10952 10953 } else { 10954 10955 if(Flag) { 10956 if(SiS_Pr->SiS_UseROM) { 10957 romptr = SISGETROMW(0x255); 10958 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo]; 10959 else tempbx = 0xff; 10960 } else { 10961 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo]; 10962 } 10963 if(tempbx == 0xFF) return 0xFFFF; 10964 tempbx <<= 2; 10965 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2; 10966 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 10967 return tempbx; 10968 } 10969 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2; 10970 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2; 10971 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 10972 10973 } 10974 10975 return tempbx; 10976} 10977 10978static void 10979SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 10980{ 10981 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10982 unsigned short index,temp,romptr=0; 10983 10984 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return; 10985 10986 if(SiS_Pr->SiS_UseROM) { 10987 if(!(ROMAddr[0x237] & 0x01)) return; 10988 if(!(ROMAddr[0x237] & 0x02)) return; 10989 romptr = SISGETROMW(0x24b); 10990 } 10991 10992 /* The Panel Compensation Delay should be set according to tables 10993 * here. Unfortunately, various BIOS versions don't care about 10994 * a uniform way using eg. ROM byte 0x220, but use different 10995 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1(). 10996 * Thus we don't set this if the user selected a custom pdc or if 10997 * we otherwise detected a valid pdc. 10998 */ 10999 if(SiS_Pr->PDC != -1) return; 11000 11001 temp = GetOEMLCDPtr(SiS_Pr, 0); 11002 11003 if(SiS_Pr->UseCustomMode) 11004 index = 0; 11005 else 11006 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex; 11007 11008 if(SiS_Pr->ChipType != SIS_300) { 11009 if(romptr) { 11010 romptr += (temp * 2); 11011 romptr = SISGETROMW(romptr); 11012 romptr += index; 11013 temp = ROMAddr[romptr]; 11014 } else { 11015 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11016 temp = SiS300_OEMLCDDelay2[temp][index]; 11017 } else { 11018 temp = SiS300_OEMLCDDelay3[temp][index]; 11019 } 11020 } 11021 } else { 11022 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) { 11023 if(romptr) { 11024 romptr += (temp * 2); 11025 romptr = SISGETROMW(romptr); 11026 romptr += index; 11027 temp = ROMAddr[romptr]; 11028 } else { 11029 temp = SiS300_OEMLCDDelay5[temp][index]; 11030 } 11031 } else { 11032 if(SiS_Pr->SiS_UseROM) { 11033 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8); 11034 if(romptr) { 11035 romptr += (temp * 2); 11036 romptr = SISGETROMW(romptr); 11037 romptr += index; 11038 temp = ROMAddr[romptr]; 11039 } else { 11040 temp = SiS300_OEMLCDDelay4[temp][index]; 11041 } 11042 } else { 11043 temp = SiS300_OEMLCDDelay4[temp][index]; 11044 } 11045 } 11046 } 11047 temp &= 0x3c; 11048 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */ 11049} 11050 11051static void 11052SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11053{ 11054#if 0 /* Unfinished; Data table missing */ 11055 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11056 unsigned short index,temp; 11057 11058 if((SiS_Pr->SiS_UseROM) { 11059 if(!(ROMAddr[0x237] & 0x01)) return; 11060 if(!(ROMAddr[0x237] & 0x04)) return; 11061 /* No rom pointer in BIOS header! */ 11062 } 11063 11064 temp = GetOEMLCDPtr(SiS_Pr, 1); 11065 if(temp == 0xFFFF) return; 11066 11067 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex; 11068 for(i=0x14, j=0; i<=0x17; i++, j++) { 11069 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]); 11070 } 11071 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07)); 11072 11073 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex; 11074 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]); 11075 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]); 11076 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38)); 11077 for(i=0x1b, j=3; i<=0x1d; i++, j++) { 11078 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]); 11079 } 11080#endif 11081} 11082 11083static unsigned short 11084GetOEMTVPtr(struct SiS_Private *SiS_Pr) 11085{ 11086 unsigned short index; 11087 11088 index = 0; 11089 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4; 11090 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11091 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2; 11092 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3; 11093 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1; 11094 } else { 11095 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2; 11096 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1; 11097 } 11098 return index; 11099} 11100 11101static void 11102SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11103{ 11104 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11105 unsigned short index,temp,romptr=0; 11106 11107 if(SiS_Pr->SiS_UseROM) { 11108 if(!(ROMAddr[0x238] & 0x01)) return; 11109 if(!(ROMAddr[0x238] & 0x02)) return; 11110 romptr = SISGETROMW(0x241); 11111 } 11112 11113 temp = GetOEMTVPtr(SiS_Pr); 11114 11115 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex; 11116 11117 if(romptr) { 11118 romptr += (temp * 2); 11119 romptr = SISGETROMW(romptr) + index; 11120 temp = ROMAddr[romptr]; 11121 } else { 11122 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11123 temp = SiS300_OEMTVDelay301[temp][index]; 11124 } else { 11125 temp = SiS300_OEMTVDelayLVDS[temp][index]; 11126 } 11127 } 11128 temp &= 0x3c; 11129 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); 11130} 11131 11132static void 11133SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11134{ 11135 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11136 unsigned short index,temp,romptr=0; 11137 11138 if(SiS_Pr->SiS_UseROM) { 11139 if(!(ROMAddr[0x238] & 0x01)) return; 11140 if(!(ROMAddr[0x238] & 0x04)) return; 11141 romptr = SISGETROMW(0x243); 11142 } 11143 11144 temp = GetOEMTVPtr(SiS_Pr); 11145 11146 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex; 11147 11148 if(romptr) { 11149 romptr += (temp * 2); 11150 romptr = SISGETROMW(romptr); 11151 romptr += index; 11152 temp = ROMAddr[romptr]; 11153 } else { 11154 temp = SiS300_OEMTVFlicker[temp][index]; 11155 } 11156 temp &= 0x70; 11157 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp); 11158} 11159 11160static void 11161SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 11162{ 11163 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11164 unsigned short index,i,j,temp,romptr=0; 11165 11166 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return; 11167 11168 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return; 11169 11170 if(SiS_Pr->SiS_UseROM) { 11171 if(!(ROMAddr[0x238] & 0x01)) return; 11172 if(!(ROMAddr[0x238] & 0x08)) return; 11173 romptr = SISGETROMW(0x245); 11174 } 11175 11176 temp = GetOEMTVPtr(SiS_Pr); 11177 11178 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex; 11179 11180 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 11181 for(i=0x31, j=0; i<=0x34; i++, j++) { 11182 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]); 11183 } 11184 } else { 11185 if(romptr) { 11186 romptr += (temp * 2); 11187 romptr = SISGETROMW(romptr); 11188 romptr += (index * 4); 11189 for(i=0x31, j=0; i<=0x34; i++, j++) { 11190 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); 11191 } 11192 } else { 11193 for(i=0x31, j=0; i<=0x34; i++, j++) { 11194 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]); 11195 } 11196 } 11197 } 11198} 11199 11200static void 11201SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11202{ 11203 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11204 unsigned short index,temp,i,j,romptr=0; 11205 11206 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return; 11207 11208 if(SiS_Pr->SiS_UseROM) { 11209 if(!(ROMAddr[0x238] & 0x01)) return; 11210 if(!(ROMAddr[0x238] & 0x10)) return; 11211 romptr = SISGETROMW(0x247); 11212 } 11213 11214 temp = GetOEMTVPtr(SiS_Pr); 11215 11216 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8; 11217 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9; 11218 /* NTSCJ uses NTSC filters */ 11219 11220 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex; 11221 11222 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 11223 for(i=0x35, j=0; i<=0x38; i++, j++) { 11224 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]); 11225 } 11226 for(i=0x48; i<=0x4A; i++, j++) { 11227 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]); 11228 } 11229 } else { 11230 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) { 11231 romptr += (temp * 2); 11232 romptr = SISGETROMW(romptr); 11233 romptr += (index * 4); 11234 for(i=0x35, j=0; i<=0x38; i++, j++) { 11235 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); 11236 } 11237 } else { 11238 for(i=0x35, j=0; i<=0x38; i++, j++) { 11239 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]); 11240 } 11241 } 11242 } 11243} 11244 11245static unsigned short 11246SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo) 11247{ 11248 unsigned short ModeIdIndex; 11249 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO; 11250 11251 if(*ModeNo <= 5) *ModeNo |= 1; 11252 11253 for(ModeIdIndex=0; ; ModeIdIndex++) { 11254 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break; 11255 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0; 11256 } 11257 11258 if(*ModeNo != 0x07) { 11259 if(*ModeNo > 0x03) return ModeIdIndex; 11260 if(VGAINFO & 0x80) return ModeIdIndex; 11261 ModeIdIndex++; 11262 } 11263 11264 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */ 11265 /* else 350 lines */ 11266 return ModeIdIndex; 11267} 11268 11269static void 11270SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 11271 unsigned short RefTableIndex) 11272{ 11273 unsigned short OEMModeIdIndex = 0; 11274 11275 if(!SiS_Pr->UseCustomMode) { 11276 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo); 11277 if(!(OEMModeIdIndex)) return; 11278 } 11279 11280 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 11281 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex); 11282 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 11283 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex); 11284 } 11285 } 11286 if(SiS_Pr->UseCustomMode) return; 11287 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 11288 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex); 11289 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11290 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex); 11291 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex); 11292 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex); 11293 } 11294 } 11295} 11296#endif 11297 11298