1#include <linux/delay.h> 2#include "XGIfb.h" 3 4#include "vb_def.h" 5#include "vb_init.h" 6#include "vb_util.h" 7#include "vb_table.h" 8#include "vb_setmode.h" 9 10#define IndexMask 0xff 11#define TVCLKBASE_315_25 (TVCLKBASE_315 + 25) 12 13static const unsigned short XGINew_VGA_DAC[] = { 14 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, 15 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, 16 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18, 17 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F, 18 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F, 19 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00, 20 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18, 21 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04, 22 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 23 0x0B, 0x0C, 0x0D, 0x0F, 0x10}; 24 25void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) 26{ 27 pVBInfo->MCLKData = XGI340New_MCLKData; 28 29 pVBInfo->LCDResInfo = 0; 30 pVBInfo->LCDTypeInfo = 0; 31 pVBInfo->LCDInfo = 0; 32 pVBInfo->VBInfo = 0; 33 pVBInfo->TVInfo = 0; 34 35 pVBInfo->SR18 = XGI340_SR18; 36 pVBInfo->CR40 = XGI340_cr41; 37 38 if (ChipType < XG20) 39 XGI_GetVBType(pVBInfo); 40 41 /* 310 customization related */ 42 if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) 43 pVBInfo->LCDCapList = XGI_LCDDLCapList; 44 else 45 pVBInfo->LCDCapList = XGI_LCDCapList; 46 47 if (ChipType >= XG20) 48 pVBInfo->XGINew_CR97 = 0x10; 49 50 if (ChipType == XG27) { 51 unsigned char temp; 52 53 pVBInfo->MCLKData = XGI27New_MCLKData; 54 pVBInfo->CR40 = XGI27_cr41; 55 pVBInfo->XGINew_CR97 = 0xc1; 56 pVBInfo->SR18 = XG27_SR18; 57 58 /*Z11m DDR*/ 59 temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); 60 /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ 61 if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) 62 pVBInfo->XGINew_CR97 = 0x80; 63 } 64 65} 66 67static void XGI_SetSeqRegs(struct vb_device_info *pVBInfo) 68{ 69 unsigned char SRdata, i; 70 71 xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ 72 73 for (i = 0; i < 4; i++) { 74 /* Get SR1,2,3,4 from file */ 75 /* SR1 is with screen off 0x20 */ 76 SRdata = XGI330_StandTable.SR[i]; 77 xgifb_reg_set(pVBInfo->P3c4, i+1, SRdata); /* Set SR 1 2 3 4 */ 78 } 79} 80 81static void XGI_SetCRTCRegs(struct vb_device_info *pVBInfo) 82{ 83 unsigned char CRTCdata; 84 unsigned short i; 85 86 CRTCdata = xgifb_reg_get(pVBInfo->P3d4, 0x11); 87 CRTCdata &= 0x7f; 88 xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */ 89 90 for (i = 0; i <= 0x18; i++) { 91 /* Get CRTC from file */ 92 CRTCdata = XGI330_StandTable.CRTC[i]; 93 xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ 94 } 95} 96 97static void XGI_SetATTRegs(unsigned short ModeIdIndex, 98 struct vb_device_info *pVBInfo) 99{ 100 unsigned char ARdata; 101 unsigned short i, modeflag; 102 103 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 104 105 for (i = 0; i <= 0x13; i++) { 106 ARdata = XGI330_StandTable.ATTR[i]; 107 108 if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */ 109 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { 110 ARdata = 0; 111 } else if ((pVBInfo->VBInfo & 112 (SetCRT2ToTV | SetCRT2ToLCD)) && 113 (pVBInfo->VBInfo & SetInSlaveMode)) { 114 ARdata = 0; 115 } 116 } 117 118 inb(pVBInfo->P3da); /* reset 3da */ 119 outb(i, pVBInfo->P3c0); /* set index */ 120 outb(ARdata, pVBInfo->P3c0); /* set data */ 121 } 122 123 inb(pVBInfo->P3da); /* reset 3da */ 124 outb(0x14, pVBInfo->P3c0); /* set index */ 125 outb(0x00, pVBInfo->P3c0); /* set data */ 126 inb(pVBInfo->P3da); /* Enable Attribute */ 127 outb(0x20, pVBInfo->P3c0); 128} 129 130static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo) 131{ 132 unsigned char GRdata; 133 unsigned short i; 134 135 for (i = 0; i <= 0x08; i++) { 136 /* Get GR from file */ 137 GRdata = XGI330_StandTable.GRC[i]; 138 xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ 139 } 140 141 if (pVBInfo->ModeType > ModeVGA) { 142 GRdata = xgifb_reg_get(pVBInfo->P3ce, 0x05); 143 GRdata &= 0xBF; /* 256 color disable */ 144 xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata); 145 } 146} 147 148static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) 149{ 150 unsigned short i; 151 152 for (i = 0x0A; i <= 0x0E; i++) 153 xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */ 154} 155 156static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) 157{ 158 159 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20); 160 xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[0].SR2B); 161 xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[0].SR2C); 162 163 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10); 164 xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[1].SR2B); 165 xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[1].SR2C); 166 167 xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30); 168 return 0; 169} 170 171static unsigned char XGI_AjustCRT2Rate(unsigned short ModeIdIndex, 172 unsigned short RefreshRateTableIndex, unsigned short *i, 173 struct vb_device_info *pVBInfo) 174{ 175 unsigned short tempax, tempbx, resinfo, modeflag, infoflag; 176 177 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 178 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 179 tempbx = XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID; 180 tempax = 0; 181 182 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { 183 tempax |= SupportRAMDAC2; 184 185 if (pVBInfo->VBType & VB_XGI301C) 186 tempax |= SupportCRT2in301C; 187 } 188 189 /* 301b */ 190 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { 191 tempax |= SupportLCD; 192 193 if (pVBInfo->LCDResInfo != Panel_1280x1024 && 194 pVBInfo->LCDResInfo != Panel_1280x960 && 195 (pVBInfo->LCDInfo & LCDNonExpanding) && 196 resinfo >= 9) 197 return 0; 198 } 199 200 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */ 201 tempax |= SupportHiVision; 202 if ((pVBInfo->VBInfo & SetInSlaveMode) && 203 ((resinfo == 4) || 204 (resinfo == 3 && (pVBInfo->SetFlag & TVSimuMode)) || 205 (resinfo > 7))) 206 return 0; 207 } else if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | 208 SetCRT2ToSCART | SetCRT2ToYPbPr525750 | 209 SetCRT2ToHiVision)) { 210 tempax |= SupportTV; 211 212 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | 213 VB_SIS302LV | VB_XGI301C)) 214 tempax |= SupportTV1024; 215 216 if (!(pVBInfo->VBInfo & TVSetPAL) && 217 (modeflag & NoSupportSimuTV) && 218 (pVBInfo->VBInfo & SetInSlaveMode) && 219 (!(pVBInfo->VBInfo & SetNotSimuMode))) 220 return 0; 221 } 222 223 for (; XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID == 224 tempbx; (*i)--) { 225 infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)]. 226 Ext_InfoFlag; 227 if (infoflag & tempax) 228 return 1; 229 230 if ((*i) == 0) 231 break; 232 } 233 234 for ((*i) = 0;; (*i)++) { 235 infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)]. 236 Ext_InfoFlag; 237 if (XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID 238 != tempbx) { 239 return 0; 240 } 241 242 if (infoflag & tempax) 243 return 1; 244 } 245 return 1; 246} 247 248static void XGI_SetSync(unsigned short RefreshRateTableIndex, 249 struct vb_device_info *pVBInfo) 250{ 251 unsigned short sync, temp; 252 253 /* di+0x00 */ 254 sync = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; 255 sync &= 0xC0; 256 temp = 0x2F; 257 temp |= sync; 258 outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */ 259} 260 261static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, 262 struct xgi_hw_device_info *HwDeviceExtension) 263{ 264 unsigned char data, data1, pushax; 265 unsigned short i, j; 266 267 /* unlock cr0-7 */ 268 data = xgifb_reg_get(pVBInfo->P3d4, 0x11); 269 data &= 0x7F; 270 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); 271 272 data = pVBInfo->TimingH.data[0]; 273 xgifb_reg_set(pVBInfo->P3d4, 0, data); 274 275 for (i = 0x01; i <= 0x04; i++) { 276 data = pVBInfo->TimingH.data[i]; 277 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data); 278 } 279 280 for (i = 0x05; i <= 0x06; i++) { 281 data = pVBInfo->TimingH.data[i]; 282 xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data); 283 } 284 285 j = xgifb_reg_get(pVBInfo->P3c4, 0x0e); 286 j &= 0x1F; 287 data = pVBInfo->TimingH.data[7]; 288 data &= 0xE0; 289 data |= j; 290 xgifb_reg_set(pVBInfo->P3c4, 0x0e, data); 291 292 if (HwDeviceExtension->jChipType >= XG20) { 293 data = xgifb_reg_get(pVBInfo->P3d4, 0x04); 294 data = data - 1; 295 xgifb_reg_set(pVBInfo->P3d4, 0x04, data); 296 data = xgifb_reg_get(pVBInfo->P3d4, 0x05); 297 data1 = data; 298 data1 &= 0xE0; 299 data &= 0x1F; 300 if (data == 0) { 301 pushax = data; 302 data = xgifb_reg_get(pVBInfo->P3c4, 0x0c); 303 data &= 0xFB; 304 xgifb_reg_set(pVBInfo->P3c4, 0x0c, data); 305 data = pushax; 306 } 307 data = data - 1; 308 data |= data1; 309 xgifb_reg_set(pVBInfo->P3d4, 0x05, data); 310 data = xgifb_reg_get(pVBInfo->P3c4, 0x0e); 311 data >>= 5; 312 data = data + 3; 313 if (data > 7) 314 data = data - 7; 315 data <<= 5; 316 xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data); 317 } 318} 319 320static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, 321 struct vb_device_info *pVBInfo) 322{ 323 unsigned char data; 324 unsigned short i, j; 325 326 for (i = 0x00; i <= 0x01; i++) { 327 data = pVBInfo->TimingV.data[i]; 328 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data); 329 } 330 331 for (i = 0x02; i <= 0x03; i++) { 332 data = pVBInfo->TimingV.data[i]; 333 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data); 334 } 335 336 for (i = 0x04; i <= 0x05; i++) { 337 data = pVBInfo->TimingV.data[i]; 338 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data); 339 } 340 341 j = xgifb_reg_get(pVBInfo->P3c4, 0x0a); 342 j &= 0xC0; 343 data = pVBInfo->TimingV.data[6]; 344 data &= 0x3F; 345 data |= j; 346 xgifb_reg_set(pVBInfo->P3c4, 0x0a, data); 347 348 data = pVBInfo->TimingV.data[6]; 349 data &= 0x80; 350 data >>= 2; 351 352 i = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 353 i &= DoubleScanMode; 354 if (i) 355 data |= 0x80; 356 357 j = xgifb_reg_get(pVBInfo->P3d4, 0x09); 358 j &= 0x5F; 359 data |= j; 360 xgifb_reg_set(pVBInfo->P3d4, 0x09, data); 361} 362 363static void XGI_SetCRT1CRTC(unsigned short ModeIdIndex, 364 unsigned short RefreshRateTableIndex, 365 struct vb_device_info *pVBInfo, 366 struct xgi_hw_device_info *HwDeviceExtension) 367{ 368 unsigned char index, data; 369 unsigned short i; 370 371 /* Get index */ 372 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; 373 index = index & IndexMask; 374 375 data = xgifb_reg_get(pVBInfo->P3d4, 0x11); 376 data &= 0x7F; 377 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ 378 379 for (i = 0; i < 8; i++) 380 pVBInfo->TimingH.data[i] 381 = XGI_CRT1Table[index].CR[i]; 382 383 for (i = 0; i < 7; i++) 384 pVBInfo->TimingV.data[i] 385 = XGI_CRT1Table[index].CR[i + 8]; 386 387 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); 388 389 XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo); 390 391 if (pVBInfo->ModeType > 0x03) 392 xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F); 393} 394 395/* --------------------------------------------------------------------- */ 396/* Function : XGI_SetXG21CRTC */ 397/* Input : Stand or enhance CRTC table */ 398/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */ 399/* Description : Set LCD timing */ 400/* --------------------------------------------------------------------- */ 401static void XGI_SetXG21CRTC(unsigned short RefreshRateTableIndex, 402 struct vb_device_info *pVBInfo) 403{ 404 unsigned char index, Tempax, Tempbx, Tempcx, Tempdx; 405 unsigned short Temp1, Temp2, Temp3; 406 407 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; 408 /* Tempax: CR4 HRS */ 409 Tempax = XGI_CRT1Table[index].CR[3]; 410 Tempcx = Tempax; /* Tempcx: HRS */ 411 /* SR2E[7:0]->HRS */ 412 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); 413 414 Tempdx = XGI_CRT1Table[index].CR[5]; /* SRB */ 415 Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ 416 Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ 417 Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ 418 Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ 419 420 Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */ 421 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ 422 423 Tempbx = XGI_CRT1Table[index].CR[6]; /* SRC */ 424 Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ 425 Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ 426 Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ 427 428 Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */ 429 Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */ 430 431 Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */ 432 if (Tempax < Tempcx) /* HRE < HRS */ 433 Temp2 |= 0x40; /* Temp2 + 0x40 */ 434 435 Temp2 &= 0xFF; 436 Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */ 437 Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ 438 Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ 439 Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ 440 /* SR2F D[7:2]->HRE, D[1:0]->HRS */ 441 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); 442 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); 443 444 /* CR10 VRS */ 445 Tempax = XGI_CRT1Table[index].CR[10]; 446 Tempbx = Tempax; /* Tempbx: VRS */ 447 Tempax &= 0x01; /* Tempax[0]: VRS[0] */ 448 xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ 449 /* CR7[2][7] VRE */ 450 Tempax = XGI_CRT1Table[index].CR[9]; 451 Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ 452 Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ 453 Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ 454 Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ 455 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ 456 457 Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ 458 Temp1 <<= 1; /* Temp1[8]: VRS[8] */ 459 Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ 460 Tempax &= 0x80; 461 Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ 462 Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ 463 /* Tempax: SRA */ 464 Tempax = XGI_CRT1Table[index].CR[14]; 465 Tempax &= 0x08; /* Tempax[3]: VRS[3] */ 466 Temp2 = Tempax; 467 Temp2 <<= 7; /* Temp2[10]: VRS[10] */ 468 Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ 469 470 /* Tempax: CR11 VRE */ 471 Tempax = XGI_CRT1Table[index].CR[11]; 472 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ 473 /* Tempbx: SRA */ 474 Tempbx = XGI_CRT1Table[index].CR[14]; 475 Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ 476 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ 477 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ 478 Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */ 479 Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */ 480 481 Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */ 482 if (Tempax < Temp3) /* VRE < VRS */ 483 Temp2 |= 0x20; /* VRE + 0x20 */ 484 485 Temp2 &= 0xFF; 486 Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */ 487 Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */ 488 Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ 489 Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */ 490 Tempbx = (unsigned char) Temp1; 491 Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ 492 Tempax &= 0x7F; 493 /* SR3F D[7:2]->VRE D[1:0]->VRS */ 494 xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); 495} 496 497static void XGI_SetXG27CRTC(unsigned short RefreshRateTableIndex, 498 struct vb_device_info *pVBInfo) 499{ 500 unsigned short index, Tempax, Tempbx, Tempcx; 501 502 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; 503 /* Tempax: CR4 HRS */ 504 Tempax = XGI_CRT1Table[index].CR[3]; 505 Tempbx = Tempax; /* Tempbx: HRS[7:0] */ 506 /* SR2E[7:0]->HRS */ 507 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); 508 509 /* SR0B */ 510 Tempax = XGI_CRT1Table[index].CR[5]; 511 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ 512 Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */ 513 514 Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */ 515 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ 516 Tempcx = Tempax; /* Tempcx: HRE[4:0] */ 517 518 Tempax = XGI_CRT1Table[index].CR[6]; /* SRC */ 519 Tempax &= 0x04; /* Tempax[2]: HRE[5] */ 520 Tempax <<= 3; /* Tempax[5]: HRE[5] */ 521 Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ 522 523 Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */ 524 Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ 525 526 /* Tempax: CR4 HRS */ 527 Tempax = XGI_CRT1Table[index].CR[3]; 528 Tempax &= 0x3F; /* Tempax: HRS[5:0] */ 529 if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ 530 Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ 531 532 Tempax = XGI_CRT1Table[index].CR[5]; /* SR0B */ 533 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ 534 Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ 535 Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ 536 /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ 537 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); 538 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); 539 540 /* CR10 VRS */ 541 Tempax = XGI_CRT1Table[index].CR[10]; 542 /* SR34[7:0]->VRS[7:0] */ 543 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); 544 545 Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ 546 /* CR7[7][2] VRS[9][8] */ 547 Tempax = XGI_CRT1Table[index].CR[9]; 548 Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ 549 Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ 550 Tempax >>= 2; /* Tempax[0]: VRS[8] */ 551 /* SR35[0]: VRS[8] */ 552 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); 553 Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */ 554 Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */ 555 /* Tempax: SR0A */ 556 Tempax = XGI_CRT1Table[index].CR[14]; 557 Tempax &= 0x08; /* SR0A[3] VRS[10] */ 558 Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */ 559 560 /* Tempax: CR11 VRE */ 561 Tempax = XGI_CRT1Table[index].CR[11]; 562 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ 563 /* Tempbx: SR0A */ 564 Tempbx = XGI_CRT1Table[index].CR[14]; 565 Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ 566 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ 567 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ 568 Tempbx = Tempcx; /* Tempbx: VRS[10:0] */ 569 Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */ 570 Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */ 571 572 if (Tempbx <= Tempcx) /* VRE <= VRS */ 573 Tempbx |= 0x20; /* VRE + 0x20 */ 574 575 /* Tempax: Tempax[7:0]; VRE[5:0]00 */ 576 Tempax = (Tempbx << 2) & 0xFF; 577 /* SR3F[7:2]:VRE[5:0] */ 578 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); 579 Tempax = Tempcx >> 8; 580 /* SR35[2:0]:VRS[10:8] */ 581 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax); 582} 583 584static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo) 585{ 586 unsigned char temp; 587 588 /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */ 589 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); 590 temp = (temp & 3) << 6; 591 /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */ 592 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80); 593 /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */ 594 xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); 595 596} 597 598static void xgifb_set_lcd(int chip_id, 599 struct vb_device_info *pVBInfo, 600 unsigned short RefreshRateTableIndex) 601{ 602 unsigned short temp; 603 604 xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00); 605 xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00); 606 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00); 607 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00); 608 609 if (chip_id == XG27) { 610 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); 611 if ((temp & 0x03) == 0) { /* dual 12 */ 612 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13); 613 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13); 614 } 615 } 616 617 if (chip_id == XG27) { 618 XGI_SetXG27FPBits(pVBInfo); 619 } else { 620 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); 621 if (temp & 0x01) { 622 /* 18 bits FP */ 623 xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40); 624 xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40); 625 } 626 } 627 628 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ 629 630 xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ 631 xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ 632 633 temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 634 if (temp & 0x4000) 635 /* Hsync polarity */ 636 xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); 637 if (temp & 0x8000) 638 /* Vsync polarity */ 639 xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); 640} 641 642/* --------------------------------------------------------------------- */ 643/* Function : XGI_UpdateXG21CRTC */ 644/* Input : */ 645/* Output : CRT1 CRTC */ 646/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */ 647/* --------------------------------------------------------------------- */ 648static void XGI_UpdateXG21CRTC(unsigned short ModeNo, 649 struct vb_device_info *pVBInfo, 650 unsigned short RefreshRateTableIndex) 651{ 652 int index = -1; 653 654 xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ 655 if (ModeNo == 0x2E && 656 (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == 657 RES640x480x60)) 658 index = 12; 659 else if (ModeNo == 0x2E && (XGI330_RefIndex[RefreshRateTableIndex]. 660 Ext_CRT1CRTC == RES640x480x72)) 661 index = 13; 662 else if (ModeNo == 0x2F) 663 index = 14; 664 else if (ModeNo == 0x50) 665 index = 15; 666 else if (ModeNo == 0x59) 667 index = 16; 668 669 if (index != -1) { 670 xgifb_reg_set(pVBInfo->P3d4, 0x02, 671 XGI_UpdateCRT1Table[index].CR02); 672 xgifb_reg_set(pVBInfo->P3d4, 0x03, 673 XGI_UpdateCRT1Table[index].CR03); 674 xgifb_reg_set(pVBInfo->P3d4, 0x15, 675 XGI_UpdateCRT1Table[index].CR15); 676 xgifb_reg_set(pVBInfo->P3d4, 0x16, 677 XGI_UpdateCRT1Table[index].CR16); 678 } 679} 680 681static void XGI_SetCRT1DE(unsigned short ModeIdIndex, 682 unsigned short RefreshRateTableIndex, 683 struct vb_device_info *pVBInfo) 684{ 685 unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag; 686 687 unsigned char data; 688 689 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 690 691 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 692 tempax = XGI330_ModeResInfo[resindex].HTotal; 693 tempbx = XGI330_ModeResInfo[resindex].VTotal; 694 695 if (modeflag & HalfDCLK) 696 tempax >>= 1; 697 698 if (modeflag & HalfDCLK) 699 tempax <<= 1; 700 701 temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 702 703 if (temp & InterlaceMode) 704 tempbx >>= 1; 705 706 if (modeflag & DoubleScanMode) 707 tempbx <<= 1; 708 709 tempcx = 8; 710 711 tempax /= tempcx; 712 tempax -= 1; 713 tempbx -= 1; 714 tempcx = tempax; 715 temp = xgifb_reg_get(pVBInfo->P3d4, 0x11); 716 data = xgifb_reg_get(pVBInfo->P3d4, 0x11); 717 data &= 0x7F; 718 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ 719 xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff)); 720 xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c, 721 (unsigned short) ((tempcx & 0x0ff00) >> 10)); 722 xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff)); 723 tempax = 0; 724 tempbx >>= 8; 725 726 if (tempbx & 0x01) 727 tempax |= 0x02; 728 729 if (tempbx & 0x02) 730 tempax |= 0x40; 731 732 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax); 733 data = xgifb_reg_get(pVBInfo->P3d4, 0x07); 734 tempax = 0; 735 736 if (tempbx & 0x04) 737 tempax |= 0x02; 738 739 xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax); 740 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp); 741} 742 743static void XGI_SetCRT1Offset(unsigned short ModeNo, 744 unsigned short ModeIdIndex, 745 unsigned short RefreshRateTableIndex, 746 struct xgi_hw_device_info *HwDeviceExtension, 747 struct vb_device_info *pVBInfo) 748{ 749 unsigned short temp, ah, al, temp2, i, DisplayUnit; 750 751 /* GetOffset */ 752 temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; 753 temp >>= 8; 754 temp = XGI330_ScreenOffset[temp]; 755 756 temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 757 temp2 &= InterlaceMode; 758 759 if (temp2) 760 temp <<= 1; 761 762 temp2 = pVBInfo->ModeType - ModeEGA; 763 764 switch (temp2) { 765 case 0: 766 temp2 = 1; 767 break; 768 case 1: 769 temp2 = 2; 770 break; 771 case 2: 772 temp2 = 4; 773 break; 774 case 3: 775 temp2 = 4; 776 break; 777 case 4: 778 temp2 = 6; 779 break; 780 case 5: 781 temp2 = 8; 782 break; 783 default: 784 break; 785 } 786 787 if ((ModeNo >= 0x26) && (ModeNo <= 0x28)) 788 temp = temp * temp2 + temp2 / 2; 789 else 790 temp *= temp2; 791 792 /* SetOffset */ 793 DisplayUnit = temp; 794 temp2 = temp; 795 temp >>= 8; /* ah */ 796 temp &= 0x0F; 797 i = xgifb_reg_get(pVBInfo->P3c4, 0x0E); 798 i &= 0xF0; 799 i |= temp; 800 xgifb_reg_set(pVBInfo->P3c4, 0x0E, i); 801 802 temp = (unsigned char) temp2; 803 temp &= 0xFF; /* al */ 804 xgifb_reg_set(pVBInfo->P3d4, 0x13, temp); 805 806 /* SetDisplayUnit */ 807 temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 808 temp2 &= InterlaceMode; 809 if (temp2) 810 DisplayUnit >>= 1; 811 812 DisplayUnit <<= 5; 813 ah = (DisplayUnit & 0xff00) >> 8; 814 al = DisplayUnit & 0x00ff; 815 if (al == 0) 816 ah += 1; 817 else 818 ah += 2; 819 820 if (HwDeviceExtension->jChipType >= XG20) 821 if ((ModeNo == 0x4A) | (ModeNo == 0x49)) 822 ah -= 1; 823 824 xgifb_reg_set(pVBInfo->P3c4, 0x10, ah); 825} 826 827static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeIdIndex, 828 unsigned short RefreshRateTableIndex, 829 struct vb_device_info *pVBInfo) 830{ 831 unsigned short VCLKIndex, modeflag; 832 833 /* si+Ext_ResInfo */ 834 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 835 836 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /*301b*/ 837 if (pVBInfo->LCDResInfo != Panel_1024x768) 838 /* LCDXlat2VCLK */ 839 VCLKIndex = VCLK108_2_315 + 5; 840 else 841 VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */ 842 } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 843 if (pVBInfo->SetFlag & RPLLDIV2XO) 844 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2; 845 else 846 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK; 847 848 if (pVBInfo->SetFlag & TVSimuMode) { 849 if (modeflag & Charx8Dot) 850 VCLKIndex = TVCLKBASE_315_25 + HiTVSimuVCLK; 851 else 852 VCLKIndex = TVCLKBASE_315_25 + HiTVTextVCLK; 853 } 854 855 /* 301lv */ 856 if (pVBInfo->VBType & VB_SIS301LV) { 857 if (pVBInfo->SetFlag & RPLLDIV2XO) 858 VCLKIndex = YPbPr525iVCLK_2; 859 else 860 VCLKIndex = YPbPr525iVCLK; 861 } 862 } else if (pVBInfo->VBInfo & SetCRT2ToTV) { 863 if (pVBInfo->SetFlag & RPLLDIV2XO) 864 VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2; 865 else 866 VCLKIndex = TVCLKBASE_315_25 + TVVCLK; 867 } else { /* for CRT2 */ 868 /* di+Ext_CRTVCLK */ 869 VCLKIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 870 VCLKIndex &= IndexMask; 871 } 872 873 return VCLKIndex; 874} 875 876static void XGI_SetCRT1VCLK(unsigned short ModeIdIndex, 877 struct xgi_hw_device_info *HwDeviceExtension, 878 unsigned short RefreshRateTableIndex, 879 struct vb_device_info *pVBInfo) 880{ 881 unsigned char index, data; 882 unsigned short vclkindex; 883 884 if ((pVBInfo->IF_DEF_LVDS == 0) && 885 (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | 886 VB_SIS302LV | VB_XGI301C)) && 887 (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) { 888 vclkindex = XGI_GetVCLK2Ptr(ModeIdIndex, RefreshRateTableIndex, 889 pVBInfo); 890 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; 891 xgifb_reg_set(pVBInfo->P3c4, 0x31, data); 892 data = XGI_VBVCLKData[vclkindex].Part4_A; 893 xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); 894 data = XGI_VBVCLKData[vclkindex].Part4_B; 895 xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); 896 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); 897 } else { 898 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 899 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; 900 xgifb_reg_set(pVBInfo->P3c4, 0x31, data); 901 xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B); 902 xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C); 903 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); 904 } 905 906 if (HwDeviceExtension->jChipType >= XG20) { 907 if (XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag & 908 HalfDCLK) { 909 data = xgifb_reg_get(pVBInfo->P3c4, 0x2B); 910 xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); 911 data = xgifb_reg_get(pVBInfo->P3c4, 0x2C); 912 index = data; 913 index &= 0xE0; 914 data &= 0x1F; 915 data <<= 1; 916 data += 1; 917 data |= index; 918 xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); 919 } 920 } 921} 922 923static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo) 924{ 925 unsigned char temp; 926 927 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */ 928 temp = (temp & 1) << 6; 929 /* SR06[6] 18bit Dither */ 930 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp); 931 /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */ 932 xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); 933 934} 935 936static void XGI_SetCRT1FIFO(struct xgi_hw_device_info *HwDeviceExtension, 937 struct vb_device_info *pVBInfo) 938{ 939 unsigned short data; 940 941 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); 942 data &= 0xfe; 943 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */ 944 945 xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); 946 data = xgifb_reg_get(pVBInfo->P3c4, 0x09); 947 data &= 0xC0; 948 xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30); 949 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); 950 data |= 0x01; 951 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); 952 953 if (HwDeviceExtension->jChipType == XG21) 954 XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */ 955} 956 957static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, 958 unsigned short RefreshRateTableIndex, 959 struct vb_device_info *pVBInfo) 960{ 961 unsigned short data, data2 = 0; 962 short VCLK; 963 964 unsigned char index; 965 966 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 967 index &= IndexMask; 968 VCLK = XGI_VCLKData[index].CLOCK; 969 970 data = xgifb_reg_get(pVBInfo->P3c4, 0x32); 971 data &= 0xf3; 972 if (VCLK >= 200) 973 data |= 0x0c; /* VCLK > 200 */ 974 975 if (HwDeviceExtension->jChipType >= XG20) 976 data &= ~0x04; /* 2 pixel mode */ 977 978 xgifb_reg_set(pVBInfo->P3c4, 0x32, data); 979 980 if (HwDeviceExtension->jChipType < XG20) { 981 data = xgifb_reg_get(pVBInfo->P3c4, 0x1F); 982 data &= 0xE7; 983 if (VCLK < 200) 984 data |= 0x10; 985 xgifb_reg_set(pVBInfo->P3c4, 0x1F, data); 986 } 987 988 data2 = 0x00; 989 990 xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2); 991 if (HwDeviceExtension->jChipType >= XG27) 992 xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03); 993 994} 995 996static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, 997 unsigned short ModeIdIndex, 998 unsigned short RefreshRateTableIndex, 999 struct vb_device_info *pVBInfo) 1000{ 1001 unsigned short data, data2, data3, infoflag = 0, modeflag, resindex, 1002 xres; 1003 1004 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 1005 infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 1006 1007 if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01) 1008 xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); 1009 1010 data = infoflag; 1011 data2 = 0; 1012 data2 |= 0x02; 1013 data3 = pVBInfo->ModeType - ModeVGA; 1014 data3 <<= 2; 1015 data2 |= data3; 1016 data &= InterlaceMode; 1017 1018 if (data) 1019 data2 |= 0x20; 1020 1021 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2); 1022 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1023 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ 1024 1025 data = 0x0000; 1026 if (infoflag & InterlaceMode) { 1027 if (xres == 1024) 1028 data = 0x0035; 1029 else if (xres == 1280) 1030 data = 0x0048; 1031 } 1032 1033 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data); 1034 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, 0); 1035 1036 if (modeflag & HalfDCLK) 1037 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08); 1038 1039 data2 = 0; 1040 1041 if (modeflag & LineCompareOff) 1042 data2 |= 0x08; 1043 1044 xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2); 1045 data = 0x60; 1046 data = data ^ 0x60; 1047 data = data ^ 0xA0; 1048 xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data); 1049 1050 XGI_SetVCLKState(HwDeviceExtension, RefreshRateTableIndex, pVBInfo); 1051 1052 data = xgifb_reg_get(pVBInfo->P3d4, 0x31); 1053 1054 if (HwDeviceExtension->jChipType == XG27) { 1055 if (data & 0x40) 1056 data = 0x2c; 1057 else 1058 data = 0x6c; 1059 xgifb_reg_set(pVBInfo->P3d4, 0x52, data); 1060 xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10); 1061 } else if (HwDeviceExtension->jChipType >= XG20) { 1062 if (data & 0x40) 1063 data = 0x33; 1064 else 1065 data = 0x73; 1066 xgifb_reg_set(pVBInfo->P3d4, 0x52, data); 1067 xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02); 1068 } else { 1069 if (data & 0x40) 1070 data = 0x2c; 1071 else 1072 data = 0x6c; 1073 xgifb_reg_set(pVBInfo->P3d4, 0x52, data); 1074 } 1075 1076} 1077 1078static void XGI_WriteDAC(unsigned short dl, 1079 unsigned short ah, 1080 unsigned short al, 1081 unsigned short dh, 1082 struct vb_device_info *pVBInfo) 1083{ 1084 unsigned short temp, bh, bl; 1085 1086 bh = ah; 1087 bl = al; 1088 1089 if (dl != 0) { 1090 temp = bh; 1091 bh = dh; 1092 dh = temp; 1093 if (dl == 1) { 1094 temp = bl; 1095 bl = dh; 1096 dh = temp; 1097 } else { 1098 temp = bl; 1099 bl = bh; 1100 bh = temp; 1101 } 1102 } 1103 outb((unsigned short) dh, pVBInfo->P3c9); 1104 outb((unsigned short) bh, pVBInfo->P3c9); 1105 outb((unsigned short) bl, pVBInfo->P3c9); 1106} 1107 1108static void XGI_LoadDAC(struct vb_device_info *pVBInfo) 1109{ 1110 unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh; 1111 const unsigned short *table = XGINew_VGA_DAC; 1112 1113 outb(0xFF, pVBInfo->P3c6); 1114 outb(0x00, pVBInfo->P3c8); 1115 1116 for (i = 0; i < 16; i++) { 1117 data = table[i]; 1118 1119 for (k = 0; k < 3; k++) { 1120 data2 = 0; 1121 1122 if (data & 0x01) 1123 data2 = 0x2A; 1124 1125 if (data & 0x02) 1126 data2 += 0x15; 1127 1128 outb(data2, pVBInfo->P3c9); 1129 data >>= 2; 1130 } 1131 } 1132 1133 for (i = 16; i < 32; i++) { 1134 data = table[i]; 1135 1136 for (k = 0; k < 3; k++) 1137 outb(data, pVBInfo->P3c9); 1138 } 1139 1140 si = 32; 1141 1142 for (m = 0; m < 9; m++) { 1143 di = si; 1144 bx = si + 0x04; 1145 dl = 0; 1146 1147 for (n = 0; n < 3; n++) { 1148 for (o = 0; o < 5; o++) { 1149 dh = table[si]; 1150 ah = table[di]; 1151 al = table[bx]; 1152 si++; 1153 XGI_WriteDAC(dl, ah, al, dh, pVBInfo); 1154 } 1155 1156 si -= 2; 1157 1158 for (o = 0; o < 3; o++) { 1159 dh = table[bx]; 1160 ah = table[di]; 1161 al = table[si]; 1162 si--; 1163 XGI_WriteDAC(dl, ah, al, dh, pVBInfo); 1164 } 1165 1166 dl++; 1167 } 1168 1169 si += 5; 1170 } 1171} 1172 1173static void XGI_GetLVDSResInfo(unsigned short ModeIdIndex, 1174 struct vb_device_info *pVBInfo) 1175{ 1176 unsigned short resindex, xres, yres, modeflag; 1177 1178 /* si+Ext_ResInfo */ 1179 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1180 1181 /* si+Ext_ResInfo */ 1182 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1183 1184 xres = XGI330_ModeResInfo[resindex].HTotal; 1185 yres = XGI330_ModeResInfo[resindex].VTotal; 1186 1187 if (modeflag & HalfDCLK) 1188 xres <<= 1; 1189 1190 if (modeflag & DoubleScanMode) 1191 yres <<= 1; 1192 1193 if (xres == 720) 1194 xres = 640; 1195 1196 pVBInfo->VGAHDE = xres; 1197 pVBInfo->HDE = xres; 1198 pVBInfo->VGAVDE = yres; 1199 pVBInfo->VDE = yres; 1200} 1201 1202static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table, 1203 unsigned short ModeIdIndex, 1204 struct vb_device_info *pVBInfo) 1205{ 1206 unsigned short i, tempdx, tempbx, modeflag; 1207 1208 tempbx = 0; 1209 1210 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 1211 1212 i = 0; 1213 1214 while (table[i].PANELID != 0xff) { 1215 tempdx = pVBInfo->LCDResInfo; 1216 if (tempbx & 0x0080) { /* OEMUtil */ 1217 tempbx &= (~0x0080); 1218 tempdx = pVBInfo->LCDTypeInfo; 1219 } 1220 1221 if (pVBInfo->LCDInfo & EnableScalingLCD) 1222 tempdx &= (~PanelResInfo); 1223 1224 if (table[i].PANELID == tempdx) { 1225 tempbx = table[i].MASK; 1226 tempdx = pVBInfo->LCDInfo; 1227 1228 if (modeflag & HalfDCLK) 1229 tempdx |= SetLCDLowResolution; 1230 1231 tempbx &= tempdx; 1232 if (tempbx == table[i].CAP) 1233 break; 1234 } 1235 i++; 1236 } 1237 1238 return table[i].DATAPTR; 1239} 1240 1241static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeIdIndex, 1242 unsigned short RefreshRateTableIndex, 1243 struct vb_device_info *pVBInfo) 1244{ 1245 unsigned short i, tempdx, tempal, modeflag; 1246 1247 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 1248 tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 1249 tempal = tempal & 0x3f; 1250 tempdx = pVBInfo->TVInfo; 1251 1252 if (pVBInfo->VBInfo & SetInSlaveMode) 1253 tempdx = tempdx | SetTVLockMode; 1254 1255 if (modeflag & HalfDCLK) 1256 tempdx = tempdx | SetTVLowResolution; 1257 1258 i = 0; 1259 1260 while (XGI_TVDataTable[i].MASK != 0xffff) { 1261 if ((tempdx & XGI_TVDataTable[i].MASK) == 1262 XGI_TVDataTable[i].CAP) 1263 break; 1264 i++; 1265 } 1266 1267 return &XGI_TVDataTable[i].DATAPTR[tempal]; 1268} 1269 1270static void XGI_GetLVDSData(unsigned short ModeIdIndex, 1271 struct vb_device_info *pVBInfo) 1272{ 1273 struct SiS_LVDSData const *LCDPtr; 1274 1275 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) 1276 return; 1277 1278 LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeIdIndex, pVBInfo); 1279 pVBInfo->VGAHT = LCDPtr->VGAHT; 1280 pVBInfo->VGAVT = LCDPtr->VGAVT; 1281 pVBInfo->HT = LCDPtr->LCDHT; 1282 pVBInfo->VT = LCDPtr->LCDVT; 1283 1284 if (pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD)) 1285 return; 1286 1287 if ((pVBInfo->LCDResInfo == Panel_1024x768) || 1288 (pVBInfo->LCDResInfo == Panel_1024x768x75)) { 1289 pVBInfo->HDE = 1024; 1290 pVBInfo->VDE = 768; 1291 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || 1292 (pVBInfo->LCDResInfo == Panel_1280x1024x75)) { 1293 pVBInfo->HDE = 1280; 1294 pVBInfo->VDE = 1024; 1295 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { 1296 pVBInfo->HDE = 1400; 1297 pVBInfo->VDE = 1050; 1298 } else { 1299 pVBInfo->HDE = 1600; 1300 pVBInfo->VDE = 1200; 1301 } 1302} 1303 1304static void XGI_ModCRT1Regs(unsigned short ModeIdIndex, 1305 struct xgi_hw_device_info *HwDeviceExtension, 1306 struct vb_device_info *pVBInfo) 1307{ 1308 unsigned short i; 1309 struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL; 1310 struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL; 1311 1312 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { 1313 LCDPtr = XGI_GetLcdPtr(xgifb_epllcd_crt1_h, ModeIdIndex, 1314 pVBInfo); 1315 1316 for (i = 0; i < 8; i++) 1317 pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i]; 1318 } 1319 1320 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); 1321 1322 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { 1323 LCDPtr1 = XGI_GetLcdPtr(xgifb_epllcd_crt1_v, ModeIdIndex, 1324 pVBInfo); 1325 for (i = 0; i < 7; i++) 1326 pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i]; 1327 } 1328 1329 XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo); 1330} 1331 1332static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo) 1333{ 1334 unsigned char tempal, tempah, tempbl, i; 1335 1336 tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36); 1337 tempal = tempah & 0x0F; 1338 tempah = tempah & 0xF0; 1339 i = 0; 1340 tempbl = pVBInfo->LCDCapList[i].LCD_ID; 1341 1342 while (tempbl != 0xFF) { 1343 if (tempbl & 0x80) { /* OEMUtil */ 1344 tempal = tempah; 1345 tempbl = tempbl & ~(0x80); 1346 } 1347 1348 if (tempal == tempbl) 1349 break; 1350 1351 i++; 1352 1353 tempbl = pVBInfo->LCDCapList[i].LCD_ID; 1354 } 1355 1356 return i; 1357} 1358 1359static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo) 1360{ 1361 unsigned short tempah, tempal, tempbl, i; 1362 1363 tempal = pVBInfo->LCDResInfo; 1364 tempah = pVBInfo->LCDTypeInfo; 1365 1366 i = 0; 1367 tempbl = pVBInfo->LCDCapList[i].LCD_ID; 1368 1369 while (tempbl != 0xFF) { 1370 if ((tempbl & 0x80) && (tempbl != 0x80)) { 1371 tempal = tempah; 1372 tempbl &= ~0x80; 1373 } 1374 1375 if (tempal == tempbl) 1376 break; 1377 1378 i++; 1379 tempbl = pVBInfo->LCDCapList[i].LCD_ID; 1380 } 1381 1382 if (tempbl == 0xFF) { 1383 pVBInfo->LCDResInfo = Panel_1024x768; 1384 pVBInfo->LCDTypeInfo = 0; 1385 i = 0; 1386 } 1387 1388 return i; 1389} 1390 1391static void XGI_GetLCDSync(unsigned short *HSyncWidth, 1392 unsigned short *VSyncWidth, 1393 struct vb_device_info *pVBInfo) 1394{ 1395 unsigned short Index; 1396 1397 Index = XGI_GetLCDCapPtr(pVBInfo); 1398 *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth; 1399 *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth; 1400} 1401 1402static void XGI_SetLVDSRegs(unsigned short ModeIdIndex, 1403 struct vb_device_info *pVBInfo) 1404{ 1405 unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag; 1406 unsigned long temp, temp1, temp2, temp3, push3; 1407 struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL; 1408 1409 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 1410 LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeIdIndex, pVBInfo); 1411 1412 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); 1413 push1 = tempbx; 1414 push2 = tempax; 1415 1416 /* GetLCDResInfo */ 1417 if ((pVBInfo->LCDResInfo == Panel_1024x768) || 1418 (pVBInfo->LCDResInfo == Panel_1024x768x75)) { 1419 tempax = 1024; 1420 tempbx = 768; 1421 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || 1422 (pVBInfo->LCDResInfo == Panel_1280x1024x75)) { 1423 tempax = 1280; 1424 tempbx = 1024; 1425 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { 1426 tempax = 1400; 1427 tempbx = 1050; 1428 } else { 1429 tempax = 1600; 1430 tempbx = 1200; 1431 } 1432 1433 if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) { 1434 pVBInfo->HDE = tempax; 1435 pVBInfo->VDE = tempbx; 1436 pVBInfo->VGAHDE = tempax; 1437 pVBInfo->VGAVDE = tempbx; 1438 } 1439 1440 tempax = pVBInfo->HT; 1441 1442 tempbx = LCDPtr1->LCDHDES; 1443 1444 tempcx = pVBInfo->HDE; 1445 tempbx = tempbx & 0x0fff; 1446 tempcx += tempbx; 1447 1448 if (tempcx >= tempax) 1449 tempcx -= tempax; 1450 1451 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07); 1452 1453 tempcx >>= 3; 1454 tempbx >>= 3; 1455 1456 xgifb_reg_set(pVBInfo->Part1Port, 0x16, 1457 (unsigned short) (tempbx & 0xff)); 1458 xgifb_reg_set(pVBInfo->Part1Port, 0x17, 1459 (unsigned short) (tempcx & 0xff)); 1460 1461 tempax = pVBInfo->HT; 1462 1463 tempbx = LCDPtr1->LCDHRS; 1464 1465 tempcx = push2; 1466 1467 if (pVBInfo->LCDInfo & EnableScalingLCD) 1468 tempcx = LCDPtr1->LCDHSync; 1469 1470 tempcx += tempbx; 1471 1472 if (tempcx >= tempax) 1473 tempcx -= tempax; 1474 1475 tempax = tempbx & 0x07; 1476 tempax >>= 5; 1477 tempcx >>= 3; 1478 tempbx >>= 3; 1479 1480 tempcx &= 0x1f; 1481 tempax |= tempcx; 1482 1483 xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax); 1484 xgifb_reg_set(pVBInfo->Part1Port, 0x14, 1485 (unsigned short) (tempbx & 0xff)); 1486 1487 tempax = pVBInfo->VT; 1488 tempbx = LCDPtr1->LCDVDES; 1489 tempcx = pVBInfo->VDE; 1490 1491 tempbx = tempbx & 0x0fff; 1492 tempcx += tempbx; 1493 if (tempcx >= tempax) 1494 tempcx -= tempax; 1495 1496 xgifb_reg_set(pVBInfo->Part1Port, 0x1b, 1497 (unsigned short) (tempbx & 0xff)); 1498 xgifb_reg_set(pVBInfo->Part1Port, 0x1c, 1499 (unsigned short) (tempcx & 0xff)); 1500 1501 tempbx = (tempbx >> 8) & 0x07; 1502 tempcx = (tempcx >> 8) & 0x07; 1503 1504 xgifb_reg_set(pVBInfo->Part1Port, 0x1d, 1505 (unsigned short) ((tempcx << 3) 1506 | tempbx)); 1507 1508 tempax = pVBInfo->VT; 1509 tempbx = LCDPtr1->LCDVRS; 1510 1511 tempcx = push1; 1512 1513 if (pVBInfo->LCDInfo & EnableScalingLCD) 1514 tempcx = LCDPtr1->LCDVSync; 1515 1516 tempcx += tempbx; 1517 if (tempcx >= tempax) 1518 tempcx -= tempax; 1519 1520 xgifb_reg_set(pVBInfo->Part1Port, 0x18, 1521 (unsigned short) (tempbx & 0xff)); 1522 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f, 1523 (unsigned short) (tempcx & 0x0f)); 1524 1525 tempax = ((tempbx >> 8) & 0x07) << 3; 1526 1527 tempbx = pVBInfo->VGAVDE; 1528 if (tempbx != pVBInfo->VDE) 1529 tempax |= 0x40; 1530 1531 if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA) 1532 tempax |= 0x40; 1533 1534 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07, 1535 tempax); 1536 1537 tempbx = pVBInfo->VDE; 1538 tempax = pVBInfo->VGAVDE; 1539 1540 temp = tempax; /* 0430 ylshieh */ 1541 temp1 = (temp << 18) / tempbx; 1542 1543 tempdx = (unsigned short) ((temp << 18) % tempbx); 1544 1545 if (tempdx != 0) 1546 temp1 += 1; 1547 1548 temp2 = temp1; 1549 push3 = temp2; 1550 1551 xgifb_reg_set(pVBInfo->Part1Port, 0x37, 1552 (unsigned short) (temp2 & 0xff)); 1553 xgifb_reg_set(pVBInfo->Part1Port, 0x36, 1554 (unsigned short) ((temp2 >> 8) & 0xff)); 1555 1556 tempbx = (unsigned short) (temp2 >> 16); 1557 tempax = tempbx & 0x03; 1558 1559 tempbx = pVBInfo->VGAVDE; 1560 if (tempbx == pVBInfo->VDE) 1561 tempax |= 0x04; 1562 1563 xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax); 1564 1565 if (pVBInfo->VBType & VB_XGI301C) { 1566 temp2 = push3; 1567 xgifb_reg_set(pVBInfo->Part4Port, 1568 0x3c, 1569 (unsigned short) (temp2 & 0xff)); 1570 xgifb_reg_set(pVBInfo->Part4Port, 1571 0x3b, 1572 (unsigned short) ((temp2 >> 8) & 1573 0xff)); 1574 tempbx = (unsigned short) (temp2 >> 16); 1575 xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a, 1576 ~0xc0, 1577 (unsigned short) ((tempbx & 1578 0xff) << 6)); 1579 1580 tempcx = pVBInfo->VGAVDE; 1581 if (tempcx == pVBInfo->VDE) 1582 xgifb_reg_and_or(pVBInfo->Part4Port, 1583 0x30, ~0x0c, 0x00); 1584 else 1585 xgifb_reg_and_or(pVBInfo->Part4Port, 1586 0x30, ~0x0c, 0x08); 1587 } 1588 1589 tempcx = pVBInfo->VGAHDE; 1590 tempbx = pVBInfo->HDE; 1591 1592 temp1 = tempcx << 16; 1593 1594 tempax = (unsigned short) (temp1 / tempbx); 1595 1596 if ((tempbx & 0xffff) == (tempcx & 0xffff)) 1597 tempax = 65535; 1598 1599 temp3 = tempax; 1600 temp1 = pVBInfo->VGAHDE << 16; 1601 1602 temp1 /= temp3; 1603 temp3 <<= 16; 1604 temp1 -= 1; 1605 1606 temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff); 1607 1608 tempax = (unsigned short) (temp3 & 0xff); 1609 xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax); 1610 1611 temp1 = pVBInfo->VGAVDE << 18; 1612 temp1 = temp1 / push3; 1613 tempbx = (unsigned short) (temp1 & 0xffff); 1614 1615 if (pVBInfo->LCDResInfo == Panel_1024x768) 1616 tempbx -= 1; 1617 1618 tempax = ((tempbx >> 8) & 0xff) << 3; 1619 tempax |= (unsigned short) ((temp3 >> 8) & 0x07); 1620 xgifb_reg_set(pVBInfo->Part1Port, 0x20, 1621 (unsigned short) (tempax & 0xff)); 1622 xgifb_reg_set(pVBInfo->Part1Port, 0x21, 1623 (unsigned short) (tempbx & 0xff)); 1624 1625 temp3 >>= 16; 1626 1627 if (modeflag & HalfDCLK) 1628 temp3 >>= 1; 1629 1630 xgifb_reg_set(pVBInfo->Part1Port, 0x22, 1631 (unsigned short) ((temp3 >> 8) & 0xff)); 1632 xgifb_reg_set(pVBInfo->Part1Port, 0x23, 1633 (unsigned short) (temp3 & 0xff)); 1634} 1635 1636/* --------------------------------------------------------------------- */ 1637/* Function : XGI_GETLCDVCLKPtr */ 1638/* Input : */ 1639/* Output : al -> VCLK Index */ 1640/* Description : */ 1641/* --------------------------------------------------------------------- */ 1642static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, 1643 struct vb_device_info *pVBInfo) 1644{ 1645 unsigned short index; 1646 1647 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { 1648 index = XGI_GetLCDCapPtr1(pVBInfo); 1649 1650 if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */ 1651 *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1; 1652 *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2; 1653 } else { /* LCDA */ 1654 *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1; 1655 *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2; 1656 } 1657 } 1658} 1659 1660static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, 1661 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) 1662{ 1663 1664 unsigned short index, modeflag; 1665 unsigned char tempal; 1666 1667 /* si+Ext_ResInfo */ 1668 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 1669 1670 if ((pVBInfo->SetFlag & ProgrammingCRT2) && 1671 (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */ 1672 index = XGI_GetLCDCapPtr(pVBInfo); 1673 tempal = pVBInfo->LCDCapList[index].LCD_VCLK; 1674 1675 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) 1676 return tempal; 1677 1678 /* {TV} */ 1679 if (pVBInfo->VBType & 1680 (VB_SIS301B | 1681 VB_SIS302B | 1682 VB_SIS301LV | 1683 VB_SIS302LV | 1684 VB_XGI301C)) { 1685 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 1686 tempal = TVCLKBASE_315 + HiTVVCLKDIV2; 1687 if (!(pVBInfo->TVInfo & RPLLDIV2XO)) 1688 tempal = TVCLKBASE_315 + HiTVVCLK; 1689 if (pVBInfo->TVInfo & TVSimuMode) { 1690 tempal = TVCLKBASE_315 + HiTVSimuVCLK; 1691 if (!(modeflag & Charx8Dot)) 1692 tempal = TVCLKBASE_315 + 1693 HiTVTextVCLK; 1694 1695 } 1696 return tempal; 1697 } 1698 1699 if (pVBInfo->TVInfo & TVSetYPbPr750p) { 1700 tempal = XGI_YPbPr750pVCLK; 1701 return tempal; 1702 } 1703 1704 if (pVBInfo->TVInfo & TVSetYPbPr525p) { 1705 tempal = YPbPr525pVCLK; 1706 return tempal; 1707 } 1708 1709 tempal = NTSC1024VCLK; 1710 1711 if (!(pVBInfo->TVInfo & NTSC1024x768)) { 1712 tempal = TVCLKBASE_315 + TVVCLKDIV2; 1713 if (!(pVBInfo->TVInfo & RPLLDIV2XO)) 1714 tempal = TVCLKBASE_315 + TVVCLK; 1715 } 1716 1717 if (pVBInfo->VBInfo & SetCRT2ToTV) 1718 return tempal; 1719 } 1720 } /* {End of VB} */ 1721 1722 inb((pVBInfo->P3ca + 0x02)); 1723 tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 1724 return tempal; 1725} 1726 1727static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, 1728 unsigned char *di_1, struct vb_device_info *pVBInfo) 1729{ 1730 if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B 1731 | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { 1732 if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) && 1733 (pVBInfo->SetFlag & ProgrammingCRT2)) { 1734 *di_0 = XGI_VBVCLKData[tempal].Part4_A; 1735 *di_1 = XGI_VBVCLKData[tempal].Part4_B; 1736 } 1737 } else { 1738 *di_0 = XGI_VCLKData[tempal].SR2B; 1739 *di_1 = XGI_VCLKData[tempal].SR2C; 1740 } 1741} 1742 1743static void XGI_SetCRT2ECLK(unsigned short ModeIdIndex, 1744 unsigned short RefreshRateTableIndex, 1745 struct vb_device_info *pVBInfo) 1746{ 1747 unsigned char di_0, di_1, tempal; 1748 int i; 1749 1750 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo); 1751 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); 1752 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); 1753 1754 for (i = 0; i < 4; i++) { 1755 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30, 1756 (unsigned short) (0x10 * i)); 1757 if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) 1758 && (!(pVBInfo->VBInfo & SetInSlaveMode))) { 1759 xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0); 1760 xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1); 1761 } else { 1762 xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0); 1763 xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1); 1764 } 1765 } 1766} 1767 1768static void XGI_UpdateModeInfo(struct vb_device_info *pVBInfo) 1769{ 1770 unsigned short tempcl, tempch, temp, tempbl, tempax; 1771 1772 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 1773 | VB_SIS302LV | VB_XGI301C)) { 1774 tempcl = 0; 1775 tempch = 0; 1776 temp = xgifb_reg_get(pVBInfo->P3c4, 0x01); 1777 1778 if (!(temp & 0x20)) { 1779 temp = xgifb_reg_get(pVBInfo->P3d4, 0x17); 1780 if (temp & 0x80) { 1781 temp = xgifb_reg_get(pVBInfo->P3d4, 0x53); 1782 if (!(temp & 0x40)) 1783 tempcl |= ActiveCRT1; 1784 } 1785 } 1786 1787 temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e); 1788 temp &= 0x0f; 1789 1790 if (!(temp == 0x08)) { 1791 /* Check ChannelA */ 1792 tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13); 1793 if (tempax & 0x04) 1794 tempcl = tempcl | ActiveLCD; 1795 1796 temp &= 0x05; 1797 1798 if (!(tempcl & ActiveLCD)) 1799 if (temp == 0x01) 1800 tempcl |= ActiveCRT2; 1801 1802 if (temp == 0x04) 1803 tempcl |= ActiveLCD; 1804 1805 if (temp == 0x05) { 1806 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00); 1807 1808 if (!(temp & 0x08)) 1809 tempch |= ActiveAVideo; 1810 1811 if (!(temp & 0x04)) 1812 tempch |= ActiveSVideo; 1813 1814 if (temp & 0x02) 1815 tempch |= ActiveSCART; 1816 1817 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 1818 if (temp & 0x01) 1819 tempch |= ActiveHiTV; 1820 } 1821 1822 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { 1823 temp = xgifb_reg_get( 1824 pVBInfo->Part2Port, 1825 0x4d); 1826 1827 if (temp & 0x10) 1828 tempch |= ActiveYPbPr; 1829 } 1830 1831 if (tempch != 0) 1832 tempcl |= ActiveTV; 1833 } 1834 } 1835 1836 temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d); 1837 if (tempcl & ActiveLCD) { 1838 if ((pVBInfo->SetFlag & ReserveTVOption)) { 1839 if (temp & ActiveTV) 1840 tempcl |= ActiveTV; 1841 } 1842 } 1843 temp = tempcl; 1844 tempbl = ~XGI_ModeSwitchStatus; 1845 xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp); 1846 1847 if (!(pVBInfo->SetFlag & ReserveTVOption)) 1848 xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch); 1849 } 1850} 1851 1852void XGI_GetVBType(struct vb_device_info *pVBInfo) 1853{ 1854 unsigned short flag, tempbx, tempah; 1855 1856 tempbx = VB_SIS302B; 1857 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00); 1858 if (flag == 0x02) 1859 goto finish; 1860 1861 tempbx = VB_SIS301; 1862 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01); 1863 if (flag < 0xB0) 1864 goto finish; 1865 1866 tempbx = VB_SIS301B; 1867 if (flag < 0xC0) 1868 goto bigger_than_0xB0; 1869 1870 tempbx = VB_XGI301C; 1871 if (flag < 0xD0) 1872 goto bigger_than_0xB0; 1873 1874 tempbx = VB_SIS301LV; 1875 if (flag < 0xE0) 1876 goto bigger_than_0xB0; 1877 1878 tempbx = VB_SIS302LV; 1879 tempah = xgifb_reg_get(pVBInfo->Part4Port, 0x39); 1880 if (tempah != 0xFF) 1881 tempbx = VB_XGI301C; 1882 1883bigger_than_0xB0: 1884 if (tempbx & (VB_SIS301B | VB_SIS302B)) { 1885 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x23); 1886 if (!(flag & 0x02)) 1887 tempbx = tempbx | VB_NoLCD; 1888 } 1889 1890finish: 1891 pVBInfo->VBType = tempbx; 1892} 1893 1894static void XGI_GetVBInfo(unsigned short ModeIdIndex, 1895 struct vb_device_info *pVBInfo) 1896{ 1897 unsigned short tempax, push, tempbx, temp, modeflag; 1898 1899 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 1900 pVBInfo->SetFlag = 0; 1901 pVBInfo->ModeType = modeflag & ModeTypeMask; 1902 tempbx = 0; 1903 1904 if (!(pVBInfo->VBType & 0xFFFF)) 1905 return; 1906 1907 /* Check Display Device */ 1908 temp = xgifb_reg_get(pVBInfo->P3d4, 0x30); 1909 tempbx = tempbx | temp; 1910 temp = xgifb_reg_get(pVBInfo->P3d4, 0x31); 1911 push = temp; 1912 push <<= 8; 1913 tempax = temp << 8; 1914 tempbx = tempbx | tempax; 1915 temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA 1916 | SetInSlaveMode | DisableCRT2Display); 1917 temp = 0xFFFF ^ temp; 1918 tempbx &= temp; 1919 1920 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); 1921 1922 if (pVBInfo->VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV | 1923 VB_XGI301C)) { 1924 if (temp & EnableDualEdge) { 1925 tempbx |= SetCRT2ToDualEdge; 1926 if (temp & SetToLCDA) 1927 tempbx |= XGI_SetCRT2ToLCDA; 1928 } 1929 } 1930 1931 if (pVBInfo->VBType & (VB_SIS301LV|VB_SIS302LV|VB_XGI301C)) { 1932 if (temp & SetYPbPr) { 1933 /* shampoo add for new scratch */ 1934 temp = xgifb_reg_get(pVBInfo->P3d4, 0x35); 1935 temp &= YPbPrMode; 1936 tempbx |= SetCRT2ToHiVision; 1937 1938 if (temp != YPbPrMode1080i) { 1939 tempbx &= (~SetCRT2ToHiVision); 1940 tempbx |= SetCRT2ToYPbPr525750; 1941 } 1942 } 1943 } 1944 1945 tempax = push; /* restore CR31 */ 1946 1947 temp = 0x09FC; 1948 1949 if (!(tempbx & temp)) { 1950 tempax |= DisableCRT2Display; 1951 tempbx = 0; 1952 } 1953 1954 if (!(pVBInfo->VBType & VB_NoLCD)) { 1955 if (tempbx & XGI_SetCRT2ToLCDA) { 1956 if (tempbx & SetSimuScanMode) 1957 tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC | 1958 SwitchCRT2)); 1959 else 1960 tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC | 1961 SetCRT2ToTV | SwitchCRT2)); 1962 } 1963 } 1964 1965 /* shampoo add */ 1966 /* for driver abnormal */ 1967 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) { 1968 if (tempbx & SetCRT2ToRAMDAC) { 1969 tempbx &= (0xFF00 | SetCRT2ToRAMDAC | 1970 SwitchCRT2 | SetSimuScanMode); 1971 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); 1972 } 1973 } 1974 1975 if (!(pVBInfo->VBType & VB_NoLCD)) { 1976 if (tempbx & SetCRT2ToLCD) { 1977 tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchCRT2 | 1978 SetSimuScanMode); 1979 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); 1980 } 1981 } 1982 1983 if (tempbx & SetCRT2ToSCART) { 1984 tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchCRT2 | 1985 SetSimuScanMode); 1986 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); 1987 } 1988 1989 if (tempbx & SetCRT2ToYPbPr525750) 1990 tempbx &= (0xFF00 | SwitchCRT2 | SetSimuScanMode); 1991 1992 if (tempbx & SetCRT2ToHiVision) 1993 tempbx &= (0xFF00 | SetCRT2ToHiVision | SwitchCRT2 | 1994 SetSimuScanMode); 1995 1996 if (tempax & DisableCRT2Display) { /* Set Display Device Info */ 1997 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) 1998 tempbx = DisableCRT2Display; 1999 } 2000 2001 if (!(tempbx & DisableCRT2Display)) { 2002 if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) { 2003 if (!(tempbx & XGI_SetCRT2ToLCDA)) 2004 tempbx |= (SetInSlaveMode | SetSimuScanMode); 2005 } 2006 2007 /* LCD+TV can't support in slave mode 2008 * (Force LCDA+TV->LCDB) */ 2009 if ((tempbx & SetInSlaveMode) && (tempbx & XGI_SetCRT2ToLCDA)) { 2010 tempbx ^= (SetCRT2ToLCD | XGI_SetCRT2ToLCDA | 2011 SetCRT2ToDualEdge); 2012 pVBInfo->SetFlag |= ReserveTVOption; 2013 } 2014 } 2015 2016 pVBInfo->VBInfo = tempbx; 2017} 2018 2019static void XGI_GetTVInfo(unsigned short ModeIdIndex, 2020 struct vb_device_info *pVBInfo) 2021{ 2022 unsigned short tempbx = 0, resinfo = 0, modeflag, index1; 2023 2024 if (pVBInfo->VBInfo & SetCRT2ToTV) { 2025 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2026 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2027 2028 tempbx = xgifb_reg_get(pVBInfo->P3d4, 0x35); 2029 if (tempbx & TVSetPAL) { 2030 tempbx &= (SetCHTVOverScan | 2031 TVSetPALM | 2032 TVSetPALN | 2033 TVSetPAL); 2034 if (tempbx & TVSetPALM) 2035 /* set to NTSC if PAL-M */ 2036 tempbx &= ~TVSetPAL; 2037 } else 2038 tempbx &= (SetCHTVOverScan | 2039 TVSetNTSCJ | 2040 TVSetPAL); 2041 2042 if (pVBInfo->VBInfo & SetCRT2ToSCART) 2043 tempbx |= TVSetPAL; 2044 2045 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { 2046 index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35); 2047 index1 &= YPbPrMode; 2048 2049 if (index1 == YPbPrMode525i) 2050 tempbx |= TVSetYPbPr525i; 2051 2052 if (index1 == YPbPrMode525p) 2053 tempbx = tempbx | TVSetYPbPr525p; 2054 if (index1 == YPbPrMode750p) 2055 tempbx = tempbx | TVSetYPbPr750p; 2056 } 2057 2058 if (pVBInfo->VBInfo & SetCRT2ToHiVision) 2059 tempbx = tempbx | TVSetHiVision | TVSetPAL; 2060 2061 if ((pVBInfo->VBInfo & SetInSlaveMode) && 2062 (!(pVBInfo->VBInfo & SetNotSimuMode))) 2063 tempbx |= TVSimuMode; 2064 2065 if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8)) 2066 /* NTSC 1024x768, */ 2067 tempbx |= NTSC1024x768; 2068 2069 tempbx |= RPLLDIV2XO; 2070 2071 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 2072 if (pVBInfo->VBInfo & SetInSlaveMode) 2073 tempbx &= (~RPLLDIV2XO); 2074 } else if (tempbx & (TVSetYPbPr525p | TVSetYPbPr750p)) { 2075 tempbx &= (~RPLLDIV2XO); 2076 } else if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | 2077 VB_SIS301LV | VB_SIS302LV | 2078 VB_XGI301C))) { 2079 if (tempbx & TVSimuMode) 2080 tempbx &= (~RPLLDIV2XO); 2081 } 2082 } 2083 pVBInfo->TVInfo = tempbx; 2084} 2085 2086static unsigned char XGI_GetLCDInfo(unsigned short ModeIdIndex, 2087 struct vb_device_info *pVBInfo) 2088{ 2089 unsigned short temp, tempax, tempbx, resinfo = 0, LCDIdIndex; 2090 2091 pVBInfo->LCDResInfo = 0; 2092 pVBInfo->LCDTypeInfo = 0; 2093 pVBInfo->LCDInfo = 0; 2094 2095 /* si+Ext_ResInfo // */ 2096 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2097 temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ 2098 tempbx = temp & 0x0F; 2099 2100 if (tempbx == 0) 2101 tempbx = Panel_1024x768; /* default */ 2102 2103 /* LCD75 */ 2104 if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) { 2105 if (pVBInfo->VBInfo & DriverMode) { 2106 tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33); 2107 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) 2108 tempax &= 0x0F; 2109 else 2110 tempax >>= 4; 2111 2112 if ((resinfo == 6) || (resinfo == 9)) { 2113 if (tempax >= 3) 2114 tempbx |= PanelRef75Hz; 2115 } else if ((resinfo == 7) || (resinfo == 8)) { 2116 if (tempax >= 4) 2117 tempbx |= PanelRef75Hz; 2118 } 2119 } 2120 } 2121 2122 pVBInfo->LCDResInfo = tempbx; 2123 2124 /* End of LCD75 */ 2125 2126 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) 2127 return 0; 2128 2129 tempbx = 0; 2130 2131 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); 2132 2133 temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable); 2134 2135 tempbx |= temp; 2136 2137 LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo); 2138 2139 tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability; 2140 2141 if (((pVBInfo->VBType & VB_SIS302LV) || 2142 (pVBInfo->VBType & VB_XGI301C)) && (tempax & XGI_LCDDualLink)) 2143 tempbx |= SetLCDDualLink; 2144 2145 if ((pVBInfo->LCDResInfo == Panel_1400x1050) && 2146 (pVBInfo->VBInfo & SetCRT2ToLCD) && (resinfo == 9) && 2147 (!(tempbx & EnableScalingLCD))) 2148 /* 2149 * set to center in 1280x1024 LCDB 2150 * for Panel_1400x1050 2151 */ 2152 tempbx |= SetLCDtoNonExpanding; 2153 2154 if (pVBInfo->VBInfo & SetInSlaveMode) { 2155 if (pVBInfo->VBInfo & SetNotSimuMode) 2156 tempbx |= XGI_LCDVESATiming; 2157 } else { 2158 tempbx |= XGI_LCDVESATiming; 2159 } 2160 2161 pVBInfo->LCDInfo = tempbx; 2162 2163 return 1; 2164} 2165 2166unsigned char XGI_SearchModeID(unsigned short ModeNo, 2167 unsigned short *ModeIdIndex) 2168{ 2169 for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { 2170 if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo) 2171 break; 2172 if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) 2173 return 0; 2174 } 2175 2176 return 1; 2177} 2178 2179static unsigned char XG21GPIODataTransfer(unsigned char ujDate) 2180{ 2181 unsigned char ujRet = 0; 2182 unsigned char i = 0; 2183 2184 for (i = 0; i < 8; i++) { 2185 ujRet <<= 1; 2186 ujRet |= (ujDate >> i) & 1; 2187 } 2188 2189 return ujRet; 2190} 2191 2192/*----------------------------------------------------------------------------*/ 2193/* output */ 2194/* bl[5] : LVDS signal */ 2195/* bl[1] : LVDS backlight */ 2196/* bl[0] : LVDS VDD */ 2197/*----------------------------------------------------------------------------*/ 2198static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) 2199{ 2200 unsigned char CR4A, temp; 2201 2202 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); 2203 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */ 2204 2205 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); 2206 2207 temp = XG21GPIODataTransfer(temp); 2208 temp &= 0x23; 2209 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); 2210 return temp; 2211} 2212 2213/*----------------------------------------------------------------------------*/ 2214/* output */ 2215/* bl[5] : LVDS signal */ 2216/* bl[1] : LVDS backlight */ 2217/* bl[0] : LVDS VDD */ 2218/*----------------------------------------------------------------------------*/ 2219static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) 2220{ 2221 unsigned char CR4A, CRB4, temp; 2222 2223 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); 2224 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */ 2225 2226 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); 2227 2228 temp &= 0x0C; 2229 temp >>= 2; 2230 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); 2231 CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4); 2232 temp |= ((CRB4 & 0x04) << 3); 2233 return temp; 2234} 2235 2236/*----------------------------------------------------------------------------*/ 2237/* input */ 2238/* bl[5] : 1;LVDS signal on */ 2239/* bl[1] : 1;LVDS backlight on */ 2240/* bl[0] : 1:LVDS VDD on */ 2241/* bh: 100000b : clear bit 5, to set bit5 */ 2242/* 000010b : clear bit 1, to set bit1 */ 2243/* 000001b : clear bit 0, to set bit0 */ 2244/*----------------------------------------------------------------------------*/ 2245static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, 2246 struct vb_device_info *pVBInfo) 2247{ 2248 unsigned char CR4A, temp; 2249 2250 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); 2251 tempbh &= 0x23; 2252 tempbl &= 0x23; 2253 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ 2254 2255 if (tempbh & 0x20) { 2256 temp = (tempbl >> 4) & 0x02; 2257 2258 /* CR B4[1] */ 2259 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); 2260 2261 } 2262 2263 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); 2264 2265 temp = XG21GPIODataTransfer(temp); 2266 temp &= ~tempbh; 2267 temp |= tempbl; 2268 xgifb_reg_set(pVBInfo->P3d4, 0x48, temp); 2269} 2270 2271static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, 2272 struct vb_device_info *pVBInfo) 2273{ 2274 unsigned char CR4A, temp; 2275 unsigned short tempbh0, tempbl0; 2276 2277 tempbh0 = tempbh; 2278 tempbl0 = tempbl; 2279 tempbh0 &= 0x20; 2280 tempbl0 &= 0x20; 2281 tempbh0 >>= 3; 2282 tempbl0 >>= 3; 2283 2284 if (tempbh & 0x20) { 2285 temp = (tempbl >> 4) & 0x02; 2286 2287 /* CR B4[1] */ 2288 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); 2289 2290 } 2291 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0); 2292 2293 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); 2294 tempbh &= 0x03; 2295 tempbl &= 0x03; 2296 tempbh <<= 2; 2297 tempbl <<= 2; /* GPIOC,GPIOD */ 2298 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ 2299 xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl); 2300} 2301 2302static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info, 2303 struct xgi_hw_device_info *pXGIHWDE, 2304 struct vb_device_info *pVBInfo) 2305{ 2306 2307 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00); 2308 if (pXGIHWDE->jChipType == XG21) { 2309 if (pVBInfo->IF_DEF_LVDS == 1) { 2310 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) { 2311 /* LVDS VDD on */ 2312 XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); 2313 mdelay(xgifb_info->lvds_data.PSC_S2); 2314 } 2315 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20)) 2316 /* LVDS signal on */ 2317 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); 2318 mdelay(xgifb_info->lvds_data.PSC_S3); 2319 /* LVDS backlight on */ 2320 XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); 2321 } else { 2322 /* DVO/DVI signal on */ 2323 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); 2324 } 2325 2326 } 2327 2328 if (pXGIHWDE->jChipType == XG27) { 2329 if (pVBInfo->IF_DEF_LVDS == 1) { 2330 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) { 2331 /* LVDS VDD on */ 2332 XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); 2333 mdelay(xgifb_info->lvds_data.PSC_S2); 2334 } 2335 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20)) 2336 /* LVDS signal on */ 2337 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); 2338 mdelay(xgifb_info->lvds_data.PSC_S3); 2339 /* LVDS backlight on */ 2340 XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); 2341 } else { 2342 /* DVO/DVI signal on */ 2343 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); 2344 } 2345 2346 } 2347} 2348 2349void XGI_DisplayOff(struct xgifb_video_info *xgifb_info, 2350 struct xgi_hw_device_info *pXGIHWDE, 2351 struct vb_device_info *pVBInfo) 2352{ 2353 2354 if (pXGIHWDE->jChipType == XG21) { 2355 if (pVBInfo->IF_DEF_LVDS == 1) { 2356 /* LVDS backlight off */ 2357 XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); 2358 mdelay(xgifb_info->lvds_data.PSC_S3); 2359 } else { 2360 /* DVO/DVI signal off */ 2361 XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); 2362 } 2363 } 2364 2365 if (pXGIHWDE->jChipType == XG27) { 2366 if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) { 2367 /* LVDS backlight off */ 2368 XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); 2369 mdelay(xgifb_info->lvds_data.PSC_S3); 2370 } 2371 2372 if (pVBInfo->IF_DEF_LVDS == 0) 2373 /* DVO/DVI signal off */ 2374 XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); 2375 } 2376 2377 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20); 2378} 2379 2380static void XGI_WaitDisply(struct vb_device_info *pVBInfo) 2381{ 2382 while ((inb(pVBInfo->P3da) & 0x01)) 2383 break; 2384 2385 while (!(inb(pVBInfo->P3da) & 0x01)) 2386 break; 2387} 2388 2389static void XGI_AutoThreshold(struct vb_device_info *pVBInfo) 2390{ 2391 xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40); 2392} 2393 2394static void XGI_SaveCRT2Info(unsigned short ModeNo, 2395 struct vb_device_info *pVBInfo) 2396{ 2397 unsigned short temp1, temp2; 2398 2399 /* reserve CR34 for CRT1 Mode No */ 2400 xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo); 2401 temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8; 2402 temp2 = ~(SetInSlaveMode >> 8); 2403 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1); 2404} 2405 2406static void XGI_GetCRT2ResInfo(unsigned short ModeIdIndex, 2407 struct vb_device_info *pVBInfo) 2408{ 2409 unsigned short xres, yres, modeflag, resindex; 2410 2411 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2412 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ 2413 yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ 2414 /* si+St_ModeFlag */ 2415 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2416 2417 if (modeflag & HalfDCLK) 2418 xres *= 2; 2419 2420 if (modeflag & DoubleScanMode) 2421 yres *= 2; 2422 2423 if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) 2424 goto exit; 2425 2426 if (pVBInfo->LCDResInfo == Panel_1600x1200) { 2427 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { 2428 if (yres == 1024) 2429 yres = 1056; 2430 } 2431 } 2432 2433 if (pVBInfo->LCDResInfo == Panel_1280x1024) { 2434 if (yres == 400) 2435 yres = 405; 2436 else if (yres == 350) 2437 yres = 360; 2438 2439 if (pVBInfo->LCDInfo & XGI_LCDVESATiming) { 2440 if (yres == 360) 2441 yres = 375; 2442 } 2443 } 2444 2445 if (pVBInfo->LCDResInfo == Panel_1024x768) { 2446 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { 2447 if (!(pVBInfo->LCDInfo & LCDNonExpanding)) { 2448 if (yres == 350) 2449 yres = 357; 2450 else if (yres == 400) 2451 yres = 420; 2452 else if (yres == 480) 2453 yres = 525; 2454 } 2455 } 2456 } 2457 2458 if (xres == 720) 2459 xres = 640; 2460 2461exit: 2462 pVBInfo->VGAHDE = xres; 2463 pVBInfo->HDE = xres; 2464 pVBInfo->VGAVDE = yres; 2465 pVBInfo->VDE = yres; 2466} 2467 2468static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) 2469{ 2470 2471 if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) && 2472 (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */ 2473 return 1; 2474 2475 return 0; 2476} 2477 2478static void XGI_GetRAMDAC2DATA(unsigned short ModeIdIndex, 2479 unsigned short RefreshRateTableIndex, 2480 struct vb_device_info *pVBInfo) 2481{ 2482 unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, 2483 CRT1Index; 2484 2485 pVBInfo->RVBHCMAX = 1; 2486 pVBInfo->RVBHCFACT = 1; 2487 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2488 CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; 2489 CRT1Index &= IndexMask; 2490 temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[0]; 2491 temp2 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[5]; 2492 tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); 2493 tempbx = (unsigned short) XGI_CRT1Table[CRT1Index].CR[8]; 2494 tempcx = (unsigned short) 2495 XGI_CRT1Table[CRT1Index].CR[14] << 8; 2496 tempcx &= 0x0100; 2497 tempcx <<= 2; 2498 tempbx |= tempcx; 2499 temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[9]; 2500 2501 if (temp1 & 0x01) 2502 tempbx |= 0x0100; 2503 2504 if (temp1 & 0x20) 2505 tempbx |= 0x0200; 2506 tempax += 5; 2507 2508 if (modeflag & Charx8Dot) 2509 tempax *= 8; 2510 else 2511 tempax *= 9; 2512 2513 pVBInfo->VGAHT = tempax; 2514 pVBInfo->HT = tempax; 2515 tempbx++; 2516 pVBInfo->VGAVT = tempbx; 2517 pVBInfo->VT = tempbx; 2518} 2519 2520static void XGI_GetCRT2Data(unsigned short ModeIdIndex, 2521 unsigned short RefreshRateTableIndex, 2522 struct vb_device_info *pVBInfo) 2523{ 2524 unsigned short tempax = 0, tempbx = 0, modeflag, resinfo; 2525 2526 struct SiS_LCDData const *LCDPtr = NULL; 2527 2528 /* si+Ext_ResInfo */ 2529 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2530 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2531 pVBInfo->NewFlickerMode = 0; 2532 pVBInfo->RVBHRS = 50; 2533 2534 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { 2535 XGI_GetRAMDAC2DATA(ModeIdIndex, RefreshRateTableIndex, pVBInfo); 2536 return; 2537 } 2538 2539 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { 2540 LCDPtr = XGI_GetLcdPtr(XGI_LCDDataTable, ModeIdIndex, 2541 pVBInfo); 2542 2543 pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX; 2544 pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT; 2545 pVBInfo->VGAHT = LCDPtr->VGAHT; 2546 pVBInfo->VGAVT = LCDPtr->VGAVT; 2547 pVBInfo->HT = LCDPtr->LCDHT; 2548 pVBInfo->VT = LCDPtr->LCDVT; 2549 2550 if (pVBInfo->LCDResInfo == Panel_1024x768) { 2551 tempax = 1024; 2552 tempbx = 768; 2553 2554 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { 2555 if (pVBInfo->VGAVDE == 357) 2556 tempbx = 527; 2557 else if (pVBInfo->VGAVDE == 420) 2558 tempbx = 620; 2559 else if (pVBInfo->VGAVDE == 525) 2560 tempbx = 775; 2561 else if (pVBInfo->VGAVDE == 600) 2562 tempbx = 775; 2563 } 2564 } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) { 2565 tempax = 1024; 2566 tempbx = 768; 2567 } else if (pVBInfo->LCDResInfo == Panel_1280x1024) { 2568 tempax = 1280; 2569 if (pVBInfo->VGAVDE == 360) 2570 tempbx = 768; 2571 else if (pVBInfo->VGAVDE == 375) 2572 tempbx = 800; 2573 else if (pVBInfo->VGAVDE == 405) 2574 tempbx = 864; 2575 else 2576 tempbx = 1024; 2577 } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) { 2578 tempax = 1280; 2579 tempbx = 1024; 2580 } else if (pVBInfo->LCDResInfo == Panel_1280x960) { 2581 tempax = 1280; 2582 if (pVBInfo->VGAVDE == 350) 2583 tempbx = 700; 2584 else if (pVBInfo->VGAVDE == 400) 2585 tempbx = 800; 2586 else if (pVBInfo->VGAVDE == 1024) 2587 tempbx = 960; 2588 else 2589 tempbx = 960; 2590 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { 2591 tempax = 1400; 2592 tempbx = 1050; 2593 2594 if (pVBInfo->VGAVDE == 1024) { 2595 tempax = 1280; 2596 tempbx = 1024; 2597 } 2598 } else if (pVBInfo->LCDResInfo == Panel_1600x1200) { 2599 tempax = 1600; 2600 tempbx = 1200; /* alan 10/14/2003 */ 2601 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { 2602 if (pVBInfo->VGAVDE == 350) 2603 tempbx = 875; 2604 else if (pVBInfo->VGAVDE == 400) 2605 tempbx = 1000; 2606 } 2607 } 2608 2609 if (pVBInfo->LCDInfo & LCDNonExpanding) { 2610 tempax = pVBInfo->VGAHDE; 2611 tempbx = pVBInfo->VGAVDE; 2612 } 2613 2614 pVBInfo->HDE = tempax; 2615 pVBInfo->VDE = tempbx; 2616 return; 2617 } 2618 2619 if (pVBInfo->VBInfo & (SetCRT2ToTV)) { 2620 struct SiS_TVData const *TVPtr; 2621 2622 TVPtr = XGI_GetTVPtr(ModeIdIndex, RefreshRateTableIndex, 2623 pVBInfo); 2624 2625 pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX; 2626 pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT; 2627 pVBInfo->VGAHT = TVPtr->VGAHT; 2628 pVBInfo->VGAVT = TVPtr->VGAVT; 2629 pVBInfo->HDE = TVPtr->TVHDE; 2630 pVBInfo->VDE = TVPtr->TVVDE; 2631 pVBInfo->RVBHRS = TVPtr->RVBHRS; 2632 pVBInfo->NewFlickerMode = TVPtr->FlickerMode; 2633 2634 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 2635 if (resinfo == 0x08) 2636 pVBInfo->NewFlickerMode = 0x40; 2637 else if (resinfo == 0x09) 2638 pVBInfo->NewFlickerMode = 0x40; 2639 else if (resinfo == 0x12) 2640 pVBInfo->NewFlickerMode = 0x40; 2641 2642 if (pVBInfo->VGAVDE == 350) 2643 pVBInfo->TVInfo |= TVSimuMode; 2644 2645 tempax = ExtHiTVHT; 2646 tempbx = ExtHiTVVT; 2647 2648 if (pVBInfo->VBInfo & SetInSlaveMode) { 2649 if (pVBInfo->TVInfo & TVSimuMode) { 2650 tempax = StHiTVHT; 2651 tempbx = StHiTVVT; 2652 2653 if (!(modeflag & Charx8Dot)) { 2654 tempax = StHiTextTVHT; 2655 tempbx = StHiTextTVVT; 2656 } 2657 } 2658 } 2659 } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { 2660 if (pVBInfo->TVInfo & TVSetYPbPr750p) { 2661 tempax = YPbPrTV750pHT; /* Ext750pTVHT */ 2662 tempbx = YPbPrTV750pVT; /* Ext750pTVVT */ 2663 } 2664 2665 if (pVBInfo->TVInfo & TVSetYPbPr525p) { 2666 tempax = YPbPrTV525pHT; /* Ext525pTVHT */ 2667 tempbx = YPbPrTV525pVT; /* Ext525pTVVT */ 2668 } else if (pVBInfo->TVInfo & TVSetYPbPr525i) { 2669 tempax = YPbPrTV525iHT; /* Ext525iTVHT */ 2670 tempbx = YPbPrTV525iVT; /* Ext525iTVVT */ 2671 if (pVBInfo->TVInfo & NTSC1024x768) 2672 tempax = NTSC1024x768HT; 2673 } 2674 } else { 2675 tempax = PALHT; 2676 tempbx = PALVT; 2677 if (!(pVBInfo->TVInfo & TVSetPAL)) { 2678 tempax = NTSCHT; 2679 tempbx = NTSCVT; 2680 if (pVBInfo->TVInfo & NTSC1024x768) 2681 tempax = NTSC1024x768HT; 2682 } 2683 } 2684 2685 pVBInfo->HT = tempax; 2686 pVBInfo->VT = tempbx; 2687 } 2688} 2689 2690static void XGI_SetCRT2VCLK(unsigned short ModeIdIndex, 2691 unsigned short RefreshRateTableIndex, 2692 struct vb_device_info *pVBInfo) 2693{ 2694 unsigned char di_0, di_1, tempal; 2695 2696 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo); 2697 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); 2698 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); 2699 2700 if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */ 2701 /* 301 */ 2702 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10); 2703 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1); 2704 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0); 2705 } else { /* 301b/302b/301lv/302lv */ 2706 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0); 2707 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1); 2708 } 2709 2710 xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12); 2711 2712 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) 2713 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28); 2714 else 2715 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08); 2716} 2717 2718static unsigned short XGI_GetColorDepth(unsigned short ModeIdIndex) 2719{ 2720 unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; 2721 short index; 2722 unsigned short modeflag; 2723 2724 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2725 index = (modeflag & ModeTypeMask) - ModeEGA; 2726 2727 if (index < 0) 2728 index = 0; 2729 2730 return ColorDepth[index]; 2731} 2732 2733static unsigned short XGI_GetOffset(unsigned short ModeNo, 2734 unsigned short ModeIdIndex, 2735 unsigned short RefreshRateTableIndex) 2736{ 2737 unsigned short temp, colordepth, modeinfo, index, infoflag, 2738 ColorDepth[] = { 0x01, 0x02, 0x04 }; 2739 2740 modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; 2741 infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 2742 2743 index = (modeinfo >> 8) & 0xFF; 2744 2745 temp = XGI330_ScreenOffset[index]; 2746 2747 if (infoflag & InterlaceMode) 2748 temp <<= 1; 2749 2750 colordepth = XGI_GetColorDepth(ModeIdIndex); 2751 2752 if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) { 2753 temp = ModeNo - 0x7C; 2754 colordepth = ColorDepth[temp]; 2755 temp = 0x6B; 2756 if (infoflag & InterlaceMode) 2757 temp <<= 1; 2758 } 2759 return temp * colordepth; 2760} 2761 2762static void XGI_SetCRT2Offset(unsigned short ModeNo, 2763 unsigned short ModeIdIndex, 2764 unsigned short RefreshRateTableIndex, 2765 struct vb_device_info *pVBInfo) 2766{ 2767 unsigned short offset; 2768 unsigned char temp; 2769 2770 if (pVBInfo->VBInfo & SetInSlaveMode) 2771 return; 2772 2773 offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex); 2774 temp = (unsigned char) (offset & 0xFF); 2775 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp); 2776 temp = (unsigned char) ((offset & 0xFF00) >> 8); 2777 xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp); 2778 temp = (unsigned char) (((offset >> 3) & 0xFF) + 1); 2779 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp); 2780} 2781 2782static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo) 2783{ 2784 /* threshold high ,disable auto threshold */ 2785 xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B); 2786 /* threshold low default 04h */ 2787 xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); 2788} 2789 2790static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, 2791 unsigned short RefreshRateTableIndex, 2792 struct vb_device_info *pVBInfo) 2793{ 2794 u8 tempcx; 2795 2796 XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); 2797 XGI_SetCRT2FIFO(pVBInfo); 2798 2799 for (tempcx = 4; tempcx < 7; tempcx++) 2800 xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0); 2801 2802 xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00); 2803 xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */ 2804} 2805 2806static void XGI_SetGroup1(unsigned short ModeIdIndex, 2807 unsigned short RefreshRateTableIndex, 2808 struct vb_device_info *pVBInfo) 2809{ 2810 unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0, 2811 pushbx = 0, CRT1Index, modeflag; 2812 2813 CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; 2814 CRT1Index &= IndexMask; 2815 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2816 2817 /* bainy change table name */ 2818 if (modeflag & HalfDCLK) { 2819 /* BTVGA2HT 0x08,0x09 */ 2820 temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; 2821 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); 2822 temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4; 2823 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); 2824 /* BTVGA2HDEE 0x0A,0x0C */ 2825 temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; 2826 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); 2827 tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2; 2828 pushbx = pVBInfo->VGAHDE / 2 + 16; 2829 tempcx >>= 1; 2830 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ 2831 tempcx += tempbx; 2832 2833 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { 2834 tempbx = XGI_CRT1Table[CRT1Index].CR[4]; 2835 tempbx |= ((XGI_CRT1Table[CRT1Index].CR[14] & 2836 0xC0) << 2); 2837 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ 2838 tempcx = XGI_CRT1Table[CRT1Index].CR[5]; 2839 tempcx &= 0x1F; 2840 temp = XGI_CRT1Table[CRT1Index].CR[15]; 2841 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ 2842 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ 2843 } 2844 2845 tempbx += 4; 2846 tempcx += 4; 2847 2848 if (tempcx > (pVBInfo->VGAHT / 2)) 2849 tempcx = pVBInfo->VGAHT / 2; 2850 2851 temp = tempbx & 0x00FF; 2852 2853 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); 2854 } else { 2855 temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ 2856 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); 2857 temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4; 2858 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); 2859 /* BTVGA2HDEE 0x0A,0x0C */ 2860 temp = (pVBInfo->VGAHDE + 16) & 0x0FF; 2861 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); 2862 tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */ 2863 pushbx = pVBInfo->VGAHDE + 16; 2864 tempcx >>= 1; 2865 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ 2866 tempcx += tempbx; 2867 2868 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { 2869 tempbx = XGI_CRT1Table[CRT1Index].CR[3]; 2870 tempbx |= ((XGI_CRT1Table[CRT1Index].CR[5] & 2871 0xC0) << 2); 2872 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ 2873 tempcx = XGI_CRT1Table[CRT1Index].CR[4]; 2874 tempcx &= 0x1F; 2875 temp = XGI_CRT1Table[CRT1Index].CR[6]; 2876 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ 2877 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ 2878 tempbx += 16; 2879 tempcx += 16; 2880 } 2881 2882 if (tempcx > pVBInfo->VGAHT) 2883 tempcx = pVBInfo->VGAHT; 2884 2885 temp = tempbx & 0x00FF; 2886 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); 2887 } 2888 2889 tempax = (tempax & 0x00FF) | (tempbx & 0xFF00); 2890 tempbx = pushbx; 2891 tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4); 2892 tempax |= (tempbx & 0xFF00); 2893 temp = (tempax & 0xFF00) >> 8; 2894 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp); 2895 temp = tempcx & 0x00FF; 2896 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp); 2897 tempcx = (pVBInfo->VGAVT - 1); 2898 temp = tempcx & 0x00FF; 2899 2900 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp); 2901 tempbx = pVBInfo->VGAVDE - 1; 2902 temp = tempbx & 0x00FF; 2903 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp); 2904 temp = ((tempbx & 0xFF00) << 3) >> 8; 2905 temp |= ((tempcx & 0xFF00) >> 8); 2906 xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp); 2907 2908 /* BTVGA2VRS 0x10,0x11 */ 2909 tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; 2910 /* BTVGA2VRE 0x11 */ 2911 tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; 2912 2913 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { 2914 tempbx = XGI_CRT1Table[CRT1Index].CR[10]; 2915 temp = XGI_CRT1Table[CRT1Index].CR[9]; 2916 2917 if (temp & 0x04) 2918 tempbx |= 0x0100; 2919 2920 if (temp & 0x080) 2921 tempbx |= 0x0200; 2922 2923 temp = XGI_CRT1Table[CRT1Index].CR[14]; 2924 2925 if (temp & 0x08) 2926 tempbx |= 0x0400; 2927 2928 temp = XGI_CRT1Table[CRT1Index].CR[11]; 2929 tempcx = (tempcx & 0xFF00) | (temp & 0x00FF); 2930 } 2931 2932 temp = tempbx & 0x00FF; 2933 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); 2934 temp = ((tempbx & 0xFF00) >> 8) << 4; 2935 temp = ((tempcx & 0x000F) | (temp)); 2936 xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp); 2937 tempax = 0; 2938 2939 if (modeflag & DoubleScanMode) 2940 tempax |= 0x80; 2941 2942 if (modeflag & HalfDCLK) 2943 tempax |= 0x40; 2944 2945 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax); 2946} 2947 2948static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo) 2949{ 2950 unsigned long tempax, tempbx; 2951 2952 tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX) 2953 & 0xFFFF; 2954 tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT; 2955 tempax = (tempax * pVBInfo->HT) / tempbx; 2956 2957 return (unsigned short) tempax; 2958} 2959 2960static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, 2961 struct vb_device_info *pVBInfo) 2962{ 2963 unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo, 2964 modeflag; 2965 2966 /* si+Ext_ResInfo */ 2967 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2968 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2969 2970 if (!(pVBInfo->VBInfo & SetInSlaveMode)) 2971 return; 2972 2973 temp = 0xFF; /* set MAX HT */ 2974 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp); 2975 tempcx = 0x08; 2976 2977 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) 2978 modeflag |= Charx8Dot; 2979 2980 tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */ 2981 2982 if (modeflag & HalfDCLK) 2983 tempax >>= 1; 2984 2985 tempax = (tempax / tempcx) - 1; 2986 tempbx |= ((tempax & 0x00FF) << 8); 2987 temp = tempax & 0x00FF; 2988 xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp); 2989 2990 temp = (tempbx & 0xFF00) >> 8; 2991 2992 if (pVBInfo->VBInfo & SetCRT2ToTV) { 2993 if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 2994 | VB_SIS302LV | VB_XGI301C))) 2995 temp += 2; 2996 2997 if ((pVBInfo->VBInfo & SetCRT2ToHiVision) && 2998 !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7)) 2999 temp -= 2; 3000 } 3001 3002 /* 0x05 Horizontal Display Start */ 3003 xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp); 3004 /* 0x06 Horizontal Blank end */ 3005 xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03); 3006 3007 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */ 3008 if (pVBInfo->VBInfo & SetCRT2ToTV) 3009 tempax = pVBInfo->VGAHT; 3010 else 3011 tempax = XGI_GetVGAHT2(pVBInfo); 3012 } 3013 3014 if (tempax >= pVBInfo->VGAHT) 3015 tempax = pVBInfo->VGAHT; 3016 3017 if (modeflag & HalfDCLK) 3018 tempax >>= 1; 3019 3020 tempax = (tempax / tempcx) - 5; 3021 tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */ 3022 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 3023 temp = (tempbx & 0x00FF) - 1; 3024 if (!(modeflag & HalfDCLK)) { 3025 temp -= 6; 3026 if (pVBInfo->TVInfo & TVSimuMode) { 3027 temp -= 4; 3028 temp -= 10; 3029 } 3030 } 3031 } else { 3032 tempbx = (tempbx & 0xFF00) >> 8; 3033 tempcx = (tempcx + tempbx) >> 1; 3034 temp = (tempcx & 0x00FF) + 2; 3035 3036 if (pVBInfo->VBInfo & SetCRT2ToTV) { 3037 temp -= 1; 3038 if (!(modeflag & HalfDCLK)) { 3039 if ((modeflag & Charx8Dot)) { 3040 temp += 4; 3041 if (pVBInfo->VGAHDE >= 800) 3042 temp -= 6; 3043 } 3044 } 3045 } else if (!(modeflag & HalfDCLK)) { 3046 temp -= 4; 3047 if (pVBInfo->LCDResInfo != Panel_1280x960 && 3048 pVBInfo->VGAHDE >= 800) { 3049 temp -= 7; 3050 if (pVBInfo->VGAHDE >= 1280 && 3051 pVBInfo->LCDResInfo != Panel_1280x960 && 3052 (pVBInfo->LCDInfo & LCDNonExpanding)) 3053 temp += 28; 3054 } 3055 } 3056 } 3057 3058 /* 0x07 Horizontal Retrace Start */ 3059 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp); 3060 /* 0x08 Horizontal Retrace End */ 3061 xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0); 3062 3063 if (pVBInfo->VBInfo & SetCRT2ToTV) { 3064 if (pVBInfo->TVInfo & TVSimuMode) { 3065 if (ModeNo == 0x50) { 3066 if (pVBInfo->TVInfo == SetNTSCTV) { 3067 xgifb_reg_set(pVBInfo->Part1Port, 3068 0x07, 0x30); 3069 xgifb_reg_set(pVBInfo->Part1Port, 3070 0x08, 0x03); 3071 } else { 3072 xgifb_reg_set(pVBInfo->Part1Port, 3073 0x07, 0x2f); 3074 xgifb_reg_set(pVBInfo->Part1Port, 3075 0x08, 0x02); 3076 } 3077 } 3078 } 3079 } 3080 3081 xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */ 3082 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00); 3083 xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */ 3084 3085 tempbx = pVBInfo->VGAVT; 3086 push1 = tempbx; 3087 tempcx = 0x121; 3088 tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */ 3089 3090 if (tempbx == 357) 3091 tempbx = 350; 3092 if (tempbx == 360) 3093 tempbx = 350; 3094 if (tempbx == 375) 3095 tempbx = 350; 3096 if (tempbx == 405) 3097 tempbx = 400; 3098 if (tempbx == 525) 3099 tempbx = 480; 3100 3101 push2 = tempbx; 3102 3103 if (pVBInfo->VBInfo & SetCRT2ToLCD) { 3104 if (pVBInfo->LCDResInfo == Panel_1024x768) { 3105 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { 3106 if (tempbx == 350) 3107 tempbx += 5; 3108 if (tempbx == 480) 3109 tempbx += 5; 3110 } 3111 } 3112 } 3113 tempbx--; 3114 tempbx--; 3115 temp = tempbx & 0x00FF; 3116 /* 0x10 vertical Blank Start */ 3117 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); 3118 tempbx = push2; 3119 tempbx--; 3120 temp = tempbx & 0x00FF; 3121 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp); 3122 3123 if (tempbx & 0x0100) 3124 tempcx |= 0x0002; 3125 3126 tempax = 0x000B; 3127 3128 if (modeflag & DoubleScanMode) 3129 tempax |= 0x08000; 3130 3131 if (tempbx & 0x0200) 3132 tempcx |= 0x0040; 3133 3134 temp = (tempax & 0xFF00) >> 8; 3135 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); 3136 3137 if (tempbx & 0x0400) 3138 tempcx |= 0x0600; 3139 3140 /* 0x11 Vertival Blank End */ 3141 xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00); 3142 3143 tempax = push1; 3144 tempax -= tempbx; /* 0x0C Vertical Retrace Start */ 3145 tempax >>= 2; 3146 push1 = tempax; /* push ax */ 3147 3148 if (resinfo != 0x09) { 3149 tempax <<= 1; 3150 tempbx += tempax; 3151 } 3152 3153 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 3154 if ((pVBInfo->VBType & VB_SIS301LV) && 3155 !(pVBInfo->TVInfo & TVSetHiVision)) { 3156 if ((pVBInfo->TVInfo & TVSimuMode) && 3157 (pVBInfo->TVInfo & TVSetPAL)) { 3158 if (!(pVBInfo->VBType & VB_SIS301LV) || 3159 !(pVBInfo->TVInfo & 3160 (TVSetYPbPr525p | 3161 TVSetYPbPr750p | 3162 TVSetHiVision))) 3163 tempbx += 40; 3164 } 3165 } else { 3166 tempbx -= 10; 3167 } 3168 } else if (pVBInfo->TVInfo & TVSimuMode) { 3169 if (pVBInfo->TVInfo & TVSetPAL) { 3170 if (pVBInfo->VBType & VB_SIS301LV) { 3171 if (!(pVBInfo->TVInfo & 3172 (TVSetYPbPr525p | 3173 TVSetYPbPr750p | 3174 TVSetHiVision))) 3175 tempbx += 40; 3176 } else { 3177 tempbx += 40; 3178 } 3179 } 3180 } 3181 tempax = push1; 3182 tempax >>= 2; 3183 tempax++; 3184 tempax += tempbx; 3185 push1 = tempax; /* push ax */ 3186 3187 if ((pVBInfo->TVInfo & TVSetPAL)) { 3188 if (tempbx <= 513) { 3189 if (tempax >= 513) 3190 tempbx = 513; 3191 } 3192 } 3193 3194 temp = tempbx & 0x00FF; 3195 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp); 3196 tempbx--; 3197 temp = tempbx & 0x00FF; 3198 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); 3199 3200 if (tempbx & 0x0100) 3201 tempcx |= 0x0008; 3202 3203 if (tempbx & 0x0200) 3204 xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20); 3205 3206 tempbx++; 3207 3208 if (tempbx & 0x0100) 3209 tempcx |= 0x0004; 3210 3211 if (tempbx & 0x0200) 3212 tempcx |= 0x0080; 3213 3214 if (tempbx & 0x0400) 3215 tempcx |= 0x0C00; 3216 3217 tempbx = push1; /* pop ax */ 3218 temp = tempbx & 0x00FF; 3219 temp &= 0x0F; 3220 /* 0x0D vertical Retrace End */ 3221 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp); 3222 3223 if (tempbx & 0x0010) 3224 tempcx |= 0x2000; 3225 3226 temp = tempcx & 0x00FF; 3227 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */ 3228 temp = (tempcx & 0x0FF00) >> 8; 3229 xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */ 3230 tempax = modeflag; 3231 temp = (tempax & 0xFF00) >> 8; 3232 3233 temp = (temp >> 1) & 0x09; 3234 3235 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) 3236 temp |= 0x01; 3237 3238 xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */ 3239 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */ 3240 xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */ 3241 3242 if (pVBInfo->LCDInfo & LCDRGB18Bit) 3243 temp = 0x80; 3244 else 3245 temp = 0x00; 3246 3247 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */ 3248} 3249 3250static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, 3251 struct vb_device_info *pVBInfo) 3252{ 3253 unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2, 3254 modeflag; 3255 unsigned char const *TimingPoint; 3256 3257 unsigned long longtemp, tempeax, tempebx, temp2, tempecx; 3258 3259 /* si+Ext_ResInfo */ 3260 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3261 3262 tempax = 0; 3263 3264 if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO)) 3265 tempax |= 0x0800; 3266 3267 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) 3268 tempax |= 0x0400; 3269 3270 if (pVBInfo->VBInfo & SetCRT2ToSCART) 3271 tempax |= 0x0200; 3272 3273 if (!(pVBInfo->TVInfo & TVSetPAL)) 3274 tempax |= 0x1000; 3275 3276 if (pVBInfo->VBInfo & SetCRT2ToHiVision) 3277 tempax |= 0x0100; 3278 3279 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) 3280 tempax &= 0xfe00; 3281 3282 tempax = (tempax & 0xff00) >> 8; 3283 3284 xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax); 3285 TimingPoint = XGI330_NTSCTiming; 3286 3287 if (pVBInfo->TVInfo & TVSetPAL) 3288 TimingPoint = XGI330_PALTiming; 3289 3290 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 3291 TimingPoint = XGI330_HiTVExtTiming; 3292 3293 if (pVBInfo->VBInfo & SetInSlaveMode) 3294 TimingPoint = XGI330_HiTVSt2Timing; 3295 3296 if (pVBInfo->SetFlag & TVSimuMode) 3297 TimingPoint = XGI330_HiTVSt1Timing; 3298 3299 if (!(modeflag & Charx8Dot)) 3300 TimingPoint = XGI330_HiTVTextTiming; 3301 } 3302 3303 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { 3304 if (pVBInfo->TVInfo & TVSetYPbPr525i) 3305 TimingPoint = XGI330_YPbPr525iTiming; 3306 3307 if (pVBInfo->TVInfo & TVSetYPbPr525p) 3308 TimingPoint = XGI330_YPbPr525pTiming; 3309 3310 if (pVBInfo->TVInfo & TVSetYPbPr750p) 3311 TimingPoint = XGI330_YPbPr750pTiming; 3312 } 3313 3314 for (i = 0x01, j = 0; i <= 0x2D; i++, j++) 3315 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); 3316 3317 for (i = 0x39; i <= 0x45; i++, j++) 3318 /* di->temp2[j] */ 3319 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); 3320 3321 if (pVBInfo->VBInfo & SetCRT2ToTV) 3322 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00); 3323 3324 temp = pVBInfo->NewFlickerMode; 3325 temp &= 0x80; 3326 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp); 3327 3328 if (pVBInfo->TVInfo & TVSetPAL) 3329 tempax = 520; 3330 else 3331 tempax = 440; 3332 3333 if (pVBInfo->VDE <= tempax) { 3334 tempax -= pVBInfo->VDE; 3335 tempax >>= 2; 3336 tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8); 3337 push1 = tempax; 3338 temp = (tempax & 0xFF00) >> 8; 3339 temp += (unsigned short) TimingPoint[0]; 3340 3341 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 3342 | VB_SIS302LV | VB_XGI301C)) { 3343 if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO 3344 | SetCRT2ToSVIDEO | SetCRT2ToSCART 3345 | SetCRT2ToYPbPr525750)) { 3346 tempcx = pVBInfo->VGAHDE; 3347 if (tempcx >= 1024) { 3348 temp = 0x17; /* NTSC */ 3349 if (pVBInfo->TVInfo & TVSetPAL) 3350 temp = 0x19; /* PAL */ 3351 } 3352 } 3353 } 3354 3355 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp); 3356 tempax = push1; 3357 temp = (tempax & 0xFF00) >> 8; 3358 temp += TimingPoint[1]; 3359 3360 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 3361 | VB_SIS302LV | VB_XGI301C)) { 3362 if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO 3363 | SetCRT2ToSVIDEO | SetCRT2ToSCART 3364 | SetCRT2ToYPbPr525750))) { 3365 tempcx = pVBInfo->VGAHDE; 3366 if (tempcx >= 1024) { 3367 temp = 0x1D; /* NTSC */ 3368 if (pVBInfo->TVInfo & TVSetPAL) 3369 temp = 0x52; /* PAL */ 3370 } 3371 } 3372 } 3373 xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp); 3374 } 3375 3376 /* 301b */ 3377 tempcx = pVBInfo->HT; 3378 3379 if (XGI_IsLCDDualLink(pVBInfo)) 3380 tempcx >>= 1; 3381 3382 tempcx -= 2; 3383 temp = tempcx & 0x00FF; 3384 xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp); 3385 3386 temp = (tempcx & 0xFF00) >> 8; 3387 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp); 3388 3389 tempcx = pVBInfo->HT >> 1; 3390 push1 = tempcx; /* push cx */ 3391 tempcx += 7; 3392 3393 if (pVBInfo->VBInfo & SetCRT2ToHiVision) 3394 tempcx -= 4; 3395 3396 temp = tempcx & 0x00FF; 3397 temp <<= 4; 3398 xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp); 3399 3400 tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); 3401 tempbx += tempcx; 3402 push2 = tempbx; 3403 temp = tempbx & 0x00FF; 3404 xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp); 3405 temp = (tempbx & 0xFF00) >> 8; 3406 temp <<= 4; 3407 xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp); 3408 3409 tempbx = push2; 3410 tempbx = tempbx + 8; 3411 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 3412 tempbx = tempbx - 4; 3413 tempcx = tempbx; 3414 } 3415 3416 temp = (tempbx & 0x00FF) << 4; 3417 xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp); 3418 3419 j += 2; 3420 tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8)); 3421 temp = tempcx & 0x00FF; 3422 xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp); 3423 temp = ((tempcx & 0xFF00) >> 8) << 4; 3424 xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp); 3425 3426 tempcx += 8; 3427 if (pVBInfo->VBInfo & SetCRT2ToHiVision) 3428 tempcx -= 4; 3429 3430 temp = tempcx & 0xFF; 3431 temp <<= 4; 3432 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp); 3433 3434 tempcx = push1; /* pop cx */ 3435 j += 2; 3436 temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); 3437 tempcx -= temp; 3438 temp = tempcx & 0x00FF; 3439 temp <<= 4; 3440 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp); 3441 3442 tempcx -= 11; 3443 3444 if (!(pVBInfo->VBInfo & SetCRT2ToTV)) { 3445 tempax = XGI_GetVGAHT2(pVBInfo); 3446 tempcx = tempax - 1; 3447 } 3448 temp = tempcx & 0x00FF; 3449 xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp); 3450 3451 tempbx = pVBInfo->VDE; 3452 3453 if (pVBInfo->VGAVDE == 360) 3454 tempbx = 746; 3455 if (pVBInfo->VGAVDE == 375) 3456 tempbx = 746; 3457 if (pVBInfo->VGAVDE == 405) 3458 tempbx = 853; 3459 3460 if (pVBInfo->VBInfo & SetCRT2ToTV) { 3461 if (pVBInfo->VBType & 3462 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { 3463 if (!(pVBInfo->TVInfo & 3464 (TVSetYPbPr525p | TVSetYPbPr750p))) 3465 tempbx >>= 1; 3466 } else 3467 tempbx >>= 1; 3468 } 3469 3470 tempbx -= 2; 3471 temp = tempbx & 0x00FF; 3472 3473 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 3474 if (pVBInfo->VBType & VB_SIS301LV) { 3475 if (pVBInfo->TVInfo & TVSetHiVision) { 3476 if (pVBInfo->VBInfo & SetInSlaveMode) { 3477 if (ModeNo == 0x2f) 3478 temp += 1; 3479 } 3480 } 3481 } else if (pVBInfo->VBInfo & SetInSlaveMode) { 3482 if (ModeNo == 0x2f) 3483 temp += 1; 3484 } 3485 } 3486 3487 xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp); 3488 3489 temp = (tempcx & 0xFF00) >> 8; 3490 temp |= ((tempbx & 0xFF00) >> 8) << 6; 3491 3492 if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) { 3493 if (pVBInfo->VBType & VB_SIS301LV) { 3494 if (pVBInfo->TVInfo & TVSetHiVision) { 3495 temp |= 0x10; 3496 3497 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) 3498 temp |= 0x20; 3499 } 3500 } else { 3501 temp |= 0x10; 3502 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) 3503 temp |= 0x20; 3504 } 3505 } 3506 3507 xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp); 3508 3509 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 3510 | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */ 3511 tempbx = pVBInfo->VDE; 3512 tempcx = tempbx - 2; 3513 3514 if (pVBInfo->VBInfo & SetCRT2ToTV) { 3515 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p 3516 | TVSetYPbPr750p))) 3517 tempbx >>= 1; 3518 } 3519 3520 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { 3521 temp = 0; 3522 if (tempcx & 0x0400) 3523 temp |= 0x20; 3524 3525 if (tempbx & 0x0400) 3526 temp |= 0x40; 3527 3528 xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp); 3529 } 3530 3531 temp = (((tempbx - 3) & 0x0300) >> 8) << 5; 3532 xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp); 3533 temp = (tempbx - 3) & 0x00FF; 3534 xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp); 3535 } 3536 3537 tempbx = tempbx & 0x00FF; 3538 3539 if (!(modeflag & HalfDCLK)) { 3540 tempcx = pVBInfo->VGAHDE; 3541 if (tempcx >= pVBInfo->HDE) { 3542 tempbx |= 0x2000; 3543 tempax &= 0x00FF; 3544 } 3545 } 3546 3547 tempcx = 0x0101; 3548 3549 if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/ 3550 if (pVBInfo->VGAHDE >= 1024) { 3551 tempcx = 0x1920; 3552 if (pVBInfo->VGAHDE >= 1280) { 3553 tempcx = 0x1420; 3554 tempbx = tempbx & 0xDFFF; 3555 } 3556 } 3557 } 3558 3559 if (!(tempbx & 0x2000)) { 3560 if (modeflag & HalfDCLK) 3561 tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1); 3562 3563 push1 = tempbx; 3564 tempeax = pVBInfo->VGAHDE; 3565 tempebx = (tempcx & 0xFF00) >> 8; 3566 longtemp = tempeax * tempebx; 3567 tempecx = tempcx & 0x00FF; 3568 longtemp = longtemp / tempecx; 3569 3570 /* 301b */ 3571 tempecx = 8 * 1024; 3572 3573 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 3574 | VB_SIS302LV | VB_XGI301C)) { 3575 tempecx = tempecx * 8; 3576 } 3577 3578 longtemp = longtemp * tempecx; 3579 tempecx = pVBInfo->HDE; 3580 temp2 = longtemp % tempecx; 3581 tempeax = longtemp / tempecx; 3582 if (temp2 != 0) 3583 tempeax += 1; 3584 3585 tempax = (unsigned short) tempeax; 3586 3587 /* 301b */ 3588 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 3589 | VB_SIS302LV | VB_XGI301C)) { 3590 tempcx = ((tempax & 0xFF00) >> 5) >> 8; 3591 } 3592 /* end 301b */ 3593 3594 tempbx = push1; 3595 tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00) 3596 | (tempbx & 0x00FF)); 3597 tempax = (unsigned short) (((tempeax & 0x000000FF) << 8) 3598 | (tempax & 0x00FF)); 3599 temp = (tempax & 0xFF00) >> 8; 3600 } else { 3601 temp = (tempax & 0x00FF) >> 8; 3602 } 3603 3604 xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp); 3605 temp = (tempbx & 0xFF00) >> 8; 3606 xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp); 3607 temp = tempcx & 0x00FF; 3608 3609 if (tempbx & 0x2000) 3610 temp = 0; 3611 3612 if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) 3613 temp |= 0x18; 3614 3615 xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp); 3616 if (pVBInfo->TVInfo & TVSetPAL) { 3617 tempbx = 0x0382; 3618 tempcx = 0x007e; 3619 } else { 3620 tempbx = 0x0369; 3621 tempcx = 0x0061; 3622 } 3623 3624 temp = tempbx & 0x00FF; 3625 xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp); 3626 temp = tempcx & 0x00FF; 3627 xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp); 3628 3629 temp = ((tempcx & 0xFF00) >> 8) & 0x03; 3630 temp <<= 2; 3631 temp |= ((tempbx & 0xFF00) >> 8) & 0x03; 3632 3633 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { 3634 temp |= 0x10; 3635 3636 if (pVBInfo->TVInfo & TVSetYPbPr525p) 3637 temp |= 0x20; 3638 3639 if (pVBInfo->TVInfo & TVSetYPbPr750p) 3640 temp |= 0x60; 3641 } 3642 3643 xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp); 3644 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */ 3645 xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3)); 3646 3647 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) { 3648 if (pVBInfo->TVInfo & NTSC1024x768) { 3649 TimingPoint = XGI_NTSC1024AdjTime; 3650 for (i = 0x1c, j = 0; i <= 0x30; i++, j++) { 3651 xgifb_reg_set(pVBInfo->Part2Port, i, 3652 TimingPoint[j]); 3653 } 3654 xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72); 3655 } 3656 } 3657 3658 /* Modify for 301C PALM Support */ 3659 if (pVBInfo->VBType & VB_XGI301C) { 3660 if (pVBInfo->TVInfo & TVSetPALM) 3661 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08, 3662 0x08); /* PALM Mode */ 3663 } 3664 3665 if (pVBInfo->TVInfo & TVSetPALM) { 3666 tempax = xgifb_reg_get(pVBInfo->Part2Port, 0x01); 3667 tempax--; 3668 xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax); 3669 3670 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF); 3671 } 3672 3673 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { 3674 if (!(pVBInfo->VBInfo & SetInSlaveMode)) 3675 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00); 3676 } 3677} 3678 3679static void XGI_SetLCDRegs(unsigned short ModeIdIndex, 3680 struct vb_device_info *pVBInfo) 3681{ 3682 unsigned short pushbx, tempax, tempbx, tempcx, temp, tempah, 3683 tempbh, tempch; 3684 3685 struct XGI_LCDDesStruct const *LCDBDesPtr = NULL; 3686 3687 /* si+Ext_ResInfo */ 3688 if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) 3689 return; 3690 3691 tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */ 3692 3693 if (XGI_IsLCDDualLink(pVBInfo)) 3694 tempbx >>= 1; 3695 3696 tempbx -= 1; 3697 temp = tempbx & 0x00FF; 3698 xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp); 3699 temp = (tempbx & 0xFF00) >> 8; 3700 temp <<= 4; 3701 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp); 3702 temp = 0x01; 3703 3704 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp); 3705 tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */ 3706 tempbx--; 3707 temp = tempbx & 0x00FF; 3708 xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp); 3709 temp = ((tempbx & 0xFF00) >> 8) & 0x07; 3710 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp); 3711 3712 tempcx = pVBInfo->VT - 1; 3713 temp = tempcx & 0x00FF; /* RVTVT=VT-1 */ 3714 xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp); 3715 temp = (tempcx & 0xFF00) >> 8; 3716 temp <<= 5; 3717 xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp); 3718 xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00); 3719 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00); 3720 xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00); 3721 xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00); 3722 3723 /* Customized LCDB Does not add */ 3724 if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) 3725 LCDBDesPtr = XGI_GetLcdPtr(xgifb_lcddldes, ModeIdIndex, 3726 pVBInfo); 3727 else 3728 LCDBDesPtr = XGI_GetLcdPtr(XGI_LCDDesDataTable, ModeIdIndex, 3729 pVBInfo); 3730 3731 tempah = pVBInfo->LCDResInfo; 3732 tempah &= PanelResInfo; 3733 3734 if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) { 3735 tempbx = 1024; 3736 tempcx = 768; 3737 } else if ((tempah == Panel_1280x1024) || 3738 (tempah == Panel_1280x1024x75)) { 3739 tempbx = 1280; 3740 tempcx = 1024; 3741 } else if (tempah == Panel_1400x1050) { 3742 tempbx = 1400; 3743 tempcx = 1050; 3744 } else { 3745 tempbx = 1600; 3746 tempcx = 1200; 3747 } 3748 3749 if (pVBInfo->LCDInfo & EnableScalingLCD) { 3750 tempbx = pVBInfo->HDE; 3751 tempcx = pVBInfo->VDE; 3752 } 3753 3754 pushbx = tempbx; 3755 tempax = pVBInfo->VT; 3756 pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES; 3757 pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS; 3758 pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES; 3759 pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS; 3760 tempbx = pVBInfo->LCDVDES; 3761 tempcx += tempbx; 3762 3763 if (tempcx >= tempax) 3764 tempcx -= tempax; /* lcdvdes */ 3765 3766 temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */ 3767 xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp); 3768 temp = tempcx & 0x00FF; 3769 xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp); 3770 tempch = ((tempcx & 0xFF00) >> 8) & 0x07; 3771 tempbh = ((tempbx & 0xFF00) >> 8) & 0x07; 3772 tempah = tempch; 3773 tempah <<= 3; 3774 tempah |= tempbh; 3775 xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah); 3776 3777 /* getlcdsync() */ 3778 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); 3779 tempcx = tempbx; 3780 tempax = pVBInfo->VT; 3781 tempbx = pVBInfo->LCDVRS; 3782 3783 tempcx += tempbx; 3784 if (tempcx >= tempax) 3785 tempcx -= tempax; 3786 3787 temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */ 3788 xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp); 3789 temp = (tempbx & 0xFF00) >> 8; 3790 temp <<= 4; 3791 temp |= (tempcx & 0x000F); 3792 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp); 3793 tempcx = pushbx; 3794 tempax = pVBInfo->HT; 3795 tempbx = pVBInfo->LCDHDES; 3796 tempbx &= 0x0FFF; 3797 3798 if (XGI_IsLCDDualLink(pVBInfo)) { 3799 tempax >>= 1; 3800 tempbx >>= 1; 3801 tempcx >>= 1; 3802 } 3803 3804 if (pVBInfo->VBType & VB_SIS302LV) 3805 tempbx += 1; 3806 3807 if (pVBInfo->VBType & VB_XGI301C) /* tap4 */ 3808 tempbx += 1; 3809 3810 tempcx += tempbx; 3811 3812 if (tempcx >= tempax) 3813 tempcx -= tempax; 3814 3815 temp = tempbx & 0x00FF; 3816 xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */ 3817 temp = ((tempbx & 0xFF00) >> 8) << 4; 3818 xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp); 3819 temp = tempcx & 0x00FF; 3820 xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */ 3821 temp = (tempcx & 0xFF00) >> 8; 3822 xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp); 3823 3824 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); 3825 tempcx = tempax; 3826 tempax = pVBInfo->HT; 3827 tempbx = pVBInfo->LCDHRS; 3828 if (XGI_IsLCDDualLink(pVBInfo)) { 3829 tempax >>= 1; 3830 tempbx >>= 1; 3831 tempcx >>= 1; 3832 } 3833 3834 if (pVBInfo->VBType & VB_SIS302LV) 3835 tempbx += 1; 3836 3837 tempcx += tempbx; 3838 3839 if (tempcx >= tempax) 3840 tempcx -= tempax; 3841 3842 temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */ 3843 xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp); 3844 3845 temp = (tempbx & 0xFF00) >> 8; 3846 temp <<= 4; 3847 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp); 3848 temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */ 3849 xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp); 3850 3851 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { 3852 if (pVBInfo->VGAVDE == 525) { 3853 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B 3854 | VB_SIS301LV | VB_SIS302LV 3855 | VB_XGI301C)) { 3856 temp = 0xC6; 3857 } else 3858 temp = 0xC4; 3859 3860 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); 3861 xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3); 3862 } 3863 3864 if (pVBInfo->VGAVDE == 420) { 3865 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B 3866 | VB_SIS301LV | VB_SIS302LV 3867 | VB_XGI301C)) { 3868 temp = 0x4F; 3869 } else 3870 temp = 0x4E; 3871 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); 3872 } 3873 } 3874} 3875 3876/* --------------------------------------------------------------------- */ 3877/* Function : XGI_GetTap4Ptr */ 3878/* Input : */ 3879/* Output : di -> Tap4 Reg. Setting Pointer */ 3880/* Description : */ 3881/* --------------------------------------------------------------------- */ 3882static struct XGI301C_Tap4TimingStruct const 3883*XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo) 3884{ 3885 unsigned short tempax, tempbx, i; 3886 struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr; 3887 3888 if (tempcx == 0) { 3889 tempax = pVBInfo->VGAHDE; 3890 tempbx = pVBInfo->HDE; 3891 } else { 3892 tempax = pVBInfo->VGAVDE; 3893 tempbx = pVBInfo->VDE; 3894 } 3895 3896 if (tempax <= tempbx) 3897 return &xgifb_tap4_timing[0]; 3898 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */ 3899 3900 if (pVBInfo->TVInfo & TVSetPAL) 3901 Tap4TimingPtr = PALTap4Timing; 3902 3903 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { 3904 if ((pVBInfo->TVInfo & TVSetYPbPr525i) || 3905 (pVBInfo->TVInfo & TVSetYPbPr525p)) 3906 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; 3907 if (pVBInfo->TVInfo & TVSetYPbPr750p) 3908 Tap4TimingPtr = YPbPr750pTap4Timing; 3909 } 3910 3911 if (pVBInfo->VBInfo & SetCRT2ToHiVision) 3912 Tap4TimingPtr = xgifb_tap4_timing; 3913 3914 i = 0; 3915 while (Tap4TimingPtr[i].DE != 0xFFFF) { 3916 if (Tap4TimingPtr[i].DE == tempax) 3917 break; 3918 i++; 3919 } 3920 return &Tap4TimingPtr[i]; 3921} 3922 3923static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) 3924{ 3925 unsigned short i, j; 3926 struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr; 3927 3928 if (!(pVBInfo->VBType & VB_XGI301C)) 3929 return; 3930 3931 Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */ 3932 for (i = 0x80, j = 0; i <= 0xBF; i++, j++) 3933 xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); 3934 3935 if ((pVBInfo->VBInfo & SetCRT2ToTV) && 3936 (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) { 3937 /* Set Vertical Scaling */ 3938 Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); 3939 for (i = 0xC0, j = 0; i < 0xFF; i++, j++) 3940 xgifb_reg_set(pVBInfo->Part2Port, 3941 i, 3942 Tap4TimingPtr->Reg[j]); 3943 } 3944 3945 if ((pVBInfo->VBInfo & SetCRT2ToTV) && 3946 (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) 3947 /* Enable V.Scaling */ 3948 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); 3949 else 3950 /* Enable H.Scaling */ 3951 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); 3952} 3953 3954static void XGI_SetGroup3(unsigned short ModeIdIndex, 3955 struct vb_device_info *pVBInfo) 3956{ 3957 unsigned short i; 3958 unsigned char const *tempdi; 3959 unsigned short modeflag; 3960 3961 /* si+Ext_ResInfo */ 3962 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3963 3964 xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00); 3965 if (pVBInfo->TVInfo & TVSetPAL) { 3966 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); 3967 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); 3968 } else { 3969 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5); 3970 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7); 3971 } 3972 3973 if (!(pVBInfo->VBInfo & SetCRT2ToTV)) 3974 return; 3975 3976 if (pVBInfo->TVInfo & TVSetPALM) { 3977 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); 3978 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); 3979 xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8); 3980 } 3981 3982 if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo 3983 & SetCRT2ToYPbPr525750)) { 3984 if (pVBInfo->TVInfo & TVSetYPbPr525i) 3985 return; 3986 3987 tempdi = XGI330_HiTVGroup3Data; 3988 if (pVBInfo->SetFlag & TVSimuMode) { 3989 tempdi = XGI330_HiTVGroup3Simu; 3990 if (!(modeflag & Charx8Dot)) 3991 tempdi = XGI330_HiTVGroup3Text; 3992 } 3993 3994 if (pVBInfo->TVInfo & TVSetYPbPr525p) 3995 tempdi = XGI330_Ren525pGroup3; 3996 3997 if (pVBInfo->TVInfo & TVSetYPbPr750p) 3998 tempdi = XGI330_Ren750pGroup3; 3999 4000 for (i = 0; i <= 0x3E; i++) 4001 xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]); 4002 4003 if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */ 4004 if (pVBInfo->TVInfo & TVSetYPbPr525p) 4005 xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f); 4006 } 4007 } 4008} 4009 4010static void XGI_SetGroup4(unsigned short ModeIdIndex, 4011 unsigned short RefreshRateTableIndex, 4012 struct vb_device_info *pVBInfo) 4013{ 4014 unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2; 4015 4016 unsigned long tempebx, tempeax, templong; 4017 4018 /* si+Ext_ResInfo */ 4019 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 4020 temp = pVBInfo->RVBHCFACT; 4021 xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp); 4022 4023 tempbx = pVBInfo->RVBHCMAX; 4024 temp = tempbx & 0x00FF; 4025 xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp); 4026 temp2 = ((tempbx & 0xFF00) >> 8) << 7; 4027 tempcx = pVBInfo->VGAHT - 1; 4028 temp = tempcx & 0x00FF; 4029 xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp); 4030 4031 temp = ((tempcx & 0xFF00) >> 8) << 3; 4032 temp2 |= temp; 4033 4034 tempcx = pVBInfo->VGAVT - 1; 4035 if (!(pVBInfo->VBInfo & SetCRT2ToTV)) 4036 tempcx -= 5; 4037 4038 temp = tempcx & 0x00FF; 4039 xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp); 4040 temp = temp2 | ((tempcx & 0xFF00) >> 8); 4041 xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp); 4042 xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08); 4043 tempcx = pVBInfo->VBInfo; 4044 tempbx = pVBInfo->VGAHDE; 4045 4046 if (modeflag & HalfDCLK) 4047 tempbx >>= 1; 4048 4049 if (XGI_IsLCDDualLink(pVBInfo)) 4050 tempbx >>= 1; 4051 4052 if (tempcx & SetCRT2ToHiVision) { 4053 temp = 0; 4054 if (tempbx <= 1024) 4055 temp = 0xA0; 4056 if (tempbx == 1280) 4057 temp = 0xC0; 4058 } else if (tempcx & SetCRT2ToTV) { 4059 temp = 0xA0; 4060 if (tempbx <= 800) 4061 temp = 0x80; 4062 } else { 4063 temp = 0x80; 4064 if (pVBInfo->VBInfo & SetCRT2ToLCD) { 4065 temp = 0; 4066 if (tempbx > 800) 4067 temp = 0x60; 4068 } 4069 } 4070 4071 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) { 4072 temp = 0x00; 4073 if (pVBInfo->VGAHDE == 1280) 4074 temp = 0x40; 4075 if (pVBInfo->VGAHDE == 1024) 4076 temp = 0x20; 4077 } 4078 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp); 4079 4080 tempebx = pVBInfo->VDE; 4081 4082 tempcx = pVBInfo->RVBHRS; 4083 temp = tempcx & 0x00FF; 4084 xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp); 4085 4086 tempeax = pVBInfo->VGAVDE; 4087 tempcx |= 0x04000; 4088 4089 if (tempeax <= tempebx) { 4090 tempcx = (tempcx & (~0x4000)); 4091 tempeax = pVBInfo->VGAVDE; 4092 } else { 4093 tempeax -= tempebx; 4094 } 4095 4096 templong = (tempeax * 256 * 1024) % tempebx; 4097 tempeax = (tempeax * 256 * 1024) / tempebx; 4098 tempebx = tempeax; 4099 4100 if (templong != 0) 4101 tempebx++; 4102 4103 temp = (unsigned short) (tempebx & 0x000000FF); 4104 xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp); 4105 4106 temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8); 4107 xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp); 4108 tempbx = (unsigned short) (tempebx >> 16); 4109 temp = tempbx & 0x00FF; 4110 temp <<= 4; 4111 temp |= ((tempcx & 0xFF00) >> 8); 4112 xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp); 4113 4114 /* 301b */ 4115 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 4116 | VB_SIS302LV | VB_XGI301C)) { 4117 temp = 0x0028; 4118 xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp); 4119 tempax = pVBInfo->VGAHDE; 4120 if (modeflag & HalfDCLK) 4121 tempax >>= 1; 4122 4123 if (XGI_IsLCDDualLink(pVBInfo)) 4124 tempax >>= 1; 4125 4126 if (pVBInfo->VBInfo & SetCRT2ToLCD) { 4127 if (tempax > 800) 4128 tempax -= 800; 4129 } else if (pVBInfo->VGAHDE > 800) { 4130 if (pVBInfo->VGAHDE == 1024) 4131 tempax = (tempax * 25 / 32) - 1; 4132 else 4133 tempax = (tempax * 20 / 32) - 1; 4134 } 4135 tempax -= 1; 4136 4137 temp = (tempax & 0xFF00) >> 8; 4138 temp = (temp & 0x0003) << 4; 4139 xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp); 4140 temp = (tempax & 0x00FF); 4141 xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp); 4142 4143 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) { 4144 if (pVBInfo->VGAHDE > 800) 4145 xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08); 4146 4147 } 4148 temp = 0x0036; 4149 4150 if (pVBInfo->VBInfo & SetCRT2ToTV) { 4151 if (!(pVBInfo->TVInfo & (NTSC1024x768 4152 | TVSetYPbPr525p | TVSetYPbPr750p 4153 | TVSetHiVision))) { 4154 temp |= 0x0001; 4155 if ((pVBInfo->VBInfo & SetInSlaveMode) 4156 && (!(pVBInfo->TVInfo 4157 & TVSimuMode))) 4158 temp &= (~0x0001); 4159 } 4160 } 4161 4162 xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp); 4163 tempbx = pVBInfo->HT; 4164 if (XGI_IsLCDDualLink(pVBInfo)) 4165 tempbx >>= 1; 4166 tempbx = (tempbx >> 1) - 2; 4167 temp = ((tempbx & 0x0700) >> 8) << 3; 4168 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp); 4169 temp = tempbx & 0x00FF; 4170 xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp); 4171 } 4172 /* end 301b */ 4173 4174 XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo); 4175} 4176 4177static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) 4178{ 4179 xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20); 4180} 4181 4182static void XGI_SetGroup5(struct vb_device_info *pVBInfo) 4183{ 4184 if (pVBInfo->ModeType == ModeVGA) { 4185 if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag 4186 | DisableCRT2Display))) { 4187 XGINew_EnableCRT2(pVBInfo); 4188 } 4189 } 4190} 4191 4192static void XGI_DisableGatingCRT(struct vb_device_info *pVBInfo) 4193{ 4194 xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00); 4195} 4196 4197static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, 4198 unsigned short ModeNo, unsigned short ModeIdIndex) 4199{ 4200 unsigned short xres, yres, colordepth, modeflag, resindex; 4201 4202 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 4203 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ 4204 yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ 4205 /* si+St_ModeFlag */ 4206 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 4207 4208 if (!(modeflag & Charx8Dot)) { 4209 xres /= 9; 4210 xres *= 8; 4211 } 4212 4213 if ((ModeNo > 0x13) && (modeflag & HalfDCLK)) 4214 xres *= 2; 4215 4216 if ((ModeNo > 0x13) && (modeflag & DoubleScanMode)) 4217 yres *= 2; 4218 4219 if (xres > xgifb_info->lvds_data.LVDSHDE) 4220 return 0; 4221 4222 if (yres > xgifb_info->lvds_data.LVDSVDE) 4223 return 0; 4224 4225 if (xres != xgifb_info->lvds_data.LVDSHDE || 4226 yres != xgifb_info->lvds_data.LVDSVDE) { 4227 colordepth = XGI_GetColorDepth(ModeIdIndex); 4228 if (colordepth > 2) 4229 return 0; 4230 } 4231 return 1; 4232} 4233 4234static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, 4235 int chip_id, 4236 unsigned short ModeIdIndex, 4237 struct vb_device_info *pVBInfo) 4238{ 4239 unsigned char temp, Miscdata; 4240 unsigned short xres, yres, modeflag, resindex; 4241 unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE; 4242 unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE; 4243 unsigned short value; 4244 4245 temp = (unsigned char) ((xgifb_info->lvds_data.LVDS_Capability & 4246 (LCDPolarity << 8)) >> 8); 4247 temp &= LCDPolarity; 4248 Miscdata = inb(pVBInfo->P3cc); 4249 4250 outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2); 4251 4252 temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity; 4253 /* SR35[7] FP VSync polarity */ 4254 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); 4255 /* SR30[5] FP HSync polarity */ 4256 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); 4257 4258 if (chip_id == XG27) 4259 XGI_SetXG27FPBits(pVBInfo); 4260 else 4261 XGI_SetXG21FPBits(pVBInfo); 4262 4263 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; 4264 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ 4265 yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ 4266 /* si+St_ModeFlag */ 4267 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 4268 4269 if (!(modeflag & Charx8Dot)) 4270 xres = xres * 8 / 9; 4271 4272 LVDSHT = xgifb_info->lvds_data.LVDSHT; 4273 4274 LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2; 4275 4276 if (LVDSHBS > LVDSHT) 4277 LVDSHBS -= LVDSHT; 4278 4279 LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP; 4280 if (LVDSHRS > LVDSHT) 4281 LVDSHRS -= LVDSHT; 4282 4283 LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC; 4284 if (LVDSHRE > LVDSHT) 4285 LVDSHRE -= LVDSHT; 4286 4287 LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE; 4288 4289 LVDSVT = xgifb_info->lvds_data.LVDSVT; 4290 4291 LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2; 4292 if (modeflag & DoubleScanMode) 4293 LVDSVBS += yres / 2; 4294 4295 if (LVDSVBS > LVDSVT) 4296 LVDSVBS -= LVDSVT; 4297 4298 LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP; 4299 if (LVDSVRS > LVDSVT) 4300 LVDSVRS -= LVDSVT; 4301 4302 LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC; 4303 if (LVDSVRE > LVDSVT) 4304 LVDSVRE -= LVDSVT; 4305 4306 LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE; 4307 4308 temp = xgifb_reg_get(pVBInfo->P3d4, 0x11); 4309 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ 4310 4311 if (!(modeflag & Charx8Dot)) 4312 xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1); 4313 4314 /* HT SR0B[1:0] CR00 */ 4315 value = (LVDSHT >> 3) - 5; 4316 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8); 4317 xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF)); 4318 4319 /* HBS SR0B[5:4] CR02 */ 4320 value = (LVDSHBS >> 3) - 1; 4321 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4); 4322 xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF)); 4323 4324 /* HBE SR0C[1:0] CR05[7] CR03[4:0] */ 4325 value = (LVDSHBE >> 3) - 1; 4326 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6); 4327 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2); 4328 xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F); 4329 4330 /* HRS SR0B[7:6] CR04 */ 4331 value = (LVDSHRS >> 3) + 2; 4332 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2); 4333 xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF)); 4334 4335 /* Panel HRS SR2F[1:0] SR2E[7:0] */ 4336 value--; 4337 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8); 4338 xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF)); 4339 4340 /* HRE SR0C[2] CR05[4:0] */ 4341 value = (LVDSHRE >> 3) + 2; 4342 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3); 4343 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F); 4344 4345 /* Panel HRE SR2F[7:2] */ 4346 value--; 4347 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2); 4348 4349 /* VT SR0A[0] CR07[5][0] CR06 */ 4350 value = LVDSVT - 2; 4351 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10); 4352 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4); 4353 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8); 4354 xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF)); 4355 4356 /* VBS SR0A[2] CR09[5] CR07[3] CR15 */ 4357 value = LVDSVBS - 1; 4358 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8); 4359 xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4); 4360 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5); 4361 xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF)); 4362 4363 /* VBE SR0A[4] CR16 */ 4364 value = LVDSVBE - 1; 4365 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4); 4366 xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF)); 4367 4368 /* VRS SR0A[3] CR7[7][2] CR10 */ 4369 value = LVDSVRS - 1; 4370 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7); 4371 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2); 4372 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6); 4373 xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF)); 4374 4375 if (chip_id == XG27) { 4376 /* Panel VRS SR35[2:0] SR34[7:0] */ 4377 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, 4378 (value & 0x700) >> 8); 4379 xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF); 4380 } else { 4381 /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */ 4382 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03, 4383 (value & 0x600) >> 9); 4384 xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF); 4385 xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01); 4386 } 4387 4388 /* VRE SR0A[5] CR11[3:0] */ 4389 value = LVDSVRE - 1; 4390 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1); 4391 xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F); 4392 4393 /* Panel VRE SR3F[7:2] */ 4394 if (chip_id == XG27) 4395 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, 4396 (value << 2) & 0xFC); 4397 else 4398 /* SR3F[7] has to be 0, h/w bug */ 4399 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, 4400 (value << 2) & 0x7C); 4401 4402 for (temp = 0, value = 0; temp < 3; temp++) { 4403 4404 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value); 4405 xgifb_reg_set(pVBInfo->P3c4, 4406 0x2B, xgifb_info->lvds_data.VCLKData1); 4407 xgifb_reg_set(pVBInfo->P3c4, 4408 0x2C, xgifb_info->lvds_data.VCLKData2); 4409 value += 0x10; 4410 } 4411 4412 if (!(modeflag & Charx8Dot)) { 4413 inb(pVBInfo->P3da); /* reset 3da */ 4414 outb(0x13, pVBInfo->P3c0); /* set index */ 4415 /* set data, panning = 0, shift left 1 dot*/ 4416 outb(0x00, pVBInfo->P3c0); 4417 4418 inb(pVBInfo->P3da); /* Enable Attribute */ 4419 outb(0x20, pVBInfo->P3c0); 4420 4421 inb(pVBInfo->P3da); /* reset 3da */ 4422 } 4423 4424} 4425 4426/* --------------------------------------------------------------------- */ 4427/* Function : XGI_IsLCDON */ 4428/* Input : */ 4429/* Output : 0 : Skip PSC Control */ 4430/* 1: Disable PSC */ 4431/* Description : */ 4432/* --------------------------------------------------------------------- */ 4433static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo) 4434{ 4435 unsigned short tempax; 4436 4437 tempax = pVBInfo->VBInfo; 4438 if (tempax & SetCRT2ToDualEdge) 4439 return 0; 4440 else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode)) 4441 return 1; 4442 4443 return 0; 4444} 4445 4446static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, 4447 struct xgi_hw_device_info *HwDeviceExtension, 4448 struct vb_device_info *pVBInfo) 4449{ 4450 unsigned short tempah = 0; 4451 4452 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 4453 | VB_SIS302LV | VB_XGI301C)) { 4454 tempah = 0x3F; 4455 if (!(pVBInfo->VBInfo & 4456 (DisableCRT2Display | SetSimuScanMode))) { 4457 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { 4458 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) 4459 tempah = 0x7F; /* Disable Channel A */ 4460 } 4461 } 4462 4463 /* disable part4_1f */ 4464 xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah); 4465 4466 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { 4467 if (((pVBInfo->VBInfo & 4468 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) || 4469 (XGI_IsLCDON(pVBInfo))) 4470 /* LVDS Driver power down */ 4471 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80); 4472 } 4473 4474 if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA | 4475 SetSimuScanMode)) 4476 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); 4477 4478 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) 4479 /* Power down */ 4480 xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf); 4481 4482 /* disable TV as primary VGA swap */ 4483 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf); 4484 4485 if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge))) 4486 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf); 4487 4488 if ((pVBInfo->VBInfo & 4489 (DisableCRT2Display | SetSimuScanMode)) || 4490 ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) && 4491 (pVBInfo->VBInfo & 4492 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)))) 4493 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); 4494 4495 if ((pVBInfo->VBInfo & 4496 (DisableCRT2Display | SetSimuScanMode)) || 4497 (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) || 4498 (pVBInfo->VBInfo & 4499 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) { 4500 /* save Part1 index 0 */ 4501 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); 4502 /* BTDAC = 1, avoid VB reset */ 4503 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10); 4504 /* disable CRT2 */ 4505 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); 4506 /* restore Part1 index 0 */ 4507 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); 4508 } 4509 } else { /* {301} */ 4510 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { 4511 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); 4512 /* Disable CRT2 */ 4513 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); 4514 /* Disable TV asPrimary VGA swap */ 4515 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF); 4516 } 4517 4518 if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA 4519 | SetSimuScanMode)) 4520 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); 4521 } 4522} 4523 4524/* --------------------------------------------------------------------- */ 4525/* Function : XGI_GetTVPtrIndex */ 4526/* Input : */ 4527/* Output : */ 4528/* Description : bx 0 : ExtNTSC */ 4529/* 1 : StNTSC */ 4530/* 2 : ExtPAL */ 4531/* 3 : StPAL */ 4532/* 4 : ExtHiTV */ 4533/* 5 : StHiTV */ 4534/* 6 : Ext525i */ 4535/* 7 : St525i */ 4536/* 8 : Ext525p */ 4537/* 9 : St525p */ 4538/* A : Ext750p */ 4539/* B : St750p */ 4540/* --------------------------------------------------------------------- */ 4541static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) 4542{ 4543 unsigned short tempbx = 0; 4544 4545 if (pVBInfo->TVInfo & TVSetPAL) 4546 tempbx = 2; 4547 if (pVBInfo->TVInfo & TVSetHiVision) 4548 tempbx = 4; 4549 if (pVBInfo->TVInfo & TVSetYPbPr525i) 4550 tempbx = 6; 4551 if (pVBInfo->TVInfo & TVSetYPbPr525p) 4552 tempbx = 8; 4553 if (pVBInfo->TVInfo & TVSetYPbPr750p) 4554 tempbx = 10; 4555 if (pVBInfo->TVInfo & TVSimuMode) 4556 tempbx++; 4557 4558 return tempbx; 4559} 4560 4561/* --------------------------------------------------------------------- */ 4562/* Function : XGI_GetTVPtrIndex2 */ 4563/* Input : */ 4564/* Output : bx 0 : NTSC */ 4565/* 1 : PAL */ 4566/* 2 : PALM */ 4567/* 3 : PALN */ 4568/* 4 : NTSC1024x768 */ 4569/* 5 : PAL-M 1024x768 */ 4570/* 6-7: reserved */ 4571/* cl 0 : YFilter1 */ 4572/* 1 : YFilter2 */ 4573/* ch 0 : 301A */ 4574/* 1 : 301B/302B/301LV/302LV */ 4575/* Description : */ 4576/* --------------------------------------------------------------------- */ 4577static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, 4578 unsigned char *tempch, struct vb_device_info *pVBInfo) 4579{ 4580 *tempbx = 0; 4581 *tempcl = 0; 4582 *tempch = 0; 4583 4584 if (pVBInfo->TVInfo & TVSetPAL) 4585 *tempbx = 1; 4586 4587 if (pVBInfo->TVInfo & TVSetPALM) 4588 *tempbx = 2; 4589 4590 if (pVBInfo->TVInfo & TVSetPALN) 4591 *tempbx = 3; 4592 4593 if (pVBInfo->TVInfo & NTSC1024x768) { 4594 *tempbx = 4; 4595 if (pVBInfo->TVInfo & TVSetPALM) 4596 *tempbx = 5; 4597 } 4598 4599 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 4600 | VB_SIS302LV | VB_XGI301C)) { 4601 if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo 4602 & TVSimuMode)) { 4603 *tempbx += 8; 4604 *tempcl += 1; 4605 } 4606 } 4607 4608 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 4609 | VB_SIS302LV | VB_XGI301C)) 4610 (*tempch)++; 4611} 4612 4613static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) 4614{ 4615 unsigned char tempah, tempbl, tempbh; 4616 4617 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 4618 | VB_SIS302LV | VB_XGI301C)) { 4619 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA 4620 | SetCRT2ToTV | SetCRT2ToRAMDAC)) { 4621 tempbh = 0; 4622 tempbl = XGI301TVDelay; 4623 4624 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) 4625 tempbl >>= 4; 4626 if (pVBInfo->VBInfo & 4627 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { 4628 tempbh = XGI301LCDDelay; 4629 4630 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) 4631 tempbl = tempbh; 4632 } 4633 4634 tempbl &= 0x0F; 4635 tempbh &= 0xF0; 4636 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D); 4637 4638 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD 4639 | SetCRT2ToTV)) { /* Channel B */ 4640 tempah &= 0xF0; 4641 tempah |= tempbl; 4642 } 4643 4644 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { 4645 /* Channel A */ 4646 tempah &= 0x0F; 4647 tempah |= tempbh; 4648 } 4649 xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah); 4650 } 4651 } 4652} 4653 4654static void XGI_SetLCDCap_A(unsigned short tempcx, 4655 struct vb_device_info *pVBInfo) 4656{ 4657 unsigned short temp; 4658 4659 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); 4660 4661 if (temp & LCDRGB18Bit) { 4662 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, 4663 /* Enable Dither */ 4664 (unsigned short) (0x20 | (tempcx & 0x00C0))); 4665 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); 4666 } else { 4667 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, 4668 (unsigned short) (0x30 | (tempcx & 0x00C0))); 4669 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); 4670 } 4671} 4672 4673/* --------------------------------------------------------------------- */ 4674/* Function : XGI_SetLCDCap_B */ 4675/* Input : cx -> LCD Capability */ 4676/* Output : */ 4677/* Description : */ 4678/* --------------------------------------------------------------------- */ 4679static void XGI_SetLCDCap_B(unsigned short tempcx, 4680 struct vb_device_info *pVBInfo) 4681{ 4682 if (tempcx & EnableLCD24bpp) /* 24bits */ 4683 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, 4684 (unsigned short) (((tempcx & 0x00ff) >> 6) 4685 | 0x0c)); 4686 else 4687 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, 4688 (unsigned short) (((tempcx & 0x00ff) >> 6) 4689 | 0x18)); /* Enable Dither */ 4690} 4691 4692static void XGI_LongWait(struct vb_device_info *pVBInfo) 4693{ 4694 unsigned short i; 4695 4696 i = xgifb_reg_get(pVBInfo->P3c4, 0x1F); 4697 4698 if (!(i & 0xC0)) { 4699 for (i = 0; i < 0xFFFF; i++) { 4700 if (!(inb(pVBInfo->P3da) & 0x08)) 4701 break; 4702 } 4703 4704 for (i = 0; i < 0xFFFF; i++) { 4705 if ((inb(pVBInfo->P3da) & 0x08)) 4706 break; 4707 } 4708 } 4709} 4710 4711static void SetSpectrum(struct vb_device_info *pVBInfo) 4712{ 4713 unsigned short index; 4714 4715 index = XGI_GetLCDCapPtr(pVBInfo); 4716 4717 /* disable down spectrum D[4] */ 4718 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F); 4719 XGI_LongWait(pVBInfo); 4720 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */ 4721 XGI_LongWait(pVBInfo); 4722 4723 xgifb_reg_set(pVBInfo->Part4Port, 0x31, 4724 pVBInfo->LCDCapList[index].Spectrum_31); 4725 xgifb_reg_set(pVBInfo->Part4Port, 0x32, 4726 pVBInfo->LCDCapList[index].Spectrum_32); 4727 xgifb_reg_set(pVBInfo->Part4Port, 0x33, 4728 pVBInfo->LCDCapList[index].Spectrum_33); 4729 xgifb_reg_set(pVBInfo->Part4Port, 0x34, 4730 pVBInfo->LCDCapList[index].Spectrum_34); 4731 XGI_LongWait(pVBInfo); 4732 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */ 4733} 4734 4735static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) 4736{ 4737 unsigned short tempcx; 4738 4739 tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability; 4740 4741 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | 4742 VB_SIS302LV | VB_XGI301C)) { 4743 if (pVBInfo->VBType & 4744 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { 4745 /* Set 301LV Capability */ 4746 xgifb_reg_set(pVBInfo->Part4Port, 0x24, 4747 (unsigned char) (tempcx & 0x1F)); 4748 } 4749 /* VB Driving */ 4750 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, 4751 ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8), 4752 (unsigned short) ((tempcx & (EnableVBCLKDRVLOW 4753 | EnablePLLSPLOW)) >> 8)); 4754 4755 if (pVBInfo->VBInfo & SetCRT2ToLCD) 4756 XGI_SetLCDCap_B(tempcx, pVBInfo); 4757 else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) 4758 XGI_SetLCDCap_A(tempcx, pVBInfo); 4759 4760 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { 4761 if (tempcx & EnableSpectrum) 4762 SetSpectrum(pVBInfo); 4763 } 4764 } else { 4765 /* LVDS,CH7017 */ 4766 XGI_SetLCDCap_A(tempcx, pVBInfo); 4767 } 4768} 4769 4770/* --------------------------------------------------------------------- */ 4771/* Function : XGI_SetAntiFlicker */ 4772/* Input : */ 4773/* Output : */ 4774/* Description : Set TV Customized Param. */ 4775/* --------------------------------------------------------------------- */ 4776static void XGI_SetAntiFlicker(struct vb_device_info *pVBInfo) 4777{ 4778 unsigned short tempbx; 4779 4780 unsigned char tempah; 4781 4782 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) 4783 return; 4784 4785 tempbx = XGI_GetTVPtrIndex(pVBInfo); 4786 tempbx &= 0xFE; 4787 tempah = TVAntiFlickList[tempbx]; 4788 tempah <<= 4; 4789 4790 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah); 4791} 4792 4793static void XGI_SetEdgeEnhance(struct vb_device_info *pVBInfo) 4794{ 4795 unsigned short tempbx; 4796 4797 unsigned char tempah; 4798 4799 tempbx = XGI_GetTVPtrIndex(pVBInfo); 4800 tempbx &= 0xFE; 4801 tempah = TVEdgeList[tempbx]; 4802 tempah <<= 5; 4803 4804 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah); 4805} 4806 4807static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) 4808{ 4809 unsigned short tempbx; 4810 4811 unsigned char tempcl, tempch; 4812 4813 unsigned long tempData; 4814 4815 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ 4816 tempData = TVPhaseList[tempbx]; 4817 4818 xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData 4819 & 0x000000FF)); 4820 xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData 4821 & 0x0000FF00) >> 8)); 4822 xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData 4823 & 0x00FF0000) >> 16)); 4824 xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData 4825 & 0xFF000000) >> 24)); 4826} 4827 4828static void XGI_SetYFilter(unsigned short ModeIdIndex, 4829 struct vb_device_info *pVBInfo) 4830{ 4831 unsigned short tempbx, index; 4832 unsigned char const *filterPtr; 4833 unsigned char tempcl, tempch, tempal; 4834 4835 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ 4836 4837 switch (tempbx) { 4838 case 0x00: 4839 case 0x04: 4840 filterPtr = NTSCYFilter1; 4841 break; 4842 4843 case 0x01: 4844 filterPtr = PALYFilter1; 4845 break; 4846 4847 case 0x02: 4848 case 0x05: 4849 case 0x0D: 4850 case 0x03: 4851 filterPtr = xgifb_palmn_yfilter1; 4852 break; 4853 4854 case 0x08: 4855 case 0x0C: 4856 case 0x0A: 4857 case 0x0B: 4858 case 0x09: 4859 filterPtr = xgifb_yfilter2; 4860 break; 4861 4862 default: 4863 return; 4864 } 4865 4866 tempal = XGI330_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; 4867 if (tempcl == 0) 4868 index = tempal * 4; 4869 else 4870 index = tempal * 7; 4871 4872 if ((tempcl == 0) && (tempch == 1)) { 4873 xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0); 4874 xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0); 4875 xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0); 4876 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]); 4877 } else { 4878 xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]); 4879 xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]); 4880 xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]); 4881 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]); 4882 } 4883 4884 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 4885 | VB_SIS302LV | VB_XGI301C)) { 4886 xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]); 4887 xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]); 4888 xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]); 4889 } 4890} 4891 4892/* --------------------------------------------------------------------- */ 4893/* Function : XGI_OEM310Setting */ 4894/* Input : */ 4895/* Output : */ 4896/* Description : Customized Param. for 301 */ 4897/* --------------------------------------------------------------------- */ 4898static void XGI_OEM310Setting(unsigned short ModeIdIndex, 4899 struct vb_device_info *pVBInfo) 4900{ 4901 XGI_SetDelayComp(pVBInfo); 4902 4903 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) 4904 XGI_SetLCDCap(pVBInfo); 4905 4906 if (pVBInfo->VBInfo & SetCRT2ToTV) { 4907 XGI_SetPhaseIncr(pVBInfo); 4908 XGI_SetYFilter(ModeIdIndex, pVBInfo); 4909 XGI_SetAntiFlicker(pVBInfo); 4910 4911 if (pVBInfo->VBType & VB_SIS301) 4912 XGI_SetEdgeEnhance(pVBInfo); 4913 } 4914} 4915 4916/* --------------------------------------------------------------------- */ 4917/* Function : XGI_SetCRT2ModeRegs */ 4918/* Input : */ 4919/* Output : */ 4920/* Description : Origin code for crt2group */ 4921/* --------------------------------------------------------------------- */ 4922static void XGI_SetCRT2ModeRegs(struct vb_device_info *pVBInfo) 4923{ 4924 unsigned short tempbl; 4925 short tempcl; 4926 4927 unsigned char tempah; 4928 4929 tempah = 0; 4930 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { 4931 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); 4932 tempah &= ~0x10; /* BTRAMDAC */ 4933 tempah |= 0x40; /* BTRAM */ 4934 4935 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV 4936 | SetCRT2ToLCD)) { 4937 tempah = 0x40; /* BTDRAM */ 4938 tempcl = pVBInfo->ModeType; 4939 tempcl -= ModeVGA; 4940 if (tempcl >= 0) { 4941 /* BT Color */ 4942 tempah = (0x008 >> tempcl); 4943 if (tempah == 0) 4944 tempah = 1; 4945 tempah |= 0x040; 4946 } 4947 if (pVBInfo->VBInfo & SetInSlaveMode) 4948 tempah ^= 0x50; /* BTDAC */ 4949 } 4950 } 4951 4952 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); 4953 tempah = 0x08; 4954 tempbl = 0xf0; 4955 4956 if (pVBInfo->VBInfo & DisableCRT2Display) 4957 goto reg_and_or; 4958 4959 tempah = 0x00; 4960 tempbl = 0xff; 4961 4962 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | 4963 SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) 4964 goto reg_and_or; 4965 4966 if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && 4967 (!(pVBInfo->VBInfo & SetSimuScanMode))) { 4968 tempbl &= 0xf7; 4969 tempah |= 0x01; 4970 goto reg_and_or; 4971 } 4972 4973 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { 4974 tempbl &= 0xf7; 4975 tempah |= 0x01; 4976 } 4977 4978 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD))) 4979 goto reg_and_or; 4980 4981 tempbl &= 0xf8; 4982 tempah = 0x01; 4983 4984 if (!(pVBInfo->VBInfo & SetInSlaveMode)) 4985 tempah |= 0x02; 4986 4987 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { 4988 tempah = tempah ^ 0x05; 4989 if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) 4990 tempah = tempah ^ 0x01; 4991 } 4992 4993 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) 4994 tempah |= 0x08; 4995 4996reg_and_or: 4997 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah); 4998 4999 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD 5000 | XGI_SetCRT2ToLCDA)) { 5001 tempah &= (~0x08); 5002 if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo 5003 & SetInSlaveMode))) { 5004 tempah |= 0x010; 5005 } 5006 tempah |= 0x080; 5007 5008 if (pVBInfo->VBInfo & SetCRT2ToTV) { 5009 tempah |= 0x020; 5010 if (pVBInfo->VBInfo & DriverMode) 5011 tempah = tempah ^ 0x20; 5012 } 5013 5014 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah); 5015 tempah = 0; 5016 5017 if (pVBInfo->LCDInfo & SetLCDDualLink) 5018 tempah |= 0x40; 5019 5020 if (pVBInfo->VBInfo & SetCRT2ToTV) { 5021 if (pVBInfo->TVInfo & RPLLDIV2XO) 5022 tempah |= 0x40; 5023 } 5024 5025 if ((pVBInfo->LCDResInfo == Panel_1280x1024) 5026 || (pVBInfo->LCDResInfo == Panel_1280x1024x75)) 5027 tempah |= 0x80; 5028 5029 if (pVBInfo->LCDResInfo == Panel_1280x960) 5030 tempah |= 0x80; 5031 5032 xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah); 5033 } 5034 5035 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 5036 | VB_SIS302LV | VB_XGI301C)) { 5037 tempah = 0; 5038 tempbl = 0xfb; 5039 5040 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { 5041 tempbl = 0xff; 5042 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) 5043 tempah |= 0x04; /* shampoo 0129 */ 5044 } 5045 5046 xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah); 5047 tempah = 0x00; 5048 tempbl = 0xcf; 5049 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { 5050 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) 5051 tempah |= 0x30; 5052 } 5053 5054 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah); 5055 tempah = 0; 5056 tempbl = 0x3f; 5057 5058 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { 5059 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) 5060 tempah |= 0xc0; 5061 } 5062 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah); 5063 } 5064 5065 tempah = 0; 5066 tempbl = 0x7f; 5067 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) { 5068 tempbl = 0xff; 5069 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) 5070 tempah |= 0x80; 5071 } 5072 5073 xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah); 5074 5075 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { 5076 if (pVBInfo->LCDInfo & SetLCDDualLink) { 5077 xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20); 5078 xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10); 5079 } 5080 } 5081} 5082 5083 5084void XGI_UnLockCRT2(struct vb_device_info *pVBInfo) 5085{ 5086 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01); 5087} 5088 5089void XGI_LockCRT2(struct vb_device_info *pVBInfo) 5090{ 5091 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00); 5092} 5093 5094unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, 5095 unsigned short ModeNo, unsigned short ModeIdIndex, 5096 struct vb_device_info *pVBInfo) 5097{ 5098 const u8 LCDARefreshIndex[] = { 5099 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00 }; 5100 5101 unsigned short RefreshRateTableIndex, i, index, temp; 5102 5103 index = xgifb_reg_get(pVBInfo->P3d4, 0x33); 5104 index >>= pVBInfo->SelectCRT2Rate; 5105 index &= 0x0F; 5106 5107 if (pVBInfo->LCDInfo & LCDNonExpanding) 5108 index = 0; 5109 5110 if (index > 0) 5111 index--; 5112 5113 if (pVBInfo->SetFlag & ProgrammingCRT2) { 5114 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { 5115 temp = LCDARefreshIndex[pVBInfo->LCDResInfo & 0x07]; 5116 5117 if (index > temp) 5118 index = temp; 5119 } 5120 } 5121 5122 RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex; 5123 ModeNo = XGI330_RefIndex[RefreshRateTableIndex].ModeID; 5124 if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */ 5125 if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 800) && 5126 (XGI330_RefIndex[RefreshRateTableIndex].YRes == 600)) { 5127 index++; 5128 } 5129 /* do the similar adjustment like XGISearchCRT1Rate() */ 5130 if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1024) && 5131 (XGI330_RefIndex[RefreshRateTableIndex].YRes == 768)) { 5132 index++; 5133 } 5134 if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1280) && 5135 (XGI330_RefIndex[RefreshRateTableIndex].YRes == 1024)) { 5136 index++; 5137 } 5138 } 5139 5140 i = 0; 5141 do { 5142 if (XGI330_RefIndex[RefreshRateTableIndex + i]. 5143 ModeID != ModeNo) 5144 break; 5145 temp = XGI330_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag; 5146 temp &= ModeTypeMask; 5147 if (temp < pVBInfo->ModeType) 5148 break; 5149 i++; 5150 index--; 5151 5152 } while (index != 0xFFFF); 5153 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { 5154 if (pVBInfo->VBInfo & SetInSlaveMode) { 5155 temp = XGI330_RefIndex[RefreshRateTableIndex + i - 1]. 5156 Ext_InfoFlag; 5157 if (temp & InterlaceMode) 5158 i++; 5159 } 5160 } 5161 i--; 5162 if ((pVBInfo->SetFlag & ProgrammingCRT2)) { 5163 temp = XGI_AjustCRT2Rate(ModeIdIndex, RefreshRateTableIndex, 5164 &i, pVBInfo); 5165 } 5166 return RefreshRateTableIndex + i; 5167} 5168 5169static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, 5170 struct xgi_hw_device_info *HwDeviceExtension, 5171 struct vb_device_info *pVBInfo) 5172{ 5173 unsigned short RefreshRateTableIndex; 5174 5175 pVBInfo->SetFlag |= ProgrammingCRT2; 5176 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, 5177 ModeIdIndex, pVBInfo); 5178 XGI_GetLVDSResInfo(ModeIdIndex, pVBInfo); 5179 XGI_GetLVDSData(ModeIdIndex, pVBInfo); 5180 XGI_ModCRT1Regs(ModeIdIndex, HwDeviceExtension, pVBInfo); 5181 XGI_SetLVDSRegs(ModeIdIndex, pVBInfo); 5182 XGI_SetCRT2ECLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo); 5183} 5184 5185static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo, 5186 struct xgi_hw_device_info *HwDeviceExtension, 5187 struct vb_device_info *pVBInfo) 5188{ 5189 unsigned short ModeIdIndex, RefreshRateTableIndex; 5190 5191 pVBInfo->SetFlag |= ProgrammingCRT2; 5192 XGI_SearchModeID(ModeNo, &ModeIdIndex); 5193 pVBInfo->SelectCRT2Rate = 4; 5194 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, 5195 ModeIdIndex, pVBInfo); 5196 XGI_SaveCRT2Info(ModeNo, pVBInfo); 5197 XGI_GetCRT2ResInfo(ModeIdIndex, pVBInfo); 5198 XGI_GetCRT2Data(ModeIdIndex, RefreshRateTableIndex, pVBInfo); 5199 XGI_PreSetGroup1(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); 5200 XGI_SetGroup1(ModeIdIndex, RefreshRateTableIndex, pVBInfo); 5201 XGI_SetLockRegs(ModeNo, ModeIdIndex, pVBInfo); 5202 XGI_SetGroup2(ModeNo, ModeIdIndex, pVBInfo); 5203 XGI_SetLCDRegs(ModeIdIndex, pVBInfo); 5204 XGI_SetTap4Regs(pVBInfo); 5205 XGI_SetGroup3(ModeIdIndex, pVBInfo); 5206 XGI_SetGroup4(ModeIdIndex, RefreshRateTableIndex, pVBInfo); 5207 XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo); 5208 XGI_SetGroup5(pVBInfo); 5209 XGI_AutoThreshold(pVBInfo); 5210 return 1; 5211} 5212 5213void XGI_SenseCRT1(struct vb_device_info *pVBInfo) 5214{ 5215 unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 5216 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00, 5217 0x05, 0x00 }; 5218 5219 unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0; 5220 5221 unsigned char CR17, CR63, SR31; 5222 unsigned short temp; 5223 5224 int i; 5225 5226 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); 5227 5228 /* to fix XG42 single LCD sense to CRT+LCD */ 5229 xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A); 5230 xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get( 5231 pVBInfo->P3d4, 0x53) | 0x02)); 5232 5233 SR31 = xgifb_reg_get(pVBInfo->P3c4, 0x31); 5234 CR63 = xgifb_reg_get(pVBInfo->P3d4, 0x63); 5235 SR01 = xgifb_reg_get(pVBInfo->P3c4, 0x01); 5236 5237 xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF)); 5238 xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF)); 5239 5240 CR17 = xgifb_reg_get(pVBInfo->P3d4, 0x17); 5241 xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80)); 5242 5243 SR1F = xgifb_reg_get(pVBInfo->P3c4, 0x1F); 5244 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04)); 5245 5246 SR07 = xgifb_reg_get(pVBInfo->P3c4, 0x07); 5247 xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB)); 5248 SR06 = xgifb_reg_get(pVBInfo->P3c4, 0x06); 5249 xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3)); 5250 5251 xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00); 5252 5253 for (i = 0; i < 8; i++) 5254 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]); 5255 5256 for (i = 8; i < 11; i++) 5257 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 8), 5258 CRTCData[i]); 5259 5260 for (i = 11; i < 13; i++) 5261 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 4), 5262 CRTCData[i]); 5263 5264 for (i = 13; i < 16; i++) 5265 xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i - 3), 5266 CRTCData[i]); 5267 5268 xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16] 5269 & 0xE0)); 5270 5271 xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00); 5272 xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B); 5273 xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1); 5274 5275 outb(0x00, pVBInfo->P3c8); 5276 5277 for (i = 0; i < 256 * 3; i++) 5278 outb(0x0F, (pVBInfo->P3c8 + 1)); /* DAC_TEST_PARMS */ 5279 5280 mdelay(1); 5281 5282 XGI_WaitDisply(pVBInfo); 5283 temp = inb(pVBInfo->P3c2); 5284 5285 if (temp & 0x10) 5286 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20); 5287 else 5288 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00); 5289 5290 /* avoid display something, set BLACK DAC if not restore DAC */ 5291 outb(0x00, pVBInfo->P3c8); 5292 5293 for (i = 0; i < 256 * 3; i++) 5294 outb(0, (pVBInfo->P3c8 + 1)); 5295 5296 xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01); 5297 xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63); 5298 xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31); 5299 5300 xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get( 5301 pVBInfo->P3d4, 0x53) & 0xFD)); 5302 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F); 5303} 5304 5305static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info, 5306 struct xgi_hw_device_info *HwDeviceExtension, 5307 struct vb_device_info *pVBInfo) 5308{ 5309 unsigned short tempah; 5310 5311 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 5312 | VB_SIS302LV | VB_XGI301C)) { 5313 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) 5314 /* Power on */ 5315 xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20); 5316 5317 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV | 5318 SetCRT2ToRAMDAC)) { 5319 tempah = xgifb_reg_get(pVBInfo->P3c4, 0x32); 5320 tempah &= 0xDF; 5321 if (pVBInfo->VBInfo & SetInSlaveMode) { 5322 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) 5323 tempah |= 0x20; 5324 } 5325 xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah); 5326 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20); 5327 5328 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E); 5329 5330 if (!(tempah & 0x80)) 5331 xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); 5332 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F); 5333 } 5334 5335 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { 5336 xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0, 5337 0x20); /* shampoo 0129 */ 5338 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { 5339 if (pVBInfo->VBInfo & 5340 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) 5341 /* LVDS PLL power on */ 5342 xgifb_reg_and(pVBInfo->Part4Port, 0x2A, 5343 0x7F); 5344 /* LVDS Driver power on */ 5345 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F); 5346 } 5347 } 5348 5349 tempah = 0x00; 5350 5351 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { 5352 tempah = 0xc0; 5353 5354 if (!(pVBInfo->VBInfo & SetSimuScanMode) && 5355 (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && 5356 (pVBInfo->VBInfo & SetCRT2ToDualEdge)) { 5357 tempah = tempah & 0x40; 5358 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) 5359 tempah = tempah ^ 0xC0; 5360 } 5361 } 5362 5363 /* EnablePart4_1F */ 5364 xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah); 5365 5366 XGI_DisableGatingCRT(pVBInfo); 5367 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo); 5368 } /* 301 */ 5369 else { /* LVDS */ 5370 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD 5371 | XGI_SetCRT2ToLCDA)) 5372 /* enable CRT2 */ 5373 xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20); 5374 5375 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E); 5376 if (!(tempah & 0x80)) 5377 xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); 5378 5379 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F); 5380 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo); 5381 } /* End of VB */ 5382} 5383 5384static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, 5385 struct xgi_hw_device_info *HwDeviceExtension, 5386 unsigned short ModeNo, unsigned short ModeIdIndex, 5387 struct vb_device_info *pVBInfo) 5388{ 5389 unsigned short RefreshRateTableIndex, temp; 5390 5391 XGI_SetSeqRegs(pVBInfo); 5392 outb(XGI330_StandTable.MISC, pVBInfo->P3c2); 5393 XGI_SetCRTCRegs(pVBInfo); 5394 XGI_SetATTRegs(ModeIdIndex, pVBInfo); 5395 XGI_SetGRCRegs(pVBInfo); 5396 XGI_ClearExt1Regs(pVBInfo); 5397 5398 if (HwDeviceExtension->jChipType == XG27) { 5399 if (pVBInfo->IF_DEF_LVDS == 0) 5400 XGI_SetDefaultVCLK(pVBInfo); 5401 } 5402 5403 temp = ~ProgrammingCRT2; 5404 pVBInfo->SetFlag &= temp; 5405 pVBInfo->SelectCRT2Rate = 0; 5406 5407 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV 5408 | VB_SIS302LV | VB_XGI301C)) { 5409 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA 5410 | SetInSlaveMode)) { 5411 pVBInfo->SetFlag |= ProgrammingCRT2; 5412 } 5413 } 5414 5415 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, 5416 ModeIdIndex, pVBInfo); 5417 if (RefreshRateTableIndex != 0xFFFF) { 5418 XGI_SetSync(RefreshRateTableIndex, pVBInfo); 5419 XGI_SetCRT1CRTC(ModeIdIndex, RefreshRateTableIndex, 5420 pVBInfo, HwDeviceExtension); 5421 XGI_SetCRT1DE(ModeIdIndex, RefreshRateTableIndex, pVBInfo); 5422 XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, 5423 HwDeviceExtension, pVBInfo); 5424 XGI_SetCRT1VCLK(ModeIdIndex, HwDeviceExtension, 5425 RefreshRateTableIndex, pVBInfo); 5426 } 5427 5428 if (HwDeviceExtension->jChipType >= XG21) { 5429 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); 5430 if (temp & 0xA0) { 5431 5432 if (HwDeviceExtension->jChipType == XG27) 5433 XGI_SetXG27CRTC(RefreshRateTableIndex, pVBInfo); 5434 else 5435 XGI_SetXG21CRTC(RefreshRateTableIndex, pVBInfo); 5436 5437 XGI_UpdateXG21CRTC(ModeNo, pVBInfo, 5438 RefreshRateTableIndex); 5439 5440 xgifb_set_lcd(HwDeviceExtension->jChipType, 5441 pVBInfo, RefreshRateTableIndex); 5442 5443 if (pVBInfo->IF_DEF_LVDS == 1) 5444 xgifb_set_lvds(xgifb_info, 5445 HwDeviceExtension->jChipType, 5446 ModeIdIndex, pVBInfo); 5447 } 5448 } 5449 5450 pVBInfo->SetFlag &= (~ProgrammingCRT2); 5451 XGI_SetCRT1FIFO(HwDeviceExtension, pVBInfo); 5452 XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeIdIndex, 5453 RefreshRateTableIndex, pVBInfo); 5454 XGI_LoadDAC(pVBInfo); 5455} 5456 5457unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, 5458 struct xgi_hw_device_info *HwDeviceExtension, 5459 unsigned short ModeNo) 5460{ 5461 unsigned short ModeIdIndex; 5462 struct vb_device_info VBINF; 5463 struct vb_device_info *pVBInfo = &VBINF; 5464 5465 pVBInfo->IF_DEF_LVDS = 0; 5466 5467 if (HwDeviceExtension->jChipType >= XG20) 5468 pVBInfo->VBType = 0; /*set VBType default 0*/ 5469 5470 XGIRegInit(pVBInfo, xgifb_info->vga_base); 5471 5472 /* for x86 Linux, XG21 LVDS */ 5473 if (HwDeviceExtension->jChipType == XG21) { 5474 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) 5475 pVBInfo->IF_DEF_LVDS = 1; 5476 } 5477 if (HwDeviceExtension->jChipType == XG27) { 5478 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) { 5479 if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20) 5480 pVBInfo->IF_DEF_LVDS = 1; 5481 } 5482 } 5483 5484 InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); 5485 if (ModeNo & 0x80) 5486 ModeNo = ModeNo & 0x7F; 5487 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); 5488 5489 if (HwDeviceExtension->jChipType < XG20) 5490 XGI_UnLockCRT2(pVBInfo); 5491 5492 XGI_SearchModeID(ModeNo, &ModeIdIndex); 5493 5494 if (HwDeviceExtension->jChipType < XG20) { 5495 XGI_GetVBInfo(ModeIdIndex, pVBInfo); 5496 XGI_GetTVInfo(ModeIdIndex, pVBInfo); 5497 XGI_GetLCDInfo(ModeIdIndex, pVBInfo); 5498 XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo); 5499 5500 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA) || 5501 (!(pVBInfo->VBInfo & SwitchCRT2))) { 5502 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo, 5503 ModeIdIndex, pVBInfo); 5504 5505 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { 5506 XGI_SetLCDAGroup(ModeNo, ModeIdIndex, 5507 HwDeviceExtension, pVBInfo); 5508 } 5509 } 5510 5511 if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) { 5512 switch (HwDeviceExtension->ujVBChipID) { 5513 case VB_CHIP_301: /* fall through */ 5514 case VB_CHIP_302: 5515 XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, 5516 pVBInfo); /*add for CRT2 */ 5517 break; 5518 5519 default: 5520 break; 5521 } 5522 } 5523 5524 XGI_SetCRT2ModeRegs(pVBInfo); 5525 XGI_OEM310Setting(ModeIdIndex, pVBInfo); /*0212*/ 5526 XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo); 5527 } /* !XG20 */ 5528 else { 5529 if (pVBInfo->IF_DEF_LVDS == 1) 5530 if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo, 5531 ModeIdIndex)) 5532 return 0; 5533 5534 pVBInfo->ModeType = XGI330_EModeIDTable[ModeIdIndex]. 5535 Ext_ModeFlag & ModeTypeMask; 5536 5537 pVBInfo->SetFlag = 0; 5538 pVBInfo->VBInfo = DisableCRT2Display; 5539 5540 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); 5541 5542 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo, 5543 ModeIdIndex, pVBInfo); 5544 5545 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo); 5546 } 5547 5548 XGI_UpdateModeInfo(pVBInfo); 5549 5550 if (HwDeviceExtension->jChipType < XG20) 5551 XGI_LockCRT2(pVBInfo); 5552 5553 return 1; 5554} 5555