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