1 #include <linux/delay.h>
7 #include "vb_setmode.h"
10 #define TVCLKBASE_315_25 (TVCLKBASE_315 + 25)
12 static const unsigned short XGINew_VGA_DAC[] = {
13 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
14 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
15 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
16 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
17 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
18 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
19 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
20 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
21 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
22 0x0B, 0x0C, 0x0D, 0x0F, 0x10};
24 void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
26 pVBInfo->StandTable = &XGI330_StandTable;
27 pVBInfo->EModeIDTable = XGI330_EModeIDTable;
28 pVBInfo->RefIndex = XGI330_RefIndex;
29 pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table;
31 pVBInfo->MCLKData = XGI340New_MCLKData;
32 pVBInfo->ECLKData = XGI340_ECLKData;
33 pVBInfo->VCLKData = XGI_VCLKData;
34 pVBInfo->VBVCLKData = XGI_VBVCLKData;
35 pVBInfo->ScreenOffset = XGI330_ScreenOffset;
36 pVBInfo->StResInfo = XGI330_StResInfo;
37 pVBInfo->ModeResInfo = XGI330_ModeResInfo;
39 pVBInfo->LCDResInfo = 0;
40 pVBInfo->LCDTypeInfo = 0;
45 pVBInfo->SR15 = XGI340_SR13;
46 pVBInfo->CR40 = XGI340_cr41;
47 pVBInfo->CR6B = XGI340_CR6B;
48 pVBInfo->CR6E = XGI340_CR6E;
49 pVBInfo->CR6F = XGI340_CR6F;
50 pVBInfo->CR89 = XGI340_CR89;
51 pVBInfo->AGPReg = XGI340_AGPReg;
52 pVBInfo->SR16 = XGI340_SR16;
57 pVBInfo->TimingH = XGI_TimingH;
58 pVBInfo->TimingV = XGI_TimingV;
59 pVBInfo->UpdateCRT1 = XGI_UpdateCRT1Table;
61 /* 310 customization related */
62 if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
63 pVBInfo->LCDCapList = XGI_LCDDLCapList;
65 pVBInfo->LCDCapList = XGI_LCDCapList;
68 pVBInfo->XGINew_CR97 = 0x10;
70 if (ChipType == XG27) {
72 pVBInfo->MCLKData = XGI27New_MCLKData;
73 pVBInfo->CR40 = XGI27_cr41;
74 pVBInfo->XGINew_CR97 = 0xc1;
75 pVBInfo->SR15 = XG27_SR13;
78 temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
79 /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
80 if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
81 pVBInfo->XGINew_CR97 = 0x80;
86 static void XGI_SetSeqRegs(unsigned short ModeNo,
87 unsigned short ModeIdIndex,
88 struct vb_device_info *pVBInfo)
90 unsigned char tempah, SRdata;
91 unsigned short i, modeflag;
93 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
95 xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
96 tempah = pVBInfo->StandTable->SR[0];
98 i = XGI_SetCRT2ToLCDA;
99 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
101 } else if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
102 if (pVBInfo->VBInfo & SetInSlaveMode)
106 tempah |= 0x20; /* screen off */
107 xgifb_reg_set(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */
109 for (i = 02; i <= 04; i++) {
110 /* Get SR2,3,4 from file */
111 SRdata = pVBInfo->StandTable->SR[i - 1];
112 xgifb_reg_set(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */
116 static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
117 struct vb_device_info *pVBInfo)
119 unsigned char CRTCdata;
122 CRTCdata = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
124 xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
126 for (i = 0; i <= 0x18; i++) {
127 /* Get CRTC from file */
128 CRTCdata = pVBInfo->StandTable->CRTC[i];
129 xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
133 static void XGI_SetATTRegs(unsigned short ModeNo,
134 unsigned short ModeIdIndex,
135 struct vb_device_info *pVBInfo)
137 unsigned char ARdata;
138 unsigned short i, modeflag;
140 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
142 for (i = 0; i <= 0x13; i++) {
143 ARdata = pVBInfo->StandTable->ATTR[i];
145 if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */
146 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
148 } else if ((pVBInfo->VBInfo &
149 (SetCRT2ToTV | SetCRT2ToLCD)) &&
150 (pVBInfo->VBInfo & SetInSlaveMode)) {
155 inb(pVBInfo->P3da); /* reset 3da */
156 outb(i, pVBInfo->P3c0); /* set index */
157 outb(ARdata, pVBInfo->P3c0); /* set data */
160 inb(pVBInfo->P3da); /* reset 3da */
161 outb(0x14, pVBInfo->P3c0); /* set index */
162 outb(0x00, pVBInfo->P3c0); /* set data */
163 inb(pVBInfo->P3da); /* Enable Attribute */
164 outb(0x20, pVBInfo->P3c0);
167 static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo)
169 unsigned char GRdata;
172 for (i = 0; i <= 0x08; i++) {
173 /* Get GR from file */
174 GRdata = pVBInfo->StandTable->GRC[i];
175 xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
178 if (pVBInfo->ModeType > ModeVGA) {
179 GRdata = (unsigned char) xgifb_reg_get(pVBInfo->P3ce, 0x05);
180 GRdata &= 0xBF; /* 256 color disable */
181 xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata);
185 static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
189 for (i = 0x0A; i <= 0x0E; i++)
190 xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
193 static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
196 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
197 xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B);
198 xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C);
200 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
201 xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B);
202 xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C);
204 xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30);
208 static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
209 unsigned short ModeIdIndex,
210 unsigned short RefreshRateTableIndex, unsigned short *i,
211 struct vb_device_info *pVBInfo)
213 unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
215 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
216 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
217 tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
220 if (pVBInfo->IF_DEF_LVDS == 0) {
221 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
222 tempax |= SupportRAMDAC2;
224 if (pVBInfo->VBType & VB_XGI301C)
225 tempax |= SupportCRT2in301C;
229 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
230 tempax |= SupportLCD;
232 if (pVBInfo->LCDResInfo != Panel_1280x1024 &&
233 pVBInfo->LCDResInfo != Panel_1280x960 &&
234 (pVBInfo->LCDInfo & LCDNonExpanding) &&
239 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */
240 tempax |= SupportHiVision;
241 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
244 (pVBInfo->SetFlag & TVSimuMode)) ||
247 } else if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO |
250 SetCRT2ToYPbPr525750 |
251 SetCRT2ToHiVision)) {
254 if (pVBInfo->VBType & (VB_SIS301B |
259 tempax |= SupportTV1024;
261 if (!(pVBInfo->VBInfo & TVSetPAL) &&
262 (modeflag & NoSupportSimuTV) &&
263 (pVBInfo->VBInfo & SetInSlaveMode) &&
264 (!(pVBInfo->VBInfo & SetNotSimuMode)))
267 } else if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* for LVDS */
268 tempax |= SupportLCD;
271 return 0; /* 1024x768 */
273 if (pVBInfo->LCDResInfo < Panel_1024x768) {
275 return 0; /* 800x600 */
278 return 0; /* 512x384 */
282 for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
284 infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
286 if (infoflag & tempax)
293 for ((*i) = 0;; (*i)++) {
294 infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
296 if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID
301 if (infoflag & tempax)
307 static void XGI_SetSync(unsigned short RefreshRateTableIndex,
308 struct vb_device_info *pVBInfo)
310 unsigned short sync, temp;
313 sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
317 outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */
320 static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
321 struct xgi_hw_device_info *HwDeviceExtension)
323 unsigned char data, data1, pushax;
327 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
329 xgifb_reg_set(pVBInfo->P3d4, 0x11, data);
331 data = pVBInfo->TimingH[0].data[0];
332 xgifb_reg_set(pVBInfo->P3d4, 0, data);
334 for (i = 0x01; i <= 0x04; i++) {
335 data = pVBInfo->TimingH[0].data[i];
336 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data);
339 for (i = 0x05; i <= 0x06; i++) {
340 data = pVBInfo->TimingH[0].data[i];
341 xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data);
344 j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e);
346 data = pVBInfo->TimingH[0].data[7];
349 xgifb_reg_set(pVBInfo->P3c4, 0x0e, data);
351 if (HwDeviceExtension->jChipType >= XG20) {
352 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x04);
354 xgifb_reg_set(pVBInfo->P3d4, 0x04, data);
355 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x05);
361 data = (unsigned char) xgifb_reg_get(pVBInfo->P3c4,
364 xgifb_reg_set(pVBInfo->P3c4, 0x0c, data);
369 xgifb_reg_set(pVBInfo->P3d4, 0x05, data);
370 data = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e);
376 xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data);
380 static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
381 unsigned short ModeNo,
382 struct vb_device_info *pVBInfo)
387 for (i = 0x00; i <= 0x01; i++) {
388 data = pVBInfo->TimingV[0].data[i];
389 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data);
392 for (i = 0x02; i <= 0x03; i++) {
393 data = pVBInfo->TimingV[0].data[i];
394 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
397 for (i = 0x04; i <= 0x05; i++) {
398 data = pVBInfo->TimingV[0].data[i];
399 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
402 j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0a);
404 data = pVBInfo->TimingV[0].data[6];
407 xgifb_reg_set(pVBInfo->P3c4, 0x0a, data);
409 data = pVBInfo->TimingV[0].data[6];
413 i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
418 j = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x09);
421 xgifb_reg_set(pVBInfo->P3d4, 0x09, data);
424 static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
425 unsigned short RefreshRateTableIndex,
426 struct vb_device_info *pVBInfo,
427 struct xgi_hw_device_info *HwDeviceExtension)
429 unsigned char index, data;
433 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
434 index = index & IndexMask;
436 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
438 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
440 for (i = 0; i < 8; i++)
441 pVBInfo->TimingH[0].data[i]
442 = pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
444 for (i = 0; i < 7; i++)
445 pVBInfo->TimingV[0].data[i]
446 = pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
448 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
450 XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
452 if (pVBInfo->ModeType > 0x03)
453 xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F);
456 /* --------------------------------------------------------------------- */
457 /* Function : XGI_SetXG21CRTC */
458 /* Input : Stand or enhance CRTC table */
459 /* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
460 /* Description : Set LCD timing */
461 /* --------------------------------------------------------------------- */
462 static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
463 unsigned short RefreshRateTableIndex,
464 struct vb_device_info *pVBInfo)
466 unsigned char index, Tempax, Tempbx, Tempcx, Tempdx;
467 unsigned short Temp1, Temp2, Temp3;
469 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
470 /* Tempax: CR4 HRS */
471 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
472 Tempcx = Tempax; /* Tempcx: HRS */
474 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
476 Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */
477 Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
478 Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
479 Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
480 Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
482 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
483 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
485 Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
486 Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
487 Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
488 Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
490 Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
491 Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
493 Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
494 if (Tempax < Tempcx) /* HRE < HRS */
495 Temp2 |= 0x40; /* Temp2 + 0x40 */
498 Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
499 Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
500 Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
501 Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
502 /* SR2F D[7:2]->HRE, D[1:0]->HRS */
503 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
504 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
507 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
508 Tempbx = Tempax; /* Tempbx: VRS */
509 Tempax &= 0x01; /* Tempax[0]: VRS[0] */
510 xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
512 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
513 Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
514 Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
515 Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
516 Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
517 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
519 Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
520 Temp1 <<= 1; /* Temp1[8]: VRS[8] */
521 Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
523 Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
524 Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
526 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
527 Tempax &= 0x08; /* Tempax[3]: VRS[3] */
529 Temp2 <<= 7; /* Temp2[10]: VRS[10] */
530 Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
532 /* Tempax: CR11 VRE */
533 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
534 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
536 Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
537 Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
538 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
539 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
540 Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
541 Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
543 Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
544 if (Tempax < Temp3) /* VRE < VRS */
545 Temp2 |= 0x20; /* VRE + 0x20 */
548 Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
549 Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
550 Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
551 Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
552 Tempbx = (unsigned char) Temp1;
553 Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
555 /* SR3F D[7:2]->VRE D[1:0]->VRS */
556 xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
559 static void XGI_SetXG27CRTC(unsigned short ModeNo,
560 unsigned short ModeIdIndex,
561 unsigned short RefreshRateTableIndex,
562 struct vb_device_info *pVBInfo)
564 unsigned short index, Tempax, Tempbx, Tempcx;
566 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
567 /* Tempax: CR4 HRS */
568 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
569 Tempbx = Tempax; /* Tempbx: HRS[7:0] */
571 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
574 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5];
575 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
576 Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
578 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
579 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
580 Tempcx = Tempax; /* Tempcx: HRE[4:0] */
582 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
583 Tempax &= 0x04; /* Tempax[2]: HRE[5] */
584 Tempax <<= 3; /* Tempax[5]: HRE[5] */
585 Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
587 Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
588 Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
590 /* Tempax: CR4 HRS */
591 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
592 Tempax &= 0x3F; /* Tempax: HRS[5:0] */
593 if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
594 Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
596 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
597 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
598 Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
599 Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
600 /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
601 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
602 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
605 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
606 /* SR34[7:0]->VRS[7:0] */
607 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax);
609 Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
610 /* CR7[7][2] VRS[9][8] */
611 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
612 Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
613 Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
614 Tempax >>= 2; /* Tempax[0]: VRS[8] */
615 /* SR35[0]: VRS[8] */
616 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
617 Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
618 Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
620 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
621 Tempax &= 0x08; /* SR0A[3] VRS[10] */
622 Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
624 /* Tempax: CR11 VRE */
625 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
626 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
628 Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
629 Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
630 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
631 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
632 Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
633 Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
634 Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
636 if (Tempbx <= Tempcx) /* VRE <= VRS */
637 Tempbx |= 0x20; /* VRE + 0x20 */
639 /* Tempax: Tempax[7:0]; VRE[5:0]00 */
640 Tempax = (Tempbx << 2) & 0xFF;
641 /* SR3F[7:2]:VRE[5:0] */
642 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
643 Tempax = Tempcx >> 8;
644 /* SR35[2:0]:VRS[10:8] */
645 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax);
648 static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
652 /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
653 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
654 temp = (temp & 3) << 6;
655 /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
656 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80);
657 /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
658 xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
662 static void xgifb_set_lcd(int chip_id,
663 struct vb_device_info *pVBInfo,
664 unsigned short RefreshRateTableIndex,
665 unsigned short ModeNo)
667 unsigned short Data, Temp;
668 unsigned short XGI_P3cc;
670 XGI_P3cc = pVBInfo->P3cc;
672 xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00);
673 xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00);
674 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00);
675 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00);
677 if (chip_id == XG27) {
678 Temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
679 if ((Temp & 0x03) == 0) { /* dual 12 */
680 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13);
681 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13);
685 if (chip_id == XG27) {
686 XGI_SetXG27FPBits(pVBInfo);
688 Temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
691 xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40);
692 xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40);
696 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
698 xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
699 xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
701 Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
704 xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
707 xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
710 /* --------------------------------------------------------------------- */
711 /* Function : XGI_UpdateXG21CRTC */
713 /* Output : CRT1 CRTC */
714 /* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
715 /* --------------------------------------------------------------------- */
716 static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
717 struct vb_device_info *pVBInfo,
718 unsigned short RefreshRateTableIndex)
722 xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
723 if (ModeNo == 0x2E &&
724 (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
727 else if (ModeNo == 0x2E && (pVBInfo->RefIndex[RefreshRateTableIndex].
728 Ext_CRT1CRTC == RES640x480x72))
730 else if (ModeNo == 0x2F)
732 else if (ModeNo == 0x50)
734 else if (ModeNo == 0x59)
738 xgifb_reg_set(pVBInfo->P3d4, 0x02,
739 pVBInfo->UpdateCRT1[index].CR02);
740 xgifb_reg_set(pVBInfo->P3d4, 0x03,
741 pVBInfo->UpdateCRT1[index].CR03);
742 xgifb_reg_set(pVBInfo->P3d4, 0x15,
743 pVBInfo->UpdateCRT1[index].CR15);
744 xgifb_reg_set(pVBInfo->P3d4, 0x16,
745 pVBInfo->UpdateCRT1[index].CR16);
749 static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
750 unsigned short ModeNo, unsigned short ModeIdIndex,
751 unsigned short RefreshRateTableIndex,
752 struct vb_device_info *pVBInfo)
754 unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
758 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
760 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
761 tempax = pVBInfo->ModeResInfo[resindex].HTotal;
762 tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
764 if (modeflag & HalfDCLK)
765 tempax = tempax >> 1;
767 if (modeflag & HalfDCLK)
768 tempax = tempax << 1;
770 temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
772 if (temp & InterlaceMode)
773 tempbx = tempbx >> 1;
775 if (modeflag & DoubleScanMode)
776 tempbx = tempbx << 1;
784 temp = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
785 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
787 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
788 xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
789 xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c,
790 (unsigned short) ((tempcx & 0x0ff00) >> 10));
791 xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
793 tempbx = tempbx >> 8;
801 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax);
802 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x07);
809 xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
810 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp);
813 static void XGI_SetCRT1Offset(unsigned short ModeNo,
814 unsigned short ModeIdIndex,
815 unsigned short RefreshRateTableIndex,
816 struct xgi_hw_device_info *HwDeviceExtension,
817 struct vb_device_info *pVBInfo)
819 unsigned short temp, ah, al, temp2, i, DisplayUnit;
822 temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
824 temp = pVBInfo->ScreenOffset[temp];
826 temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
827 temp2 &= InterlaceMode;
832 temp2 = pVBInfo->ModeType - ModeEGA;
857 if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
858 temp = temp * temp2 + temp2 / 2;
865 temp = temp >> 8; /* ah */
867 i = xgifb_reg_get(pVBInfo->P3c4, 0x0E);
870 xgifb_reg_set(pVBInfo->P3c4, 0x0E, i);
872 temp = (unsigned char) temp2;
873 temp &= 0xFF; /* al */
874 xgifb_reg_set(pVBInfo->P3d4, 0x13, temp);
877 temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
878 temp2 &= InterlaceMode;
882 DisplayUnit = DisplayUnit << 5;
883 ah = (DisplayUnit & 0xff00) >> 8;
884 al = DisplayUnit & 0x00ff;
890 if (HwDeviceExtension->jChipType >= XG20)
891 if ((ModeNo == 0x4A) | (ModeNo == 0x49))
894 xgifb_reg_set(pVBInfo->P3c4, 0x10, ah);
897 static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
898 unsigned short ModeIdIndex,
899 unsigned short RefreshRateTableIndex,
900 struct xgi_hw_device_info *HwDeviceExtension,
901 struct vb_device_info *pVBInfo)
903 unsigned short CRT2Index, VCLKIndex;
904 unsigned short modeflag, resinfo;
907 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
908 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
909 CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
911 if (pVBInfo->IF_DEF_LVDS == 0) {
912 CRT2Index = CRT2Index >> 6; /* for LCD */
913 if (pVBInfo->VBInfo &
914 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /*301b*/
915 if (pVBInfo->LCDResInfo != Panel_1024x768)
917 VCLKIndex = VCLK108_2_315 + 5;
919 VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */
920 } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
921 if (pVBInfo->SetFlag & RPLLDIV2XO)
922 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2;
924 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK;
926 if (pVBInfo->SetFlag & TVSimuMode) {
927 if (modeflag & Charx8Dot) {
928 VCLKIndex = TVCLKBASE_315_25 +
931 VCLKIndex = TVCLKBASE_315_25 +
937 if (pVBInfo->VBType & VB_SIS301LV) {
938 if (pVBInfo->SetFlag & RPLLDIV2XO)
939 VCLKIndex = YPbPr525iVCLK_2;
941 VCLKIndex = YPbPr525iVCLK;
943 } else if (pVBInfo->VBInfo & SetCRT2ToTV) {
944 if (pVBInfo->SetFlag & RPLLDIV2XO)
945 VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2;
947 VCLKIndex = TVCLKBASE_315_25 + TVVCLK;
948 } else { /* for CRT2 */
950 VCLKIndex = pVBInfo->RefIndex[RefreshRateTableIndex].
952 VCLKIndex &= IndexMask;
954 } else if ((pVBInfo->LCDResInfo == Panel_800x600) ||
955 (pVBInfo->LCDResInfo == Panel_320x480)) { /* LVDS */
956 VCLKIndex = VCLK40; /* LVDSXlat1VCLK */
958 VCLKIndex = VCLK65_315 + 2; /* LVDSXlat2VCLK, LVDSXlat3VCLK */
964 static void XGI_SetCRT1VCLK(unsigned short ModeNo,
965 unsigned short ModeIdIndex,
966 struct xgi_hw_device_info *HwDeviceExtension,
967 unsigned short RefreshRateTableIndex,
968 struct vb_device_info *pVBInfo)
970 unsigned char index, data;
971 unsigned short vclkindex;
973 if (pVBInfo->IF_DEF_LVDS == 1) {
974 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
975 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
976 xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
977 xgifb_reg_set(pVBInfo->P3c4, 0x2B,
978 pVBInfo->VCLKData[index].SR2B);
979 xgifb_reg_set(pVBInfo->P3c4, 0x2C,
980 pVBInfo->VCLKData[index].SR2C);
981 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
982 } else if ((pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
983 | VB_SIS302LV | VB_XGI301C)) && (pVBInfo->VBInfo
984 & XGI_SetCRT2ToLCDA)) {
985 vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex,
986 RefreshRateTableIndex, HwDeviceExtension,
988 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
989 xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
990 data = pVBInfo->VBVCLKData[vclkindex].Part4_A;
991 xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
992 data = pVBInfo->VBVCLKData[vclkindex].Part4_B;
993 xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
994 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
996 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
997 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
998 xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
999 xgifb_reg_set(pVBInfo->P3c4, 0x2B,
1000 pVBInfo->VCLKData[index].SR2B);
1001 xgifb_reg_set(pVBInfo->P3c4, 0x2C,
1002 pVBInfo->VCLKData[index].SR2C);
1003 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
1006 if (HwDeviceExtension->jChipType >= XG20) {
1007 if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag &
1009 data = xgifb_reg_get(pVBInfo->P3c4, 0x2B);
1010 xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
1011 data = xgifb_reg_get(pVBInfo->P3c4, 0x2C);
1018 xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
1023 static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
1027 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
1028 temp = (temp & 1) << 6;
1029 /* SR06[6] 18bit Dither */
1030 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp);
1031 /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
1032 xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
1036 static void XGI_SetCRT1FIFO(unsigned short ModeNo,
1037 struct xgi_hw_device_info *HwDeviceExtension,
1038 struct vb_device_info *pVBInfo)
1040 unsigned short data;
1042 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
1044 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
1046 xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34);
1047 data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
1049 xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30);
1050 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
1052 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data);
1054 if (HwDeviceExtension->jChipType == XG21)
1055 XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
1058 static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
1059 unsigned short ModeNo, unsigned short RefreshRateTableIndex,
1060 struct vb_device_info *pVBInfo)
1062 unsigned short data, data2 = 0;
1065 unsigned char index;
1067 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1069 VCLK = pVBInfo->VCLKData[index].CLOCK;
1071 data = xgifb_reg_get(pVBInfo->P3c4, 0x32);
1074 data |= 0x0c; /* VCLK > 200 */
1076 if (HwDeviceExtension->jChipType >= XG20)
1077 data &= ~0x04; /* 2 pixel mode */
1079 xgifb_reg_set(pVBInfo->P3c4, 0x32, data);
1081 if (HwDeviceExtension->jChipType < XG20) {
1082 data = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
1086 xgifb_reg_set(pVBInfo->P3c4, 0x1F, data);
1091 xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2);
1092 if (HwDeviceExtension->jChipType >= XG27)
1093 xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
1097 static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
1098 unsigned short ModeNo, unsigned short ModeIdIndex,
1099 unsigned short RefreshRateTableIndex,
1100 struct vb_device_info *pVBInfo)
1102 unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
1105 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1106 infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1108 if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01)
1109 xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
1114 data3 = pVBInfo->ModeType - ModeVGA;
1117 data &= InterlaceMode;
1122 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2);
1123 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
1124 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
1127 if (infoflag & InterlaceMode) {
1130 else if (xres == 1280)
1134 data2 = data & 0x00FF;
1135 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data2);
1136 data2 = (data & 0xFF00) >> 8;
1137 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, data2);
1139 if (modeflag & HalfDCLK)
1140 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08);
1144 if (modeflag & LineCompareOff)
1147 xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2);
1151 xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data);
1153 XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
1156 data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
1158 if (HwDeviceExtension->jChipType == XG27) {
1163 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1164 xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10);
1165 } else if (HwDeviceExtension->jChipType >= XG20) {
1170 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1171 xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02);
1177 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1182 static void XGI_WriteDAC(unsigned short dl,
1186 struct vb_device_info *pVBInfo)
1188 unsigned short temp, bh, bl;
1207 outb((unsigned short) dh, pVBInfo->P3c9);
1208 outb((unsigned short) bh, pVBInfo->P3c9);
1209 outb((unsigned short) bl, pVBInfo->P3c9);
1212 static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex,
1213 struct vb_device_info *pVBInfo)
1215 unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh;
1216 const unsigned short *table = XGINew_VGA_DAC;
1218 outb(0xFF, pVBInfo->P3c6);
1219 outb(0x00, pVBInfo->P3c8);
1221 for (i = 0; i < 16; i++) {
1224 for (k = 0; k < 3; k++) {
1233 outb(data2, pVBInfo->P3c9);
1238 for (i = 16; i < 32; i++) {
1241 for (k = 0; k < 3; k++)
1242 outb(data, pVBInfo->P3c9);
1247 for (m = 0; m < 9; m++) {
1252 for (n = 0; n < 3; n++) {
1253 for (o = 0; o < 5; o++) {
1258 XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1263 for (o = 0; o < 3; o++) {
1268 XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1278 static void XGI_GetLVDSResInfo(unsigned short ModeNo,
1279 unsigned short ModeIdIndex,
1280 struct vb_device_info *pVBInfo)
1282 unsigned short resindex, xres, yres, modeflag;
1284 /* si+Ext_ResInfo */
1285 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
1287 /* si+Ext_ResInfo */
1288 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
1290 xres = pVBInfo->ModeResInfo[resindex].HTotal;
1291 yres = pVBInfo->ModeResInfo[resindex].VTotal;
1293 if (modeflag & HalfDCLK)
1296 if (modeflag & DoubleScanMode)
1302 pVBInfo->VGAHDE = xres;
1303 pVBInfo->HDE = xres;
1304 pVBInfo->VGAVDE = yres;
1305 pVBInfo->VDE = yres;
1308 static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
1309 unsigned short ModeIdIndex,
1310 unsigned short RefreshRateTableIndex,
1311 struct vb_device_info *pVBInfo)
1313 unsigned short i, tempdx, tempbx, tempal, modeflag, table;
1315 struct XGI330_LCDDataTablStruct *tempdi = NULL;
1319 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1320 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1322 tempal = tempal & 0x0f;
1324 if (tempbx <= 1) { /* ExpLink */
1325 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1327 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
1328 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].
1333 tempal = (tempal >> 4);
1335 tempal = (tempal & 0x0f);
1341 tempdi = xgifb_epllcd_crt1;
1344 tempdi = XGI_EPLLCDDataPtr;
1347 tempdi = XGI_EPLLCDDesDataPtr;
1350 tempdi = XGI_LCDDataTable;
1353 tempdi = XGI_LCDDesDataTable;
1359 if (tempdi == NULL) /* OEMUtil */
1365 while (tempdi[i].PANELID != 0xff) {
1366 tempdx = pVBInfo->LCDResInfo;
1367 if (tempbx & 0x0080) { /* OEMUtil */
1368 tempbx &= (~0x0080);
1369 tempdx = pVBInfo->LCDTypeInfo;
1372 if (pVBInfo->LCDInfo & EnableScalingLCD)
1373 tempdx &= (~PanelResInfo);
1375 if (tempdi[i].PANELID == tempdx) {
1376 tempbx = tempdi[i].MASK;
1377 tempdx = pVBInfo->LCDInfo;
1379 if (modeflag & HalfDCLK)
1380 tempdx |= SetLCDLowResolution;
1383 if (tempbx == tempdi[i].CAP)
1390 switch (tempdi[i].DATAPTR) {
1392 return &XGI_LVDSCRT11024x768_1_H[tempal];
1395 return &XGI_LVDSCRT11024x768_2_H[tempal];
1398 return &XGI_LVDSCRT11280x1024_1_H[tempal];
1401 return &XGI_LVDSCRT11280x1024_2_H[tempal];
1404 return &XGI_LVDSCRT11400x1050_1_H[tempal];
1407 return &XGI_LVDSCRT11400x1050_2_H[tempal];
1410 return &XGI_LVDSCRT11600x1200_1_H[tempal];
1413 return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
1416 return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
1419 return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
1422 return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
1427 } else if (table == 1) {
1428 switch (tempdi[i].DATAPTR) {
1430 return &XGI_LVDSCRT11024x768_1_V[tempal];
1433 return &XGI_LVDSCRT11024x768_2_V[tempal];
1436 return &XGI_LVDSCRT11280x1024_1_V[tempal];
1439 return &XGI_LVDSCRT11280x1024_2_V[tempal];
1442 return &XGI_LVDSCRT11400x1050_1_V[tempal];
1445 return &XGI_LVDSCRT11400x1050_2_V[tempal];
1448 return &XGI_LVDSCRT11600x1200_1_V[tempal];
1451 return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
1454 return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
1457 return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
1460 return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
1465 } else if (table == 2) {
1466 switch (tempdi[i].DATAPTR) {
1468 return &XGI_LVDS1024x768Data_1[tempal];
1471 return &XGI_LVDS1024x768Data_2[tempal];
1474 return &XGI_LVDS1280x1024Data_1[tempal];
1477 return &XGI_LVDS1280x1024Data_2[tempal];
1480 return &XGI_LVDS1400x1050Data_1[tempal];
1483 return &XGI_LVDS1400x1050Data_2[tempal];
1486 return &XGI_LVDS1600x1200Data_1[tempal];
1489 return &XGI_LVDSNoScalingData[tempal];
1492 return &XGI_LVDS1024x768Data_1x75[tempal];
1495 return &XGI_LVDS1024x768Data_2x75[tempal];
1498 return &XGI_LVDS1280x1024Data_1x75[tempal];
1501 return &XGI_LVDS1280x1024Data_2x75[tempal];
1504 return &XGI_LVDSNoScalingDatax75[tempal];
1509 } else if (table == 3) {
1510 switch (tempdi[i].DATAPTR) {
1512 return &XGI_LVDS1024x768Des_1[tempal];
1515 return &XGI_LVDS1024x768Des_3[tempal];
1518 return &XGI_LVDS1024x768Des_2[tempal];
1521 return &XGI_LVDS1280x1024Des_1[tempal];
1524 return &XGI_LVDS1280x1024Des_2[tempal];
1527 return &XGI_LVDS1400x1050Des_1[tempal];
1530 return &XGI_LVDS1400x1050Des_2[tempal];
1533 return &XGI_LVDS1600x1200Des_1[tempal];
1536 return &XGI_LVDSNoScalingDesData[tempal];
1539 return &XGI_LVDS1024x768Des_1x75[tempal];
1542 return &XGI_LVDS1024x768Des_3x75[tempal];
1545 return &XGI_LVDS1024x768Des_2x75[tempal];
1548 return &XGI_LVDS1280x1024Des_1x75[tempal];
1551 return &XGI_LVDS1280x1024Des_2x75[tempal];
1554 return &XGI_LVDSNoScalingDesDatax75[tempal];
1559 } else if (table == 4) {
1560 switch (tempdi[i].DATAPTR) {
1562 return &XGI_ExtLCD1024x768Data[tempal];
1565 return &XGI_StLCD1024x768Data[tempal];
1568 return &XGI_CetLCD1024x768Data[tempal];
1571 return &XGI_ExtLCD1280x1024Data[tempal];
1574 return &XGI_StLCD1280x1024Data[tempal];
1577 return &XGI_CetLCD1280x1024Data[tempal];
1581 return &xgifb_lcd_1400x1050[tempal];
1584 return &XGI_CetLCD1400x1050Data[tempal];
1587 return &XGI_ExtLCD1600x1200Data[tempal];
1590 return &XGI_StLCD1600x1200Data[tempal];
1593 return &XGI_NoScalingData[tempal];
1596 return &XGI_ExtLCD1024x768x75Data[tempal];
1599 return &XGI_ExtLCD1024x768x75Data[tempal];
1602 return &XGI_CetLCD1024x768x75Data[tempal];
1606 return &xgifb_lcd_1280x1024x75[tempal];
1609 return &XGI_CetLCD1280x1024x75Data[tempal];
1612 return &XGI_NoScalingDatax75[tempal];
1617 } else if (table == 5) {
1618 switch (tempdi[i].DATAPTR) {
1620 return &XGI_ExtLCDDes1024x768Data[tempal];
1623 return &XGI_StLCDDes1024x768Data[tempal];
1626 return &XGI_CetLCDDes1024x768Data[tempal];
1629 if ((pVBInfo->VBType & VB_SIS301LV) ||
1630 (pVBInfo->VBType & VB_SIS302LV))
1631 return &XGI_ExtLCDDLDes1280x1024Data[tempal];
1633 return &XGI_ExtLCDDes1280x1024Data[tempal];
1636 if ((pVBInfo->VBType & VB_SIS301LV) ||
1637 (pVBInfo->VBType & VB_SIS302LV))
1638 return &XGI_StLCDDLDes1280x1024Data[tempal];
1640 return &XGI_StLCDDes1280x1024Data[tempal];
1643 if ((pVBInfo->VBType & VB_SIS301LV) ||
1644 (pVBInfo->VBType & VB_SIS302LV))
1645 return &XGI_CetLCDDLDes1280x1024Data[tempal];
1647 return &XGI_CetLCDDes1280x1024Data[tempal];
1651 if ((pVBInfo->VBType & VB_SIS301LV) ||
1652 (pVBInfo->VBType & VB_SIS302LV))
1653 return &xgifb_lcddldes_1400x1050[tempal];
1655 return &xgifb_lcddes_1400x1050[tempal];
1658 return &XGI_CetLCDDes1400x1050Data[tempal];
1661 return &XGI_CetLCDDes1400x1050Data2[tempal];
1664 if ((pVBInfo->VBType & VB_SIS301LV) ||
1665 (pVBInfo->VBType & VB_SIS302LV))
1666 return &XGI_ExtLCDDLDes1600x1200Data[tempal];
1668 return &XGI_ExtLCDDes1600x1200Data[tempal];
1671 if ((pVBInfo->VBType & VB_SIS301LV) ||
1672 (pVBInfo->VBType & VB_SIS302LV))
1673 return &XGI_StLCDDLDes1600x1200Data[tempal];
1675 return &XGI_StLCDDes1600x1200Data[tempal];
1678 return &XGI_NoScalingDesData[tempal];
1682 return &xgifb_lcddes_1024x768x75[tempal];
1685 return &XGI_CetLCDDes1024x768x75Data[tempal];
1689 if ((pVBInfo->VBType & VB_SIS301LV) ||
1690 (pVBInfo->VBType & VB_SIS302LV))
1691 return &xgifb_lcddldes_1280x1024x75[tempal];
1693 return &xgifb_lcddes_1280x1024x75[tempal];
1696 if ((pVBInfo->VBType & VB_SIS301LV) ||
1697 (pVBInfo->VBType & VB_SIS302LV))
1698 return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
1700 return &XGI_CetLCDDes1280x1024x75Data[tempal];
1703 return &XGI_NoScalingDesDatax75[tempal];
1712 static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo,
1713 unsigned short ModeIdIndex,
1714 unsigned short RefreshRateTableIndex,
1715 struct vb_device_info *pVBInfo)
1717 unsigned short i, tempdx, tempal, modeflag;
1719 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1720 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1721 tempal = tempal & 0x3f;
1722 tempdx = pVBInfo->TVInfo;
1724 if (pVBInfo->VBInfo & SetInSlaveMode)
1725 tempdx = tempdx | SetTVLockMode;
1727 if (modeflag & HalfDCLK)
1728 tempdx = tempdx | SetTVLowResolution;
1732 while (XGI_TVDataTable[i].MASK != 0xffff) {
1733 if ((tempdx & XGI_TVDataTable[i].MASK) ==
1734 XGI_TVDataTable[i].CAP)
1739 return &XGI_TVDataTable[i].DATAPTR[tempal];
1742 static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
1743 unsigned short RefreshRateTableIndex,
1744 struct vb_device_info *pVBInfo)
1746 unsigned short tempbx;
1747 struct SiS_LVDSData *LCDPtr = NULL;
1751 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1752 LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
1753 RefreshRateTableIndex, pVBInfo);
1754 pVBInfo->VGAHT = LCDPtr->VGAHT;
1755 pVBInfo->VGAVT = LCDPtr->VGAVT;
1756 pVBInfo->HT = LCDPtr->LCDHT;
1757 pVBInfo->VT = LCDPtr->LCDVT;
1760 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1761 if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
1762 | EnableScalingLCD))) {
1763 if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
1764 (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
1765 pVBInfo->HDE = 1024;
1767 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
1768 (pVBInfo->LCDResInfo ==
1769 Panel_1280x1024x75)) {
1770 pVBInfo->HDE = 1280;
1771 pVBInfo->VDE = 1024;
1772 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
1773 pVBInfo->HDE = 1400;
1774 pVBInfo->VDE = 1050;
1776 pVBInfo->HDE = 1600;
1777 pVBInfo->VDE = 1200;
1783 static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
1784 unsigned short RefreshRateTableIndex,
1785 struct xgi_hw_device_info *HwDeviceExtension,
1786 struct vb_device_info *pVBInfo)
1788 unsigned char index;
1789 unsigned short tempbx, i;
1790 struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
1791 struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
1793 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1794 index = index & IndexMask;
1798 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1799 LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
1800 RefreshRateTableIndex, pVBInfo);
1802 for (i = 0; i < 8; i++)
1803 pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i];
1806 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
1810 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1811 LCDPtr1 = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
1812 RefreshRateTableIndex, pVBInfo);
1813 for (i = 0; i < 7; i++)
1814 pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i];
1817 XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
1820 static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
1822 unsigned char tempal, tempah, tempbl, i;
1824 tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36);
1825 tempal = tempah & 0x0F;
1826 tempah = tempah & 0xF0;
1828 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1830 while (tempbl != 0xFF) {
1831 if (tempbl & 0x80) { /* OEMUtil */
1833 tempbl = tempbl & ~(0x80);
1836 if (tempal == tempbl)
1841 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1847 static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
1849 unsigned short tempah, tempal, tempbl, i;
1851 tempal = pVBInfo->LCDResInfo;
1852 tempah = pVBInfo->LCDTypeInfo;
1855 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1857 while (tempbl != 0xFF) {
1858 if ((tempbl & 0x80) && (tempbl != 0x80)) {
1863 if (tempal == tempbl)
1867 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1870 if (tempbl == 0xFF) {
1871 pVBInfo->LCDResInfo = Panel_1024x768;
1872 pVBInfo->LCDTypeInfo = 0;
1879 static void XGI_GetLCDSync(unsigned short *HSyncWidth,
1880 unsigned short *VSyncWidth,
1881 struct vb_device_info *pVBInfo)
1883 unsigned short Index;
1885 Index = XGI_GetLCDCapPtr(pVBInfo);
1886 *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
1887 *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
1892 static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
1893 unsigned short RefreshRateTableIndex,
1894 struct vb_device_info *pVBInfo)
1896 unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
1897 unsigned long temp, temp1, temp2, temp3, push3;
1898 struct XGI_LCDDesStruct *LCDPtr = NULL;
1899 struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
1901 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1903 if (pVBInfo->LCDInfo & EnableScalingLCD)
1904 LCDPtr1 = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
1905 RefreshRateTableIndex, pVBInfo);
1907 LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
1908 RefreshRateTableIndex, pVBInfo);
1910 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
1915 if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
1916 (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
1919 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
1920 (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
1923 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
1931 if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
1932 pVBInfo->HDE = tempax;
1933 pVBInfo->VDE = tempbx;
1934 pVBInfo->VGAHDE = tempax;
1935 pVBInfo->VGAVDE = tempbx;
1938 tempax = pVBInfo->HT;
1940 if (pVBInfo->LCDInfo & EnableScalingLCD)
1941 tempbx = LCDPtr1->LCDHDES;
1943 tempbx = LCDPtr->LCDHDES;
1945 tempcx = pVBInfo->HDE;
1946 tempbx = tempbx & 0x0fff;
1949 if (tempcx >= tempax)
1952 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
1954 tempcx = tempcx >> 3;
1955 tempbx = tempbx >> 3;
1957 xgifb_reg_set(pVBInfo->Part1Port, 0x16,
1958 (unsigned short) (tempbx & 0xff));
1959 xgifb_reg_set(pVBInfo->Part1Port, 0x17,
1960 (unsigned short) (tempcx & 0xff));
1962 tempax = pVBInfo->HT;
1964 if (pVBInfo->LCDInfo & EnableScalingLCD)
1965 tempbx = LCDPtr1->LCDHRS;
1967 tempbx = LCDPtr->LCDHRS;
1971 if (pVBInfo->LCDInfo & EnableScalingLCD)
1972 tempcx = LCDPtr1->LCDHSync;
1976 if (tempcx >= tempax)
1979 tempax = tempbx & 0x07;
1980 tempax = tempax >> 5;
1981 tempcx = tempcx >> 3;
1982 tempbx = tempbx >> 3;
1987 xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax);
1988 xgifb_reg_set(pVBInfo->Part1Port, 0x14,
1989 (unsigned short) (tempbx & 0xff));
1991 tempax = pVBInfo->VT;
1992 if (pVBInfo->LCDInfo & EnableScalingLCD)
1993 tempbx = LCDPtr1->LCDVDES;
1995 tempbx = LCDPtr->LCDVDES;
1996 tempcx = pVBInfo->VDE;
1998 tempbx = tempbx & 0x0fff;
2000 if (tempcx >= tempax)
2003 xgifb_reg_set(pVBInfo->Part1Port, 0x1b,
2004 (unsigned short) (tempbx & 0xff));
2005 xgifb_reg_set(pVBInfo->Part1Port, 0x1c,
2006 (unsigned short) (tempcx & 0xff));
2008 tempbx = (tempbx >> 8) & 0x07;
2009 tempcx = (tempcx >> 8) & 0x07;
2011 xgifb_reg_set(pVBInfo->Part1Port, 0x1d,
2012 (unsigned short) ((tempcx << 3)
2015 tempax = pVBInfo->VT;
2016 if (pVBInfo->LCDInfo & EnableScalingLCD)
2017 tempbx = LCDPtr1->LCDVRS;
2019 tempbx = LCDPtr->LCDVRS;
2023 if (pVBInfo->LCDInfo & EnableScalingLCD)
2024 tempcx = LCDPtr1->LCDVSync;
2027 if (tempcx >= tempax)
2030 xgifb_reg_set(pVBInfo->Part1Port, 0x18,
2031 (unsigned short) (tempbx & 0xff));
2032 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f,
2033 (unsigned short) (tempcx & 0x0f));
2035 tempax = ((tempbx >> 8) & 0x07) << 3;
2037 tempbx = pVBInfo->VGAVDE;
2038 if (tempbx != pVBInfo->VDE)
2041 if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA)
2044 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07,
2047 tempcx = pVBInfo->VGAVT;
2048 tempbx = pVBInfo->VDE;
2049 tempax = pVBInfo->VGAVDE;
2052 temp = tempax; /* 0430 ylshieh */
2053 temp1 = (temp << 18) / tempbx;
2055 tempdx = (unsigned short) ((temp << 18) % tempbx);
2063 xgifb_reg_set(pVBInfo->Part1Port, 0x37,
2064 (unsigned short) (temp2 & 0xff));
2065 xgifb_reg_set(pVBInfo->Part1Port, 0x36,
2066 (unsigned short) ((temp2 >> 8) & 0xff));
2068 tempbx = (unsigned short) (temp2 >> 16);
2069 tempax = tempbx & 0x03;
2071 tempbx = pVBInfo->VGAVDE;
2072 if (tempbx == pVBInfo->VDE)
2075 xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax);
2077 if (pVBInfo->VBType & VB_XGI301C) {
2079 xgifb_reg_set(pVBInfo->Part4Port,
2081 (unsigned short) (temp2 & 0xff));
2082 xgifb_reg_set(pVBInfo->Part4Port,
2084 (unsigned short) ((temp2 >> 8) &
2086 tempbx = (unsigned short) (temp2 >> 16);
2087 xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a,
2089 (unsigned short) ((tempbx &
2092 tempcx = pVBInfo->VGAVDE;
2093 if (tempcx == pVBInfo->VDE)
2094 xgifb_reg_and_or(pVBInfo->Part4Port,
2097 xgifb_reg_and_or(pVBInfo->Part4Port,
2101 tempcx = pVBInfo->VGAHDE;
2102 tempbx = pVBInfo->HDE;
2104 temp1 = tempcx << 16;
2106 tempax = (unsigned short) (temp1 / tempbx);
2108 if ((tempbx & 0xffff) == (tempcx & 0xffff))
2112 temp1 = pVBInfo->VGAHDE << 16;
2115 temp3 = temp3 << 16;
2118 temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
2120 tempax = (unsigned short) (temp3 & 0xff);
2121 xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax);
2123 temp1 = pVBInfo->VGAVDE << 18;
2124 temp1 = temp1 / push3;
2125 tempbx = (unsigned short) (temp1 & 0xffff);
2127 if (pVBInfo->LCDResInfo == Panel_1024x768)
2130 tempax = ((tempbx >> 8) & 0xff) << 3;
2131 tempax |= (unsigned short) ((temp3 >> 8) & 0x07);
2132 xgifb_reg_set(pVBInfo->Part1Port, 0x20,
2133 (unsigned short) (tempax & 0xff));
2134 xgifb_reg_set(pVBInfo->Part1Port, 0x21,
2135 (unsigned short) (tempbx & 0xff));
2137 temp3 = temp3 >> 16;
2139 if (modeflag & HalfDCLK)
2142 xgifb_reg_set(pVBInfo->Part1Port, 0x22,
2143 (unsigned short) ((temp3 >> 8) & 0xff));
2144 xgifb_reg_set(pVBInfo->Part1Port, 0x23,
2145 (unsigned short) (temp3 & 0xff));
2148 /* --------------------------------------------------------------------- */
2149 /* Function : XGI_GETLCDVCLKPtr */
2151 /* Output : al -> VCLK Index */
2153 /* --------------------------------------------------------------------- */
2154 static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
2155 struct vb_device_info *pVBInfo)
2157 unsigned short index;
2159 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
2160 index = XGI_GetLCDCapPtr1(pVBInfo);
2162 if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
2163 *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
2164 *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
2166 *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
2167 *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
2173 static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
2174 unsigned short ModeNo, unsigned short ModeIdIndex,
2175 struct vb_device_info *pVBInfo)
2178 unsigned short index, modeflag;
2179 unsigned char tempal;
2181 /* si+Ext_ResInfo */
2182 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2184 if ((pVBInfo->SetFlag & ProgrammingCRT2) &&
2185 (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
2186 index = XGI_GetLCDCapPtr(pVBInfo);
2187 tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
2189 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
2193 if (pVBInfo->VBType &
2199 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2200 tempal = TVCLKBASE_315 + HiTVVCLKDIV2;
2201 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
2202 tempal = TVCLKBASE_315 + HiTVVCLK;
2203 if (pVBInfo->TVInfo & TVSimuMode) {
2204 tempal = TVCLKBASE_315 + HiTVSimuVCLK;
2205 if (!(modeflag & Charx8Dot))
2206 tempal = TVCLKBASE_315 +
2213 if (pVBInfo->TVInfo & TVSetYPbPr750p) {
2214 tempal = XGI_YPbPr750pVCLK;
2218 if (pVBInfo->TVInfo & TVSetYPbPr525p) {
2219 tempal = YPbPr525pVCLK;
2223 tempal = NTSC1024VCLK;
2225 if (!(pVBInfo->TVInfo & NTSC1024x768)) {
2226 tempal = TVCLKBASE_315 + TVVCLKDIV2;
2227 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
2228 tempal = TVCLKBASE_315 + TVVCLK;
2231 if (pVBInfo->VBInfo & SetCRT2ToTV)
2236 tempal = (unsigned char) inb((pVBInfo->P3ca + 0x02));
2237 tempal = tempal >> 2;
2240 /* for Dot8 Scaling LCD */
2241 if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot))
2242 tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */
2244 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2248 static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
2249 unsigned char *di_1, struct vb_device_info *pVBInfo)
2251 if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B
2252 | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
2253 if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
2254 (pVBInfo->SetFlag & ProgrammingCRT2)) {
2255 *di_0 = XGI_VBVCLKData[tempal].Part4_A;
2256 *di_1 = XGI_VBVCLKData[tempal].Part4_B;
2259 *di_0 = XGI_VCLKData[tempal].SR2B;
2260 *di_1 = XGI_VCLKData[tempal].SR2C;
2264 static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex,
2265 unsigned short RefreshRateTableIndex,
2266 struct vb_device_info *pVBInfo)
2268 unsigned char di_0, di_1, tempal;
2271 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
2273 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
2274 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
2276 for (i = 0; i < 4; i++) {
2277 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30,
2278 (unsigned short) (0x10 * i));
2279 if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
2280 && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
2281 xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0);
2282 xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1);
2284 xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0);
2285 xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1);
2290 static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
2291 struct vb_device_info *pVBInfo)
2293 unsigned short tempcl, tempch, temp, tempbl, tempax;
2295 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
2296 | VB_SIS302LV | VB_XGI301C)) {
2299 temp = xgifb_reg_get(pVBInfo->P3c4, 0x01);
2301 if (!(temp & 0x20)) {
2302 temp = xgifb_reg_get(pVBInfo->P3d4, 0x17);
2304 temp = xgifb_reg_get(pVBInfo->P3d4, 0x53);
2306 tempcl |= ActiveCRT1;
2310 temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e);
2313 if (!(temp == 0x08)) {
2314 /* Check ChannelA */
2315 tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13);
2317 tempcl = tempcl | ActiveLCD;
2321 if (!(tempcl & ActiveLCD))
2323 tempcl |= ActiveCRT2;
2326 tempcl |= ActiveLCD;
2329 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00);
2332 tempch |= ActiveAVideo;
2335 tempch |= ActiveSVideo;
2338 tempch |= ActiveSCART;
2340 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2342 tempch |= ActiveHiTV;
2345 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
2346 temp = xgifb_reg_get(
2351 tempch |= ActiveYPbPr;
2359 temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
2360 if (tempcl & ActiveLCD) {
2361 if ((pVBInfo->SetFlag & ReserveTVOption)) {
2362 if (temp & ActiveTV)
2367 tempbl = ~XGI_ModeSwitchStatus;
2368 xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp);
2370 if (!(pVBInfo->SetFlag & ReserveTVOption))
2371 xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch);
2377 void XGI_GetVBType(struct vb_device_info *pVBInfo)
2379 unsigned short flag, tempbx, tempah;
2381 if (pVBInfo->IF_DEF_LVDS != 0)
2384 tempbx = VB_SIS302B;
2385 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
2390 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01);
2394 tempbx = VB_SIS301B;
2396 goto bigger_than_0xB0;
2398 tempbx = VB_XGI301C;
2400 goto bigger_than_0xB0;
2402 tempbx = VB_SIS301LV;
2404 goto bigger_than_0xB0;
2406 tempbx = VB_SIS302LV;
2407 tempah = xgifb_reg_get(pVBInfo->Part4Port, 0x39);
2409 tempbx = VB_XGI301C;
2412 if (tempbx & (VB_SIS301B | VB_SIS302B)) {
2413 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x23);
2415 tempbx = tempbx | VB_NoLCD;
2419 pVBInfo->VBType = tempbx;
2422 static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
2423 struct xgi_hw_device_info *HwDeviceExtension,
2424 struct vb_device_info *pVBInfo)
2426 unsigned short tempax, push, tempbx, temp, modeflag;
2428 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2429 pVBInfo->SetFlag = 0;
2430 pVBInfo->ModeType = modeflag & ModeTypeMask;
2433 if (!(pVBInfo->VBType & 0xFFFF))
2436 /* Check Display Device */
2437 temp = xgifb_reg_get(pVBInfo->P3d4, 0x30);
2438 tempbx = tempbx | temp;
2439 temp = xgifb_reg_get(pVBInfo->P3d4, 0x31);
2443 tempbx = tempbx | tempax;
2444 temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA
2445 | SetInSlaveMode | DisableCRT2Display);
2446 temp = 0xFFFF ^ temp;
2449 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
2451 if (pVBInfo->IF_DEF_LVDS == 0) {
2452 if (pVBInfo->VBType &
2457 if (temp & EnableDualEdge) {
2458 tempbx |= SetCRT2ToDualEdge;
2459 if (temp & SetToLCDA)
2460 tempbx |= XGI_SetCRT2ToLCDA;
2465 if (pVBInfo->IF_DEF_YPbPr == 1) {
2466 if (((pVBInfo->IF_DEF_LVDS == 0) &&
2467 ((pVBInfo->VBType & VB_SIS301LV) ||
2468 (pVBInfo->VBType & VB_SIS302LV) ||
2469 (pVBInfo->VBType & VB_XGI301C)))) {
2470 if (temp & SetYPbPr) {
2471 if (pVBInfo->IF_DEF_HiVision == 1) {
2472 /* shampoo add for new
2474 temp = xgifb_reg_get(
2478 tempbx |= SetCRT2ToHiVision;
2480 if (temp != YPbPrMode1080i) {
2482 (~SetCRT2ToHiVision);
2484 SetCRT2ToYPbPr525750;
2491 tempax = push; /* restore CR31 */
2493 if (pVBInfo->IF_DEF_LVDS == 0) {
2494 if (pVBInfo->IF_DEF_YPbPr == 1) {
2495 if (pVBInfo->IF_DEF_HiVision == 1)
2499 } else if (pVBInfo->IF_DEF_HiVision == 1) {
2504 } else { /* 3nd party chip */
2505 temp = SetCRT2ToLCD;
2508 if (!(tempbx & temp)) {
2509 tempax |= DisableCRT2Display;
2513 if (!(pVBInfo->VBType & VB_NoLCD)) {
2514 if (tempbx & XGI_SetCRT2ToLCDA) {
2515 if (tempbx & SetSimuScanMode)
2516 tempbx &= (~(SetCRT2ToLCD |
2520 tempbx &= (~(SetCRT2ToLCD |
2528 /* for driver abnormal */
2529 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
2530 if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
2531 if (tempbx & SetCRT2ToRAMDAC) {
2536 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2539 tempbx &= (~(SetCRT2ToRAMDAC |
2545 if (!(pVBInfo->VBType & VB_NoLCD)) {
2546 if (tempbx & SetCRT2ToLCD) {
2551 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2555 if (tempbx & SetCRT2ToSCART) {
2560 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2563 if (pVBInfo->IF_DEF_YPbPr == 1) {
2564 if (tempbx & SetCRT2ToYPbPr525750)
2570 if (pVBInfo->IF_DEF_HiVision == 1) {
2571 if (tempbx & SetCRT2ToHiVision)
2578 if (tempax & DisableCRT2Display) { /* Set Display Device Info */
2579 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode)))
2580 tempbx = DisableCRT2Display;
2583 if (!(tempbx & DisableCRT2Display)) {
2584 if ((!(tempbx & DriverMode)) ||
2585 (!(modeflag & CRT2Mode))) {
2586 if (!(tempbx & XGI_SetCRT2ToLCDA))
2587 tempbx |= (SetInSlaveMode |
2591 /* LCD+TV can't support in slave mode
2592 * (Force LCDA+TV->LCDB) */
2593 if ((tempbx & SetInSlaveMode) &&
2594 (tempbx & XGI_SetCRT2ToLCDA)) {
2595 tempbx ^= (SetCRT2ToLCD |
2598 pVBInfo->SetFlag |= ReserveTVOption;
2602 pVBInfo->VBInfo = tempbx;
2605 static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
2606 struct vb_device_info *pVBInfo)
2608 unsigned short temp, tempbx = 0, resinfo = 0, modeflag, index1;
2613 if (pVBInfo->VBInfo & SetCRT2ToTV) {
2614 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2615 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
2617 if (pVBInfo->VBInfo & SetCRT2ToTV) {
2618 temp = xgifb_reg_get(pVBInfo->P3d4, 0x35);
2620 if (tempbx & TVSetPAL) {
2621 tempbx &= (SetCHTVOverScan |
2625 if (tempbx & TVSetPALM)
2626 /* set to NTSC if PAL-M */
2627 tempbx &= ~TVSetPAL;
2629 tempbx &= (SetCHTVOverScan |
2634 if (pVBInfo->IF_DEF_LVDS == 0) {
2635 if (pVBInfo->VBInfo & SetCRT2ToSCART)
2639 if (pVBInfo->IF_DEF_YPbPr == 1) {
2640 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
2641 index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35);
2642 index1 &= YPbPrMode;
2644 if (index1 == YPbPrMode525i)
2645 tempbx |= TVSetYPbPr525i;
2647 if (index1 == YPbPrMode525p)
2648 tempbx = tempbx | TVSetYPbPr525p;
2649 if (index1 == YPbPrMode750p)
2650 tempbx = tempbx | TVSetYPbPr750p;
2654 if (pVBInfo->IF_DEF_HiVision == 1) {
2655 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
2656 tempbx = tempbx | TVSetHiVision | TVSetPAL;
2659 if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
2660 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
2661 (!(pVBInfo->VBInfo & SetNotSimuMode)))
2662 tempbx |= TVSimuMode;
2664 if (!(tempbx & TVSetPAL) &&
2666 (resinfo == 8)) /* NTSC 1024x768, */
2667 tempbx |= NTSC1024x768;
2669 tempbx |= RPLLDIV2XO;
2671 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2672 if (pVBInfo->VBInfo & SetInSlaveMode)
2673 tempbx &= (~RPLLDIV2XO);
2675 (TVSetYPbPr525p | TVSetYPbPr750p)) {
2676 tempbx &= (~RPLLDIV2XO);
2677 } else if (!(pVBInfo->VBType &
2683 if (tempbx & TVSimuMode)
2684 tempbx &= (~RPLLDIV2XO);
2688 pVBInfo->TVInfo = tempbx;
2691 static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
2692 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
2694 unsigned short temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
2696 pVBInfo->LCDResInfo = 0;
2697 pVBInfo->LCDTypeInfo = 0;
2698 pVBInfo->LCDInfo = 0;
2700 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2701 /* si+Ext_ResInfo // */
2702 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
2703 temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
2704 tempbx = temp & 0x0F;
2707 tempbx = Panel_1024x768; /* default */
2710 if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) {
2711 if (pVBInfo->VBInfo & DriverMode) {
2712 tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33);
2713 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
2716 tempax = tempax >> 4;
2718 if ((resinfo == 6) || (resinfo == 9)) {
2720 tempbx |= PanelRef75Hz;
2721 } else if ((resinfo == 7) || (resinfo == 8)) {
2723 tempbx |= PanelRef75Hz;
2728 pVBInfo->LCDResInfo = tempbx;
2732 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
2737 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
2739 temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
2743 LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
2745 tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
2747 if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
2748 if (((pVBInfo->VBType & VB_SIS302LV) || (pVBInfo->VBType
2749 & VB_XGI301C)) && (tempax & XGI_LCDDualLink)) {
2750 tempbx |= SetLCDDualLink;
2754 if (pVBInfo->IF_DEF_LVDS == 0) {
2755 if ((pVBInfo->LCDResInfo == Panel_1400x1050) && (pVBInfo->VBInfo
2756 & SetCRT2ToLCD) && (resinfo == 9) &&
2757 (!(tempbx & EnableScalingLCD)))
2759 * set to center in 1280x1024 LCDB
2760 * for Panel_1400x1050
2762 tempbx |= SetLCDtoNonExpanding;
2765 if (pVBInfo->VBInfo & SetInSlaveMode) {
2766 if (pVBInfo->VBInfo & SetNotSimuMode)
2767 tempbx |= XGI_LCDVESATiming;
2769 tempbx |= XGI_LCDVESATiming;
2772 pVBInfo->LCDInfo = tempbx;
2777 unsigned char XGI_SearchModeID(unsigned short ModeNo,
2778 unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo)
2780 for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
2781 if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
2783 if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
2790 static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
2792 unsigned char ujRet = 0;
2793 unsigned char i = 0;
2795 for (i = 0; i < 8; i++) {
2797 ujRet |= (ujDate >> i) & 1;
2803 /*----------------------------------------------------------------------------*/
2805 /* bl[5] : LVDS signal */
2806 /* bl[1] : LVDS backlight */
2807 /* bl[0] : LVDS VDD */
2808 /*----------------------------------------------------------------------------*/
2809 static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
2811 unsigned char CR4A, temp;
2813 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2814 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
2816 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2818 temp = XG21GPIODataTransfer(temp);
2820 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
2824 /*----------------------------------------------------------------------------*/
2826 /* bl[5] : LVDS signal */
2827 /* bl[1] : LVDS backlight */
2828 /* bl[0] : LVDS VDD */
2829 /*----------------------------------------------------------------------------*/
2830 static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
2832 unsigned char CR4A, CRB4, temp;
2834 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2835 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
2837 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2841 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
2842 CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4);
2843 temp |= ((CRB4 & 0x04) << 3);
2847 /*----------------------------------------------------------------------------*/
2849 /* bl[5] : 1;LVDS signal on */
2850 /* bl[1] : 1;LVDS backlight on */
2851 /* bl[0] : 1:LVDS VDD on */
2852 /* bh: 100000b : clear bit 5, to set bit5 */
2853 /* 000010b : clear bit 1, to set bit1 */
2854 /* 000001b : clear bit 0, to set bit0 */
2855 /*----------------------------------------------------------------------------*/
2856 static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
2857 struct vb_device_info *pVBInfo)
2859 unsigned char CR4A, temp;
2861 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2864 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
2866 if (tempbh & 0x20) {
2867 temp = (tempbl >> 4) & 0x02;
2870 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
2874 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2876 temp = XG21GPIODataTransfer(temp);
2879 xgifb_reg_set(pVBInfo->P3d4, 0x48, temp);
2882 static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
2883 struct vb_device_info *pVBInfo)
2885 unsigned char CR4A, temp;
2886 unsigned short tempbh0, tempbl0;
2895 if (tempbh & 0x20) {
2896 temp = (tempbl >> 4) & 0x02;
2899 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
2902 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
2904 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2908 tempbl <<= 2; /* GPIOC,GPIOD */
2909 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
2910 xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
2913 static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
2914 struct xgi_hw_device_info *pXGIHWDE,
2915 struct vb_device_info *pVBInfo)
2918 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
2919 if (pXGIHWDE->jChipType == XG21) {
2920 if (pVBInfo->IF_DEF_LVDS == 1) {
2921 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
2923 XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo);
2924 mdelay(xgifb_info->lvds_data.PSC_S2);
2926 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
2927 /* LVDS signal on */
2928 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
2929 mdelay(xgifb_info->lvds_data.PSC_S3);
2930 /* LVDS backlight on */
2931 XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo);
2933 /* DVO/DVI signal on */
2934 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
2939 if (pXGIHWDE->jChipType == XG27) {
2940 if (pVBInfo->IF_DEF_LVDS == 1) {
2941 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
2943 XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo);
2944 mdelay(xgifb_info->lvds_data.PSC_S2);
2946 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
2947 /* LVDS signal on */
2948 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
2949 mdelay(xgifb_info->lvds_data.PSC_S3);
2950 /* LVDS backlight on */
2951 XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo);
2953 /* DVO/DVI signal on */
2954 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
2960 void XGI_DisplayOff(struct xgifb_video_info *xgifb_info,
2961 struct xgi_hw_device_info *pXGIHWDE,
2962 struct vb_device_info *pVBInfo)
2965 if (pXGIHWDE->jChipType == XG21) {
2966 if (pVBInfo->IF_DEF_LVDS == 1) {
2967 /* LVDS backlight off */
2968 XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo);
2969 mdelay(xgifb_info->lvds_data.PSC_S3);
2971 /* DVO/DVI signal off */
2972 XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo);
2976 if (pXGIHWDE->jChipType == XG27) {
2977 if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
2978 /* LVDS backlight off */
2979 XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo);
2980 mdelay(xgifb_info->lvds_data.PSC_S3);
2983 if (pVBInfo->IF_DEF_LVDS == 0)
2984 /* DVO/DVI signal off */
2985 XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo);
2988 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
2991 static void XGI_WaitDisply(struct vb_device_info *pVBInfo)
2993 while ((inb(pVBInfo->P3da) & 0x01))
2996 while (!(inb(pVBInfo->P3da) & 0x01))
3000 static void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
3002 xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40);
3005 static void XGI_SaveCRT2Info(unsigned short ModeNo,
3006 struct vb_device_info *pVBInfo)
3008 unsigned short temp1, temp2;
3010 /* reserve CR34 for CRT1 Mode No */
3011 xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo);
3012 temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
3013 temp2 = ~(SetInSlaveMode >> 8);
3014 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1);
3017 static void XGI_GetCRT2ResInfo(unsigned short ModeNo,
3018 unsigned short ModeIdIndex,
3019 struct vb_device_info *pVBInfo)
3021 unsigned short xres, yres, modeflag, resindex;
3023 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3024 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
3025 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
3026 /* si+St_ModeFlag */
3027 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3029 if (modeflag & HalfDCLK)
3032 if (modeflag & DoubleScanMode)
3035 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
3038 if (pVBInfo->IF_DEF_LVDS == 0) {
3039 if (pVBInfo->LCDResInfo == Panel_1600x1200) {
3040 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3046 if (pVBInfo->LCDResInfo == Panel_1280x1024) {
3049 else if (yres == 350)
3052 if (pVBInfo->LCDInfo & XGI_LCDVESATiming) {
3058 if (pVBInfo->LCDResInfo == Panel_1024x768) {
3059 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3060 if (!(pVBInfo->LCDInfo & LCDNonExpanding)) {
3063 else if (yres == 400)
3065 else if (yres == 480)
3076 pVBInfo->VGAHDE = xres;
3077 pVBInfo->HDE = xres;
3078 pVBInfo->VGAVDE = yres;
3079 pVBInfo->VDE = yres;
3082 static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
3085 if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) &&
3086 (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
3092 static void XGI_GetRAMDAC2DATA(unsigned short ModeNo,
3093 unsigned short ModeIdIndex,
3094 unsigned short RefreshRateTableIndex,
3095 struct vb_device_info *pVBInfo)
3097 unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
3100 pVBInfo->RVBHCMAX = 1;
3101 pVBInfo->RVBHCFACT = 1;
3102 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3103 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3104 CRT1Index &= IndexMask;
3105 temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
3106 temp2 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
3107 tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
3108 tempbx = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
3109 tempcx = (unsigned short)
3110 pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
3112 tempcx = tempcx << 2;
3114 temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
3123 if (modeflag & Charx8Dot)
3128 pVBInfo->VGAHT = tempax;
3129 pVBInfo->HT = tempax;
3131 pVBInfo->VGAVT = tempbx;
3132 pVBInfo->VT = tempbx;
3135 static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
3136 unsigned short RefreshRateTableIndex,
3137 struct vb_device_info *pVBInfo)
3139 unsigned short tempax = 0, tempbx, modeflag, resinfo;
3141 struct SiS_LCDData *LCDPtr = NULL;
3143 /* si+Ext_ResInfo */
3144 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3145 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3146 pVBInfo->NewFlickerMode = 0;
3147 pVBInfo->RVBHRS = 50;
3149 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
3150 XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
3157 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
3158 LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
3159 RefreshRateTableIndex, pVBInfo);
3161 pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
3162 pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
3163 pVBInfo->VGAHT = LCDPtr->VGAHT;
3164 pVBInfo->VGAVT = LCDPtr->VGAVT;
3165 pVBInfo->HT = LCDPtr->LCDHT;
3166 pVBInfo->VT = LCDPtr->LCDVT;
3168 if (pVBInfo->LCDResInfo == Panel_1024x768) {
3172 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3173 if (pVBInfo->VGAVDE == 357)
3175 else if (pVBInfo->VGAVDE == 420)
3177 else if (pVBInfo->VGAVDE == 525)
3179 else if (pVBInfo->VGAVDE == 600)
3185 } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) {
3188 } else if (pVBInfo->LCDResInfo == Panel_1280x1024) {
3190 if (pVBInfo->VGAVDE == 360)
3192 else if (pVBInfo->VGAVDE == 375)
3194 else if (pVBInfo->VGAVDE == 405)
3198 } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) {
3201 } else if (pVBInfo->LCDResInfo == Panel_1280x960) {
3203 if (pVBInfo->VGAVDE == 350)
3205 else if (pVBInfo->VGAVDE == 400)
3207 else if (pVBInfo->VGAVDE == 1024)
3211 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
3215 if (pVBInfo->VGAVDE == 1024) {
3219 } else if (pVBInfo->LCDResInfo == Panel_1600x1200) {
3221 tempbx = 1200; /* alan 10/14/2003 */
3222 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3223 if (pVBInfo->VGAVDE == 350)
3225 else if (pVBInfo->VGAVDE == 400)
3230 if (pVBInfo->LCDInfo & LCDNonExpanding) {
3231 tempax = pVBInfo->VGAHDE;
3232 tempbx = pVBInfo->VGAVDE;
3235 pVBInfo->HDE = tempax;
3236 pVBInfo->VDE = tempbx;
3240 if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
3241 struct SiS_TVData const *TVPtr;
3243 TVPtr = XGI_GetTVPtr(ModeNo, ModeIdIndex, RefreshRateTableIndex,
3246 pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
3247 pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
3248 pVBInfo->VGAHT = TVPtr->VGAHT;
3249 pVBInfo->VGAVT = TVPtr->VGAVT;
3250 pVBInfo->HDE = TVPtr->TVHDE;
3251 pVBInfo->VDE = TVPtr->TVVDE;
3252 pVBInfo->RVBHRS = TVPtr->RVBHRS;
3253 pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
3255 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3256 if (resinfo == 0x08)
3257 pVBInfo->NewFlickerMode = 0x40;
3258 else if (resinfo == 0x09)
3259 pVBInfo->NewFlickerMode = 0x40;
3260 else if (resinfo == 0x12)
3261 pVBInfo->NewFlickerMode = 0x40;
3263 if (pVBInfo->VGAVDE == 350)
3264 pVBInfo->TVInfo |= TVSimuMode;
3269 if (pVBInfo->VBInfo & SetInSlaveMode) {
3270 if (pVBInfo->TVInfo & TVSimuMode) {
3274 if (!(modeflag & Charx8Dot)) {
3275 tempax = StHiTextTVHT;
3276 tempbx = StHiTextTVVT;
3280 } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
3281 if (pVBInfo->TVInfo & TVSetYPbPr750p) {
3282 tempax = YPbPrTV750pHT; /* Ext750pTVHT */
3283 tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
3286 if (pVBInfo->TVInfo & TVSetYPbPr525p) {
3287 tempax = YPbPrTV525pHT; /* Ext525pTVHT */
3288 tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
3289 } else if (pVBInfo->TVInfo & TVSetYPbPr525i) {
3290 tempax = YPbPrTV525iHT; /* Ext525iTVHT */
3291 tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
3292 if (pVBInfo->TVInfo & NTSC1024x768)
3293 tempax = NTSC1024x768HT;
3298 if (!(pVBInfo->TVInfo & TVSetPAL)) {
3301 if (pVBInfo->TVInfo & NTSC1024x768)
3302 tempax = NTSC1024x768HT;
3306 pVBInfo->HT = tempax;
3307 pVBInfo->VT = tempbx;
3312 static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
3313 unsigned short RefreshRateTableIndex,
3314 struct vb_device_info *pVBInfo)
3316 unsigned char di_0, di_1, tempal;
3318 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
3320 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
3321 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
3323 if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */
3325 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10);
3326 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
3327 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
3328 } else { /* 301b/302b/301lv/302lv */
3329 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
3330 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
3333 xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12);
3335 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
3336 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28);
3338 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08);
3341 static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
3342 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
3344 unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
3346 unsigned short modeflag;
3348 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3349 index = (modeflag & ModeTypeMask) - ModeEGA;
3354 return ColorDepth[index];
3357 static unsigned short XGI_GetOffset(unsigned short ModeNo,
3358 unsigned short ModeIdIndex,
3359 unsigned short RefreshRateTableIndex,
3360 struct xgi_hw_device_info *HwDeviceExtension,
3361 struct vb_device_info *pVBInfo)
3363 unsigned short temp, colordepth, modeinfo, index, infoflag,
3364 ColorDepth[] = { 0x01, 0x02, 0x04 };
3366 modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
3367 infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
3369 index = (modeinfo >> 8) & 0xFF;
3371 temp = pVBInfo->ScreenOffset[index];
3373 if (infoflag & InterlaceMode)
3376 colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
3378 if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
3379 temp = ModeNo - 0x7C;
3380 colordepth = ColorDepth[temp];
3382 if (infoflag & InterlaceMode)
3384 return temp * colordepth;
3386 return temp * colordepth;
3390 static void XGI_SetCRT2Offset(unsigned short ModeNo,
3391 unsigned short ModeIdIndex,
3392 unsigned short RefreshRateTableIndex,
3393 struct xgi_hw_device_info *HwDeviceExtension,
3394 struct vb_device_info *pVBInfo)
3396 unsigned short offset;
3399 if (pVBInfo->VBInfo & SetInSlaveMode)
3402 offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
3403 HwDeviceExtension, pVBInfo);
3404 temp = (unsigned char) (offset & 0xFF);
3405 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
3406 temp = (unsigned char) ((offset & 0xFF00) >> 8);
3407 xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp);
3408 temp = (unsigned char) (((offset >> 3) & 0xFF) + 1);
3409 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
3412 static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
3414 /* threshold high ,disable auto threshold */
3415 xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B);
3416 /* threshold low default 04h */
3417 xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04);
3420 static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
3421 struct xgi_hw_device_info *HwDeviceExtension,
3422 unsigned short RefreshRateTableIndex,
3423 struct vb_device_info *pVBInfo)
3425 unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0;
3427 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3428 CRT1Index &= IndexMask;
3429 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3431 XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
3432 HwDeviceExtension, pVBInfo);
3433 XGI_SetCRT2FIFO(pVBInfo);
3435 for (tempcx = 4; tempcx < 7; tempcx++)
3436 xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0);
3438 xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00);
3439 xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
3442 static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
3443 struct xgi_hw_device_info *HwDeviceExtension,
3444 unsigned short RefreshRateTableIndex,
3445 struct vb_device_info *pVBInfo)
3447 unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
3448 pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
3450 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3451 CRT1Index &= IndexMask;
3452 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3453 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3455 /* bainy change table name */
3456 if (modeflag & HalfDCLK) {
3457 /* BTVGA2HT 0x08,0x09 */
3458 temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF;
3459 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
3460 temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
3461 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
3462 /* BTVGA2HDEE 0x0A,0x0C */
3463 temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF;
3464 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
3465 tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
3466 pushbx = pVBInfo->VGAHDE / 2 + 16;
3467 tempcx = tempcx >> 1;
3468 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
3471 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
3472 tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
3473 tempbx |= ((pVBInfo->
3474 XGINEWUB_CRT1Table[CRT1Index].CR[14] &
3476 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
3477 tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
3479 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
3480 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
3481 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
3487 if (tempcx > (pVBInfo->VGAHT / 2))
3488 tempcx = pVBInfo->VGAHT / 2;
3490 temp = tempbx & 0x00FF;
3492 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
3494 temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
3495 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
3496 temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
3497 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
3498 /* BTVGA2HDEE 0x0A,0x0C */
3499 temp = (pVBInfo->VGAHDE + 16) & 0x0FF;
3500 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
3501 tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
3502 pushbx = pVBInfo->VGAHDE + 16;
3503 tempcx = tempcx >> 1;
3504 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
3507 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
3508 tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
3509 tempbx |= ((pVBInfo->
3510 XGINEWUB_CRT1Table[CRT1Index].CR[5] &
3512 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
3513 tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
3515 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
3516 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
3517 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
3522 if (tempcx > pVBInfo->VGAHT)
3523 tempcx = pVBInfo->VGAHT;
3525 temp = tempbx & 0x00FF;
3526 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
3529 tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
3531 tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
3532 tempax |= (tempbx & 0xFF00);
3533 temp = (tempax & 0xFF00) >> 8;
3534 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
3535 temp = tempcx & 0x00FF;
3536 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
3537 tempcx = (pVBInfo->VGAVT - 1);
3538 temp = tempcx & 0x00FF;
3540 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
3541 tempbx = pVBInfo->VGAVDE - 1;
3542 temp = tempbx & 0x00FF;
3543 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp);
3544 temp = ((tempbx & 0xFF00) << 3) >> 8;
3545 temp |= ((tempcx & 0xFF00) >> 8);
3546 xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp);
3548 tempax = pVBInfo->VGAVDE;
3549 tempbx = pVBInfo->VGAVDE;
3550 tempcx = pVBInfo->VGAVT;
3551 /* BTVGA2VRS 0x10,0x11 */
3552 tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1;
3553 /* BTVGA2VRE 0x11 */
3554 tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1;
3556 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
3557 tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
3558 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
3566 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
3571 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
3572 tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
3575 temp = tempbx & 0x00FF;
3576 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
3577 temp = ((tempbx & 0xFF00) >> 8) << 4;
3578 temp = ((tempcx & 0x000F) | (temp));
3579 xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp);
3582 if (modeflag & DoubleScanMode)
3585 if (modeflag & HalfDCLK)
3588 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
3591 static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
3593 unsigned long tempax, tempbx;
3595 tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
3597 tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
3598 tempax = (tempax * pVBInfo->HT) / tempbx;
3600 return (unsigned short) tempax;
3603 static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
3604 struct xgi_hw_device_info *HwDeviceExtension,
3605 unsigned short RefreshRateTableIndex,
3606 struct vb_device_info *pVBInfo)
3608 unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
3609 modeflag, CRT1Index;
3611 /* si+Ext_ResInfo */
3612 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3613 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3614 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3615 CRT1Index &= IndexMask;
3617 if (!(pVBInfo->VBInfo & SetInSlaveMode))
3620 temp = 0xFF; /* set MAX HT */
3621 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
3624 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
3625 modeflag |= Charx8Dot;
3627 tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
3629 if (modeflag & HalfDCLK)
3630 tempax = tempax >> 1;
3632 tempax = (tempax / tempcx) - 1;
3633 tempbx |= ((tempax & 0x00FF) << 8);
3634 temp = tempax & 0x00FF;
3635 xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp);
3637 temp = (tempbx & 0xFF00) >> 8;
3639 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3640 if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3641 | VB_SIS302LV | VB_XGI301C)))
3644 if ((pVBInfo->VBInfo & SetCRT2ToHiVision) &&
3645 !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7))
3649 /* 0x05 Horizontal Display Start */
3650 xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp);
3651 /* 0x06 Horizontal Blank end */
3652 xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03);
3654 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
3655 if (pVBInfo->VBInfo & SetCRT2ToTV)
3656 tempax = pVBInfo->VGAHT;
3658 tempax = XGI_GetVGAHT2(pVBInfo);
3661 if (tempax >= pVBInfo->VGAHT)
3662 tempax = pVBInfo->VGAHT;
3664 if (modeflag & HalfDCLK)
3665 tempax = tempax >> 1;
3667 tempax = (tempax / tempcx) - 5;
3668 tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
3669 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3670 temp = (tempbx & 0x00FF) - 1;
3671 if (!(modeflag & HalfDCLK)) {
3673 if (pVBInfo->TVInfo & TVSimuMode) {
3679 tempbx = (tempbx & 0xFF00) >> 8;
3680 tempcx = (tempcx + tempbx) >> 1;
3681 temp = (tempcx & 0x00FF) + 2;
3683 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3685 if (!(modeflag & HalfDCLK)) {
3686 if ((modeflag & Charx8Dot)) {
3688 if (pVBInfo->VGAHDE >= 800)
3692 } else if (!(modeflag & HalfDCLK)) {
3694 if (pVBInfo->LCDResInfo != Panel_1280x960 &&
3695 pVBInfo->VGAHDE >= 800) {
3697 if (pVBInfo->VGAHDE >= 1280 &&
3698 pVBInfo->LCDResInfo != Panel_1280x960 &&
3699 (pVBInfo->LCDInfo & LCDNonExpanding))
3705 /* 0x07 Horizontal Retrace Start */
3706 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
3707 /* 0x08 Horizontal Retrace End */
3708 xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0);
3710 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3711 if (pVBInfo->TVInfo & TVSimuMode) {
3712 if (ModeNo == 0x50) {
3713 if (pVBInfo->TVInfo & SetNTSCTV) {
3714 xgifb_reg_set(pVBInfo->Part1Port,
3716 xgifb_reg_set(pVBInfo->Part1Port,
3719 xgifb_reg_set(pVBInfo->Part1Port,
3721 xgifb_reg_set(pVBInfo->Part1Port,
3728 xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
3729 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
3730 xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
3732 tempbx = pVBInfo->VGAVT;
3735 tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
3750 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
3751 if (pVBInfo->LCDResInfo == Panel_1024x768) {
3752 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3761 temp = tempbx & 0x00FF;
3763 temp = tempbx & 0x00FF;
3764 /* 0x10 vertical Blank Start */
3765 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
3768 temp = tempbx & 0x00FF;
3769 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
3771 if (tempbx & 0x0100)
3776 if (modeflag & DoubleScanMode)
3779 if (tempbx & 0x0200)
3782 temp = (tempax & 0xFF00) >> 8;
3783 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
3785 if (tempbx & 0x0400)
3788 /* 0x11 Vertival Blank End */
3789 xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00);
3792 tempax -= tempbx; /* 0x0C Vertical Retrace Start */
3793 tempax = tempax >> 2;
3794 push1 = tempax; /* push ax */
3796 if (resinfo != 0x09) {
3797 tempax = tempax << 1;
3801 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3802 if ((pVBInfo->VBType & VB_SIS301LV) &&
3803 !(pVBInfo->TVInfo & TVSetHiVision)) {
3804 if ((pVBInfo->TVInfo & TVSimuMode) &&
3805 (pVBInfo->TVInfo & TVSetPAL)) {
3806 if (!(pVBInfo->VBType & VB_SIS301LV) ||
3816 } else if (pVBInfo->TVInfo & TVSimuMode) {
3817 if (pVBInfo->TVInfo & TVSetPAL) {
3818 if (pVBInfo->VBType & VB_SIS301LV) {
3819 if (!(pVBInfo->TVInfo &
3830 tempax = tempax >> 2;
3833 push1 = tempax; /* push ax */
3835 if ((pVBInfo->TVInfo & TVSetPAL)) {
3836 if (tempbx <= 513) {
3842 temp = tempbx & 0x00FF;
3843 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
3845 temp = tempbx & 0x00FF;
3846 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
3848 if (tempbx & 0x0100)
3851 if (tempbx & 0x0200)
3852 xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
3856 if (tempbx & 0x0100)
3859 if (tempbx & 0x0200)
3862 if (tempbx & 0x0400)
3865 tempbx = push1; /* pop ax */
3866 temp = tempbx & 0x00FF;
3868 /* 0x0D vertical Retrace End */
3869 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
3871 if (tempbx & 0x0010)
3874 temp = tempcx & 0x00FF;
3875 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
3876 temp = (tempcx & 0x0FF00) >> 8;
3877 xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
3879 temp = (tempax & 0xFF00) >> 8;
3881 temp = (temp >> 1) & 0x09;
3883 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
3886 xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
3887 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
3888 xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
3890 if (pVBInfo->LCDInfo & LCDRGB18Bit)
3895 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
3900 static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
3901 unsigned short RefreshRateTableIndex,
3902 struct xgi_hw_device_info *HwDeviceExtension,
3903 struct vb_device_info *pVBInfo)
3905 unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
3906 modeflag, resinfo, crt2crtc;
3907 unsigned char const *TimingPoint;
3909 unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
3911 /* si+Ext_ResInfo */
3912 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3913 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3914 crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3918 if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
3921 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3924 if (pVBInfo->VBInfo & SetCRT2ToSCART)
3927 if (!(pVBInfo->TVInfo & TVSetPAL))
3930 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3933 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
3936 tempax = (tempax & 0xff00) >> 8;
3938 xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax);
3939 TimingPoint = XGI330_NTSCTiming;
3941 if (pVBInfo->TVInfo & TVSetPAL)
3942 TimingPoint = XGI330_PALTiming;
3944 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3945 TimingPoint = XGI330_HiTVExtTiming;
3947 if (pVBInfo->VBInfo & SetInSlaveMode)
3948 TimingPoint = XGI330_HiTVSt2Timing;
3950 if (pVBInfo->SetFlag & TVSimuMode)
3951 TimingPoint = XGI330_HiTVSt1Timing;
3953 if (!(modeflag & Charx8Dot))
3954 TimingPoint = XGI330_HiTVTextTiming;
3957 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
3958 if (pVBInfo->TVInfo & TVSetYPbPr525i)
3959 TimingPoint = XGI330_YPbPr525iTiming;
3961 if (pVBInfo->TVInfo & TVSetYPbPr525p)
3962 TimingPoint = XGI330_YPbPr525pTiming;
3964 if (pVBInfo->TVInfo & TVSetYPbPr750p)
3965 TimingPoint = XGI330_YPbPr750pTiming;
3968 for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
3969 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
3971 for (i = 0x39; i <= 0x45; i++, j++)
3973 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
3975 if (pVBInfo->VBInfo & SetCRT2ToTV)
3976 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
3978 temp = pVBInfo->NewFlickerMode;
3980 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
3982 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3985 if (pVBInfo->TVInfo & TVSetPAL)
3990 if (pVBInfo->VDE <= tempax) {
3991 tempax -= pVBInfo->VDE;
3992 tempax = tempax >> 2;
3993 tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
3995 temp = (tempax & 0xFF00) >> 8;
3996 temp += (unsigned short) TimingPoint[0];
3998 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3999 | VB_SIS302LV | VB_XGI301C)) {
4000 if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
4001 | SetCRT2ToSVIDEO | SetCRT2ToSCART
4002 | SetCRT2ToYPbPr525750)) {
4003 tempcx = pVBInfo->VGAHDE;
4004 if (tempcx >= 1024) {
4005 temp = 0x17; /* NTSC */
4006 if (pVBInfo->TVInfo & TVSetPAL)
4007 temp = 0x19; /* PAL */
4012 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
4014 temp = (tempax & 0xFF00) >> 8;
4015 temp += TimingPoint[1];
4017 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4018 | VB_SIS302LV | VB_XGI301C)) {
4019 if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
4020 | SetCRT2ToSVIDEO | SetCRT2ToSCART
4021 | SetCRT2ToYPbPr525750))) {
4022 tempcx = pVBInfo->VGAHDE;
4023 if (tempcx >= 1024) {
4024 temp = 0x1D; /* NTSC */
4025 if (pVBInfo->TVInfo & TVSetPAL)
4026 temp = 0x52; /* PAL */
4030 xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp);
4034 tempcx = pVBInfo->HT;
4036 if (XGI_IsLCDDualLink(pVBInfo))
4037 tempcx = tempcx >> 1;
4040 temp = tempcx & 0x00FF;
4041 xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp);
4043 temp = (tempcx & 0xFF00) >> 8;
4044 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
4046 tempcx = pVBInfo->HT >> 1;
4047 push1 = tempcx; /* push cx */
4050 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
4053 temp = tempcx & 0x00FF;
4055 xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp);
4057 tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
4060 temp = tempbx & 0x00FF;
4061 xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp);
4062 temp = (tempbx & 0xFF00) >> 8;
4064 xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp);
4067 tempbx = tempbx + 8;
4068 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
4069 tempbx = tempbx - 4;
4073 temp = (tempbx & 0x00FF) << 4;
4074 xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp);
4077 tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
4078 temp = tempcx & 0x00FF;
4079 xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp);
4080 temp = ((tempcx & 0xFF00) >> 8) << 4;
4081 xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp);
4084 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
4087 temp = tempcx & 0xFF;
4089 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
4091 tempcx = push1; /* pop cx */
4093 temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
4095 temp = tempcx & 0x00FF;
4097 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
4101 if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
4102 tempax = XGI_GetVGAHT2(pVBInfo);
4103 tempcx = tempax - 1;
4105 temp = tempcx & 0x00FF;
4106 xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp);
4108 tempbx = pVBInfo->VDE;
4110 if (pVBInfo->VGAVDE == 360)
4112 if (pVBInfo->VGAVDE == 375)
4114 if (pVBInfo->VGAVDE == 405)
4117 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4118 if (pVBInfo->VBType &
4119 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
4120 if (!(pVBInfo->TVInfo &
4121 (TVSetYPbPr525p | TVSetYPbPr750p)))
4122 tempbx = tempbx >> 1;
4124 tempbx = tempbx >> 1;
4128 temp = tempbx & 0x00FF;
4130 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
4131 if (pVBInfo->VBType & VB_SIS301LV) {
4132 if (pVBInfo->TVInfo & TVSetHiVision) {
4133 if (pVBInfo->VBInfo & SetInSlaveMode) {
4138 } else if (pVBInfo->VBInfo & SetInSlaveMode) {
4144 xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp);
4146 temp = (tempcx & 0xFF00) >> 8;
4147 temp |= ((tempbx & 0xFF00) >> 8) << 6;
4149 if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) {
4150 if (pVBInfo->VBType & VB_SIS301LV) {
4151 if (pVBInfo->TVInfo & TVSetHiVision) {
4154 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
4159 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
4164 xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp);
4166 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4167 | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */
4168 tempbx = pVBInfo->VDE;
4169 tempcx = tempbx - 2;
4171 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4172 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p
4174 tempbx = tempbx >> 1;
4177 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
4179 if (tempcx & 0x0400)
4182 if (tempbx & 0x0400)
4185 xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp);
4188 temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
4189 xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp);
4190 temp = (tempbx - 3) & 0x00FF;
4191 xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp);
4194 tempbx = tempbx & 0x00FF;
4196 if (!(modeflag & HalfDCLK)) {
4197 tempcx = pVBInfo->VGAHDE;
4198 if (tempcx >= pVBInfo->HDE) {
4206 if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/
4207 if (pVBInfo->VGAHDE >= 1024) {
4209 if (pVBInfo->VGAHDE >= 1280) {
4211 tempbx = tempbx & 0xDFFF;
4216 if (!(tempbx & 0x2000)) {
4217 if (modeflag & HalfDCLK)
4218 tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
4221 tempeax = pVBInfo->VGAHDE;
4222 tempebx = (tempcx & 0xFF00) >> 8;
4223 longtemp = tempeax * tempebx;
4224 tempecx = tempcx & 0x00FF;
4225 longtemp = longtemp / tempecx;
4230 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4231 | VB_SIS302LV | VB_XGI301C)) {
4232 tempecx = tempecx * 8;
4235 longtemp = longtemp * tempecx;
4236 tempecx = pVBInfo->HDE;
4237 temp2 = longtemp % tempecx;
4238 tempeax = longtemp / tempecx;
4242 tempax = (unsigned short) tempeax;
4245 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4246 | VB_SIS302LV | VB_XGI301C)) {
4247 tempcx = ((tempax & 0xFF00) >> 5) >> 8;
4252 tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00)
4253 | (tempbx & 0x00FF));
4254 tempax = (unsigned short) (((tempeax & 0x000000FF) << 8)
4255 | (tempax & 0x00FF));
4256 temp = (tempax & 0xFF00) >> 8;
4258 temp = (tempax & 0x00FF) >> 8;
4261 xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp);
4262 temp = (tempbx & 0xFF00) >> 8;
4263 xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
4264 temp = tempcx & 0x00FF;
4266 if (tempbx & 0x2000)
4269 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
4272 xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
4273 if (pVBInfo->TVInfo & TVSetPAL) {
4281 temp = tempbx & 0x00FF;
4282 xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp);
4283 temp = tempcx & 0x00FF;
4284 xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp);
4286 temp = ((tempcx & 0xFF00) >> 8) & 0x03;
4288 temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
4290 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
4293 if (pVBInfo->TVInfo & TVSetYPbPr525p)
4296 if (pVBInfo->TVInfo & TVSetYPbPr750p)
4300 xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp);
4301 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */
4302 xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
4304 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) {
4305 if (pVBInfo->TVInfo & NTSC1024x768) {
4306 TimingPoint = XGI_NTSC1024AdjTime;
4307 for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
4308 xgifb_reg_set(pVBInfo->Part2Port, i,
4311 xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72);
4315 /* Modify for 301C PALM Support */
4316 if (pVBInfo->VBType & VB_XGI301C) {
4317 if (pVBInfo->TVInfo & TVSetPALM)
4318 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08,
4319 0x08); /* PALM Mode */
4322 if (pVBInfo->TVInfo & TVSetPALM) {
4323 tempax = (unsigned char) xgifb_reg_get(pVBInfo->Part2Port,
4326 xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax);
4328 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF);
4331 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
4332 if (!(pVBInfo->VBInfo & SetInSlaveMode))
4333 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00);
4336 if (pVBInfo->VBInfo & SetCRT2ToTV)
4340 static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
4341 struct xgi_hw_device_info *HwDeviceExtension,
4342 unsigned short RefreshRateTableIndex,
4343 struct vb_device_info *pVBInfo)
4345 unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp,
4346 tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
4348 struct XGI_LCDDesStruct *LCDBDesPtr = NULL;
4350 /* si+Ext_ResInfo */
4351 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4352 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
4353 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
4354 CRT1Index &= IndexMask;
4356 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
4359 tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
4361 if (XGI_IsLCDDualLink(pVBInfo))
4362 tempbx = tempbx >> 1;
4365 temp = tempbx & 0x00FF;
4366 xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp);
4367 temp = (tempbx & 0xFF00) >> 8;
4369 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
4372 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp);
4373 tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
4376 temp = tempbx & 0x00FF;
4377 xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp);
4378 temp = ((tempbx & 0xFF00) >> 8) & 0x07;
4379 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
4381 tempcx = pVBInfo->VT - 1;
4383 temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
4384 xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp);
4385 temp = (tempcx & 0xFF00) >> 8;
4387 xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp);
4388 xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
4389 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
4390 xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
4391 xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
4393 /* Customized LCDB Des no add */
4395 LCDBDesPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
4396 RefreshRateTableIndex, pVBInfo);
4397 tempah = pVBInfo->LCDResInfo;
4398 tempah &= PanelResInfo;
4400 if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) {
4403 } else if ((tempah == Panel_1280x1024) ||
4404 (tempah == Panel_1280x1024x75)) {
4407 } else if (tempah == Panel_1400x1050) {
4415 if (pVBInfo->LCDInfo & EnableScalingLCD) {
4416 tempbx = pVBInfo->HDE;
4417 tempcx = pVBInfo->VDE;
4421 tempax = pVBInfo->VT;
4422 pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
4423 pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
4424 pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
4425 pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
4426 tempbx = pVBInfo->LCDVDES;
4429 if (tempcx >= tempax)
4430 tempcx -= tempax; /* lcdvdes */
4432 temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
4433 xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp);
4434 temp = tempcx & 0x00FF;
4435 xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp);
4436 tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
4437 tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
4439 tempah = tempah << 3;
4441 xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah);
4444 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
4446 tempax = pVBInfo->VT;
4447 tempbx = pVBInfo->LCDVRS;
4450 if (tempcx >= tempax)
4453 temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
4454 xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp);
4455 temp = (tempbx & 0xFF00) >> 8;
4457 temp |= (tempcx & 0x000F);
4458 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
4460 tempax = pVBInfo->HT;
4461 tempbx = pVBInfo->LCDHDES;
4464 if (XGI_IsLCDDualLink(pVBInfo)) {
4465 tempax = tempax >> 1;
4466 tempbx = tempbx >> 1;
4467 tempcx = tempcx >> 1;
4470 if (pVBInfo->VBType & VB_SIS302LV)
4473 if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
4478 if (tempcx >= tempax)
4481 temp = tempbx & 0x00FF;
4482 xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
4483 temp = ((tempbx & 0xFF00) >> 8) << 4;
4484 xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp);
4485 temp = tempcx & 0x00FF;
4486 xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
4487 temp = (tempcx & 0xFF00) >> 8;
4488 xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp);
4490 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
4492 tempax = pVBInfo->HT;
4493 tempbx = pVBInfo->LCDHRS;
4494 if (XGI_IsLCDDualLink(pVBInfo)) {
4495 tempax = tempax >> 1;
4496 tempbx = tempbx >> 1;
4497 tempcx = tempcx >> 1;
4500 if (pVBInfo->VBType & VB_SIS302LV)
4505 if (tempcx >= tempax)
4508 temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
4509 xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp);
4511 temp = (tempbx & 0xFF00) >> 8;
4513 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
4514 temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
4515 xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp);
4517 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
4518 if (pVBInfo->VGAVDE == 525) {
4519 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
4520 | VB_SIS301LV | VB_SIS302LV
4526 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
4527 xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3);
4530 if (pVBInfo->VGAVDE == 420) {
4531 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
4532 | VB_SIS301LV | VB_SIS302LV
4537 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
4542 /* --------------------------------------------------------------------- */
4543 /* Function : XGI_GetTap4Ptr */
4545 /* Output : di -> Tap4 Reg. Setting Pointer */
4547 /* --------------------------------------------------------------------- */
4548 static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
4549 struct vb_device_info *pVBInfo)
4551 unsigned short tempax, tempbx, i;
4553 struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
4556 tempax = pVBInfo->VGAHDE;
4557 tempbx = pVBInfo->HDE;
4559 tempax = pVBInfo->VGAVDE;
4560 tempbx = pVBInfo->VDE;
4563 if (tempax <= tempbx)
4564 return &xgifb_tap4_timing[0];
4566 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */
4568 if (pVBInfo->TVInfo & TVSetPAL)
4569 Tap4TimingPtr = PALTap4Timing;
4571 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
4572 if ((pVBInfo->TVInfo & TVSetYPbPr525i) ||
4573 (pVBInfo->TVInfo & TVSetYPbPr525p))
4574 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing;
4575 if (pVBInfo->TVInfo & TVSetYPbPr750p)
4576 Tap4TimingPtr = YPbPr750pTap4Timing;
4579 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
4580 Tap4TimingPtr = xgifb_tap4_timing;
4583 while (Tap4TimingPtr[i].DE != 0xFFFF) {
4584 if (Tap4TimingPtr[i].DE == tempax)
4588 return &Tap4TimingPtr[i];
4591 static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
4593 unsigned short i, j;
4595 struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
4597 if (!(pVBInfo->VBType & VB_XGI301C))
4600 Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
4601 for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
4602 xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
4604 if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
4605 (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) {
4606 /* Set Vertical Scaling */
4607 Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo);
4608 for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
4609 xgifb_reg_set(pVBInfo->Part2Port,
4611 Tap4TimingPtr->Reg[j]);
4614 if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
4615 (!(pVBInfo->VBInfo & SetCRT2ToHiVision)))
4616 /* Enable V.Scaling */
4617 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04);
4619 /* Enable H.Scaling */
4620 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10);
4623 static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
4624 struct vb_device_info *pVBInfo)
4627 unsigned char const *tempdi;
4628 unsigned short modeflag;
4630 /* si+Ext_ResInfo */
4631 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4633 xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00);
4634 if (pVBInfo->TVInfo & TVSetPAL) {
4635 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
4636 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
4638 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5);
4639 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7);
4642 if (!(pVBInfo->VBInfo & SetCRT2ToTV))
4645 if (pVBInfo->TVInfo & TVSetPALM) {
4646 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
4647 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
4648 xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8);
4651 if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo
4652 & SetCRT2ToYPbPr525750)) {
4653 if (pVBInfo->TVInfo & TVSetYPbPr525i)
4656 tempdi = XGI330_HiTVGroup3Data;
4657 if (pVBInfo->SetFlag & TVSimuMode) {
4658 tempdi = XGI330_HiTVGroup3Simu;
4659 if (!(modeflag & Charx8Dot))
4660 tempdi = XGI330_HiTVGroup3Text;
4663 if (pVBInfo->TVInfo & TVSetYPbPr525p)
4664 tempdi = XGI330_Ren525pGroup3;
4666 if (pVBInfo->TVInfo & TVSetYPbPr750p)
4667 tempdi = XGI330_Ren750pGroup3;
4669 for (i = 0; i <= 0x3E; i++)
4670 xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]);
4672 if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
4673 if (pVBInfo->TVInfo & TVSetYPbPr525p)
4674 xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f);
4678 } /* {end of XGI_SetGroup3} */
4680 static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
4681 unsigned short RefreshRateTableIndex,
4682 struct xgi_hw_device_info *HwDeviceExtension,
4683 struct vb_device_info *pVBInfo)
4685 unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
4687 unsigned long tempebx, tempeax, templong;
4689 /* si+Ext_ResInfo */
4690 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4691 temp = pVBInfo->RVBHCFACT;
4692 xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp);
4694 tempbx = pVBInfo->RVBHCMAX;
4695 temp = tempbx & 0x00FF;
4696 xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp);
4697 temp2 = ((tempbx & 0xFF00) >> 8) << 7;
4698 tempcx = pVBInfo->VGAHT - 1;
4699 temp = tempcx & 0x00FF;
4700 xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp);
4702 temp = ((tempcx & 0xFF00) >> 8) << 3;
4705 tempcx = pVBInfo->VGAVT - 1;
4706 if (!(pVBInfo->VBInfo & SetCRT2ToTV))
4709 temp = tempcx & 0x00FF;
4710 xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp);
4711 temp = temp2 | ((tempcx & 0xFF00) >> 8);
4712 xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp);
4713 xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08);
4714 tempcx = pVBInfo->VBInfo;
4715 tempbx = pVBInfo->VGAHDE;
4717 if (modeflag & HalfDCLK)
4718 tempbx = tempbx >> 1;
4720 if (XGI_IsLCDDualLink(pVBInfo))
4721 tempbx = tempbx >> 1;
4723 if (tempcx & SetCRT2ToHiVision) {
4729 } else if (tempcx & SetCRT2ToTV) {
4735 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4742 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) {
4744 if (pVBInfo->VGAHDE == 1280)
4746 if (pVBInfo->VGAHDE == 1024)
4749 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
4751 tempebx = pVBInfo->VDE;
4753 if (tempcx & SetCRT2ToHiVision) {
4754 if (!(temp & 0xE000))
4755 tempbx = tempbx >> 1;
4758 tempcx = pVBInfo->RVBHRS;
4759 temp = tempcx & 0x00FF;
4760 xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp);
4762 tempeax = pVBInfo->VGAVDE;
4765 if (tempeax <= tempebx) {
4766 tempcx = (tempcx & (~0x4000));
4767 tempeax = pVBInfo->VGAVDE;
4772 templong = (tempeax * 256 * 1024) % tempebx;
4773 tempeax = (tempeax * 256 * 1024) / tempebx;
4779 temp = (unsigned short) (tempebx & 0x000000FF);
4780 xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp);
4782 temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8);
4783 xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp);
4784 tempbx = (unsigned short) (tempebx >> 16);
4785 temp = tempbx & 0x00FF;
4787 temp |= ((tempcx & 0xFF00) >> 8);
4788 xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp);
4791 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4792 | VB_SIS302LV | VB_XGI301C)) {
4794 xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp);
4795 tempax = pVBInfo->VGAHDE;
4796 if (modeflag & HalfDCLK)
4797 tempax = tempax >> 1;
4799 if (XGI_IsLCDDualLink(pVBInfo))
4800 tempax = tempax >> 1;
4802 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4805 } else if (pVBInfo->VGAHDE > 800) {
4806 if (pVBInfo->VGAHDE == 1024)
4807 tempax = (tempax * 25 / 32) - 1;
4809 tempax = (tempax * 20 / 32) - 1;
4813 temp = (tempax & 0xFF00) >> 8;
4814 temp = ((temp & 0x0003) << 4);
4815 xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp);
4816 temp = (tempax & 0x00FF);
4817 xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp);
4819 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) {
4820 if (pVBInfo->VGAHDE > 800)
4821 xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08);
4826 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4827 if (!(pVBInfo->TVInfo & (NTSC1024x768
4828 | TVSetYPbPr525p | TVSetYPbPr750p
4829 | TVSetHiVision))) {
4831 if ((pVBInfo->VBInfo & SetInSlaveMode)
4832 && (!(pVBInfo->TVInfo
4838 xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
4839 tempbx = pVBInfo->HT;
4840 if (XGI_IsLCDDualLink(pVBInfo))
4841 tempbx = tempbx >> 1;
4842 tempbx = (tempbx >> 1) - 2;
4843 temp = ((tempbx & 0x0700) >> 8) << 3;
4844 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
4845 temp = tempbx & 0x00FF;
4846 xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp);
4850 XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
4853 static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
4855 xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
4858 static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex,
4859 struct vb_device_info *pVBInfo)
4861 unsigned short Pindex, Pdata;
4863 Pindex = pVBInfo->Part5Port;
4864 Pdata = pVBInfo->Part5Port + 1;
4865 if (pVBInfo->ModeType == ModeVGA) {
4866 if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
4867 | DisableCRT2Display))) {
4868 XGINew_EnableCRT2(pVBInfo);
4874 static void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
4875 struct vb_device_info *pVBInfo)
4877 xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x40);
4880 static void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
4881 struct vb_device_info *pVBInfo)
4884 xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00);
4887 static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info,
4888 unsigned short ModeNo, unsigned short ModeIdIndex,
4889 struct vb_device_info *pVBInfo)
4891 unsigned short xres, yres, colordepth, modeflag, resindex;
4893 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
4894 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
4895 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
4896 /* si+St_ModeFlag */
4897 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4899 if (!(modeflag & Charx8Dot)) {
4904 if ((ModeNo > 0x13) && (modeflag & HalfDCLK))
4907 if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
4910 if (xres > xgifb_info->lvds_data.LVDSHDE)
4913 if (yres > xgifb_info->lvds_data.LVDSVDE)
4916 if (xres != xgifb_info->lvds_data.LVDSHDE ||
4917 yres != xgifb_info->lvds_data.LVDSVDE) {
4918 colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
4925 static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
4927 unsigned short ModeNo,
4928 unsigned short ModeIdIndex,
4929 struct vb_device_info *pVBInfo)
4931 unsigned char temp, Miscdata;
4932 unsigned short xres, yres, modeflag, resindex;
4933 unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
4934 unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
4935 unsigned short value;
4937 temp = (unsigned char) ((xgifb_info->lvds_data.LVDS_Capability &
4938 (LCDPolarity << 8)) >> 8);
4939 temp &= LCDPolarity;
4940 Miscdata = (unsigned char) inb(pVBInfo->P3cc);
4942 outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2);
4944 temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity;
4945 /* SR35[7] FP VSync polarity */
4946 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80);
4947 /* SR30[5] FP HSync polarity */
4948 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1);
4950 if (chip_id == XG27)
4951 XGI_SetXG27FPBits(pVBInfo);
4953 XGI_SetXG21FPBits(pVBInfo);
4955 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
4956 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
4957 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
4958 /* si+St_ModeFlag */
4959 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4961 if (!(modeflag & Charx8Dot))
4962 xres = xres * 8 / 9;
4964 LVDSHT = xgifb_info->lvds_data.LVDSHT;
4966 LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2;
4968 if (LVDSHBS > LVDSHT)
4971 LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP;
4972 if (LVDSHRS > LVDSHT)
4975 LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC;
4976 if (LVDSHRE > LVDSHT)
4979 LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE;
4981 LVDSVT = xgifb_info->lvds_data.LVDSVT;
4983 LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2;
4984 if (modeflag & DoubleScanMode)
4985 LVDSVBS += yres / 2;
4987 if (LVDSVBS > LVDSVT)
4990 LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP;
4991 if (LVDSVRS > LVDSVT)
4994 LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC;
4995 if (LVDSVRE > LVDSVT)
4998 LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE;
5000 temp = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
5001 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
5003 if (!(modeflag & Charx8Dot))
5004 xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1);
5006 /* HT SR0B[1:0] CR00 */
5007 value = (LVDSHT >> 3) - 5;
5008 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
5009 xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF));
5011 /* HBS SR0B[5:4] CR02 */
5012 value = (LVDSHBS >> 3) - 1;
5013 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
5014 xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF));
5016 /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
5017 value = (LVDSHBE >> 3) - 1;
5018 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
5019 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
5020 xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
5022 /* HRS SR0B[7:6] CR04 */
5023 value = (LVDSHRS >> 3) + 2;
5024 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
5025 xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF));
5027 /* Panel HRS SR2F[1:0] SR2E[7:0] */
5029 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
5030 xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF));
5032 /* HRE SR0C[2] CR05[4:0] */
5033 value = (LVDSHRE >> 3) + 2;
5034 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
5035 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
5037 /* Panel HRE SR2F[7:2] */
5039 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
5041 /* VT SR0A[0] CR07[5][0] CR06 */
5043 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
5044 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
5045 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
5046 xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF));
5048 /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
5049 value = LVDSVBS - 1;
5050 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
5051 xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
5052 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
5053 xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF));
5055 /* VBE SR0A[4] CR16 */
5056 value = LVDSVBE - 1;
5057 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
5058 xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF));
5060 /* VRS SR0A[3] CR7[7][2] CR10 */
5061 value = LVDSVRS - 1;
5062 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
5063 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
5064 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
5065 xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF));
5067 if (chip_id == XG27) {
5068 /* Panel VRS SR35[2:0] SR34[7:0] */
5069 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07,
5070 (value & 0x700) >> 8);
5071 xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF);
5073 /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
5074 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03,
5075 (value & 0x600) >> 9);
5076 xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF);
5077 xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01);
5080 /* VRE SR0A[5] CR11[3:0] */
5081 value = LVDSVRE - 1;
5082 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
5083 xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
5085 /* Panel VRE SR3F[7:2] */
5086 if (chip_id == XG27)
5087 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
5088 (value << 2) & 0xFC);
5090 /* SR3F[7] has to be 0, h/w bug */
5091 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
5092 (value << 2) & 0x7C);
5094 for (temp = 0, value = 0; temp < 3; temp++) {
5096 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
5097 xgifb_reg_set(pVBInfo->P3c4,
5098 0x2B, xgifb_info->lvds_data.VCLKData1);
5099 xgifb_reg_set(pVBInfo->P3c4,
5100 0x2C, xgifb_info->lvds_data.VCLKData2);
5104 if (!(modeflag & Charx8Dot)) {
5105 inb(pVBInfo->P3da); /* reset 3da */
5106 outb(0x13, pVBInfo->P3c0); /* set index */
5107 /* set data, panning = 0, shift left 1 dot*/
5108 outb(0x00, pVBInfo->P3c0);
5110 inb(pVBInfo->P3da); /* Enable Attribute */
5111 outb(0x20, pVBInfo->P3c0);
5113 inb(pVBInfo->P3da); /* reset 3da */
5118 /* --------------------------------------------------------------------- */
5119 /* Function : XGI_IsLCDON */
5121 /* Output : 0 : Skip PSC Control */
5122 /* 1: Disable PSC */
5124 /* --------------------------------------------------------------------- */
5125 static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
5127 unsigned short tempax;
5129 tempax = pVBInfo->VBInfo;
5130 if (tempax & SetCRT2ToDualEdge)
5132 else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode))
5138 /* --------------------------------------------------------------------- */
5139 /* Function : XGI_DisableChISLCD */
5141 /* Output : 0 -> Not LCD Mode */
5143 /* --------------------------------------------------------------------- */
5144 static unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo)
5146 unsigned short tempbx, tempah;
5148 tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
5149 tempah = ~((unsigned short) xgifb_reg_get(pVBInfo->Part1Port, 0x2E));
5151 if (tempbx & (EnableChA | DisableChA)) {
5152 if (!(tempah & 0x08)) /* Chk LCDA Mode */
5156 if (!(tempbx & (EnableChB | DisableChB)))
5159 if (tempah & 0x01) /* Chk LCDB Mode */
5165 /* --------------------------------------------------------------------- */
5166 /* Function : XGI_EnableChISLCD */
5168 /* Output : 0 -> Not LCD mode */
5170 /* --------------------------------------------------------------------- */
5171 static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo)
5173 unsigned short tempbx, tempah;
5175 tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
5176 tempah = ~((unsigned short) xgifb_reg_get(pVBInfo->Part1Port, 0x2E));
5178 if (tempbx & (EnableChA | DisableChA)) {
5179 if (!(tempah & 0x08)) /* Chk LCDA Mode */
5183 if (!(tempbx & (EnableChB | DisableChB)))
5186 if (tempah & 0x01) /* Chk LCDB Mode */
5192 static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
5193 struct xgi_hw_device_info *HwDeviceExtension,
5194 struct vb_device_info *pVBInfo)
5196 unsigned short tempah = 0;
5198 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5199 | VB_SIS302LV | VB_XGI301C)) {
5201 if (!(pVBInfo->VBInfo &
5202 (DisableCRT2Display | SetSimuScanMode))) {
5203 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5204 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
5205 tempah = 0x7F; /* Disable Channel A */
5206 if (!(pVBInfo->VBInfo &
5208 /* Disable Channel B */
5211 if (pVBInfo->SetFlag & DisableChB)
5212 /* force to disable Cahnnel */
5215 if (pVBInfo->SetFlag & DisableChA)
5216 /* Force to disable Channel B */
5222 /* disable part4_1f */
5223 xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah);
5225 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
5226 if (((pVBInfo->VBInfo &
5227 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
5228 || (XGI_DisableChISLCD(pVBInfo))
5229 || (XGI_IsLCDON(pVBInfo)))
5230 /* LVDS Driver power down */
5231 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80);
5234 if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
5235 & (DisableCRT2Display | XGI_SetCRT2ToLCDA
5236 | SetSimuScanMode))) {
5237 if (pVBInfo->SetFlag & GatingCRT)
5238 XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
5239 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
5242 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5243 if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
5244 & XGI_SetCRT2ToLCDA))
5246 xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf);
5249 /* disable TV as primary VGA swap */
5250 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf);
5252 if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
5253 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf);
5255 if ((pVBInfo->SetFlag & DisableChB) ||
5257 (DisableCRT2Display | SetSimuScanMode)) ||
5258 ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
5260 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
5261 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
5263 if ((pVBInfo->SetFlag & DisableChB) ||
5265 (DisableCRT2Display | SetSimuScanMode)) ||
5266 (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) ||
5268 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
5269 /* save Part1 index 0 */
5270 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
5271 /* BTDAC = 1, avoid VB reset */
5272 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10);
5274 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
5275 /* restore Part1 index 0 */
5276 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
5278 } else { /* {301} */
5279 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
5280 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
5282 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
5283 /* Disable TV asPrimary VGA swap */
5284 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF);
5287 if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA
5289 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
5293 /* --------------------------------------------------------------------- */
5294 /* Function : XGI_GetTVPtrIndex */
5297 /* Description : bx 0 : ExtNTSC */
5309 /* --------------------------------------------------------------------- */
5310 static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
5312 unsigned short tempbx = 0;
5314 if (pVBInfo->TVInfo & TVSetPAL)
5316 if (pVBInfo->TVInfo & TVSetHiVision)
5318 if (pVBInfo->TVInfo & TVSetYPbPr525i)
5320 if (pVBInfo->TVInfo & TVSetYPbPr525p)
5322 if (pVBInfo->TVInfo & TVSetYPbPr750p)
5324 if (pVBInfo->TVInfo & TVSimuMode)
5330 /* --------------------------------------------------------------------- */
5331 /* Function : XGI_GetTVPtrIndex2 */
5333 /* Output : bx 0 : NTSC */
5337 /* 4 : NTSC1024x768 */
5338 /* 5 : PAL-M 1024x768 */
5340 /* cl 0 : YFilter1 */
5343 /* 1 : 301B/302B/301LV/302LV */
5345 /* --------------------------------------------------------------------- */
5346 static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
5347 unsigned char *tempch, struct vb_device_info *pVBInfo)
5353 if (pVBInfo->TVInfo & TVSetPAL)
5356 if (pVBInfo->TVInfo & TVSetPALM)
5359 if (pVBInfo->TVInfo & TVSetPALN)
5362 if (pVBInfo->TVInfo & NTSC1024x768) {
5364 if (pVBInfo->TVInfo & TVSetPALM)
5368 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5369 | VB_SIS302LV | VB_XGI301C)) {
5370 if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
5377 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5378 | VB_SIS302LV | VB_XGI301C))
5382 static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
5384 unsigned char tempah, tempbl, tempbh;
5386 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5387 | VB_SIS302LV | VB_XGI301C)) {
5388 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA
5389 | SetCRT2ToTV | SetCRT2ToRAMDAC)) {
5391 tempbl = XGI301TVDelay;
5393 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5394 tempbl = tempbl >> 4;
5395 if (pVBInfo->VBInfo &
5396 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
5397 tempbh = XGI301LCDDelay;
5399 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
5405 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D);
5407 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
5408 | SetCRT2ToTV)) { /* Channel B */
5413 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5418 xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah);
5420 } else if (pVBInfo->IF_DEF_LVDS == 1) {
5423 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
5424 tempah = XGI301LCDDelay;
5426 tempah = tempah << 4;
5427 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2D, 0x0f,
5433 static void XGI_SetLCDCap_A(unsigned short tempcx,
5434 struct vb_device_info *pVBInfo)
5436 unsigned short temp;
5438 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
5440 if (temp & LCDRGB18Bit) {
5441 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
5443 (unsigned short) (0x20 | (tempcx & 0x00C0)));
5444 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
5446 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
5447 (unsigned short) (0x30 | (tempcx & 0x00C0)));
5448 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
5452 /* --------------------------------------------------------------------- */
5453 /* Function : XGI_SetLCDCap_B */
5454 /* Input : cx -> LCD Capability */
5457 /* --------------------------------------------------------------------- */
5458 static void XGI_SetLCDCap_B(unsigned short tempcx,
5459 struct vb_device_info *pVBInfo)
5461 if (tempcx & EnableLCD24bpp) /* 24bits */
5462 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
5463 (unsigned short) (((tempcx & 0x00ff) >> 6)
5466 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
5467 (unsigned short) (((tempcx & 0x00ff) >> 6)
5468 | 0x18)); /* Enable Dither */
5471 static void XGI_LongWait(struct vb_device_info *pVBInfo)
5475 i = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
5478 for (i = 0; i < 0xFFFF; i++) {
5479 if (!(inb(pVBInfo->P3da) & 0x08))
5483 for (i = 0; i < 0xFFFF; i++) {
5484 if ((inb(pVBInfo->P3da) & 0x08))
5490 static void SetSpectrum(struct vb_device_info *pVBInfo)
5492 unsigned short index;
5494 index = XGI_GetLCDCapPtr(pVBInfo);
5496 /* disable down spectrum D[4] */
5497 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F);
5498 XGI_LongWait(pVBInfo);
5499 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
5500 XGI_LongWait(pVBInfo);
5502 xgifb_reg_set(pVBInfo->Part4Port, 0x31,
5503 pVBInfo->LCDCapList[index].Spectrum_31);
5504 xgifb_reg_set(pVBInfo->Part4Port, 0x32,
5505 pVBInfo->LCDCapList[index].Spectrum_32);
5506 xgifb_reg_set(pVBInfo->Part4Port, 0x33,
5507 pVBInfo->LCDCapList[index].Spectrum_33);
5508 xgifb_reg_set(pVBInfo->Part4Port, 0x34,
5509 pVBInfo->LCDCapList[index].Spectrum_34);
5510 XGI_LongWait(pVBInfo);
5511 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
5514 static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
5516 unsigned short tempcx;
5518 tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
5520 if (pVBInfo->VBType &
5525 VB_XGI301C)) { /* 301LV/302LV only */
5526 if (pVBInfo->VBType &
5527 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
5528 /* Set 301LV Capability */
5529 xgifb_reg_set(pVBInfo->Part4Port, 0x24,
5530 (unsigned char) (tempcx & 0x1F));
5533 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D,
5534 ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
5535 (unsigned short) ((tempcx & (EnableVBCLKDRVLOW
5536 | EnablePLLSPLOW)) >> 8));
5539 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5540 | VB_SIS302LV | VB_XGI301C)) {
5541 if (pVBInfo->VBInfo & SetCRT2ToLCD)
5542 XGI_SetLCDCap_B(tempcx, pVBInfo);
5543 else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
5544 XGI_SetLCDCap_A(tempcx, pVBInfo);
5546 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
5547 if (tempcx & EnableSpectrum)
5548 SetSpectrum(pVBInfo);
5552 XGI_SetLCDCap_A(tempcx, pVBInfo);
5556 /* --------------------------------------------------------------------- */
5557 /* Function : XGI_SetAntiFlicker */
5560 /* Description : Set TV Customized Param. */
5561 /* --------------------------------------------------------------------- */
5562 static void XGI_SetAntiFlicker(unsigned short ModeNo,
5563 unsigned short ModeIdIndex,
5564 struct vb_device_info *pVBInfo)
5566 unsigned short tempbx;
5568 unsigned char tempah;
5570 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
5573 tempbx = XGI_GetTVPtrIndex(pVBInfo);
5575 tempah = TVAntiFlickList[tempbx];
5576 tempah = tempah << 4;
5578 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
5581 static void XGI_SetEdgeEnhance(unsigned short ModeNo,
5582 unsigned short ModeIdIndex,
5583 struct vb_device_info *pVBInfo)
5585 unsigned short tempbx;
5587 unsigned char tempah;
5589 tempbx = XGI_GetTVPtrIndex(pVBInfo);
5591 tempah = TVEdgeList[tempbx];
5592 tempah = tempah << 5;
5594 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
5597 static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
5599 unsigned short tempbx;
5601 unsigned char tempcl, tempch;
5603 unsigned long tempData;
5605 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
5606 tempData = TVPhaseList[tempbx];
5608 xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData
5610 xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData
5611 & 0x0000FF00) >> 8));
5612 xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData
5613 & 0x00FF0000) >> 16));
5614 xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData
5615 & 0xFF000000) >> 24));
5618 static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
5619 struct vb_device_info *pVBInfo)
5621 unsigned short tempbx, index;
5623 unsigned char tempcl, tempch, tempal, *filterPtr;
5625 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
5630 filterPtr = NTSCYFilter1;
5634 filterPtr = PALYFilter1;
5641 filterPtr = xgifb_palmn_yfilter1;
5649 filterPtr = xgifb_yfilter2;
5656 tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
5662 if ((tempcl == 0) && (tempch == 1)) {
5663 xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0);
5664 xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0);
5665 xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0);
5666 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
5668 xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
5669 xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
5670 xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
5671 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
5674 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5675 | VB_SIS302LV | VB_XGI301C)) {
5676 xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
5677 xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
5678 xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
5682 /* --------------------------------------------------------------------- */
5683 /* Function : XGI_OEM310Setting */
5686 /* Description : Customized Param. for 301 */
5687 /* --------------------------------------------------------------------- */
5688 static void XGI_OEM310Setting(unsigned short ModeNo,
5689 unsigned short ModeIdIndex,
5690 struct vb_device_info *pVBInfo)
5692 XGI_SetDelayComp(pVBInfo);
5694 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
5695 XGI_SetLCDCap(pVBInfo);
5697 if (pVBInfo->VBInfo & SetCRT2ToTV) {
5698 XGI_SetPhaseIncr(pVBInfo);
5699 XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
5700 XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
5702 if (pVBInfo->VBType & VB_SIS301)
5703 XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
5707 /* --------------------------------------------------------------------- */
5708 /* Function : XGI_SetCRT2ModeRegs */
5711 /* Description : Origin code for crt2group */
5712 /* --------------------------------------------------------------------- */
5713 static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
5714 struct xgi_hw_device_info *HwDeviceExtension,
5715 struct vb_device_info *pVBInfo)
5717 unsigned short tempbl;
5720 unsigned char tempah;
5723 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5724 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
5725 tempah &= ~0x10; /* BTRAMDAC */
5726 tempah |= 0x40; /* BTRAM */
5728 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
5730 tempah = 0x40; /* BTDRAM */
5731 tempcl = pVBInfo->ModeType;
5735 tempah = (0x008 >> tempcl);
5740 if (pVBInfo->VBInfo & SetInSlaveMode)
5741 tempah ^= 0x50; /* BTDAC */
5745 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
5749 if (pVBInfo->VBInfo & DisableCRT2Display)
5755 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV |
5756 SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
5759 if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
5760 (!(pVBInfo->VBInfo & SetSimuScanMode))) {
5766 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5771 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)))
5777 if (!(pVBInfo->VBInfo & SetInSlaveMode))
5780 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
5781 tempah = tempah ^ 0x05;
5782 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
5783 tempah = tempah ^ 0x01;
5786 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
5790 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
5792 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
5793 | XGI_SetCRT2ToLCDA)) {
5795 if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
5796 & SetInSlaveMode))) {
5801 if (pVBInfo->VBInfo & SetCRT2ToTV) {
5803 if (pVBInfo->VBInfo & DriverMode)
5804 tempah = tempah ^ 0x20;
5807 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
5810 if (pVBInfo->LCDInfo & SetLCDDualLink)
5813 if (pVBInfo->VBInfo & SetCRT2ToTV) {
5814 if (pVBInfo->TVInfo & RPLLDIV2XO)
5818 if ((pVBInfo->LCDResInfo == Panel_1280x1024)
5819 || (pVBInfo->LCDResInfo == Panel_1280x1024x75))
5822 if (pVBInfo->LCDResInfo == Panel_1280x960)
5825 xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah);
5828 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5829 | VB_SIS302LV | VB_XGI301C)) {
5833 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
5835 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
5836 tempah |= 0x04; /* shampoo 0129 */
5839 xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah);
5842 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5843 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5847 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
5851 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5852 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5855 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah);
5860 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) {
5862 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
5866 xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah);
5868 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
5869 if (pVBInfo->LCDInfo & SetLCDDualLink) {
5870 xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20);
5871 xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10);
5877 void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
5878 struct vb_device_info *pVBInfo)
5881 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
5885 void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
5886 struct vb_device_info *pVBInfo)
5889 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
5893 unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo)
5895 unsigned short flag;
5897 if (pVBInfo->IF_DEF_LVDS == 1) {
5900 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
5901 if ((flag == 1) || (flag == 2))
5902 return 1; /* 301b */
5908 unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
5909 unsigned short ModeNo, unsigned short ModeIdIndex,
5910 struct vb_device_info *pVBInfo)
5912 short LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 },
5913 LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01,
5916 unsigned short RefreshRateTableIndex, i, modeflag, index, temp;
5918 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5920 index = xgifb_reg_get(pVBInfo->P3d4, 0x33);
5921 index = index >> pVBInfo->SelectCRT2Rate;
5924 if (pVBInfo->LCDInfo & LCDNonExpanding)
5930 if (pVBInfo->SetFlag & ProgrammingCRT2) {
5931 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
5932 if (pVBInfo->IF_DEF_LVDS == 0) {
5933 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
5934 | VB_SIS301LV | VB_SIS302LV
5937 temp = LCDARefreshIndex[
5938 pVBInfo->LCDResInfo & 0x0F];
5940 temp = LCDRefreshIndex[
5941 pVBInfo->LCDResInfo & 0x0F];
5951 RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
5952 ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
5953 if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
5954 if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800) &&
5955 (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 600)) {
5958 /* do the similar adjustment like XGISearchCRT1Rate() */
5959 if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024) &&
5960 (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 768)) {
5963 if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280) &&
5964 (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 1024)) {
5971 if (pVBInfo->RefIndex[RefreshRateTableIndex + i].
5974 temp = pVBInfo->RefIndex[RefreshRateTableIndex + i].
5976 temp &= ModeTypeMask;
5977 if (temp < pVBInfo->ModeType)
5982 } while (index != 0xFFFF);
5983 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
5984 if (pVBInfo->VBInfo & SetInSlaveMode) {
5985 temp = pVBInfo->RefIndex[RefreshRateTableIndex + i - 1].
5987 if (temp & InterlaceMode)
5992 if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
5993 temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex,
5994 RefreshRateTableIndex, &i, pVBInfo);
5996 return RefreshRateTableIndex + i;
5999 static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
6000 struct xgi_hw_device_info *HwDeviceExtension,
6001 struct vb_device_info *pVBInfo)
6003 unsigned short RefreshRateTableIndex;
6005 pVBInfo->SetFlag |= ProgrammingCRT2;
6006 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
6007 ModeIdIndex, pVBInfo);
6008 XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
6009 XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6010 XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6011 HwDeviceExtension, pVBInfo);
6012 XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6013 XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6016 static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
6017 struct xgi_hw_device_info *HwDeviceExtension,
6018 struct vb_device_info *pVBInfo)
6020 unsigned short tempbx, ModeIdIndex, RefreshRateTableIndex;
6022 tempbx = pVBInfo->VBInfo;
6023 pVBInfo->SetFlag |= ProgrammingCRT2;
6024 XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
6025 pVBInfo->SelectCRT2Rate = 4;
6026 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
6027 ModeIdIndex, pVBInfo);
6028 XGI_SaveCRT2Info(ModeNo, pVBInfo);
6029 XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
6030 XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6031 XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
6032 RefreshRateTableIndex, pVBInfo);
6033 XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
6034 RefreshRateTableIndex, pVBInfo);
6035 XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
6036 RefreshRateTableIndex, pVBInfo);
6037 XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6038 HwDeviceExtension, pVBInfo);
6039 XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
6040 RefreshRateTableIndex, pVBInfo);
6041 XGI_SetTap4Regs(pVBInfo);
6042 XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
6043 XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6044 HwDeviceExtension, pVBInfo);
6045 XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6046 XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
6047 XGI_AutoThreshold(pVBInfo);
6051 void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
6053 unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
6054 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
6057 unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
6059 unsigned char CR17, CR63, SR31;
6060 unsigned short temp;
6061 unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
6064 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
6066 /* to fix XG42 single LCD sense to CRT+LCD */
6067 xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A);
6068 xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (xgifb_reg_get(
6069 pVBInfo->P3d4, 0x53) | 0x02));
6071 SR31 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x31);
6072 CR63 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x63);
6073 SR01 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x01);
6075 xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF));
6076 xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF));
6078 CR17 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x17);
6079 xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80));
6081 SR1F = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x1F);
6082 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04));
6084 SR07 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x07);
6085 xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB));
6086 SR06 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x06);
6087 xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3));
6089 xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00);
6091 for (i = 0; i < 8; i++)
6092 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]);
6094 for (i = 8; i < 11; i++)
6095 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 8),
6098 for (i = 11; i < 13; i++)
6099 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 4),
6102 for (i = 13; i < 16; i++)
6103 xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i - 3),
6106 xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16]
6109 xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00);
6110 xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B);
6111 xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1);
6113 outb(0x00, pVBInfo->P3c8);
6115 for (i = 0; i < 256; i++) {
6116 outb((unsigned char) DAC_TEST_PARMS[0], (pVBInfo->P3c8 + 1));
6117 outb((unsigned char) DAC_TEST_PARMS[1], (pVBInfo->P3c8 + 1));
6118 outb((unsigned char) DAC_TEST_PARMS[2], (pVBInfo->P3c8 + 1));
6123 XGI_WaitDisply(pVBInfo);
6124 temp = inb(pVBInfo->P3c2);
6127 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
6129 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
6131 /* avoid display something, set BLACK DAC if not restore DAC */
6132 outb(0x00, pVBInfo->P3c8);
6134 for (i = 0; i < 256; i++) {
6135 outb(0, (pVBInfo->P3c8 + 1));
6136 outb(0, (pVBInfo->P3c8 + 1));
6137 outb(0, (pVBInfo->P3c8 + 1));
6140 xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01);
6141 xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63);
6142 xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31);
6144 xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (xgifb_reg_get(
6145 pVBInfo->P3d4, 0x53) & 0xFD));
6146 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
6149 static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
6150 struct xgi_hw_device_info *HwDeviceExtension,
6151 struct vb_device_info *pVBInfo)
6153 unsigned short tempah;
6155 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
6156 | VB_SIS302LV | VB_XGI301C)) {
6157 if (!(pVBInfo->SetFlag & DisableChA)) {
6158 if (pVBInfo->SetFlag & EnableChA) {
6160 xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20);
6161 } else if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
6163 xgifb_reg_set(pVBInfo->Part1Port,
6168 if (!(pVBInfo->SetFlag & DisableChB)) {
6169 if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo
6170 & (SetCRT2ToLCD | SetCRT2ToTV
6171 | SetCRT2ToRAMDAC))) {
6172 tempah = (unsigned char) xgifb_reg_get(
6173 pVBInfo->P3c4, 0x32);
6175 if (pVBInfo->VBInfo & SetInSlaveMode) {
6176 if (!(pVBInfo->VBInfo &
6180 xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah);
6181 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20);
6183 tempah = (unsigned char) xgifb_reg_get(
6184 pVBInfo->Part1Port, 0x2E);
6186 if (!(tempah & 0x80))
6187 xgifb_reg_or(pVBInfo->Part1Port,
6189 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
6193 if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
6194 || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
6195 xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0,
6196 0x20); /* shampoo 0129 */
6197 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
6198 if (!XGI_DisableChISLCD(pVBInfo)) {
6199 if (XGI_EnableChISLCD(pVBInfo) ||
6201 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
6202 /* LVDS PLL power on */
6208 /* LVDS Driver power on */
6209 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F);
6215 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
6218 if (!(pVBInfo->VBInfo & SetSimuScanMode) &&
6219 (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
6220 (pVBInfo->VBInfo & SetCRT2ToDualEdge)) {
6221 tempah = tempah & 0x40;
6222 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
6223 tempah = tempah ^ 0xC0;
6225 if (pVBInfo->SetFlag & DisableChB)
6228 if (pVBInfo->SetFlag & DisableChA)
6231 if (pVBInfo->SetFlag & EnableChB)
6234 if (pVBInfo->SetFlag & EnableChA)
6239 /* EnablePart4_1F */
6240 xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah);
6242 if (!(pVBInfo->SetFlag & DisableChA)) {
6243 if (!(pVBInfo->SetFlag & GatingCRT)) {
6244 XGI_DisableGatingCRT(HwDeviceExtension,
6246 XGI_DisplayOn(xgifb_info, HwDeviceExtension,
6252 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
6253 | XGI_SetCRT2ToLCDA))
6255 xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20);
6257 tempah = (unsigned char) xgifb_reg_get(pVBInfo->Part1Port,
6259 if (!(tempah & 0x80))
6260 xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
6262 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
6263 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
6267 static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
6268 struct xgi_hw_device_info *HwDeviceExtension,
6269 unsigned short ModeNo, unsigned short ModeIdIndex,
6270 struct vb_device_info *pVBInfo)
6272 unsigned short RefreshRateTableIndex, temp;
6274 XGI_SetSeqRegs(ModeNo, ModeIdIndex, pVBInfo);
6275 outb(pVBInfo->StandTable->MISC, pVBInfo->P3c2);
6276 XGI_SetCRTCRegs(HwDeviceExtension, pVBInfo);
6277 XGI_SetATTRegs(ModeNo, ModeIdIndex, pVBInfo);
6278 XGI_SetGRCRegs(pVBInfo);
6279 XGI_ClearExt1Regs(pVBInfo);
6281 if (HwDeviceExtension->jChipType == XG27) {
6282 if (pVBInfo->IF_DEF_LVDS == 0)
6283 XGI_SetDefaultVCLK(pVBInfo);
6286 temp = ~ProgrammingCRT2;
6287 pVBInfo->SetFlag &= temp;
6288 pVBInfo->SelectCRT2Rate = 0;
6290 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
6291 | VB_SIS302LV | VB_XGI301C)) {
6292 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA
6293 | SetInSlaveMode)) {
6294 pVBInfo->SetFlag |= ProgrammingCRT2;
6298 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
6299 ModeIdIndex, pVBInfo);
6300 if (RefreshRateTableIndex != 0xFFFF) {
6301 XGI_SetSync(RefreshRateTableIndex, pVBInfo);
6302 XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6303 pVBInfo, HwDeviceExtension);
6304 XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
6305 RefreshRateTableIndex, pVBInfo);
6306 XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6307 HwDeviceExtension, pVBInfo);
6308 XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
6309 RefreshRateTableIndex, pVBInfo);
6312 if (HwDeviceExtension->jChipType >= XG21) {
6313 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
6316 if (HwDeviceExtension->jChipType == XG27)
6317 XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
6318 RefreshRateTableIndex, pVBInfo);
6320 XGI_SetXG21CRTC(ModeNo, ModeIdIndex,
6321 RefreshRateTableIndex, pVBInfo);
6323 XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
6324 RefreshRateTableIndex);
6326 xgifb_set_lcd(HwDeviceExtension->jChipType,
6327 pVBInfo, RefreshRateTableIndex, ModeNo);
6329 if (pVBInfo->IF_DEF_LVDS == 1)
6330 xgifb_set_lvds(xgifb_info,
6331 HwDeviceExtension->jChipType,
6332 ModeNo, ModeIdIndex, pVBInfo);
6336 pVBInfo->SetFlag &= (~ProgrammingCRT2);
6337 XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
6338 XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
6339 RefreshRateTableIndex, pVBInfo);
6340 XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
6343 unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
6344 struct xgi_hw_device_info *HwDeviceExtension,
6345 unsigned short ModeNo)
6347 unsigned short ModeIdIndex;
6348 struct vb_device_info VBINF;
6349 struct vb_device_info *pVBInfo = &VBINF;
6350 pVBInfo->BaseAddr = xgifb_info->vga_base;
6351 pVBInfo->IF_DEF_LVDS = 0;
6353 if (HwDeviceExtension->jChipType >= XG20) {
6354 pVBInfo->IF_DEF_YPbPr = 0;
6355 pVBInfo->IF_DEF_HiVision = 0;
6356 pVBInfo->IF_DEF_CRT2Monitor = 0;
6357 pVBInfo->VBType = 0; /*set VBType default 0*/
6359 pVBInfo->IF_DEF_YPbPr = 1;
6360 pVBInfo->IF_DEF_HiVision = 1;
6361 pVBInfo->IF_DEF_CRT2Monitor = 1;
6364 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
6365 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
6366 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
6367 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
6368 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
6369 pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C;
6370 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
6371 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
6372 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
6373 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
6374 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
6375 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
6376 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
6377 pVBInfo->Part1Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_04;
6378 pVBInfo->Part2Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_10;
6379 pVBInfo->Part3Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_12;
6380 pVBInfo->Part4Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14;
6381 pVBInfo->Part5Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14 + 2;
6383 /* for x86 Linux, XG21 LVDS */
6384 if (HwDeviceExtension->jChipType == XG21) {
6385 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
6386 pVBInfo->IF_DEF_LVDS = 1;
6388 if (HwDeviceExtension->jChipType == XG27) {
6389 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
6390 if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20)
6391 pVBInfo->IF_DEF_LVDS = 1;
6395 if (HwDeviceExtension->jChipType < XG20)
6396 XGI_GetVBType(pVBInfo);
6398 InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
6400 ModeNo = ModeNo & 0x7F;
6401 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
6403 if (HwDeviceExtension->jChipType < XG20)
6404 XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
6406 XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
6408 if (HwDeviceExtension->jChipType < XG20) {
6409 XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
6410 XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
6411 XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
6412 XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
6414 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA)) {
6415 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
6416 ModeIdIndex, pVBInfo);
6418 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
6419 XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
6420 HwDeviceExtension, pVBInfo);
6422 } else if (!(pVBInfo->VBInfo & SwitchCRT2)) {
6423 XGI_SetCRT1Group(xgifb_info,
6424 HwDeviceExtension, ModeNo,
6425 ModeIdIndex, pVBInfo);
6426 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
6427 XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
6433 if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) {
6434 switch (HwDeviceExtension->ujVBChipID) {
6436 XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
6437 pVBInfo); /*add for CRT2 */
6441 XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
6442 pVBInfo); /*add for CRT2 */
6450 XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
6451 XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/
6452 XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
6455 if (pVBInfo->IF_DEF_LVDS == 1)
6456 if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo,
6461 pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex].
6462 Ext_ModeFlag & ModeTypeMask;
6464 pVBInfo->SetFlag = 0;
6465 pVBInfo->VBInfo = DisableCRT2Display;
6467 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
6469 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
6470 ModeIdIndex, pVBInfo);
6472 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
6475 XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
6477 if (HwDeviceExtension->jChipType < XG20)
6478 XGI_LockCRT2(HwDeviceExtension, pVBInfo);