1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/delay.h>
9 #include "vb_setmode.h"
11 #define IndexMask 0xff
12 #define TVCLKBASE_315_25 (TVCLKBASE_315 + 25)
14 static const unsigned short XGINew_VGA_DAC[] = {
15 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
16 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
17 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
18 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
19 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
20 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
21 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
22 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
23 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
24 0x0B, 0x0C, 0x0D, 0x0F, 0x10};
26 void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
28 pVBInfo->MCLKData = XGI340New_MCLKData;
30 pVBInfo->LCDResInfo = 0;
31 pVBInfo->LCDTypeInfo = 0;
36 pVBInfo->SR18 = XGI340_SR18;
37 pVBInfo->CR40 = XGI340_cr41;
40 XGI_GetVBType(pVBInfo);
42 /* 310 customization related */
43 if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
44 pVBInfo->LCDCapList = XGI_LCDDLCapList;
46 pVBInfo->LCDCapList = XGI_LCDCapList;
49 pVBInfo->XGINew_CR97 = 0x10;
51 if (ChipType == XG27) {
54 pVBInfo->MCLKData = XGI27New_MCLKData;
55 pVBInfo->CR40 = XGI27_cr41;
56 pVBInfo->XGINew_CR97 = 0xc1;
57 pVBInfo->SR18 = XG27_SR18;
60 temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
61 /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
62 if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
63 pVBInfo->XGINew_CR97 = 0x80;
67 static void XGI_SetSeqRegs(struct vb_device_info *pVBInfo)
69 unsigned char SRdata, i;
71 xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
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];
78 xgifb_reg_set(pVBInfo->P3c4, i + 1, SRdata);
82 static void XGI_SetCRTCRegs(struct vb_device_info *pVBInfo)
84 unsigned char CRTCdata;
87 CRTCdata = xgifb_reg_get(pVBInfo->P3d4, 0x11);
89 xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
91 for (i = 0; i <= 0x18; i++) {
92 /* Get CRTC from file */
93 CRTCdata = XGI330_StandTable.CRTC[i];
94 xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
98 static void XGI_SetATTRegs(unsigned short ModeIdIndex,
99 struct vb_device_info *pVBInfo)
101 unsigned char ARdata;
102 unsigned short i, modeflag;
104 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
106 for (i = 0; i <= 0x13; i++) {
107 ARdata = XGI330_StandTable.ATTR[i];
109 if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */
110 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
112 } else if ((pVBInfo->VBInfo &
113 (SetCRT2ToTV | SetCRT2ToLCD)) &&
114 (pVBInfo->VBInfo & SetInSlaveMode)) {
119 inb(pVBInfo->P3da); /* reset 3da */
120 outb(i, pVBInfo->P3c0); /* set index */
121 outb(ARdata, pVBInfo->P3c0); /* set data */
124 inb(pVBInfo->P3da); /* reset 3da */
125 outb(0x14, pVBInfo->P3c0); /* set index */
126 outb(0x00, pVBInfo->P3c0); /* set data */
127 inb(pVBInfo->P3da); /* Enable Attribute */
128 outb(0x20, pVBInfo->P3c0);
131 static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo)
133 unsigned char GRdata;
136 for (i = 0; i <= 0x08; i++) {
137 /* Get GR from file */
138 GRdata = XGI330_StandTable.GRC[i];
139 xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
142 if (pVBInfo->ModeType > ModeVGA) {
143 GRdata = xgifb_reg_get(pVBInfo->P3ce, 0x05);
144 GRdata &= 0xBF; /* 256 color disable */
145 xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata);
149 static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
153 for (i = 0x0A; i <= 0x0E; i++)
154 xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
157 static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
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);
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);
167 xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30);
171 static unsigned char XGI_AjustCRT2Rate(unsigned short ModeIdIndex,
172 unsigned short RefreshRateTableIndex,
174 struct vb_device_info *pVBInfo)
176 unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
178 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
179 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
180 tempbx = XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
183 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
184 tempax |= SupportRAMDAC2;
186 if (pVBInfo->VBType & VB_XGI301C)
187 tempax |= SupportCRT2in301C;
191 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
192 tempax |= SupportLCD;
194 if (pVBInfo->LCDResInfo != Panel_1280x1024 &&
195 pVBInfo->LCDResInfo != Panel_1280x960 &&
196 (pVBInfo->LCDInfo & LCDNonExpanding) &&
201 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */
202 tempax |= SupportHiVision;
203 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
205 (resinfo == 3 && (pVBInfo->SetFlag & TVSimuMode)) ||
208 } else if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO |
209 SetCRT2ToSCART | SetCRT2ToYPbPr525750 |
210 SetCRT2ToHiVision)) {
213 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV |
214 VB_SIS302LV | VB_XGI301C))
215 tempax |= SupportTV1024;
217 if (!(pVBInfo->VBInfo & TVSetPAL) &&
218 (modeflag & NoSupportSimuTV) &&
219 (pVBInfo->VBInfo & SetInSlaveMode) &&
220 !(pVBInfo->VBInfo & SetNotSimuMode))
224 for (; XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
226 infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
227 if (infoflag & tempax)
234 for ((*i) = 0;; (*i)++) {
235 infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
236 if (XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID
241 if (infoflag & tempax)
247 static void XGI_SetSync(unsigned short RefreshRateTableIndex,
248 struct vb_device_info *pVBInfo)
250 unsigned short sync, temp;
253 sync = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
257 outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */
260 static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
261 struct xgi_hw_device_info *HwDeviceExtension)
263 unsigned char data, data1, pushax;
267 data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
269 xgifb_reg_set(pVBInfo->P3d4, 0x11, data);
271 data = pVBInfo->TimingH.data[0];
272 xgifb_reg_set(pVBInfo->P3d4, 0, data);
274 for (i = 0x01; i <= 0x04; i++) {
275 data = pVBInfo->TimingH.data[i];
276 xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 1), data);
279 for (i = 0x05; i <= 0x06; i++) {
280 data = pVBInfo->TimingH.data[i];
281 xgifb_reg_set(pVBInfo->P3c4, (unsigned short)(i + 6), data);
284 j = xgifb_reg_get(pVBInfo->P3c4, 0x0e);
286 data = pVBInfo->TimingH.data[7];
289 xgifb_reg_set(pVBInfo->P3c4, 0x0e, data);
291 if (HwDeviceExtension->jChipType >= XG20) {
292 data = xgifb_reg_get(pVBInfo->P3d4, 0x04);
294 xgifb_reg_set(pVBInfo->P3d4, 0x04, data);
295 data = xgifb_reg_get(pVBInfo->P3d4, 0x05);
301 data = xgifb_reg_get(pVBInfo->P3c4, 0x0c);
303 xgifb_reg_set(pVBInfo->P3c4, 0x0c, data);
308 xgifb_reg_set(pVBInfo->P3d4, 0x05, data);
309 data = xgifb_reg_get(pVBInfo->P3c4, 0x0e);
315 xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data);
319 static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
320 struct vb_device_info *pVBInfo)
325 for (i = 0x00; i <= 0x01; i++) {
326 data = pVBInfo->TimingV.data[i];
327 xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 6), data);
330 for (i = 0x02; i <= 0x03; i++) {
331 data = pVBInfo->TimingV.data[i];
332 xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 0x0e), data);
335 for (i = 0x04; i <= 0x05; i++) {
336 data = pVBInfo->TimingV.data[i];
337 xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 0x11), data);
340 j = xgifb_reg_get(pVBInfo->P3c4, 0x0a);
342 data = pVBInfo->TimingV.data[6];
345 xgifb_reg_set(pVBInfo->P3c4, 0x0a, data);
347 data = pVBInfo->TimingV.data[6];
351 i = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
356 j = xgifb_reg_get(pVBInfo->P3d4, 0x09);
359 xgifb_reg_set(pVBInfo->P3d4, 0x09, data);
362 static void XGI_SetCRT1CRTC(unsigned short ModeIdIndex,
363 unsigned short RefreshRateTableIndex,
364 struct vb_device_info *pVBInfo,
365 struct xgi_hw_device_info *HwDeviceExtension)
367 unsigned char index, data;
371 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
372 index = index & IndexMask;
374 data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
376 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
378 for (i = 0; i < 8; i++)
379 pVBInfo->TimingH.data[i]
380 = XGI_CRT1Table[index].CR[i];
382 for (i = 0; i < 7; i++)
383 pVBInfo->TimingV.data[i]
384 = XGI_CRT1Table[index].CR[i + 8];
386 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
388 XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo);
390 if (pVBInfo->ModeType > 0x03)
391 xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F);
395 * Function : XGI_SetXG21CRTC
396 * Input : Stand or enhance CRTC table
397 * Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F
398 * Description : Set LCD timing
400 static void XGI_SetXG21CRTC(unsigned short RefreshRateTableIndex,
401 struct vb_device_info *pVBInfo)
403 unsigned char index, Tempax, Tempbx, Tempcx, Tempdx;
404 unsigned short Temp1, Temp2, Temp3;
406 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
407 /* Tempax: CR4 HRS */
408 Tempax = XGI_CRT1Table[index].CR[3];
409 Tempcx = Tempax; /* Tempcx: HRS */
411 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
413 Tempdx = XGI_CRT1Table[index].CR[5]; /* SRB */
414 Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
415 Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
416 Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
417 Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
419 Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
420 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
422 Tempbx = XGI_CRT1Table[index].CR[6]; /* SRC */
423 Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
424 Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
425 Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
427 Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
428 Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
430 Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
431 if (Tempax < Tempcx) /* HRE < HRS */
432 Temp2 |= 0x40; /* Temp2 + 0x40 */
435 Tempax = (unsigned char)Temp2; /* Tempax: HRE[7:0] */
436 Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
437 Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
438 Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
439 /* SR2F D[7:2]->HRE, D[1:0]->HRS */
440 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
441 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
444 Tempax = XGI_CRT1Table[index].CR[10];
445 Tempbx = Tempax; /* Tempbx: VRS */
446 Tempax &= 0x01; /* Tempax[0]: VRS[0] */
447 xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
449 Tempax = XGI_CRT1Table[index].CR[9];
450 Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
451 Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
452 Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
453 Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
454 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
456 Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
457 Temp1 <<= 1; /* Temp1[8]: VRS[8] */
458 Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
460 Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
461 Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
463 Tempax = XGI_CRT1Table[index].CR[14];
464 Tempax &= 0x08; /* Tempax[3]: VRS[3] */
466 Temp2 <<= 7; /* Temp2[10]: VRS[10] */
467 Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
469 /* Tempax: CR11 VRE */
470 Tempax = XGI_CRT1Table[index].CR[11];
471 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
473 Tempbx = XGI_CRT1Table[index].CR[14];
474 Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
475 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
476 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
477 Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
478 Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
480 Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
481 if (Tempax < Temp3) /* VRE < VRS */
482 Temp2 |= 0x20; /* VRE + 0x20 */
485 Tempax = (unsigned char)Temp2; /* Tempax: VRE[7:0] */
486 Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
487 Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
488 Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
489 Tempbx = (unsigned char)Temp1;
490 Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
492 /* SR3F D[7:2]->VRE D[1:0]->VRS */
493 xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
496 static void XGI_SetXG27CRTC(unsigned short RefreshRateTableIndex,
497 struct vb_device_info *pVBInfo)
499 unsigned short index, Tempax, Tempbx, Tempcx;
501 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
502 /* Tempax: CR4 HRS */
503 Tempax = XGI_CRT1Table[index].CR[3];
504 Tempbx = Tempax; /* Tempbx: HRS[7:0] */
506 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
509 Tempax = XGI_CRT1Table[index].CR[5];
510 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8] */
511 Tempbx |= Tempax << 2; /* Tempbx: HRS[9:0] */
513 Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
514 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
515 Tempcx = Tempax; /* Tempcx: HRE[4:0] */
517 Tempax = XGI_CRT1Table[index].CR[6]; /* SRC */
518 Tempax &= 0x04; /* Tempax[2]: HRE[5] */
519 Tempax <<= 3; /* Tempax[5]: HRE[5] */
520 Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
522 Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
523 Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
525 /* Tempax: CR4 HRS */
526 Tempax = XGI_CRT1Table[index].CR[3];
527 Tempax &= 0x3F; /* Tempax: HRS[5:0] */
528 if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
529 Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
531 Tempax = XGI_CRT1Table[index].CR[5]; /* SR0B */
532 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
533 Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
534 Tempax |= (Tempbx << 2) & 0xFF; /* Tempax[7:2]: HRE[5:0] */
535 /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
536 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
537 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
540 Tempax = XGI_CRT1Table[index].CR[10];
541 /* SR34[7:0]->VRS[7:0] */
542 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax);
544 Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
545 /* CR7[7][2] VRS[9][8] */
546 Tempax = XGI_CRT1Table[index].CR[9];
547 Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
548 Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
549 Tempax >>= 2; /* Tempax[0]: VRS[8] */
550 /* SR35[0]: VRS[8] */
551 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
552 Tempcx |= Tempax << 8; /* Tempcx <= VRS[8:0] */
553 Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx <= VRS[9:0] */
555 Tempax = XGI_CRT1Table[index].CR[14];
556 Tempax &= 0x08; /* SR0A[3] VRS[10] */
557 Tempcx |= Tempax << 7; /* Tempcx <= VRS[10:0] */
559 /* Tempax: CR11 VRE */
560 Tempax = XGI_CRT1Table[index].CR[11];
561 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
563 Tempbx = XGI_CRT1Table[index].CR[14];
564 Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
565 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
566 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
567 Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
568 Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
569 Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
571 if (Tempbx <= Tempcx) /* VRE <= VRS */
572 Tempbx |= 0x20; /* VRE + 0x20 */
574 /* Tempax: Tempax[7:0]; VRE[5:0]00 */
575 Tempax = (Tempbx << 2) & 0xFF;
576 /* SR3F[7:2]:VRE[5:0] */
577 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
578 Tempax = Tempcx >> 8;
579 /* SR35[2:0]:VRS[10:8] */
580 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax);
583 static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
587 /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
588 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
589 temp = (temp & 3) << 6;
590 /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
591 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80);
592 /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
593 xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
596 static void xgifb_set_lcd(int chip_id,
597 struct vb_device_info *pVBInfo,
598 unsigned short RefreshRateTableIndex)
602 xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00);
603 xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00);
604 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00);
605 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00);
607 if (chip_id == XG27) {
608 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
609 if ((temp & 0x03) == 0) { /* dual 12 */
610 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13);
611 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13);
615 if (chip_id == XG27) {
616 XGI_SetXG27FPBits(pVBInfo);
618 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
621 xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40);
622 xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40);
626 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
628 xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
629 xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
631 temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
634 xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
638 xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
643 * Function : XGI_UpdateXG21CRTC
646 * Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing
648 static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
649 struct vb_device_info *pVBInfo,
650 unsigned short RefreshRateTableIndex)
654 xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
655 if (ModeNo == 0x2E &&
656 (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
659 else if (ModeNo == 0x2E && (XGI330_RefIndex[RefreshRateTableIndex].
660 Ext_CRT1CRTC == RES640x480x72))
662 else if (ModeNo == 0x2F)
664 else if (ModeNo == 0x50)
666 else if (ModeNo == 0x59)
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);
681 static void XGI_SetCRT1DE(unsigned short ModeIdIndex,
682 unsigned short RefreshRateTableIndex,
683 struct vb_device_info *pVBInfo)
685 unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
689 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
691 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
692 tempax = XGI330_ModeResInfo[resindex].HTotal;
693 tempbx = XGI330_ModeResInfo[resindex].VTotal;
695 if (modeflag & HalfDCLK)
698 if (modeflag & HalfDCLK)
701 temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
703 if (temp & InterlaceMode)
706 if (modeflag & DoubleScanMode)
715 temp = xgifb_reg_get(pVBInfo->P3d4, 0x11);
716 data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
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));
732 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax);
733 data = xgifb_reg_get(pVBInfo->P3d4, 0x07);
739 xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
740 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp);
743 static 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)
749 unsigned short temp, ah, al, temp2, i, DisplayUnit;
752 temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
754 temp = XGI330_ScreenOffset[temp];
756 temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
757 temp2 &= InterlaceMode;
762 temp2 = pVBInfo->ModeType - ModeEGA;
787 if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
788 temp = temp * temp2 + temp2 / 2;
797 i = xgifb_reg_get(pVBInfo->P3c4, 0x0E);
800 xgifb_reg_set(pVBInfo->P3c4, 0x0E, i);
802 temp = (unsigned char)temp2;
803 temp &= 0xFF; /* al */
804 xgifb_reg_set(pVBInfo->P3d4, 0x13, temp);
807 temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
808 temp2 &= InterlaceMode;
813 ah = (DisplayUnit & 0xff00) >> 8;
814 al = DisplayUnit & 0x00ff;
820 if (HwDeviceExtension->jChipType >= XG20)
821 if ((ModeNo == 0x4A) | (ModeNo == 0x49))
824 xgifb_reg_set(pVBInfo->P3c4, 0x10, ah);
827 static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeIdIndex,
828 unsigned short RefreshRateTableIndex,
829 struct vb_device_info *pVBInfo)
831 unsigned short VCLKIndex, modeflag;
834 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
836 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /* 301b */
837 if (pVBInfo->LCDResInfo != Panel_1024x768)
839 VCLKIndex = VCLK108_2_315 + 5;
841 VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */
842 } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
843 if (pVBInfo->SetFlag & RPLLDIV2XO)
844 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2;
846 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK;
848 if (pVBInfo->SetFlag & TVSimuMode) {
849 if (modeflag & Charx8Dot)
850 VCLKIndex = TVCLKBASE_315_25 + HiTVSimuVCLK;
852 VCLKIndex = TVCLKBASE_315_25 + HiTVTextVCLK;
856 if (pVBInfo->VBType & VB_SIS301LV) {
857 if (pVBInfo->SetFlag & RPLLDIV2XO)
858 VCLKIndex = YPbPr525iVCLK_2;
860 VCLKIndex = YPbPr525iVCLK;
862 } else if (pVBInfo->VBInfo & SetCRT2ToTV) {
863 if (pVBInfo->SetFlag & RPLLDIV2XO)
864 VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2;
866 VCLKIndex = TVCLKBASE_315_25 + TVVCLK;
867 } else { /* for CRT2 */
869 VCLKIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
870 VCLKIndex &= IndexMask;
876 static void XGI_SetCRT1VCLK(unsigned short ModeIdIndex,
877 struct xgi_hw_device_info *HwDeviceExtension,
878 unsigned short RefreshRateTableIndex,
879 struct vb_device_info *pVBInfo)
881 unsigned char index, data;
882 unsigned short vclkindex;
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,
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);
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);
906 if (HwDeviceExtension->jChipType >= XG20) {
907 if (XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag &
909 data = xgifb_reg_get(pVBInfo->P3c4, 0x2B);
910 xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
911 data = xgifb_reg_get(pVBInfo->P3c4, 0x2C);
918 xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
923 static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
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);
935 static void XGI_SetCRT1FIFO(struct xgi_hw_device_info *HwDeviceExtension,
936 struct vb_device_info *pVBInfo)
940 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
942 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* disable auto-threshold */
944 xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34);
945 data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
947 xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30);
948 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
950 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data);
952 if (HwDeviceExtension->jChipType == XG21)
953 XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
956 static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
957 unsigned short RefreshRateTableIndex,
958 struct vb_device_info *pVBInfo)
960 unsigned short data, data2 = 0;
965 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
967 VCLK = XGI_VCLKData[index].CLOCK;
969 data = xgifb_reg_get(pVBInfo->P3c4, 0x32);
972 data |= 0x0c; /* VCLK > 200 */
974 if (HwDeviceExtension->jChipType >= XG20)
975 data &= ~0x04; /* 2 pixel mode */
977 xgifb_reg_set(pVBInfo->P3c4, 0x32, data);
979 if (HwDeviceExtension->jChipType < XG20) {
980 data = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
984 xgifb_reg_set(pVBInfo->P3c4, 0x1F, data);
989 xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2);
990 if (HwDeviceExtension->jChipType >= XG27)
991 xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
994 static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
995 unsigned short ModeIdIndex,
996 unsigned short RefreshRateTableIndex,
997 struct vb_device_info *pVBInfo)
999 unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
1002 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1003 infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1005 if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01)
1006 xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
1011 data3 = pVBInfo->ModeType - ModeVGA;
1014 data &= InterlaceMode;
1019 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2);
1020 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1021 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
1024 if (infoflag & InterlaceMode) {
1027 else if (xres == 1280)
1031 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data);
1032 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, 0);
1034 if (modeflag & HalfDCLK)
1035 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08);
1039 if (modeflag & LineCompareOff)
1042 xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2);
1046 xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data);
1048 XGI_SetVCLKState(HwDeviceExtension, RefreshRateTableIndex, pVBInfo);
1050 data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
1052 if (HwDeviceExtension->jChipType == XG27) {
1057 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1058 xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10);
1059 } else if (HwDeviceExtension->jChipType >= XG20) {
1064 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1065 xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02);
1071 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1075 static void XGI_WriteDAC(unsigned short dl,
1079 struct vb_device_info *pVBInfo)
1081 unsigned short bh, bl;
1093 outb((unsigned short)dh, pVBInfo->P3c9);
1094 outb((unsigned short)bh, pVBInfo->P3c9);
1095 outb((unsigned short)bl, pVBInfo->P3c9);
1098 static void XGI_LoadDAC(struct vb_device_info *pVBInfo)
1100 unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh;
1101 const unsigned short *table = XGINew_VGA_DAC;
1103 outb(0xFF, pVBInfo->P3c6);
1104 outb(0x00, pVBInfo->P3c8);
1106 for (i = 0; i < 16; i++) {
1109 for (k = 0; k < 3; k++) {
1118 outb(data2, pVBInfo->P3c9);
1123 for (i = 16; i < 32; i++) {
1126 for (k = 0; k < 3; k++)
1127 outb(data, pVBInfo->P3c9);
1132 for (m = 0; m < 9; m++) {
1137 for (n = 0; n < 3; n++) {
1138 for (o = 0; o < 5; o++) {
1143 XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1148 for (o = 0; o < 3; o++) {
1153 XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1163 static void XGI_GetLVDSResInfo(unsigned short ModeIdIndex,
1164 struct vb_device_info *pVBInfo)
1166 unsigned short resindex, xres, yres, modeflag;
1168 /* si+Ext_ResInfo */
1169 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1171 /* si+Ext_ResInfo */
1172 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1174 xres = XGI330_ModeResInfo[resindex].HTotal;
1175 yres = XGI330_ModeResInfo[resindex].VTotal;
1177 if (modeflag & HalfDCLK)
1180 if (modeflag & DoubleScanMode)
1186 pVBInfo->VGAHDE = xres;
1187 pVBInfo->HDE = xres;
1188 pVBInfo->VGAVDE = yres;
1189 pVBInfo->VDE = yres;
1192 static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table,
1193 unsigned short ModeIdIndex,
1194 struct vb_device_info *pVBInfo)
1196 unsigned short i, tempdx, tempbx, modeflag;
1200 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1204 while (table[i].PANELID != 0xff) {
1205 tempdx = pVBInfo->LCDResInfo;
1206 if (tempbx & 0x0080) { /* OEMUtil */
1208 tempdx = pVBInfo->LCDTypeInfo;
1211 if (pVBInfo->LCDInfo & EnableScalingLCD)
1212 tempdx &= ~PanelResInfo;
1214 if (table[i].PANELID == tempdx) {
1215 tempbx = table[i].MASK;
1216 tempdx = pVBInfo->LCDInfo;
1218 if (modeflag & HalfDCLK)
1219 tempdx |= SetLCDLowResolution;
1222 if (tempbx == table[i].CAP)
1228 return table[i].DATAPTR;
1231 static struct SiS_TVData const *XGI_GetTVPtr(
1232 unsigned short ModeIdIndex,
1233 unsigned short RefreshRateTableIndex,
1234 struct vb_device_info *pVBInfo)
1236 unsigned short i, tempdx, tempal, modeflag;
1238 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1239 tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1240 tempal = tempal & 0x3f;
1241 tempdx = pVBInfo->TVInfo;
1243 if (pVBInfo->VBInfo & SetInSlaveMode)
1244 tempdx = tempdx | SetTVLockMode;
1246 if (modeflag & HalfDCLK)
1247 tempdx = tempdx | SetTVLowResolution;
1251 while (XGI_TVDataTable[i].MASK != 0xffff) {
1252 if ((tempdx & XGI_TVDataTable[i].MASK) ==
1253 XGI_TVDataTable[i].CAP)
1258 return &XGI_TVDataTable[i].DATAPTR[tempal];
1261 static void XGI_GetLVDSData(unsigned short ModeIdIndex,
1262 struct vb_device_info *pVBInfo)
1264 struct SiS_LVDSData const *LCDPtr;
1266 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
1269 LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeIdIndex, pVBInfo);
1270 pVBInfo->VGAHT = LCDPtr->VGAHT;
1271 pVBInfo->VGAVT = LCDPtr->VGAVT;
1272 pVBInfo->HT = LCDPtr->LCDHT;
1273 pVBInfo->VT = LCDPtr->LCDVT;
1275 if (pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))
1278 if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
1279 (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
1280 pVBInfo->HDE = 1024;
1282 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
1283 (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
1284 pVBInfo->HDE = 1280;
1285 pVBInfo->VDE = 1024;
1286 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
1287 pVBInfo->HDE = 1400;
1288 pVBInfo->VDE = 1050;
1290 pVBInfo->HDE = 1600;
1291 pVBInfo->VDE = 1200;
1295 static void XGI_ModCRT1Regs(unsigned short ModeIdIndex,
1296 struct xgi_hw_device_info *HwDeviceExtension,
1297 struct vb_device_info *pVBInfo)
1300 struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL;
1301 struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL;
1303 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1304 LCDPtr = XGI_GetLcdPtr(xgifb_epllcd_crt1_h, ModeIdIndex,
1307 for (i = 0; i < 8; i++)
1308 pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i];
1311 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
1313 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1314 LCDPtr1 = XGI_GetLcdPtr(xgifb_epllcd_crt1_v, ModeIdIndex,
1316 for (i = 0; i < 7; i++)
1317 pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i];
1320 XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo);
1323 static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
1325 unsigned char tempal, tempah, tempbl, i;
1327 tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36);
1328 tempal = tempah & 0x0F;
1329 tempah = tempah & 0xF0;
1331 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1333 while (tempbl != 0xFF) {
1334 if (tempbl & 0x80) { /* OEMUtil */
1336 tempbl = tempbl & ~(0x80);
1339 if (tempal == tempbl)
1344 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1350 static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
1352 unsigned short tempah, tempal, tempbl, i;
1354 tempal = pVBInfo->LCDResInfo;
1355 tempah = pVBInfo->LCDTypeInfo;
1358 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1360 while (tempbl != 0xFF) {
1361 if ((tempbl & 0x80) && (tempbl != 0x80)) {
1366 if (tempal == tempbl)
1370 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1373 if (tempbl == 0xFF) {
1374 pVBInfo->LCDResInfo = Panel_1024x768;
1375 pVBInfo->LCDTypeInfo = 0;
1382 static void XGI_GetLCDSync(unsigned short *HSyncWidth,
1383 unsigned short *VSyncWidth,
1384 struct vb_device_info *pVBInfo)
1386 unsigned short Index;
1388 Index = XGI_GetLCDCapPtr(pVBInfo);
1389 *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
1390 *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
1393 static void XGI_SetLVDSRegs(unsigned short ModeIdIndex,
1394 struct vb_device_info *pVBInfo)
1396 unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
1397 unsigned long temp, temp1, temp2, temp3, push3;
1398 struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL;
1400 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1401 LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeIdIndex, pVBInfo);
1403 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
1408 if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
1409 (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
1412 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
1413 (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
1416 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
1424 if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
1425 pVBInfo->HDE = tempax;
1426 pVBInfo->VDE = tempbx;
1427 pVBInfo->VGAHDE = tempax;
1428 pVBInfo->VGAVDE = tempbx;
1431 tempax = pVBInfo->HT;
1433 tempbx = LCDPtr1->LCDHDES;
1435 tempcx = pVBInfo->HDE;
1436 tempbx = tempbx & 0x0fff;
1439 if (tempcx >= tempax)
1442 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
1447 xgifb_reg_set(pVBInfo->Part1Port, 0x16,
1448 (unsigned short)(tempbx & 0xff));
1449 xgifb_reg_set(pVBInfo->Part1Port, 0x17,
1450 (unsigned short)(tempcx & 0xff));
1452 tempax = pVBInfo->HT;
1454 tempbx = LCDPtr1->LCDHRS;
1458 if (pVBInfo->LCDInfo & EnableScalingLCD)
1459 tempcx = LCDPtr1->LCDHSync;
1463 if (tempcx >= tempax)
1466 tempax = tempbx & 0x07;
1474 xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax);
1475 xgifb_reg_set(pVBInfo->Part1Port, 0x14,
1476 (unsigned short)(tempbx & 0xff));
1478 tempax = pVBInfo->VT;
1479 tempbx = LCDPtr1->LCDVDES;
1480 tempcx = pVBInfo->VDE;
1482 tempbx = tempbx & 0x0fff;
1484 if (tempcx >= tempax)
1487 xgifb_reg_set(pVBInfo->Part1Port, 0x1b,
1488 (unsigned short)(tempbx & 0xff));
1489 xgifb_reg_set(pVBInfo->Part1Port, 0x1c,
1490 (unsigned short)(tempcx & 0xff));
1492 tempbx = (tempbx >> 8) & 0x07;
1493 tempcx = (tempcx >> 8) & 0x07;
1495 xgifb_reg_set(pVBInfo->Part1Port, 0x1d,
1496 (unsigned short)((tempcx << 3) | tempbx));
1498 tempax = pVBInfo->VT;
1499 tempbx = LCDPtr1->LCDVRS;
1503 if (pVBInfo->LCDInfo & EnableScalingLCD)
1504 tempcx = LCDPtr1->LCDVSync;
1507 if (tempcx >= tempax)
1510 xgifb_reg_set(pVBInfo->Part1Port, 0x18,
1511 (unsigned short)(tempbx & 0xff));
1512 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f,
1513 (unsigned short)(tempcx & 0x0f));
1515 tempax = ((tempbx >> 8) & 0x07) << 3;
1517 tempbx = pVBInfo->VGAVDE;
1518 if (tempbx != pVBInfo->VDE)
1521 if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA)
1524 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07, tempax);
1526 tempbx = pVBInfo->VDE;
1527 tempax = pVBInfo->VGAVDE;
1529 temp = tempax; /* 0430 ylshieh */
1530 temp1 = (temp << 18) / tempbx;
1532 tempdx = (unsigned short)((temp << 18) % tempbx);
1540 xgifb_reg_set(pVBInfo->Part1Port, 0x37, (unsigned short)(temp2 & 0xff));
1541 xgifb_reg_set(pVBInfo->Part1Port, 0x36, (unsigned short)((temp2 >> 8) & 0xff));
1543 tempbx = (unsigned short)(temp2 >> 16);
1544 tempax = tempbx & 0x03;
1546 tempbx = pVBInfo->VGAVDE;
1547 if (tempbx == pVBInfo->VDE)
1550 xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax);
1552 if (pVBInfo->VBType & VB_XGI301C) {
1554 xgifb_reg_set(pVBInfo->Part4Port,
1556 (unsigned short)(temp2 & 0xff));
1557 xgifb_reg_set(pVBInfo->Part4Port,
1559 (unsigned short)((temp2 >> 8) &
1561 tempbx = (unsigned short)(temp2 >> 16);
1562 xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a, ~0xc0,
1563 (unsigned short)((tempbx & 0xff) << 6));
1565 tempcx = pVBInfo->VGAVDE;
1566 if (tempcx == pVBInfo->VDE)
1567 xgifb_reg_and_or(pVBInfo->Part4Port, 0x30, ~0x0c, 0x00);
1569 xgifb_reg_and_or(pVBInfo->Part4Port, 0x30, ~0x0c, 0x08);
1572 tempcx = pVBInfo->VGAHDE;
1573 tempbx = pVBInfo->HDE;
1575 temp1 = tempcx << 16;
1577 tempax = (unsigned short)(temp1 / tempbx);
1579 if ((tempbx & 0xffff) == (tempcx & 0xffff))
1583 temp1 = pVBInfo->VGAHDE << 16;
1589 temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
1591 tempax = (unsigned short)(temp3 & 0xff);
1592 xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax);
1594 temp1 = pVBInfo->VGAVDE << 18;
1595 temp1 = temp1 / push3;
1596 tempbx = (unsigned short)(temp1 & 0xffff);
1598 if (pVBInfo->LCDResInfo == Panel_1024x768)
1601 tempax = ((tempbx >> 8) & 0xff) << 3;
1602 tempax |= (unsigned short)((temp3 >> 8) & 0x07);
1603 xgifb_reg_set(pVBInfo->Part1Port, 0x20,
1604 (unsigned short)(tempax & 0xff));
1605 xgifb_reg_set(pVBInfo->Part1Port, 0x21,
1606 (unsigned short)(tempbx & 0xff));
1610 if (modeflag & HalfDCLK)
1613 xgifb_reg_set(pVBInfo->Part1Port, 0x22,
1614 (unsigned short)((temp3 >> 8) & 0xff));
1615 xgifb_reg_set(pVBInfo->Part1Port, 0x23,
1616 (unsigned short)(temp3 & 0xff));
1620 * Function : XGI_GETLCDVCLKPtr
1622 * Output : al -> VCLK Index
1625 static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
1626 struct vb_device_info *pVBInfo)
1628 unsigned short index;
1630 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1631 index = XGI_GetLCDCapPtr1(pVBInfo);
1633 if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
1634 *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
1635 *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
1637 *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
1638 *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
1643 static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
1644 unsigned short ModeIdIndex,
1645 struct vb_device_info *pVBInfo)
1647 unsigned short index, modeflag;
1648 unsigned char tempal;
1650 /* si+Ext_ResInfo */
1651 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1653 if ((pVBInfo->SetFlag & ProgrammingCRT2) &&
1654 !(pVBInfo->LCDInfo & EnableScalingLCD)) { /* {LCDA/LCDB} */
1655 index = XGI_GetLCDCapPtr(pVBInfo);
1656 tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
1658 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
1662 if (pVBInfo->VBType &
1668 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
1669 tempal = TVCLKBASE_315 + HiTVVCLKDIV2;
1670 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
1671 tempal = TVCLKBASE_315 + HiTVVCLK;
1672 if (pVBInfo->TVInfo & TVSimuMode) {
1673 tempal = TVCLKBASE_315 + HiTVSimuVCLK;
1674 if (!(modeflag & Charx8Dot))
1675 tempal = TVCLKBASE_315 +
1681 if (pVBInfo->TVInfo & TVSetYPbPr750p)
1682 return XGI_YPbPr750pVCLK;
1684 if (pVBInfo->TVInfo & TVSetYPbPr525p)
1685 return YPbPr525pVCLK;
1687 tempal = NTSC1024VCLK;
1689 if (!(pVBInfo->TVInfo & NTSC1024x768)) {
1690 tempal = TVCLKBASE_315 + TVVCLKDIV2;
1691 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
1692 tempal = TVCLKBASE_315 + TVVCLK;
1695 if (pVBInfo->VBInfo & SetCRT2ToTV)
1700 inb((pVBInfo->P3ca + 0x02));
1701 return XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1704 static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
1705 unsigned char *di_1, struct vb_device_info *pVBInfo)
1707 if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B
1708 | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
1709 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
1710 (pVBInfo->SetFlag & ProgrammingCRT2)) {
1711 *di_0 = XGI_VBVCLKData[tempal].Part4_A;
1712 *di_1 = XGI_VBVCLKData[tempal].Part4_B;
1715 *di_0 = XGI_VCLKData[tempal].SR2B;
1716 *di_1 = XGI_VCLKData[tempal].SR2C;
1720 static void XGI_SetCRT2ECLK(unsigned short ModeIdIndex,
1721 unsigned short RefreshRateTableIndex,
1722 struct vb_device_info *pVBInfo)
1724 unsigned char di_0, di_1, tempal;
1727 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo);
1728 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
1729 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
1731 for (i = 0; i < 4; i++) {
1732 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30,
1733 (unsigned short)(0x10 * i));
1734 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
1735 !(pVBInfo->VBInfo & SetInSlaveMode)) {
1736 xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0);
1737 xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1);
1739 xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0);
1740 xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1);
1745 static void XGI_UpdateModeInfo(struct vb_device_info *pVBInfo)
1747 unsigned short tempcl, tempch, temp, tempbl, tempax;
1749 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
1750 | VB_SIS302LV | VB_XGI301C)) {
1753 temp = xgifb_reg_get(pVBInfo->P3c4, 0x01);
1755 if (!(temp & 0x20)) {
1756 temp = xgifb_reg_get(pVBInfo->P3d4, 0x17);
1758 temp = xgifb_reg_get(pVBInfo->P3d4, 0x53);
1760 tempcl |= ActiveCRT1;
1764 temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e);
1767 if (!(temp == 0x08)) {
1768 /* Check ChannelA */
1769 tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13);
1771 tempcl = tempcl | ActiveLCD;
1775 if (!(tempcl & ActiveLCD)) {
1777 tempcl |= ActiveCRT2;
1781 tempcl |= ActiveLCD;
1784 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00);
1787 tempch |= ActiveAVideo;
1790 tempch |= ActiveSVideo;
1793 tempch |= ActiveSCART;
1795 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
1797 tempch |= ActiveHiTV;
1800 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
1801 temp = xgifb_reg_get(
1806 tempch |= ActiveYPbPr;
1814 temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
1815 if (tempcl & ActiveLCD) {
1816 if ((pVBInfo->SetFlag & ReserveTVOption)) {
1817 if (temp & ActiveTV)
1822 tempbl = ~XGI_ModeSwitchStatus;
1823 xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp);
1825 if (!(pVBInfo->SetFlag & ReserveTVOption))
1826 xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch);
1830 void XGI_GetVBType(struct vb_device_info *pVBInfo)
1832 unsigned short flag, tempbx, tempah;
1834 tempbx = VB_SIS302B;
1835 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
1840 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01);
1844 tempbx = VB_SIS301B;
1846 goto bigger_than_0xB0;
1848 tempbx = VB_XGI301C;
1850 goto bigger_than_0xB0;
1852 tempbx = VB_SIS301LV;
1854 goto bigger_than_0xB0;
1856 tempbx = VB_SIS302LV;
1857 tempah = xgifb_reg_get(pVBInfo->Part4Port, 0x39);
1859 tempbx = VB_XGI301C;
1862 if (tempbx & (VB_SIS301B | VB_SIS302B)) {
1863 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x23);
1865 tempbx = tempbx | VB_NoLCD;
1869 pVBInfo->VBType = tempbx;
1872 static void XGI_GetVBInfo(unsigned short ModeIdIndex,
1873 struct vb_device_info *pVBInfo)
1875 unsigned short tempax, push, tempbx, temp, modeflag;
1877 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1878 pVBInfo->SetFlag = 0;
1879 pVBInfo->ModeType = modeflag & ModeTypeMask;
1882 if (!(pVBInfo->VBType & 0xFFFF))
1885 /* Check Display Device */
1886 temp = xgifb_reg_get(pVBInfo->P3d4, 0x30);
1887 tempbx = tempbx | temp;
1888 temp = xgifb_reg_get(pVBInfo->P3d4, 0x31);
1892 tempbx = tempbx | tempax;
1893 temp = SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA
1894 | SetInSlaveMode | DisableCRT2Display;
1895 temp = 0xFFFF ^ temp;
1898 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
1900 if (pVBInfo->VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV |
1902 if (temp & EnableDualEdge) {
1903 tempbx |= SetCRT2ToDualEdge;
1904 if (temp & SetToLCDA)
1905 tempbx |= XGI_SetCRT2ToLCDA;
1909 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
1910 if (temp & SetYPbPr) {
1911 /* shampoo add for new scratch */
1912 temp = xgifb_reg_get(pVBInfo->P3d4, 0x35);
1914 tempbx |= SetCRT2ToHiVision;
1916 if (temp != YPbPrMode1080i) {
1917 tempbx &= ~SetCRT2ToHiVision;
1918 tempbx |= SetCRT2ToYPbPr525750;
1923 tempax = push; /* restore CR31 */
1927 if (!(tempbx & temp)) {
1928 tempax |= DisableCRT2Display;
1932 if (!(pVBInfo->VBType & VB_NoLCD)) {
1933 if (tempbx & XGI_SetCRT2ToLCDA) {
1934 if (tempbx & SetSimuScanMode)
1935 tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC |
1938 tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC |
1939 SetCRT2ToTV | SwitchCRT2));
1944 /* for driver abnormal */
1945 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1946 if (tempbx & SetCRT2ToRAMDAC) {
1947 tempbx &= (0xFF00 | SetCRT2ToRAMDAC |
1948 SwitchCRT2 | SetSimuScanMode);
1949 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
1953 if (!(pVBInfo->VBType & VB_NoLCD)) {
1954 if (tempbx & SetCRT2ToLCD) {
1955 tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchCRT2 |
1957 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
1961 if (tempbx & SetCRT2ToSCART) {
1962 tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchCRT2 |
1964 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
1967 if (tempbx & SetCRT2ToYPbPr525750)
1968 tempbx &= (0xFF00 | SwitchCRT2 | SetSimuScanMode);
1970 if (tempbx & SetCRT2ToHiVision)
1971 tempbx &= (0xFF00 | SetCRT2ToHiVision | SwitchCRT2 |
1974 if (tempax & DisableCRT2Display) { /* Set Display Device Info */
1975 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode)))
1976 tempbx = DisableCRT2Display;
1979 if (!(tempbx & DisableCRT2Display)) {
1980 if (!(tempbx & DriverMode) || !(modeflag & CRT2Mode)) {
1981 if (!(tempbx & XGI_SetCRT2ToLCDA))
1982 tempbx |= (SetInSlaveMode | SetSimuScanMode);
1985 /* LCD+TV can't support in slave mode
1986 * (Force LCDA+TV->LCDB)
1988 if ((tempbx & SetInSlaveMode) && (tempbx & XGI_SetCRT2ToLCDA)) {
1989 tempbx ^= (SetCRT2ToLCD | XGI_SetCRT2ToLCDA |
1991 pVBInfo->SetFlag |= ReserveTVOption;
1995 pVBInfo->VBInfo = tempbx;
1998 static void XGI_GetTVInfo(unsigned short ModeIdIndex,
1999 struct vb_device_info *pVBInfo)
2001 unsigned short tempbx = 0, resinfo = 0, modeflag, index1;
2003 if (pVBInfo->VBInfo & SetCRT2ToTV) {
2004 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2005 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2007 tempbx = xgifb_reg_get(pVBInfo->P3d4, 0x35);
2008 if (tempbx & TVSetPAL) {
2009 tempbx &= (SetCHTVOverScan |
2013 if (tempbx & TVSetPALM)
2014 /* set to NTSC if PAL-M */
2015 tempbx &= ~TVSetPAL;
2017 tempbx &= (SetCHTVOverScan |
2022 if (pVBInfo->VBInfo & SetCRT2ToSCART)
2025 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
2026 index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35);
2027 index1 &= YPbPrMode;
2029 if (index1 == YPbPrMode525i)
2030 tempbx |= TVSetYPbPr525i;
2032 if (index1 == YPbPrMode525p)
2033 tempbx = tempbx | TVSetYPbPr525p;
2034 if (index1 == YPbPrMode750p)
2035 tempbx = tempbx | TVSetYPbPr750p;
2038 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
2039 tempbx = tempbx | TVSetHiVision | TVSetPAL;
2041 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
2042 (!(pVBInfo->VBInfo & SetNotSimuMode)))
2043 tempbx |= TVSimuMode;
2045 if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8)) {
2046 /* NTSC 1024x768, */
2047 tempbx |= NTSC1024x768;
2050 tempbx |= RPLLDIV2XO;
2052 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2053 if (pVBInfo->VBInfo & SetInSlaveMode)
2054 tempbx &= (~RPLLDIV2XO);
2055 } else if (tempbx & (TVSetYPbPr525p | TVSetYPbPr750p)) {
2056 tempbx &= (~RPLLDIV2XO);
2057 } else if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B |
2058 VB_SIS301LV | VB_SIS302LV |
2060 if (tempbx & TVSimuMode)
2061 tempbx &= (~RPLLDIV2XO);
2064 pVBInfo->TVInfo = tempbx;
2067 static unsigned char XGI_GetLCDInfo(unsigned short ModeIdIndex,
2068 struct vb_device_info *pVBInfo)
2070 unsigned short temp, tempax, tempbx, resinfo = 0, LCDIdIndex;
2072 pVBInfo->LCDResInfo = 0;
2073 pVBInfo->LCDTypeInfo = 0;
2074 pVBInfo->LCDInfo = 0;
2076 /* si+Ext_ResInfo */
2077 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2078 temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
2079 tempbx = temp & 0x0F;
2082 tempbx = Panel_1024x768; /* default */
2085 if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) {
2086 if (pVBInfo->VBInfo & DriverMode) {
2087 tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33);
2088 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
2093 if ((resinfo == 6) || (resinfo == 9)) {
2095 tempbx |= PanelRef75Hz;
2096 } else if ((resinfo == 7) || (resinfo == 8)) {
2098 tempbx |= PanelRef75Hz;
2103 pVBInfo->LCDResInfo = tempbx;
2107 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
2112 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
2114 temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
2118 LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
2120 tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
2122 if (((pVBInfo->VBType & VB_SIS302LV) ||
2123 (pVBInfo->VBType & VB_XGI301C)) && (tempax & XGI_LCDDualLink))
2124 tempbx |= SetLCDDualLink;
2126 if ((pVBInfo->LCDResInfo == Panel_1400x1050) &&
2127 (pVBInfo->VBInfo & SetCRT2ToLCD) && (resinfo == 9) &&
2128 !(tempbx & EnableScalingLCD))
2130 * set to center in 1280x1024 LCDB
2131 * for Panel_1400x1050
2133 tempbx |= SetLCDtoNonExpanding;
2135 if (pVBInfo->VBInfo & SetInSlaveMode) {
2136 if (pVBInfo->VBInfo & SetNotSimuMode)
2137 tempbx |= XGI_LCDVESATiming;
2139 tempbx |= XGI_LCDVESATiming;
2142 pVBInfo->LCDInfo = tempbx;
2147 unsigned char XGI_SearchModeID(unsigned short ModeNo,
2148 unsigned short *ModeIdIndex)
2150 for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
2151 if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
2153 if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
2160 static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
2162 unsigned char ujRet = 0;
2163 unsigned char i = 0;
2165 for (i = 0; i < 8; i++) {
2167 ujRet |= (ujDate >> i) & 1;
2175 * bl[5] : LVDS signal
2176 * bl[1] : LVDS backlight
2179 static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
2181 unsigned char CR4A, temp;
2183 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2184 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
2186 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2188 temp = XG21GPIODataTransfer(temp);
2190 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
2196 * bl[5] : LVDS signal
2197 * bl[1] : LVDS backlight
2200 static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
2202 unsigned char CR4A, CRB4, temp;
2204 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2205 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
2207 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2211 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
2212 CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4);
2213 temp |= ((CRB4 & 0x04) << 3);
2219 * bl[5] : 1;LVDS signal on
2220 * bl[1] : 1;LVDS backlight on
2221 * bl[0] : 1:LVDS VDD on
2222 * bh: 100000b : clear bit 5, to set bit5
2223 * 000010b : clear bit 1, to set bit1
2224 * 000001b : clear bit 0, to set bit0
2226 static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
2227 struct vb_device_info *pVBInfo)
2229 unsigned char CR4A, temp;
2231 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2234 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
2236 if (tempbh & 0x20) {
2237 temp = (tempbl >> 4) & 0x02;
2240 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
2243 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2245 temp = XG21GPIODataTransfer(temp);
2248 xgifb_reg_set(pVBInfo->P3d4, 0x48, temp);
2251 static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
2252 struct vb_device_info *pVBInfo)
2254 unsigned char CR4A, temp;
2255 unsigned short tempbh0, tempbl0;
2264 if (tempbh & 0x20) {
2265 temp = (tempbl >> 4) & 0x02;
2268 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
2270 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
2272 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2276 tempbl <<= 2; /* GPIOC,GPIOD */
2277 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
2278 xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
2281 static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
2282 struct xgi_hw_device_info *pXGIHWDE,
2283 struct vb_device_info *pVBInfo)
2285 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
2286 if (pXGIHWDE->jChipType == XG21) {
2287 if (pVBInfo->IF_DEF_LVDS == 1) {
2288 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
2290 XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo);
2291 mdelay(xgifb_info->lvds_data.PSC_S2);
2293 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
2294 /* LVDS signal on */
2295 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
2296 mdelay(xgifb_info->lvds_data.PSC_S3);
2297 /* LVDS backlight on */
2298 XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo);
2300 /* DVO/DVI signal on */
2301 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
2305 if (pXGIHWDE->jChipType == XG27) {
2306 if (pVBInfo->IF_DEF_LVDS == 1) {
2307 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
2309 XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo);
2310 mdelay(xgifb_info->lvds_data.PSC_S2);
2312 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
2313 /* LVDS signal on */
2314 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
2315 mdelay(xgifb_info->lvds_data.PSC_S3);
2316 /* LVDS backlight on */
2317 XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo);
2319 /* DVO/DVI signal on */
2320 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
2325 void XGI_DisplayOff(struct xgifb_video_info *xgifb_info,
2326 struct xgi_hw_device_info *pXGIHWDE,
2327 struct vb_device_info *pVBInfo)
2329 if (pXGIHWDE->jChipType == XG21) {
2330 if (pVBInfo->IF_DEF_LVDS == 1) {
2331 /* LVDS backlight off */
2332 XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo);
2333 mdelay(xgifb_info->lvds_data.PSC_S3);
2335 /* DVO/DVI signal off */
2336 XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo);
2340 if (pXGIHWDE->jChipType == XG27) {
2341 if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
2342 /* LVDS backlight off */
2343 XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo);
2344 mdelay(xgifb_info->lvds_data.PSC_S3);
2347 if (pVBInfo->IF_DEF_LVDS == 0) {
2348 /* DVO/DVI signal off */
2349 XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo);
2353 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
2356 static void XGI_WaitDisply(struct vb_device_info *pVBInfo)
2358 while ((inb(pVBInfo->P3da) & 0x01))
2361 while (!(inb(pVBInfo->P3da) & 0x01))
2365 static void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
2367 xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40);
2370 static void XGI_SaveCRT2Info(unsigned short ModeNo,
2371 struct vb_device_info *pVBInfo)
2373 unsigned short temp1, temp2;
2375 /* reserve CR34 for CRT1 Mode No */
2376 xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo);
2377 temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
2378 temp2 = ~(SetInSlaveMode >> 8);
2379 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1);
2382 static void XGI_GetCRT2ResInfo(unsigned short ModeIdIndex,
2383 struct vb_device_info *pVBInfo)
2385 unsigned short xres, yres, modeflag, resindex;
2387 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2388 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
2389 yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
2390 /* si+St_ModeFlag */
2391 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2393 if (modeflag & HalfDCLK)
2396 if (modeflag & DoubleScanMode)
2399 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
2402 if (pVBInfo->LCDResInfo == Panel_1600x1200) {
2403 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2409 if (pVBInfo->LCDResInfo == Panel_1280x1024) {
2412 else if (yres == 350)
2415 if (pVBInfo->LCDInfo & XGI_LCDVESATiming) {
2421 if (pVBInfo->LCDResInfo == Panel_1024x768) {
2422 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2423 if (!(pVBInfo->LCDInfo & LCDNonExpanding)) {
2426 else if (yres == 400)
2428 else if (yres == 480)
2438 pVBInfo->VGAHDE = xres;
2439 pVBInfo->HDE = xres;
2440 pVBInfo->VGAVDE = yres;
2441 pVBInfo->VDE = yres;
2444 static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
2446 if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) &&
2447 (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
2453 static void XGI_GetRAMDAC2DATA(unsigned short ModeIdIndex,
2454 unsigned short RefreshRateTableIndex,
2455 struct vb_device_info *pVBInfo)
2457 unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
2460 pVBInfo->RVBHCMAX = 1;
2461 pVBInfo->RVBHCFACT = 1;
2462 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2463 CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2464 CRT1Index &= IndexMask;
2465 temp1 = (unsigned short)XGI_CRT1Table[CRT1Index].CR[0];
2466 temp2 = (unsigned short)XGI_CRT1Table[CRT1Index].CR[5];
2467 tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
2468 tempbx = (unsigned short)XGI_CRT1Table[CRT1Index].CR[8];
2469 tempcx = (unsigned short)XGI_CRT1Table[CRT1Index].CR[14] << 8;
2473 temp1 = (unsigned short)XGI_CRT1Table[CRT1Index].CR[9];
2482 if (modeflag & Charx8Dot)
2487 pVBInfo->VGAHT = tempax;
2488 pVBInfo->HT = tempax;
2490 pVBInfo->VGAVT = tempbx;
2491 pVBInfo->VT = tempbx;
2494 static void XGI_GetCRT2Data(unsigned short ModeIdIndex,
2495 unsigned short RefreshRateTableIndex,
2496 struct vb_device_info *pVBInfo)
2498 unsigned short tempax = 0, tempbx = 0, modeflag, resinfo;
2500 struct SiS_LCDData const *LCDPtr = NULL;
2502 /* si+Ext_ResInfo */
2503 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2504 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2505 pVBInfo->NewFlickerMode = 0;
2506 pVBInfo->RVBHRS = 50;
2508 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
2509 XGI_GetRAMDAC2DATA(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
2513 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
2514 LCDPtr = XGI_GetLcdPtr(XGI_LCDDataTable, ModeIdIndex,
2517 pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
2518 pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
2519 pVBInfo->VGAHT = LCDPtr->VGAHT;
2520 pVBInfo->VGAVT = LCDPtr->VGAVT;
2521 pVBInfo->HT = LCDPtr->LCDHT;
2522 pVBInfo->VT = LCDPtr->LCDVT;
2524 if (pVBInfo->LCDResInfo == Panel_1024x768) {
2528 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2529 if (pVBInfo->VGAVDE == 357)
2531 else if (pVBInfo->VGAVDE == 420)
2533 else if (pVBInfo->VGAVDE == 525)
2535 else if (pVBInfo->VGAVDE == 600)
2538 } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) {
2541 } else if (pVBInfo->LCDResInfo == Panel_1280x1024) {
2543 if (pVBInfo->VGAVDE == 360)
2545 else if (pVBInfo->VGAVDE == 375)
2547 else if (pVBInfo->VGAVDE == 405)
2551 } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) {
2554 } else if (pVBInfo->LCDResInfo == Panel_1280x960) {
2556 if (pVBInfo->VGAVDE == 350)
2558 else if (pVBInfo->VGAVDE == 400)
2560 else if (pVBInfo->VGAVDE == 1024)
2564 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
2568 if (pVBInfo->VGAVDE == 1024) {
2572 } else if (pVBInfo->LCDResInfo == Panel_1600x1200) {
2574 tempbx = 1200; /* alan 10/14/2003 */
2575 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2576 if (pVBInfo->VGAVDE == 350)
2578 else if (pVBInfo->VGAVDE == 400)
2583 if (pVBInfo->LCDInfo & LCDNonExpanding) {
2584 tempax = pVBInfo->VGAHDE;
2585 tempbx = pVBInfo->VGAVDE;
2588 pVBInfo->HDE = tempax;
2589 pVBInfo->VDE = tempbx;
2593 if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
2594 struct SiS_TVData const *TVPtr;
2596 TVPtr = XGI_GetTVPtr(ModeIdIndex, RefreshRateTableIndex,
2599 pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
2600 pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
2601 pVBInfo->VGAHT = TVPtr->VGAHT;
2602 pVBInfo->VGAVT = TVPtr->VGAVT;
2603 pVBInfo->HDE = TVPtr->TVHDE;
2604 pVBInfo->VDE = TVPtr->TVVDE;
2605 pVBInfo->RVBHRS = TVPtr->RVBHRS;
2606 pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
2608 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2609 if (resinfo == 0x08)
2610 pVBInfo->NewFlickerMode = 0x40;
2611 else if (resinfo == 0x09)
2612 pVBInfo->NewFlickerMode = 0x40;
2613 else if (resinfo == 0x12)
2614 pVBInfo->NewFlickerMode = 0x40;
2616 if (pVBInfo->VGAVDE == 350)
2617 pVBInfo->TVInfo |= TVSimuMode;
2622 if (pVBInfo->VBInfo & SetInSlaveMode) {
2623 if (pVBInfo->TVInfo & TVSimuMode) {
2627 if (!(modeflag & Charx8Dot)) {
2628 tempax = StHiTextTVHT;
2629 tempbx = StHiTextTVVT;
2633 } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
2634 if (pVBInfo->TVInfo & TVSetYPbPr750p) {
2635 tempax = YPbPrTV750pHT; /* Ext750pTVHT */
2636 tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
2639 if (pVBInfo->TVInfo & TVSetYPbPr525p) {
2640 tempax = YPbPrTV525pHT; /* Ext525pTVHT */
2641 tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
2642 } else if (pVBInfo->TVInfo & TVSetYPbPr525i) {
2643 tempax = YPbPrTV525iHT; /* Ext525iTVHT */
2644 tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
2645 if (pVBInfo->TVInfo & NTSC1024x768)
2646 tempax = NTSC1024x768HT;
2651 if (!(pVBInfo->TVInfo & TVSetPAL)) {
2654 if (pVBInfo->TVInfo & NTSC1024x768)
2655 tempax = NTSC1024x768HT;
2659 pVBInfo->HT = tempax;
2660 pVBInfo->VT = tempbx;
2664 static void XGI_SetCRT2VCLK(unsigned short ModeIdIndex,
2665 unsigned short RefreshRateTableIndex,
2666 struct vb_device_info *pVBInfo)
2668 unsigned char di_0, di_1, tempal;
2670 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo);
2671 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
2672 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
2674 if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */
2676 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10);
2677 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
2678 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
2679 } else { /* 301b/302b/301lv/302lv */
2680 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
2681 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
2684 xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12);
2686 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
2687 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28);
2689 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08);
2692 static unsigned short XGI_GetColorDepth(unsigned short ModeIdIndex)
2694 unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
2696 unsigned short modeflag;
2698 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2699 index = (modeflag & ModeTypeMask) - ModeEGA;
2704 return ColorDepth[index];
2707 static unsigned short XGI_GetOffset(unsigned short ModeNo,
2708 unsigned short ModeIdIndex,
2709 unsigned short RefreshRateTableIndex)
2711 unsigned short temp, colordepth, modeinfo, index, infoflag,
2712 ColorDepth[] = { 0x01, 0x02, 0x04 };
2714 modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
2715 infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
2717 index = (modeinfo >> 8) & 0xFF;
2719 temp = XGI330_ScreenOffset[index];
2721 if (infoflag & InterlaceMode)
2724 colordepth = XGI_GetColorDepth(ModeIdIndex);
2726 if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
2727 temp = ModeNo - 0x7C;
2728 colordepth = ColorDepth[temp];
2730 if (infoflag & InterlaceMode)
2733 return temp * colordepth;
2736 static void XGI_SetCRT2Offset(unsigned short ModeNo,
2737 unsigned short ModeIdIndex,
2738 unsigned short RefreshRateTableIndex,
2739 struct vb_device_info *pVBInfo)
2741 unsigned short offset;
2744 if (pVBInfo->VBInfo & SetInSlaveMode)
2747 offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex);
2748 temp = (unsigned char)(offset & 0xFF);
2749 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
2750 temp = (unsigned char)((offset & 0xFF00) >> 8);
2751 xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp);
2752 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
2753 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
2756 static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
2758 /* threshold high ,disable auto threshold */
2759 xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B);
2760 /* threshold low default 04h */
2761 xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04);
2764 static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
2765 unsigned short RefreshRateTableIndex,
2766 struct vb_device_info *pVBInfo)
2770 XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
2771 XGI_SetCRT2FIFO(pVBInfo);
2773 for (tempcx = 4; tempcx < 7; tempcx++)
2774 xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0);
2776 xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00);
2777 xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
2780 static void XGI_SetGroup1(unsigned short ModeIdIndex,
2781 unsigned short RefreshRateTableIndex,
2782 struct vb_device_info *pVBInfo)
2784 unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
2785 pushbx = 0, CRT1Index, modeflag;
2787 CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2788 CRT1Index &= IndexMask;
2789 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2791 /* bainy change table name */
2792 if (modeflag & HalfDCLK) {
2793 /* BTVGA2HT 0x08,0x09 */
2794 temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF;
2795 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
2796 temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
2797 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
2798 /* BTVGA2HDEE 0x0A,0x0C */
2799 temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF;
2800 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
2801 tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
2802 pushbx = pVBInfo->VGAHDE / 2 + 16;
2804 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
2807 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
2808 tempbx = XGI_CRT1Table[CRT1Index].CR[4];
2809 tempbx |= ((XGI_CRT1Table[CRT1Index].CR[14] &
2811 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
2812 tempcx = XGI_CRT1Table[CRT1Index].CR[5];
2814 temp = XGI_CRT1Table[CRT1Index].CR[15];
2815 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
2816 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
2822 if (tempcx > (pVBInfo->VGAHT / 2))
2823 tempcx = pVBInfo->VGAHT / 2;
2825 temp = tempbx & 0x00FF;
2827 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
2829 temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
2830 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
2831 temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
2832 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
2833 /* BTVGA2HDEE 0x0A,0x0C */
2834 temp = (pVBInfo->VGAHDE + 16) & 0x0FF;
2835 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
2836 tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
2837 pushbx = pVBInfo->VGAHDE + 16;
2839 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
2842 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
2843 tempbx = XGI_CRT1Table[CRT1Index].CR[3];
2844 tempbx |= ((XGI_CRT1Table[CRT1Index].CR[5] &
2846 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
2847 tempcx = XGI_CRT1Table[CRT1Index].CR[4];
2849 temp = XGI_CRT1Table[CRT1Index].CR[6];
2850 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
2851 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
2856 if (tempcx > pVBInfo->VGAHT)
2857 tempcx = pVBInfo->VGAHT;
2859 temp = tempbx & 0x00FF;
2860 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
2863 tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
2865 tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
2866 tempax |= (tempbx & 0xFF00);
2867 temp = (tempax & 0xFF00) >> 8;
2868 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
2869 temp = tempcx & 0x00FF;
2870 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
2871 tempcx = pVBInfo->VGAVT - 1;
2872 temp = tempcx & 0x00FF;
2874 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
2875 tempbx = pVBInfo->VGAVDE - 1;
2876 temp = tempbx & 0x00FF;
2877 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp);
2878 temp = ((tempbx & 0xFF00) << 3) >> 8;
2879 temp |= ((tempcx & 0xFF00) >> 8);
2880 xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp);
2882 /* BTVGA2VRS 0x10,0x11 */
2883 tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1;
2884 /* BTVGA2VRE 0x11 */
2885 tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1;
2887 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
2888 tempbx = XGI_CRT1Table[CRT1Index].CR[10];
2889 temp = XGI_CRT1Table[CRT1Index].CR[9];
2897 temp = XGI_CRT1Table[CRT1Index].CR[14];
2902 temp = XGI_CRT1Table[CRT1Index].CR[11];
2903 tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
2906 temp = tempbx & 0x00FF;
2907 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
2908 temp = ((tempbx & 0xFF00) >> 8) << 4;
2909 temp = (tempcx & 0x000F) | (temp);
2910 xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp);
2913 if (modeflag & DoubleScanMode)
2916 if (modeflag & HalfDCLK)
2919 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
2922 static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
2924 unsigned long tempax, tempbx;
2926 tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
2928 tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
2929 tempax = (tempax * pVBInfo->HT) / tempbx;
2931 return (unsigned short)tempax;
2934 static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
2935 struct vb_device_info *pVBInfo)
2937 unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
2940 /* si+Ext_ResInfo */
2941 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2942 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2944 if (!(pVBInfo->VBInfo & SetInSlaveMode))
2947 temp = 0xFF; /* set MAX HT */
2948 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
2951 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
2952 modeflag |= Charx8Dot;
2954 tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
2956 if (modeflag & HalfDCLK)
2959 tempax = (tempax / tempcx) - 1;
2960 tempbx |= ((tempax & 0x00FF) << 8);
2961 temp = tempax & 0x00FF;
2962 xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp);
2964 temp = (tempbx & 0xFF00) >> 8;
2966 if (pVBInfo->VBInfo & SetCRT2ToTV) {
2967 if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
2968 | VB_SIS302LV | VB_XGI301C)))
2971 if ((pVBInfo->VBInfo & SetCRT2ToHiVision) &&
2972 !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7))
2976 /* 0x05 Horizontal Display Start */
2977 xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp);
2978 /* 0x06 Horizontal Blank end */
2979 xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03);
2981 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
2982 if (pVBInfo->VBInfo & SetCRT2ToTV)
2983 tempax = pVBInfo->VGAHT;
2985 tempax = XGI_GetVGAHT2(pVBInfo);
2988 if (tempax >= pVBInfo->VGAHT)
2989 tempax = pVBInfo->VGAHT;
2991 if (modeflag & HalfDCLK)
2994 tempax = (tempax / tempcx) - 5;
2995 tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
2996 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2997 temp = (tempbx & 0x00FF) - 1;
2998 if (!(modeflag & HalfDCLK)) {
3000 if (pVBInfo->TVInfo & TVSimuMode) {
3006 tempbx = (tempbx & 0xFF00) >> 8;
3007 tempcx = (tempcx + tempbx) >> 1;
3008 temp = (tempcx & 0x00FF) + 2;
3010 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3012 if (!(modeflag & HalfDCLK)) {
3013 if ((modeflag & Charx8Dot)) {
3015 if (pVBInfo->VGAHDE >= 800)
3019 } else if (!(modeflag & HalfDCLK)) {
3021 if (pVBInfo->LCDResInfo != Panel_1280x960 &&
3022 pVBInfo->VGAHDE >= 800) {
3024 if (pVBInfo->VGAHDE >= 1280 &&
3025 pVBInfo->LCDResInfo != Panel_1280x960 &&
3026 (pVBInfo->LCDInfo & LCDNonExpanding))
3032 /* 0x07 Horizontal Retrace Start */
3033 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
3034 /* 0x08 Horizontal Retrace End */
3035 xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0);
3037 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3038 if (pVBInfo->TVInfo & TVSimuMode) {
3039 if (ModeNo == 0x50) {
3040 if (pVBInfo->TVInfo == SetNTSCTV) {
3041 xgifb_reg_set(pVBInfo->Part1Port,
3043 xgifb_reg_set(pVBInfo->Part1Port,
3046 xgifb_reg_set(pVBInfo->Part1Port,
3048 xgifb_reg_set(pVBInfo->Part1Port,
3055 xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
3056 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
3057 xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
3059 tempbx = pVBInfo->VGAVT;
3062 tempbx = pVBInfo->VGAVDE; /* 0x0E Vertical Display End */
3077 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
3078 if (pVBInfo->LCDResInfo == Panel_1024x768) {
3079 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3089 temp = tempbx & 0x00FF;
3090 /* 0x10 vertical Blank Start */
3091 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
3094 temp = tempbx & 0x00FF;
3095 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
3097 if (tempbx & 0x0100)
3102 if (modeflag & DoubleScanMode)
3105 if (tempbx & 0x0200)
3108 temp = (tempax & 0xFF00) >> 8;
3109 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
3111 if (tempbx & 0x0400)
3114 /* 0x11 Vertical Blank End */
3115 xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00);
3118 tempax -= tempbx; /* 0x0C Vertical Retrace Start */
3120 push1 = tempax; /* push ax */
3122 if (resinfo != 0x09) {
3127 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3128 if ((pVBInfo->VBType & VB_SIS301LV) &&
3129 !(pVBInfo->TVInfo & TVSetHiVision)) {
3130 if ((pVBInfo->TVInfo & TVSimuMode) &&
3131 (pVBInfo->TVInfo & TVSetPAL)) {
3132 if (!(pVBInfo->VBType & VB_SIS301LV) ||
3142 } else if (pVBInfo->TVInfo & TVSimuMode) {
3143 if (pVBInfo->TVInfo & TVSetPAL) {
3144 if (pVBInfo->VBType & VB_SIS301LV) {
3145 if (!(pVBInfo->TVInfo &
3159 push1 = tempax; /* push ax */
3161 if ((pVBInfo->TVInfo & TVSetPAL)) {
3162 if (tempbx <= 513) {
3168 temp = tempbx & 0x00FF;
3169 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
3171 temp = tempbx & 0x00FF;
3172 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
3174 if (tempbx & 0x0100)
3177 if (tempbx & 0x0200)
3178 xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
3182 if (tempbx & 0x0100)
3185 if (tempbx & 0x0200)
3188 if (tempbx & 0x0400)
3191 tempbx = push1; /* pop ax */
3192 temp = tempbx & 0x00FF;
3194 /* 0x0D vertical Retrace End */
3195 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
3197 if (tempbx & 0x0010)
3200 temp = tempcx & 0x00FF;
3201 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
3202 temp = (tempcx & 0x0FF00) >> 8;
3203 xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
3205 temp = (tempax & 0xFF00) >> 8;
3207 temp = (temp >> 1) & 0x09;
3209 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
3212 xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
3213 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
3214 xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
3216 if (pVBInfo->LCDInfo & LCDRGB18Bit)
3221 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
3224 static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
3225 struct vb_device_info *pVBInfo)
3227 unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
3229 unsigned char const *TimingPoint;
3231 unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
3233 /* si+Ext_ResInfo */
3234 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3238 if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
3241 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3244 if (pVBInfo->VBInfo & SetCRT2ToSCART)
3247 if (!(pVBInfo->TVInfo & TVSetPAL))
3250 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3253 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
3256 tempax = (tempax & 0xff00) >> 8;
3258 xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax);
3259 TimingPoint = XGI330_NTSCTiming;
3261 if (pVBInfo->TVInfo & TVSetPAL)
3262 TimingPoint = XGI330_PALTiming;
3264 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3265 TimingPoint = XGI330_HiTVExtTiming;
3267 if (pVBInfo->VBInfo & SetInSlaveMode)
3268 TimingPoint = XGI330_HiTVSt2Timing;
3270 if (pVBInfo->SetFlag & TVSimuMode)
3271 TimingPoint = XGI330_HiTVSt1Timing;
3273 if (!(modeflag & Charx8Dot))
3274 TimingPoint = XGI330_HiTVTextTiming;
3277 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
3278 if (pVBInfo->TVInfo & TVSetYPbPr525i)
3279 TimingPoint = XGI330_YPbPr525iTiming;
3281 if (pVBInfo->TVInfo & TVSetYPbPr525p)
3282 TimingPoint = XGI330_YPbPr525pTiming;
3284 if (pVBInfo->TVInfo & TVSetYPbPr750p)
3285 TimingPoint = XGI330_YPbPr750pTiming;
3288 for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
3289 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
3291 for (i = 0x39; i <= 0x45; i++, j++)
3293 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
3295 if (pVBInfo->VBInfo & SetCRT2ToTV)
3296 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
3298 temp = pVBInfo->NewFlickerMode;
3300 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
3302 if (pVBInfo->TVInfo & TVSetPAL)
3307 if (pVBInfo->VDE <= tempax) {
3308 tempax -= pVBInfo->VDE;
3310 tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
3312 temp = (tempax & 0xFF00) >> 8;
3313 temp += (unsigned short)TimingPoint[0];
3315 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3316 | VB_SIS302LV | VB_XGI301C)) {
3317 if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
3318 | SetCRT2ToSVIDEO | SetCRT2ToSCART
3319 | SetCRT2ToYPbPr525750)) {
3320 tempcx = pVBInfo->VGAHDE;
3321 if (tempcx >= 1024) {
3322 temp = 0x17; /* NTSC */
3323 if (pVBInfo->TVInfo & TVSetPAL)
3324 temp = 0x19; /* PAL */
3329 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
3331 temp = (tempax & 0xFF00) >> 8;
3332 temp += TimingPoint[1];
3334 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3335 | VB_SIS302LV | VB_XGI301C)) {
3336 if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
3337 | SetCRT2ToSVIDEO | SetCRT2ToSCART
3338 | SetCRT2ToYPbPr525750))) {
3339 tempcx = pVBInfo->VGAHDE;
3340 if (tempcx >= 1024) {
3341 temp = 0x1D; /* NTSC */
3342 if (pVBInfo->TVInfo & TVSetPAL)
3343 temp = 0x52; /* PAL */
3347 xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp);
3351 tempcx = pVBInfo->HT;
3353 if (XGI_IsLCDDualLink(pVBInfo))
3357 temp = tempcx & 0x00FF;
3358 xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp);
3360 temp = (tempcx & 0xFF00) >> 8;
3361 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
3363 tempcx = pVBInfo->HT >> 1;
3364 push1 = tempcx; /* push cx */
3367 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3370 temp = tempcx & 0x00FF;
3372 xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp);
3374 tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
3377 temp = tempbx & 0x00FF;
3378 xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp);
3379 temp = (tempbx & 0xFF00) >> 8;
3381 xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp);
3384 tempbx = tempbx + 8;
3385 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3386 tempbx = tempbx - 4;
3390 temp = (tempbx & 0x00FF) << 4;
3391 xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp);
3394 tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
3395 temp = tempcx & 0x00FF;
3396 xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp);
3397 temp = ((tempcx & 0xFF00) >> 8) << 4;
3398 xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp);
3401 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3404 temp = tempcx & 0xFF;
3406 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
3408 tempcx = push1; /* pop cx */
3410 temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
3412 temp = tempcx & 0x00FF;
3414 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
3418 if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
3419 tempax = XGI_GetVGAHT2(pVBInfo);
3420 tempcx = tempax - 1;
3422 temp = tempcx & 0x00FF;
3423 xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp);
3425 tempbx = pVBInfo->VDE;
3427 if (pVBInfo->VGAVDE == 360)
3429 if (pVBInfo->VGAVDE == 375)
3431 if (pVBInfo->VGAVDE == 405)
3434 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3435 if (pVBInfo->VBType &
3436 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
3437 if (!(pVBInfo->TVInfo &
3438 (TVSetYPbPr525p | TVSetYPbPr750p)))
3446 temp = tempbx & 0x00FF;
3448 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3449 if (pVBInfo->VBType & VB_SIS301LV) {
3450 if (pVBInfo->TVInfo & TVSetHiVision) {
3451 if (pVBInfo->VBInfo & SetInSlaveMode) {
3456 } else if (pVBInfo->VBInfo & SetInSlaveMode) {
3462 xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp);
3464 temp = (tempcx & 0xFF00) >> 8;
3465 temp |= ((tempbx & 0xFF00) >> 8) << 6;
3467 if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) {
3468 if (pVBInfo->VBType & VB_SIS301LV) {
3469 if (pVBInfo->TVInfo & TVSetHiVision) {
3472 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3477 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3482 xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp);
3484 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3485 | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */
3486 tempbx = pVBInfo->VDE;
3487 tempcx = tempbx - 2;
3489 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3490 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p
3495 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
3497 if (tempcx & 0x0400)
3500 if (tempbx & 0x0400)
3503 xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp);
3506 temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
3507 xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp);
3508 temp = (tempbx - 3) & 0x00FF;
3509 xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp);
3512 tempbx = tempbx & 0x00FF;
3514 if (!(modeflag & HalfDCLK)) {
3515 tempcx = pVBInfo->VGAHDE;
3516 if (tempcx >= pVBInfo->HDE) {
3524 if (pVBInfo->VBInfo & SetCRT2ToTV) { /* 301b */
3525 if (pVBInfo->VGAHDE >= 1024) {
3527 if (pVBInfo->VGAHDE >= 1280) {
3529 tempbx = tempbx & 0xDFFF;
3534 if (!(tempbx & 0x2000)) {
3535 if (modeflag & HalfDCLK)
3536 tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
3539 tempeax = pVBInfo->VGAHDE;
3540 tempebx = (tempcx & 0xFF00) >> 8;
3541 longtemp = tempeax * tempebx;
3542 tempecx = tempcx & 0x00FF;
3543 longtemp = longtemp / tempecx;
3548 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3549 | VB_SIS302LV | VB_XGI301C)) {
3550 tempecx = tempecx * 8;
3553 longtemp = longtemp * tempecx;
3554 tempecx = pVBInfo->HDE;
3555 temp2 = longtemp % tempecx;
3556 tempeax = longtemp / tempecx;
3560 tempax = (unsigned short)tempeax;
3563 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3564 | VB_SIS302LV | VB_XGI301C)) {
3565 tempcx = ((tempax & 0xFF00) >> 5) >> 8;
3570 tempbx = (unsigned short)(((tempeax & 0x0000FF00) & 0x1F00)
3571 | (tempbx & 0x00FF));
3572 tempax = (unsigned short)(((tempeax & 0x000000FF) << 8)
3573 | (tempax & 0x00FF));
3574 temp = (tempax & 0xFF00) >> 8;
3576 temp = (tempax & 0x00FF) >> 8;
3579 xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp);
3580 temp = (tempbx & 0xFF00) >> 8;
3581 xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
3582 temp = tempcx & 0x00FF;
3584 if (tempbx & 0x2000)
3587 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
3590 xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
3591 if (pVBInfo->TVInfo & TVSetPAL) {
3599 temp = tempbx & 0x00FF;
3600 xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp);
3601 temp = tempcx & 0x00FF;
3602 xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp);
3604 temp = ((tempcx & 0xFF00) >> 8) & 0x03;
3606 temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
3608 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
3611 if (pVBInfo->TVInfo & TVSetYPbPr525p)
3614 if (pVBInfo->TVInfo & TVSetYPbPr750p)
3618 xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp);
3619 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */
3620 xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short)(temp - 3));
3622 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) {
3623 if (pVBInfo->TVInfo & NTSC1024x768) {
3624 TimingPoint = XGI_NTSC1024AdjTime;
3625 for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
3626 xgifb_reg_set(pVBInfo->Part2Port, i,
3629 xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72);
3633 /* Modify for 301C PALM Support */
3634 if (pVBInfo->VBType & VB_XGI301C) {
3635 if (pVBInfo->TVInfo & TVSetPALM)
3636 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08,
3637 0x08); /* PALM Mode */
3640 if (pVBInfo->TVInfo & TVSetPALM) {
3641 tempax = xgifb_reg_get(pVBInfo->Part2Port, 0x01);
3643 xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax);
3645 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF);
3648 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3649 if (!(pVBInfo->VBInfo & SetInSlaveMode))
3650 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00);
3654 static void XGI_SetLCDRegs(unsigned short ModeIdIndex,
3655 struct vb_device_info *pVBInfo)
3657 unsigned short pushbx, tempax, tempbx, tempcx, temp, tempah,
3660 struct XGI_LCDDesStruct const *LCDBDesPtr = NULL;
3662 /* si+Ext_ResInfo */
3663 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
3666 tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
3668 if (XGI_IsLCDDualLink(pVBInfo))
3672 temp = tempbx & 0x00FF;
3673 xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp);
3674 temp = (tempbx & 0xFF00) >> 8;
3676 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
3679 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp);
3680 tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
3682 temp = tempbx & 0x00FF;
3683 xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp);
3684 temp = ((tempbx & 0xFF00) >> 8) & 0x07;
3685 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
3687 tempcx = pVBInfo->VT - 1;
3688 temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
3689 xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp);
3690 temp = (tempcx & 0xFF00) >> 8;
3692 xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp);
3693 xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
3694 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
3695 xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
3696 xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
3698 /* Customized LCDB Does not add */
3699 if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
3700 LCDBDesPtr = XGI_GetLcdPtr(xgifb_lcddldes, ModeIdIndex,
3703 LCDBDesPtr = XGI_GetLcdPtr(XGI_LCDDesDataTable, ModeIdIndex,
3706 tempah = pVBInfo->LCDResInfo;
3707 tempah &= PanelResInfo;
3709 if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) {
3712 } else if ((tempah == Panel_1280x1024) ||
3713 (tempah == Panel_1280x1024x75)) {
3716 } else if (tempah == Panel_1400x1050) {
3724 if (pVBInfo->LCDInfo & EnableScalingLCD) {
3725 tempbx = pVBInfo->HDE;
3726 tempcx = pVBInfo->VDE;
3730 tempax = pVBInfo->VT;
3731 pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
3732 pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
3733 pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
3734 pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
3735 tempbx = pVBInfo->LCDVDES;
3738 if (tempcx >= tempax)
3739 tempcx -= tempax; /* lcdvdes */
3741 temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
3742 xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp);
3743 temp = tempcx & 0x00FF;
3744 xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp);
3745 tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
3746 tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
3750 xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah);
3753 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
3755 tempax = pVBInfo->VT;
3756 tempbx = pVBInfo->LCDVRS;
3759 if (tempcx >= tempax)
3762 temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
3763 xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp);
3764 temp = (tempbx & 0xFF00) >> 8;
3766 temp |= (tempcx & 0x000F);
3767 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
3769 tempax = pVBInfo->HT;
3770 tempbx = pVBInfo->LCDHDES;
3773 if (XGI_IsLCDDualLink(pVBInfo)) {
3779 if (pVBInfo->VBType & VB_SIS302LV)
3782 if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
3787 if (tempcx >= tempax)
3790 temp = tempbx & 0x00FF;
3791 xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
3792 temp = ((tempbx & 0xFF00) >> 8) << 4;
3793 xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp);
3794 temp = tempcx & 0x00FF;
3795 xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
3796 temp = (tempcx & 0xFF00) >> 8;
3797 xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp);
3799 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
3801 tempax = pVBInfo->HT;
3802 tempbx = pVBInfo->LCDHRS;
3803 if (XGI_IsLCDDualLink(pVBInfo)) {
3809 if (pVBInfo->VBType & VB_SIS302LV)
3814 if (tempcx >= tempax)
3817 temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
3818 xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp);
3820 temp = (tempbx & 0xFF00) >> 8;
3822 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
3823 temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
3824 xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp);
3826 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3827 if (pVBInfo->VGAVDE == 525) {
3828 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
3829 | VB_SIS301LV | VB_SIS302LV
3835 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
3836 xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3);
3839 if (pVBInfo->VGAVDE == 420) {
3840 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
3841 | VB_SIS301LV | VB_SIS302LV
3846 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
3852 * Function : XGI_GetTap4Ptr
3854 * Output : di -> Tap4 Reg. Setting Pointer
3857 static struct XGI301C_Tap4TimingStruct const
3858 *XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo)
3860 unsigned short tempax, tempbx, i;
3861 struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
3864 tempax = pVBInfo->VGAHDE;
3865 tempbx = pVBInfo->HDE;
3867 tempax = pVBInfo->VGAVDE;
3868 tempbx = pVBInfo->VDE;
3871 if (tempax <= tempbx)
3872 return &xgifb_tap4_timing[0];
3873 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */
3875 if (pVBInfo->TVInfo & TVSetPAL)
3876 Tap4TimingPtr = PALTap4Timing;
3878 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
3879 if ((pVBInfo->TVInfo & TVSetYPbPr525i) ||
3880 (pVBInfo->TVInfo & TVSetYPbPr525p))
3881 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing;
3882 if (pVBInfo->TVInfo & TVSetYPbPr750p)
3883 Tap4TimingPtr = YPbPr750pTap4Timing;
3886 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3887 Tap4TimingPtr = xgifb_tap4_timing;
3890 while (Tap4TimingPtr[i].DE != 0xFFFF) {
3891 if (Tap4TimingPtr[i].DE == tempax)
3895 return &Tap4TimingPtr[i];
3898 static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
3900 unsigned short i, j;
3901 struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
3903 if (!(pVBInfo->VBType & VB_XGI301C))
3906 Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
3907 for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
3908 xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
3910 if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
3911 !(pVBInfo->VBInfo & SetCRT2ToHiVision)) {
3912 /* Set Vertical Scaling */
3913 Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo);
3914 for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
3915 xgifb_reg_set(pVBInfo->Part2Port,
3917 Tap4TimingPtr->Reg[j]);
3920 if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
3921 !(pVBInfo->VBInfo & SetCRT2ToHiVision))
3922 /* Enable V.Scaling */
3923 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04);
3925 /* Enable H.Scaling */
3926 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10);
3929 static void XGI_SetGroup3(unsigned short ModeIdIndex,
3930 struct vb_device_info *pVBInfo)
3933 unsigned char const *tempdi;
3934 unsigned short modeflag;
3936 /* si+Ext_ResInfo */
3937 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3939 xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00);
3940 if (pVBInfo->TVInfo & TVSetPAL) {
3941 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
3942 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
3944 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5);
3945 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7);
3948 if (!(pVBInfo->VBInfo & SetCRT2ToTV))
3951 if (pVBInfo->TVInfo & TVSetPALM) {
3952 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
3953 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
3954 xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8);
3957 if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo
3958 & SetCRT2ToYPbPr525750)) {
3959 if (pVBInfo->TVInfo & TVSetYPbPr525i)
3962 tempdi = XGI330_HiTVGroup3Data;
3963 if (pVBInfo->SetFlag & TVSimuMode) {
3964 tempdi = XGI330_HiTVGroup3Simu;
3965 if (!(modeflag & Charx8Dot))
3966 tempdi = XGI330_HiTVGroup3Text;
3969 if (pVBInfo->TVInfo & TVSetYPbPr525p)
3970 tempdi = XGI330_Ren525pGroup3;
3972 if (pVBInfo->TVInfo & TVSetYPbPr750p)
3973 tempdi = XGI330_Ren750pGroup3;
3975 for (i = 0; i <= 0x3E; i++)
3976 xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]);
3978 if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
3979 if (pVBInfo->TVInfo & TVSetYPbPr525p)
3980 xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f);
3985 static void XGI_SetGroup4(unsigned short ModeIdIndex,
3986 unsigned short RefreshRateTableIndex,
3987 struct vb_device_info *pVBInfo)
3989 unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
3991 unsigned long tempebx, tempeax, templong;
3993 /* si+Ext_ResInfo */
3994 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3995 temp = pVBInfo->RVBHCFACT;
3996 xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp);
3998 tempbx = pVBInfo->RVBHCMAX;
3999 temp = tempbx & 0x00FF;
4000 xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp);
4001 temp2 = ((tempbx & 0xFF00) >> 8) << 7;
4002 tempcx = pVBInfo->VGAHT - 1;
4003 temp = tempcx & 0x00FF;
4004 xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp);
4006 temp = ((tempcx & 0xFF00) >> 8) << 3;
4009 tempcx = pVBInfo->VGAVT - 1;
4010 if (!(pVBInfo->VBInfo & SetCRT2ToTV))
4013 temp = tempcx & 0x00FF;
4014 xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp);
4015 temp = temp2 | ((tempcx & 0xFF00) >> 8);
4016 xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp);
4017 xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08);
4018 tempcx = pVBInfo->VBInfo;
4019 tempbx = pVBInfo->VGAHDE;
4021 if (modeflag & HalfDCLK)
4024 if (XGI_IsLCDDualLink(pVBInfo))
4027 if (tempcx & SetCRT2ToHiVision) {
4033 } else if (tempcx & SetCRT2ToTV) {
4039 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4046 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) {
4048 if (pVBInfo->VGAHDE == 1280)
4050 if (pVBInfo->VGAHDE == 1024)
4053 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
4055 tempebx = pVBInfo->VDE;
4057 tempcx = pVBInfo->RVBHRS;
4058 temp = tempcx & 0x00FF;
4059 xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp);
4061 tempeax = pVBInfo->VGAVDE;
4064 if (tempeax <= tempebx) {
4065 tempcx = tempcx & (~0x4000);
4066 tempeax = pVBInfo->VGAVDE;
4071 templong = (tempeax * 256 * 1024) % tempebx;
4072 tempeax = (tempeax * 256 * 1024) / tempebx;
4078 temp = (unsigned short)(tempebx & 0x000000FF);
4079 xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp);
4081 temp = (unsigned short)((tempebx & 0x0000FF00) >> 8);
4082 xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp);
4083 tempbx = (unsigned short)(tempebx >> 16);
4084 temp = tempbx & 0x00FF;
4086 temp |= ((tempcx & 0xFF00) >> 8);
4087 xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp);
4090 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4091 | VB_SIS302LV | VB_XGI301C)) {
4093 xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp);
4094 tempax = pVBInfo->VGAHDE;
4095 if (modeflag & HalfDCLK)
4098 if (XGI_IsLCDDualLink(pVBInfo))
4101 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4104 } else if (pVBInfo->VGAHDE > 800) {
4105 if (pVBInfo->VGAHDE == 1024)
4106 tempax = (tempax * 25 / 32) - 1;
4108 tempax = (tempax * 20 / 32) - 1;
4112 temp = (tempax & 0xFF00) >> 8;
4113 temp = (temp & 0x0003) << 4;
4114 xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp);
4115 temp = tempax & 0x00FF;
4116 xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp);
4118 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) {
4119 if (pVBInfo->VGAHDE > 800)
4120 xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08);
4124 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4125 if (!(pVBInfo->TVInfo & (NTSC1024x768
4126 | TVSetYPbPr525p | TVSetYPbPr750p
4127 | TVSetHiVision))) {
4129 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
4130 !(pVBInfo->TVInfo & TVSimuMode))
4135 xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
4136 tempbx = pVBInfo->HT;
4137 if (XGI_IsLCDDualLink(pVBInfo))
4139 tempbx = (tempbx >> 1) - 2;
4140 temp = ((tempbx & 0x0700) >> 8) << 3;
4141 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
4142 temp = tempbx & 0x00FF;
4143 xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp);
4147 XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
4150 static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
4152 xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
4155 static void XGI_SetGroup5(struct vb_device_info *pVBInfo)
4157 if (pVBInfo->ModeType == ModeVGA) {
4158 if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
4159 | DisableCRT2Display))) {
4160 XGINew_EnableCRT2(pVBInfo);
4165 static void XGI_DisableGatingCRT(struct vb_device_info *pVBInfo)
4167 xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00);
4170 static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info,
4171 unsigned short ModeNo,
4172 unsigned short ModeIdIndex)
4174 unsigned short xres, yres, colordepth, modeflag, resindex;
4176 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
4177 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
4178 yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
4179 /* si+St_ModeFlag */
4180 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4182 if (!(modeflag & Charx8Dot)) {
4187 if ((ModeNo > 0x13) && (modeflag & HalfDCLK))
4190 if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
4193 if (xres > xgifb_info->lvds_data.LVDSHDE)
4196 if (yres > xgifb_info->lvds_data.LVDSVDE)
4199 if (xres != xgifb_info->lvds_data.LVDSHDE ||
4200 yres != xgifb_info->lvds_data.LVDSVDE) {
4201 colordepth = XGI_GetColorDepth(ModeIdIndex);
4208 static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
4210 unsigned short ModeIdIndex,
4211 struct vb_device_info *pVBInfo)
4213 unsigned char temp, Miscdata;
4214 unsigned short xres, yres, modeflag, resindex;
4215 unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
4216 unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
4217 unsigned short value;
4219 temp = (unsigned char)((xgifb_info->lvds_data.LVDS_Capability &
4220 (LCDPolarity << 8)) >> 8);
4221 temp &= LCDPolarity;
4222 Miscdata = inb(pVBInfo->P3cc);
4224 outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2);
4226 temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity;
4227 /* SR35[7] FP VSync polarity */
4228 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80);
4229 /* SR30[5] FP HSync polarity */
4230 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1);
4232 if (chip_id == XG27)
4233 XGI_SetXG27FPBits(pVBInfo);
4235 XGI_SetXG21FPBits(pVBInfo);
4237 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
4238 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
4239 yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
4240 /* si+St_ModeFlag */
4241 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4243 if (!(modeflag & Charx8Dot))
4244 xres = xres * 8 / 9;
4246 LVDSHT = xgifb_info->lvds_data.LVDSHT;
4248 LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2;
4250 if (LVDSHBS > LVDSHT)
4253 LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP;
4254 if (LVDSHRS > LVDSHT)
4257 LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC;
4258 if (LVDSHRE > LVDSHT)
4261 LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE;
4263 LVDSVT = xgifb_info->lvds_data.LVDSVT;
4265 LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2;
4266 if (modeflag & DoubleScanMode)
4267 LVDSVBS += yres / 2;
4269 if (LVDSVBS > LVDSVT)
4272 LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP;
4273 if (LVDSVRS > LVDSVT)
4276 LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC;
4277 if (LVDSVRE > LVDSVT)
4280 LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE;
4282 temp = xgifb_reg_get(pVBInfo->P3d4, 0x11);
4283 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
4285 if (!(modeflag & Charx8Dot))
4286 xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1);
4288 /* HT SR0B[1:0] CR00 */
4289 value = (LVDSHT >> 3) - 5;
4290 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
4291 xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF));
4293 /* HBS SR0B[5:4] CR02 */
4294 value = (LVDSHBS >> 3) - 1;
4295 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
4296 xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF));
4298 /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
4299 value = (LVDSHBE >> 3) - 1;
4300 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
4301 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
4302 xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
4304 /* HRS SR0B[7:6] CR04 */
4305 value = (LVDSHRS >> 3) + 2;
4306 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
4307 xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF));
4309 /* Panel HRS SR2F[1:0] SR2E[7:0] */
4311 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
4312 xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF));
4314 /* HRE SR0C[2] CR05[4:0] */
4315 value = (LVDSHRE >> 3) + 2;
4316 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
4317 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
4319 /* Panel HRE SR2F[7:2] */
4321 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
4323 /* VT SR0A[0] CR07[5][0] CR06 */
4325 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
4326 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
4327 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
4328 xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF));
4330 /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
4331 value = LVDSVBS - 1;
4332 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
4333 xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
4334 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
4335 xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF));
4337 /* VBE SR0A[4] CR16 */
4338 value = LVDSVBE - 1;
4339 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
4340 xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF));
4342 /* VRS SR0A[3] CR7[7][2] CR10 */
4343 value = LVDSVRS - 1;
4344 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
4345 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
4346 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
4347 xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF));
4349 if (chip_id == XG27) {
4350 /* Panel VRS SR35[2:0] SR34[7:0] */
4351 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07,
4352 (value & 0x700) >> 8);
4353 xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF);
4355 /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
4356 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03,
4357 (value & 0x600) >> 9);
4358 xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF);
4359 xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01);
4362 /* VRE SR0A[5] CR11[3:0] */
4363 value = LVDSVRE - 1;
4364 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
4365 xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
4367 /* Panel VRE SR3F[7:2] */
4368 if (chip_id == XG27)
4369 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
4370 (value << 2) & 0xFC);
4372 /* SR3F[7] has to be 0, h/w bug */
4373 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
4374 (value << 2) & 0x7C);
4376 for (temp = 0, value = 0; temp < 3; temp++) {
4377 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
4378 xgifb_reg_set(pVBInfo->P3c4,
4379 0x2B, xgifb_info->lvds_data.VCLKData1);
4380 xgifb_reg_set(pVBInfo->P3c4,
4381 0x2C, xgifb_info->lvds_data.VCLKData2);
4385 if (!(modeflag & Charx8Dot)) {
4386 inb(pVBInfo->P3da); /* reset 3da */
4387 outb(0x13, pVBInfo->P3c0); /* set index */
4388 /* set data, panning = 0, shift left 1 dot*/
4389 outb(0x00, pVBInfo->P3c0);
4391 inb(pVBInfo->P3da); /* Enable Attribute */
4392 outb(0x20, pVBInfo->P3c0);
4394 inb(pVBInfo->P3da); /* reset 3da */
4399 * Function : XGI_IsLCDON
4401 * Output : 0 : Skip PSC Control
4405 static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
4407 unsigned short tempax;
4409 tempax = pVBInfo->VBInfo;
4410 if (tempax & SetCRT2ToDualEdge)
4412 else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode))
4418 static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
4419 struct xgi_hw_device_info *HwDeviceExtension,
4420 struct vb_device_info *pVBInfo)
4422 unsigned short tempah = 0;
4424 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4425 | VB_SIS302LV | VB_XGI301C)) {
4427 if (!(pVBInfo->VBInfo &
4428 (DisableCRT2Display | SetSimuScanMode))) {
4429 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
4430 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
4431 tempah = 0x7F; /* Disable Channel A */
4435 /* disable part4_1f */
4436 xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah);
4438 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
4439 if (((pVBInfo->VBInfo &
4440 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) ||
4441 (XGI_IsLCDON(pVBInfo)))
4442 /* LVDS Driver power down */
4443 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80);
4446 if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA |
4448 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
4450 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
4452 xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf);
4454 /* disable TV as primary VGA swap */
4455 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf);
4457 if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
4458 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf);
4460 if ((pVBInfo->VBInfo &
4461 (DisableCRT2Display | SetSimuScanMode)) ||
4462 (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
4464 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
4465 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
4467 if ((pVBInfo->VBInfo &
4468 (DisableCRT2Display | SetSimuScanMode)) ||
4469 (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) ||
4471 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
4472 /* save Part1 index 0 */
4473 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
4474 /* BTDAC = 1, avoid VB reset */
4475 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10);
4477 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
4478 /* restore Part1 index 0 */
4479 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
4481 } else { /* {301} */
4482 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
4483 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
4485 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
4486 /* Disable TV asPrimary VGA swap */
4487 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF);
4490 if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA
4492 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
4497 * Function : XGI_GetTVPtrIndex
4500 * Description : bx 0 : ExtNTSC
4513 static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
4515 unsigned short tempbx = 0;
4517 if (pVBInfo->TVInfo & TVSetPAL)
4519 if (pVBInfo->TVInfo & TVSetHiVision)
4521 if (pVBInfo->TVInfo & TVSetYPbPr525i)
4523 if (pVBInfo->TVInfo & TVSetYPbPr525p)
4525 if (pVBInfo->TVInfo & TVSetYPbPr750p)
4527 if (pVBInfo->TVInfo & TVSimuMode)
4534 * Function : XGI_GetTVPtrIndex2
4536 * Output : bx 0 : NTSC
4541 * 5 : PAL-M 1024x768
4546 * 1 : 301B/302B/301LV/302LV
4549 static void XGI_GetTVPtrIndex2(unsigned short *tempbx,
4550 unsigned char *tempcl,
4551 unsigned char *tempch,
4552 struct vb_device_info *pVBInfo)
4558 if (pVBInfo->TVInfo & TVSetPAL)
4561 if (pVBInfo->TVInfo & TVSetPALM)
4564 if (pVBInfo->TVInfo & TVSetPALN)
4567 if (pVBInfo->TVInfo & NTSC1024x768) {
4569 if (pVBInfo->TVInfo & TVSetPALM)
4573 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4574 | VB_SIS302LV | VB_XGI301C)) {
4575 if (!(pVBInfo->VBInfo & SetInSlaveMode) || (pVBInfo->TVInfo
4582 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4583 | VB_SIS302LV | VB_XGI301C))
4587 static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
4589 unsigned char tempah, tempbl, tempbh;
4591 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4592 | VB_SIS302LV | VB_XGI301C)) {
4593 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA
4594 | SetCRT2ToTV | SetCRT2ToRAMDAC)) {
4596 tempbl = XGI301TVDelay;
4598 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
4600 if (pVBInfo->VBInfo &
4601 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
4602 tempbh = XGI301LCDDelay;
4604 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
4610 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D);
4612 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
4613 | SetCRT2ToTV)) { /* Channel B */
4618 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
4623 xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah);
4628 static void XGI_SetLCDCap_A(unsigned short tempcx,
4629 struct vb_device_info *pVBInfo)
4631 unsigned short temp;
4633 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
4635 if (temp & LCDRGB18Bit) {
4636 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
4638 (unsigned short)(0x20 | (tempcx & 0x00C0)));
4639 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
4641 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
4642 (unsigned short)(0x30 | (tempcx & 0x00C0)));
4643 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
4648 * Function : XGI_SetLCDCap_B
4649 * Input : cx -> LCD Capability
4653 static void XGI_SetLCDCap_B(unsigned short tempcx,
4654 struct vb_device_info *pVBInfo)
4656 if (tempcx & EnableLCD24bpp) { /* 24bits */
4657 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
4658 (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x0c));
4660 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
4661 (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x18));
4666 static void XGI_LongWait(struct vb_device_info *pVBInfo)
4670 i = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
4673 for (i = 0; i < 0xFFFF; i++) {
4674 if (!(inb(pVBInfo->P3da) & 0x08))
4678 for (i = 0; i < 0xFFFF; i++) {
4679 if ((inb(pVBInfo->P3da) & 0x08))
4685 static void SetSpectrum(struct vb_device_info *pVBInfo)
4687 unsigned short index;
4689 index = XGI_GetLCDCapPtr(pVBInfo);
4691 /* disable down spectrum D[4] */
4692 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F);
4693 XGI_LongWait(pVBInfo);
4694 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
4695 XGI_LongWait(pVBInfo);
4697 xgifb_reg_set(pVBInfo->Part4Port, 0x31,
4698 pVBInfo->LCDCapList[index].Spectrum_31);
4699 xgifb_reg_set(pVBInfo->Part4Port, 0x32,
4700 pVBInfo->LCDCapList[index].Spectrum_32);
4701 xgifb_reg_set(pVBInfo->Part4Port, 0x33,
4702 pVBInfo->LCDCapList[index].Spectrum_33);
4703 xgifb_reg_set(pVBInfo->Part4Port, 0x34,
4704 pVBInfo->LCDCapList[index].Spectrum_34);
4705 XGI_LongWait(pVBInfo);
4706 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
4709 static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
4711 unsigned short tempcx;
4713 tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
4715 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV |
4716 VB_SIS302LV | VB_XGI301C)) {
4717 if (pVBInfo->VBType &
4718 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
4719 /* Set 301LV Capability */
4720 xgifb_reg_set(pVBInfo->Part4Port, 0x24,
4721 (unsigned char)(tempcx & 0x1F));
4724 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D,
4725 ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
4726 (unsigned short)((tempcx & (EnableVBCLKDRVLOW |
4727 EnablePLLSPLOW)) >> 8));
4729 if (pVBInfo->VBInfo & SetCRT2ToLCD)
4730 XGI_SetLCDCap_B(tempcx, pVBInfo);
4731 else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
4732 XGI_SetLCDCap_A(tempcx, pVBInfo);
4734 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
4735 if (tempcx & EnableSpectrum)
4736 SetSpectrum(pVBInfo);
4740 XGI_SetLCDCap_A(tempcx, pVBInfo);
4745 * Function : XGI_SetAntiFlicker
4748 * Description : Set TV Customized Param.
4750 static void XGI_SetAntiFlicker(struct vb_device_info *pVBInfo)
4752 unsigned short tempbx;
4754 unsigned char tempah;
4756 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
4759 tempbx = XGI_GetTVPtrIndex(pVBInfo);
4761 tempah = TVAntiFlickList[tempbx];
4764 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
4767 static void XGI_SetEdgeEnhance(struct vb_device_info *pVBInfo)
4769 unsigned short tempbx;
4771 unsigned char tempah;
4773 tempbx = XGI_GetTVPtrIndex(pVBInfo);
4775 tempah = TVEdgeList[tempbx];
4778 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
4781 static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
4783 unsigned short tempbx;
4785 unsigned char tempcl, tempch;
4787 unsigned long tempData;
4789 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
4790 tempData = TVPhaseList[tempbx];
4792 xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short)(tempData
4794 xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short)((tempData
4795 & 0x0000FF00) >> 8));
4796 xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short)((tempData
4797 & 0x00FF0000) >> 16));
4798 xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short)((tempData
4799 & 0xFF000000) >> 24));
4802 static void XGI_SetYFilter(unsigned short ModeIdIndex,
4803 struct vb_device_info *pVBInfo)
4805 unsigned short tempbx, index;
4806 unsigned char const *filterPtr;
4807 unsigned char tempcl, tempch, tempal;
4809 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
4814 filterPtr = NTSCYFilter1;
4818 filterPtr = PALYFilter1;
4825 filterPtr = xgifb_palmn_yfilter1;
4833 filterPtr = xgifb_yfilter2;
4840 tempal = XGI330_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
4846 if ((tempcl == 0) && (tempch == 1)) {
4847 xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0);
4848 xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0);
4849 xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0);
4850 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
4852 xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
4853 xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
4854 xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
4855 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
4858 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4859 | VB_SIS302LV | VB_XGI301C)) {
4860 xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
4861 xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
4862 xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
4867 * Function : XGI_OEM310Setting
4870 * Description : Customized Param. for 301
4872 static void XGI_OEM310Setting(unsigned short ModeIdIndex,
4873 struct vb_device_info *pVBInfo)
4875 XGI_SetDelayComp(pVBInfo);
4877 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
4878 XGI_SetLCDCap(pVBInfo);
4880 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4881 XGI_SetPhaseIncr(pVBInfo);
4882 XGI_SetYFilter(ModeIdIndex, pVBInfo);
4883 XGI_SetAntiFlicker(pVBInfo);
4885 if (pVBInfo->VBType & VB_SIS301)
4886 XGI_SetEdgeEnhance(pVBInfo);
4891 * Function : XGI_SetCRT2ModeRegs
4894 * Description : Origin code for crt2group
4896 static void XGI_SetCRT2ModeRegs(struct vb_device_info *pVBInfo)
4898 unsigned short tempbl;
4901 unsigned char tempah;
4904 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
4905 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
4906 tempah &= ~0x10; /* BTRAMDAC */
4907 tempah |= 0x40; /* BTRAM */
4909 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
4911 tempah = 0x40; /* BTDRAM */
4912 tempcl = pVBInfo->ModeType;
4916 tempah = 0x008 >> tempcl;
4921 if (pVBInfo->VBInfo & SetInSlaveMode)
4922 tempah ^= 0x50; /* BTDAC */
4926 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
4930 if (pVBInfo->VBInfo & DisableCRT2Display)
4936 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV |
4937 SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
4940 if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
4941 (!(pVBInfo->VBInfo & SetSimuScanMode))) {
4947 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
4952 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)))
4958 if (!(pVBInfo->VBInfo & SetInSlaveMode))
4961 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
4962 tempah = tempah ^ 0x05;
4963 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
4964 tempah = tempah ^ 0x01;
4967 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
4971 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
4973 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
4974 | XGI_SetCRT2ToLCDA)) {
4976 if ((pVBInfo->ModeType == ModeVGA) && !(pVBInfo->VBInfo
4977 & SetInSlaveMode)) {
4982 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4984 if (pVBInfo->VBInfo & DriverMode)
4985 tempah = tempah ^ 0x20;
4988 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
4991 if (pVBInfo->LCDInfo & SetLCDDualLink)
4994 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4995 if (pVBInfo->TVInfo & RPLLDIV2XO)
4999 if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
5000 (pVBInfo->LCDResInfo == Panel_1280x1024x75))
5003 if (pVBInfo->LCDResInfo == Panel_1280x960)
5006 xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah);
5009 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5010 | VB_SIS302LV | VB_XGI301C)) {
5014 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
5016 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
5017 tempah |= 0x04; /* shampoo 0129 */
5020 xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah);
5023 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5024 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5028 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
5032 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5033 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5036 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah);
5041 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) {
5043 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
5047 xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah);
5049 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
5050 if (pVBInfo->LCDInfo & SetLCDDualLink) {
5051 xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20);
5052 xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10);
5057 void XGI_UnLockCRT2(struct vb_device_info *pVBInfo)
5059 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
5062 void XGI_LockCRT2(struct vb_device_info *pVBInfo)
5064 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
5067 unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
5068 unsigned short ModeNo,
5069 unsigned short ModeIdIndex,
5070 struct vb_device_info *pVBInfo)
5072 static const u8 LCDARefreshIndex[] = {
5073 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00 };
5075 unsigned short RefreshRateTableIndex, i, index, temp;
5077 index = xgifb_reg_get(pVBInfo->P3d4, 0x33);
5078 index >>= pVBInfo->SelectCRT2Rate;
5081 if (pVBInfo->LCDInfo & LCDNonExpanding)
5087 if (pVBInfo->SetFlag & ProgrammingCRT2) {
5088 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
5089 temp = LCDARefreshIndex[pVBInfo->LCDResInfo & 0x07];
5096 RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex;
5097 ModeNo = XGI330_RefIndex[RefreshRateTableIndex].ModeID;
5098 if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
5099 if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 800) &&
5100 (XGI330_RefIndex[RefreshRateTableIndex].YRes == 600)) {
5103 /* do the similar adjustment like XGISearchCRT1Rate() */
5104 if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1024) &&
5105 (XGI330_RefIndex[RefreshRateTableIndex].YRes == 768)) {
5108 if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
5109 (XGI330_RefIndex[RefreshRateTableIndex].YRes == 1024)) {
5116 if (XGI330_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo)
5118 temp = XGI330_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
5119 temp &= ModeTypeMask;
5120 if (temp < pVBInfo->ModeType)
5125 } while (index != 0xFFFF);
5126 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
5127 if (pVBInfo->VBInfo & SetInSlaveMode) {
5128 temp = XGI330_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
5129 if (temp & InterlaceMode)
5134 if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
5135 temp = XGI_AjustCRT2Rate(ModeIdIndex, RefreshRateTableIndex,
5138 return RefreshRateTableIndex + i;
5141 static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
5142 struct xgi_hw_device_info *HwDeviceExtension,
5143 struct vb_device_info *pVBInfo)
5145 unsigned short RefreshRateTableIndex;
5147 pVBInfo->SetFlag |= ProgrammingCRT2;
5148 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
5149 ModeIdIndex, pVBInfo);
5150 XGI_GetLVDSResInfo(ModeIdIndex, pVBInfo);
5151 XGI_GetLVDSData(ModeIdIndex, pVBInfo);
5152 XGI_ModCRT1Regs(ModeIdIndex, HwDeviceExtension, pVBInfo);
5153 XGI_SetLVDSRegs(ModeIdIndex, pVBInfo);
5154 XGI_SetCRT2ECLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5157 static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
5158 struct xgi_hw_device_info *HwDeviceExtension,
5159 struct vb_device_info *pVBInfo)
5161 unsigned short ModeIdIndex, RefreshRateTableIndex;
5163 pVBInfo->SetFlag |= ProgrammingCRT2;
5164 XGI_SearchModeID(ModeNo, &ModeIdIndex);
5165 pVBInfo->SelectCRT2Rate = 4;
5166 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
5167 ModeIdIndex, pVBInfo);
5168 XGI_SaveCRT2Info(ModeNo, pVBInfo);
5169 XGI_GetCRT2ResInfo(ModeIdIndex, pVBInfo);
5170 XGI_GetCRT2Data(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5171 XGI_PreSetGroup1(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5172 XGI_SetGroup1(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5173 XGI_SetLockRegs(ModeNo, ModeIdIndex, pVBInfo);
5174 XGI_SetGroup2(ModeNo, ModeIdIndex, pVBInfo);
5175 XGI_SetLCDRegs(ModeIdIndex, pVBInfo);
5176 XGI_SetTap4Regs(pVBInfo);
5177 XGI_SetGroup3(ModeIdIndex, pVBInfo);
5178 XGI_SetGroup4(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5179 XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5180 XGI_SetGroup5(pVBInfo);
5181 XGI_AutoThreshold(pVBInfo);
5185 void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
5187 unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
5188 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
5191 unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
5193 unsigned char CR17, CR63, SR31;
5194 unsigned short temp;
5198 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
5200 /* to fix XG42 single LCD sense to CRT+LCD */
5201 xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A);
5202 xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get(
5203 pVBInfo->P3d4, 0x53) | 0x02));
5205 SR31 = xgifb_reg_get(pVBInfo->P3c4, 0x31);
5206 CR63 = xgifb_reg_get(pVBInfo->P3d4, 0x63);
5207 SR01 = xgifb_reg_get(pVBInfo->P3c4, 0x01);
5209 xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char)(SR01 & 0xDF));
5210 xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char)(CR63 & 0xBF));
5212 CR17 = xgifb_reg_get(pVBInfo->P3d4, 0x17);
5213 xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char)(CR17 | 0x80));
5215 SR1F = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
5216 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char)(SR1F | 0x04));
5218 SR07 = xgifb_reg_get(pVBInfo->P3c4, 0x07);
5219 xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char)(SR07 & 0xFB));
5220 SR06 = xgifb_reg_get(pVBInfo->P3c4, 0x06);
5221 xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char)(SR06 & 0xC3));
5223 xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00);
5225 for (i = 0; i < 8; i++)
5226 xgifb_reg_set(pVBInfo->P3d4, (unsigned short)i, CRTCData[i]);
5228 for (i = 8; i < 11; i++)
5229 xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 8),
5232 for (i = 11; i < 13; i++)
5233 xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 4),
5236 for (i = 13; i < 16; i++)
5237 xgifb_reg_set(pVBInfo->P3c4, (unsigned short)(i - 3),
5240 xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char)(CRTCData[16]
5243 xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00);
5244 xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B);
5245 xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1);
5247 outb(0x00, pVBInfo->P3c8);
5249 for (i = 0; i < 256 * 3; i++)
5250 outb(0x0F, (pVBInfo->P3c8 + 1)); /* DAC_TEST_PARMS */
5254 XGI_WaitDisply(pVBInfo);
5255 temp = inb(pVBInfo->P3c2);
5258 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
5260 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
5262 /* avoid display something, set BLACK DAC if not restore DAC */
5263 outb(0x00, pVBInfo->P3c8);
5265 for (i = 0; i < 256 * 3; i++)
5266 outb(0, (pVBInfo->P3c8 + 1));
5268 xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01);
5269 xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63);
5270 xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31);
5272 xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get(
5273 pVBInfo->P3d4, 0x53) & 0xFD));
5274 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char)SR1F);
5277 static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
5278 struct xgi_hw_device_info *HwDeviceExtension,
5279 struct vb_device_info *pVBInfo)
5281 unsigned short tempah;
5283 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5284 | VB_SIS302LV | VB_XGI301C)) {
5285 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5287 xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20);
5289 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV |
5291 tempah = xgifb_reg_get(pVBInfo->P3c4, 0x32);
5293 if (pVBInfo->VBInfo & SetInSlaveMode) {
5294 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
5297 xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah);
5298 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20);
5300 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E);
5302 if (!(tempah & 0x80))
5303 xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
5304 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
5307 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5308 xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0,
5309 0x20); /* shampoo 0129 */
5310 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
5311 if (pVBInfo->VBInfo &
5312 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
5313 /* LVDS PLL power on */
5314 xgifb_reg_and(pVBInfo->Part4Port, 0x2A,
5316 /* LVDS Driver power on */
5317 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F);
5323 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5326 if (!(pVBInfo->VBInfo & SetSimuScanMode) &&
5327 (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
5328 (pVBInfo->VBInfo & SetCRT2ToDualEdge)) {
5329 tempah = tempah & 0x40;
5330 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
5331 tempah = tempah ^ 0xC0;
5335 /* EnablePart4_1F */
5336 xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah);
5338 XGI_DisableGatingCRT(pVBInfo);
5339 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
5342 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
5343 | XGI_SetCRT2ToLCDA))
5345 xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20);
5347 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E);
5348 if (!(tempah & 0x80))
5349 xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
5351 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
5352 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
5356 static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
5357 struct xgi_hw_device_info *HwDeviceExtension,
5358 unsigned short ModeNo, unsigned short ModeIdIndex,
5359 struct vb_device_info *pVBInfo)
5361 unsigned short RefreshRateTableIndex, temp;
5363 XGI_SetSeqRegs(pVBInfo);
5364 outb(XGI330_StandTable.MISC, pVBInfo->P3c2);
5365 XGI_SetCRTCRegs(pVBInfo);
5366 XGI_SetATTRegs(ModeIdIndex, pVBInfo);
5367 XGI_SetGRCRegs(pVBInfo);
5368 XGI_ClearExt1Regs(pVBInfo);
5370 if (HwDeviceExtension->jChipType == XG27) {
5371 if (pVBInfo->IF_DEF_LVDS == 0)
5372 XGI_SetDefaultVCLK(pVBInfo);
5375 temp = ~ProgrammingCRT2;
5376 pVBInfo->SetFlag &= temp;
5377 pVBInfo->SelectCRT2Rate = 0;
5379 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5380 | VB_SIS302LV | VB_XGI301C)) {
5381 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA
5382 | SetInSlaveMode)) {
5383 pVBInfo->SetFlag |= ProgrammingCRT2;
5387 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
5388 ModeIdIndex, pVBInfo);
5389 if (RefreshRateTableIndex != 0xFFFF) {
5390 XGI_SetSync(RefreshRateTableIndex, pVBInfo);
5391 XGI_SetCRT1CRTC(ModeIdIndex, RefreshRateTableIndex,
5392 pVBInfo, HwDeviceExtension);
5393 XGI_SetCRT1DE(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5394 XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5395 HwDeviceExtension, pVBInfo);
5396 XGI_SetCRT1VCLK(ModeIdIndex, HwDeviceExtension,
5397 RefreshRateTableIndex, pVBInfo);
5400 if (HwDeviceExtension->jChipType >= XG21) {
5401 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
5403 if (HwDeviceExtension->jChipType == XG27)
5404 XGI_SetXG27CRTC(RefreshRateTableIndex, pVBInfo);
5406 XGI_SetXG21CRTC(RefreshRateTableIndex, pVBInfo);
5408 XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
5409 RefreshRateTableIndex);
5411 xgifb_set_lcd(HwDeviceExtension->jChipType,
5412 pVBInfo, RefreshRateTableIndex);
5414 if (pVBInfo->IF_DEF_LVDS == 1)
5415 xgifb_set_lvds(xgifb_info,
5416 HwDeviceExtension->jChipType,
5417 ModeIdIndex, pVBInfo);
5421 pVBInfo->SetFlag &= (~ProgrammingCRT2);
5422 XGI_SetCRT1FIFO(HwDeviceExtension, pVBInfo);
5423 XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeIdIndex,
5424 RefreshRateTableIndex, pVBInfo);
5425 XGI_LoadDAC(pVBInfo);
5428 unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
5429 struct xgi_hw_device_info *HwDeviceExtension,
5430 unsigned short ModeNo)
5432 unsigned short ModeIdIndex;
5433 struct vb_device_info VBINF;
5434 struct vb_device_info *pVBInfo = &VBINF;
5436 pVBInfo->IF_DEF_LVDS = 0;
5438 if (HwDeviceExtension->jChipType >= XG20)
5439 pVBInfo->VBType = 0; /* set VBType default 0 */
5441 XGIRegInit(pVBInfo, xgifb_info->vga_base);
5443 /* for x86 Linux, XG21 LVDS */
5444 if (HwDeviceExtension->jChipType == XG21) {
5445 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
5446 pVBInfo->IF_DEF_LVDS = 1;
5448 if (HwDeviceExtension->jChipType == XG27) {
5449 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
5450 if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20)
5451 pVBInfo->IF_DEF_LVDS = 1;
5455 InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
5457 ModeNo = ModeNo & 0x7F;
5458 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
5460 if (HwDeviceExtension->jChipType < XG20)
5461 XGI_UnLockCRT2(pVBInfo);
5463 XGI_SearchModeID(ModeNo, &ModeIdIndex);
5465 if (HwDeviceExtension->jChipType < XG20) {
5466 XGI_GetVBInfo(ModeIdIndex, pVBInfo);
5467 XGI_GetTVInfo(ModeIdIndex, pVBInfo);
5468 XGI_GetLCDInfo(ModeIdIndex, pVBInfo);
5469 XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
5471 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA) ||
5472 !(pVBInfo->VBInfo & SwitchCRT2)) {
5473 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
5474 ModeIdIndex, pVBInfo);
5476 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5477 XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
5478 HwDeviceExtension, pVBInfo);
5482 if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) {
5483 switch (HwDeviceExtension->ujVBChipID) {
5484 case VB_CHIP_301: /* fall through */
5487 XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
5496 XGI_SetCRT2ModeRegs(pVBInfo);
5497 XGI_OEM310Setting(ModeIdIndex, pVBInfo); /* 0212 */
5498 XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
5501 if (pVBInfo->IF_DEF_LVDS == 1)
5502 if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo,
5507 XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag
5510 pVBInfo->SetFlag = 0;
5511 pVBInfo->VBInfo = DisableCRT2Display;
5513 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
5515 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
5516 ModeIdIndex, pVBInfo);
5518 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
5521 XGI_UpdateModeInfo(pVBInfo);
5523 if (HwDeviceExtension->jChipType < XG20)
5524 XGI_LockCRT2(pVBInfo);