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