Adding support for MOXA ART SoC. Testing port of linux-2.6.32.60-moxart.
[linux-3.6.7-moxart.git] / drivers / staging / xgifb / vb_setmode.c
blobe81149fc66e38d3a454acc75a553a842d6192472
1 #include <linux/delay.h>
2 #include "XGIfb.h"
4 #include "vb_def.h"
5 #include "vb_util.h"
6 #include "vb_table.h"
7 #include "vb_setmode.h"
9 #define IndexMask 0xff
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 = (struct SiS_StandTable_S *) &XGI330_StandTable;
27 pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable;
28 pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex;
29 pVBInfo->XGINEWUB_CRT1Table
30 = (struct XGI_CRT1TableStruct *) XGI_CRT1Table;
32 pVBInfo->MCLKData = (struct SiS_MCLKData *) XGI340New_MCLKData;
33 pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData;
34 pVBInfo->VCLKData = (struct SiS_VCLKData *) XGI_VCLKData;
35 pVBInfo->VBVCLKData = (struct SiS_VBVCLKData *) XGI_VBVCLKData;
36 pVBInfo->ScreenOffset = XGI330_ScreenOffset;
37 pVBInfo->StResInfo = (struct SiS_StResInfo_S *) XGI330_StResInfo;
38 pVBInfo->ModeResInfo
39 = (struct SiS_ModeResInfo_S *) XGI330_ModeResInfo;
41 pVBInfo->LCDResInfo = 0;
42 pVBInfo->LCDTypeInfo = 0;
43 pVBInfo->LCDInfo = 0;
44 pVBInfo->VBInfo = 0;
45 pVBInfo->TVInfo = 0;
47 pVBInfo->SR15 = XGI340_SR13;
48 pVBInfo->CR40 = XGI340_cr41;
49 pVBInfo->CR6B = XGI340_CR6B;
50 pVBInfo->CR6E = XGI340_CR6E;
51 pVBInfo->CR6F = XGI340_CR6F;
52 pVBInfo->CR89 = XGI340_CR89;
53 pVBInfo->AGPReg = XGI340_AGPReg;
54 pVBInfo->SR16 = XGI340_SR16;
56 pVBInfo->SR21 = 0xa3;
57 pVBInfo->SR22 = 0xfb;
59 pVBInfo->NTSCTiming = XGI330_NTSCTiming;
60 pVBInfo->PALTiming = XGI330_PALTiming;
61 pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming;
62 pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing;
63 pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing;
64 pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming;
65 pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming;
66 pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming;
67 pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming;
68 pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data;
69 pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu;
70 pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text;
71 pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3;
72 pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3;
74 pVBInfo->TimingH = (struct XGI_TimingHStruct *) XGI_TimingH;
75 pVBInfo->TimingV = (struct XGI_TimingVStruct *) XGI_TimingV;
76 pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table;
78 /* 310 customization related */
79 if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
80 pVBInfo->LCDCapList = XGI_LCDDLCapList;
81 else
82 pVBInfo->LCDCapList = XGI_LCDCapList;
84 if (ChipType >= XG20)
85 pVBInfo->XGINew_CR97 = 0x10;
87 if (ChipType == XG27) {
88 unsigned char temp;
89 pVBInfo->MCLKData
90 = (struct SiS_MCLKData *) XGI27New_MCLKData;
91 pVBInfo->CR40 = XGI27_cr41;
92 pVBInfo->XGINew_CR97 = 0xc1;
93 pVBInfo->SR15 = XG27_SR13;
95 /*Z11m DDR*/
96 temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
97 /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
98 if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
99 pVBInfo->XGINew_CR97 = 0x80;
104 static void XGI_SetSeqRegs(unsigned short ModeNo,
105 unsigned short ModeIdIndex,
106 struct vb_device_info *pVBInfo)
108 unsigned char tempah, SRdata;
109 unsigned short i, modeflag;
111 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
113 xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
114 tempah = pVBInfo->StandTable->SR[0];
116 i = XGI_SetCRT2ToLCDA;
117 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
118 tempah |= 0x01;
119 } else {
120 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
121 if (pVBInfo->VBInfo & SetInSlaveMode)
122 tempah |= 0x01;
126 tempah |= 0x20; /* screen off */
127 xgifb_reg_set(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */
129 for (i = 02; i <= 04; i++) {
130 /* Get SR2,3,4 from file */
131 SRdata = pVBInfo->StandTable->SR[i - 1];
132 xgifb_reg_set(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */
136 static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
137 struct vb_device_info *pVBInfo)
139 unsigned char CRTCdata;
140 unsigned short i;
142 CRTCdata = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
143 CRTCdata &= 0x7f;
144 xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
146 for (i = 0; i <= 0x18; i++) {
147 /* Get CRTC from file */
148 CRTCdata = pVBInfo->StandTable->CRTC[i];
149 xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
153 static void XGI_SetATTRegs(unsigned short ModeNo,
154 unsigned short ModeIdIndex,
155 struct vb_device_info *pVBInfo)
157 unsigned char ARdata;
158 unsigned short i, modeflag;
160 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
162 for (i = 0; i <= 0x13; i++) {
163 ARdata = pVBInfo->StandTable->ATTR[i];
165 if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */
166 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
167 ARdata = 0;
168 } else {
169 if ((pVBInfo->VBInfo &
170 (SetCRT2ToTV | SetCRT2ToLCD)) &&
171 (pVBInfo->VBInfo & SetInSlaveMode))
172 ARdata = 0;
176 inb(pVBInfo->P3da); /* reset 3da */
177 outb(i, pVBInfo->P3c0); /* set index */
178 outb(ARdata, pVBInfo->P3c0); /* set data */
181 inb(pVBInfo->P3da); /* reset 3da */
182 outb(0x14, pVBInfo->P3c0); /* set index */
183 outb(0x00, pVBInfo->P3c0); /* set data */
184 inb(pVBInfo->P3da); /* Enable Attribute */
185 outb(0x20, pVBInfo->P3c0);
188 static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo)
190 unsigned char GRdata;
191 unsigned short i;
193 for (i = 0; i <= 0x08; i++) {
194 /* Get GR from file */
195 GRdata = pVBInfo->StandTable->GRC[i];
196 xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
199 if (pVBInfo->ModeType > ModeVGA) {
200 GRdata = (unsigned char) xgifb_reg_get(pVBInfo->P3ce, 0x05);
201 GRdata &= 0xBF; /* 256 color disable */
202 xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata);
206 static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
208 unsigned short i;
210 for (i = 0x0A; i <= 0x0E; i++)
211 xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
214 static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
217 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
218 xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B);
219 xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C);
221 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
222 xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B);
223 xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C);
225 xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30);
226 return 0;
229 static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
230 unsigned short ModeIdIndex,
231 unsigned short RefreshRateTableIndex, unsigned short *i,
232 struct vb_device_info *pVBInfo)
234 unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
236 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
237 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
238 tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
239 tempax = 0;
241 if (pVBInfo->IF_DEF_LVDS == 0) {
242 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
243 tempax |= SupportRAMDAC2;
245 if (pVBInfo->VBType & VB_XGI301C)
246 tempax |= SupportCRT2in301C;
249 /* 301b */
250 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
251 tempax |= SupportLCD;
253 if (pVBInfo->LCDResInfo != Panel_1280x1024 &&
254 pVBInfo->LCDResInfo != Panel_1280x960 &&
255 (pVBInfo->LCDInfo & LCDNonExpanding) &&
256 resinfo >= 9)
257 return 0;
260 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */
261 if ((pVBInfo->VBType & VB_SIS301LV) &&
262 (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
263 tempax |= SupportYPbPr750p;
264 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
265 ((resinfo == 3) ||
266 (resinfo == 4) ||
267 (resinfo > 7)))
268 return 0;
269 } else {
270 tempax |= SupportHiVision;
271 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
272 ((resinfo == 4) ||
273 (resinfo == 3 &&
274 (pVBInfo->SetFlag & TVSimuMode)) ||
275 (resinfo > 7)))
276 return 0;
278 } else {
279 if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO |
280 SetCRT2ToSVIDEO |
281 SetCRT2ToSCART |
282 SetCRT2ToYPbPr525750 |
283 SetCRT2ToHiVision)) {
284 tempax |= SupportTV;
286 if (pVBInfo->VBType & (VB_SIS301B |
287 VB_SIS302B |
288 VB_SIS301LV |
289 VB_SIS302LV |
290 VB_XGI301C))
291 tempax |= SupportTV1024;
293 if (!(pVBInfo->VBInfo & TVSetPAL) &&
294 (modeflag & NoSupportSimuTV) &&
295 (pVBInfo->VBInfo & SetInSlaveMode) &&
296 (!(pVBInfo->VBInfo & SetNotSimuMode)))
297 return 0;
300 } else { /* for LVDS */
301 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
302 tempax |= SupportLCD;
304 if (resinfo > 0x08)
305 return 0; /* 1024x768 */
307 if (pVBInfo->LCDResInfo < Panel_1024x768) {
308 if (resinfo > 0x07)
309 return 0; /* 800x600 */
311 if (resinfo == 0x04)
312 return 0; /* 512x384 */
317 for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
318 tempbx; (*i)--) {
319 infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
320 Ext_InfoFlag;
321 if (infoflag & tempax)
322 return 1;
324 if ((*i) == 0)
325 break;
328 for ((*i) = 0;; (*i)++) {
329 infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
330 Ext_InfoFlag;
331 if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID
332 != tempbx) {
333 return 0;
336 if (infoflag & tempax)
337 return 1;
339 return 1;
342 static void XGI_SetSync(unsigned short RefreshRateTableIndex,
343 struct vb_device_info *pVBInfo)
345 unsigned short sync, temp;
347 /* di+0x00 */
348 sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
349 sync &= 0xC0;
350 temp = 0x2F;
351 temp |= sync;
352 outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */
355 static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
356 struct xgi_hw_device_info *HwDeviceExtension)
358 unsigned char data, data1, pushax;
359 unsigned short i, j;
361 /* unlock cr0-7 */
362 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
363 data &= 0x7F;
364 xgifb_reg_set(pVBInfo->P3d4, 0x11, data);
366 data = pVBInfo->TimingH[0].data[0];
367 xgifb_reg_set(pVBInfo->P3d4, 0, data);
369 for (i = 0x01; i <= 0x04; i++) {
370 data = pVBInfo->TimingH[0].data[i];
371 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data);
374 for (i = 0x05; i <= 0x06; i++) {
375 data = pVBInfo->TimingH[0].data[i];
376 xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data);
379 j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e);
380 j &= 0x1F;
381 data = pVBInfo->TimingH[0].data[7];
382 data &= 0xE0;
383 data |= j;
384 xgifb_reg_set(pVBInfo->P3c4, 0x0e, data);
386 if (HwDeviceExtension->jChipType >= XG20) {
387 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x04);
388 data = data - 1;
389 xgifb_reg_set(pVBInfo->P3d4, 0x04, data);
390 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x05);
391 data1 = data;
392 data1 &= 0xE0;
393 data &= 0x1F;
394 if (data == 0) {
395 pushax = data;
396 data = (unsigned char) xgifb_reg_get(pVBInfo->P3c4,
397 0x0c);
398 data &= 0xFB;
399 xgifb_reg_set(pVBInfo->P3c4, 0x0c, data);
400 data = pushax;
402 data = data - 1;
403 data |= data1;
404 xgifb_reg_set(pVBInfo->P3d4, 0x05, data);
405 data = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e);
406 data = data >> 5;
407 data = data + 3;
408 if (data > 7)
409 data = data - 7;
410 data = data << 5;
411 xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data);
415 static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
416 unsigned short ModeNo,
417 struct vb_device_info *pVBInfo)
419 unsigned char data;
420 unsigned short i, j;
422 for (i = 0x00; i <= 0x01; i++) {
423 data = pVBInfo->TimingV[0].data[i];
424 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data);
427 for (i = 0x02; i <= 0x03; i++) {
428 data = pVBInfo->TimingV[0].data[i];
429 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
432 for (i = 0x04; i <= 0x05; i++) {
433 data = pVBInfo->TimingV[0].data[i];
434 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
437 j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0a);
438 j &= 0xC0;
439 data = pVBInfo->TimingV[0].data[6];
440 data &= 0x3F;
441 data |= j;
442 xgifb_reg_set(pVBInfo->P3c4, 0x0a, data);
444 data = pVBInfo->TimingV[0].data[6];
445 data &= 0x80;
446 data = data >> 2;
448 i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
449 i &= DoubleScanMode;
450 if (i)
451 data |= 0x80;
453 j = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x09);
454 j &= 0x5F;
455 data |= j;
456 xgifb_reg_set(pVBInfo->P3d4, 0x09, data);
459 static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
460 unsigned short RefreshRateTableIndex,
461 struct vb_device_info *pVBInfo,
462 struct xgi_hw_device_info *HwDeviceExtension)
464 unsigned char index, data;
465 unsigned short i;
467 /* Get index */
468 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
469 index = index & IndexMask;
471 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
472 data &= 0x7F;
473 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
475 for (i = 0; i < 8; i++)
476 pVBInfo->TimingH[0].data[i]
477 = pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
479 for (i = 0; i < 7; i++)
480 pVBInfo->TimingV[0].data[i]
481 = pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
483 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
485 XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
487 if (pVBInfo->ModeType > 0x03)
488 xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F);
491 /* --------------------------------------------------------------------- */
492 /* Function : XGI_SetXG21CRTC */
493 /* Input : Stand or enhance CRTC table */
494 /* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
495 /* Description : Set LCD timing */
496 /* --------------------------------------------------------------------- */
497 static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
498 unsigned short RefreshRateTableIndex,
499 struct vb_device_info *pVBInfo)
501 unsigned char index, Tempax, Tempbx, Tempcx, Tempdx;
502 unsigned short Temp1, Temp2, Temp3;
504 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
505 /* Tempax: CR4 HRS */
506 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
507 Tempcx = Tempax; /* Tempcx: HRS */
508 /* SR2E[7:0]->HRS */
509 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
511 Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */
512 Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
513 Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
514 Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
515 Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
517 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
518 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
520 Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
521 Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
522 Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
523 Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
525 Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
526 Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
528 Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
529 if (Tempax < Tempcx) /* HRE < HRS */
530 Temp2 |= 0x40; /* Temp2 + 0x40 */
532 Temp2 &= 0xFF;
533 Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
534 Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
535 Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
536 Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
537 /* SR2F D[7:2]->HRE, D[1:0]->HRS */
538 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
539 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
541 /* CR10 VRS */
542 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
543 Tempbx = Tempax; /* Tempbx: VRS */
544 Tempax &= 0x01; /* Tempax[0]: VRS[0] */
545 xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
546 /* CR7[2][7] VRE */
547 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
548 Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
549 Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
550 Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
551 Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
552 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
554 Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
555 Temp1 <<= 1; /* Temp1[8]: VRS[8] */
556 Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
557 Tempax &= 0x80;
558 Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
559 Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
560 /* Tempax: SRA */
561 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
562 Tempax &= 0x08; /* Tempax[3]: VRS[3] */
563 Temp2 = Tempax;
564 Temp2 <<= 7; /* Temp2[10]: VRS[10] */
565 Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
567 /* Tempax: CR11 VRE */
568 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
569 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
570 /* Tempbx: SRA */
571 Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
572 Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
573 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
574 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
575 Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
576 Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
578 Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
579 if (Tempax < Temp3) /* VRE < VRS */
580 Temp2 |= 0x20; /* VRE + 0x20 */
582 Temp2 &= 0xFF;
583 Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
584 Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
585 Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
586 Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
587 Tempbx = (unsigned char) Temp1;
588 Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
589 Tempax &= 0x7F;
590 /* SR3F D[7:2]->VRE D[1:0]->VRS */
591 xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
594 static void XGI_SetXG27CRTC(unsigned short ModeNo,
595 unsigned short ModeIdIndex,
596 unsigned short RefreshRateTableIndex,
597 struct vb_device_info *pVBInfo)
599 unsigned short index, Tempax, Tempbx, Tempcx;
601 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
602 /* Tempax: CR4 HRS */
603 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
604 Tempbx = Tempax; /* Tempbx: HRS[7:0] */
605 /* SR2E[7:0]->HRS */
606 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
608 /* SR0B */
609 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5];
610 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
611 Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
613 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
614 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
615 Tempcx = Tempax; /* Tempcx: HRE[4:0] */
617 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
618 Tempax &= 0x04; /* Tempax[2]: HRE[5] */
619 Tempax <<= 3; /* Tempax[5]: HRE[5] */
620 Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
622 Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
623 Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
625 /* Tempax: CR4 HRS */
626 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
627 Tempax &= 0x3F; /* Tempax: HRS[5:0] */
628 if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
629 Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
631 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
632 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
633 Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
634 Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
635 /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
636 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
637 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
639 /* CR10 VRS */
640 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
641 /* SR34[7:0]->VRS[7:0] */
642 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax);
644 Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
645 /* CR7[7][2] VRS[9][8] */
646 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
647 Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
648 Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
649 Tempax >>= 2; /* Tempax[0]: VRS[8] */
650 /* SR35[0]: VRS[8] */
651 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
652 Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
653 Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
654 /* Tempax: SR0A */
655 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
656 Tempax &= 0x08; /* SR0A[3] VRS[10] */
657 Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
659 /* Tempax: CR11 VRE */
660 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
661 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
662 /* Tempbx: SR0A */
663 Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
664 Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
665 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
666 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
667 Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
668 Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
669 Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
671 if (Tempbx <= Tempcx) /* VRE <= VRS */
672 Tempbx |= 0x20; /* VRE + 0x20 */
674 /* Tempax: Tempax[7:0]; VRE[5:0]00 */
675 Tempax = (Tempbx << 2) & 0xFF;
676 /* SR3F[7:2]:VRE[5:0] */
677 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
678 Tempax = Tempcx >> 8;
679 /* SR35[2:0]:VRS[10:8] */
680 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax);
683 static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
685 unsigned char temp;
687 /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
688 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
689 temp = (temp & 3) << 6;
690 /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
691 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80);
692 /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
693 xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
697 static void xgifb_set_lcd(int chip_id,
698 struct vb_device_info *pVBInfo,
699 unsigned short RefreshRateTableIndex,
700 unsigned short ModeNo)
702 unsigned short Data, Temp;
703 unsigned short XGI_P3cc;
705 XGI_P3cc = pVBInfo->P3cc;
707 xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00);
708 xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00);
709 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00);
710 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00);
712 if (chip_id == XG27) {
713 Temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
714 if ((Temp & 0x03) == 0) { /* dual 12 */
715 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13);
716 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13);
720 if (chip_id == XG27) {
721 XGI_SetXG27FPBits(pVBInfo);
722 } else {
723 Temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
724 if (Temp & 0x01) {
725 /* 18 bits FP */
726 xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40);
727 xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40);
731 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
733 xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
734 xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
736 Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
737 if (Data & 0x4000)
738 /* Hsync polarity */
739 xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
740 if (Data & 0x8000)
741 /* Vsync polarity */
742 xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
745 /* --------------------------------------------------------------------- */
746 /* Function : XGI_UpdateXG21CRTC */
747 /* Input : */
748 /* Output : CRT1 CRTC */
749 /* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
750 /* --------------------------------------------------------------------- */
751 static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
752 struct vb_device_info *pVBInfo,
753 unsigned short RefreshRateTableIndex)
755 int index = -1;
757 xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
758 if (ModeNo == 0x2E &&
759 (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
760 RES640x480x60))
761 index = 12;
762 else if (ModeNo == 0x2E && (pVBInfo->RefIndex[RefreshRateTableIndex].
763 Ext_CRT1CRTC == RES640x480x72))
764 index = 13;
765 else if (ModeNo == 0x2F)
766 index = 14;
767 else if (ModeNo == 0x50)
768 index = 15;
769 else if (ModeNo == 0x59)
770 index = 16;
772 if (index != -1) {
773 xgifb_reg_set(pVBInfo->P3d4, 0x02,
774 pVBInfo->UpdateCRT1[index].CR02);
775 xgifb_reg_set(pVBInfo->P3d4, 0x03,
776 pVBInfo->UpdateCRT1[index].CR03);
777 xgifb_reg_set(pVBInfo->P3d4, 0x15,
778 pVBInfo->UpdateCRT1[index].CR15);
779 xgifb_reg_set(pVBInfo->P3d4, 0x16,
780 pVBInfo->UpdateCRT1[index].CR16);
784 static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
785 unsigned short ModeNo, unsigned short ModeIdIndex,
786 unsigned short RefreshRateTableIndex,
787 struct vb_device_info *pVBInfo)
789 unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
791 unsigned char data;
793 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
795 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
796 tempax = pVBInfo->ModeResInfo[resindex].HTotal;
797 tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
799 if (modeflag & HalfDCLK)
800 tempax = tempax >> 1;
802 if (modeflag & HalfDCLK)
803 tempax = tempax << 1;
805 temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
807 if (temp & InterlaceMode)
808 tempbx = tempbx >> 1;
810 if (modeflag & DoubleScanMode)
811 tempbx = tempbx << 1;
813 tempcx = 8;
815 tempax /= tempcx;
816 tempax -= 1;
817 tempbx -= 1;
818 tempcx = tempax;
819 temp = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
820 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
821 data &= 0x7F;
822 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
823 xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
824 xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c,
825 (unsigned short) ((tempcx & 0x0ff00) >> 10));
826 xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
827 tempax = 0;
828 tempbx = tempbx >> 8;
830 if (tempbx & 0x01)
831 tempax |= 0x02;
833 if (tempbx & 0x02)
834 tempax |= 0x40;
836 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax);
837 data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x07);
838 data &= 0xFF;
839 tempax = 0;
841 if (tempbx & 0x04)
842 tempax |= 0x02;
844 xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
845 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp);
848 static void XGI_SetCRT1Offset(unsigned short ModeNo,
849 unsigned short ModeIdIndex,
850 unsigned short RefreshRateTableIndex,
851 struct xgi_hw_device_info *HwDeviceExtension,
852 struct vb_device_info *pVBInfo)
854 unsigned short temp, ah, al, temp2, i, DisplayUnit;
856 /* GetOffset */
857 temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
858 temp = temp >> 8;
859 temp = pVBInfo->ScreenOffset[temp];
861 temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
862 temp2 &= InterlaceMode;
864 if (temp2)
865 temp = temp << 1;
867 temp2 = pVBInfo->ModeType - ModeEGA;
869 switch (temp2) {
870 case 0:
871 temp2 = 1;
872 break;
873 case 1:
874 temp2 = 2;
875 break;
876 case 2:
877 temp2 = 4;
878 break;
879 case 3:
880 temp2 = 4;
881 break;
882 case 4:
883 temp2 = 6;
884 break;
885 case 5:
886 temp2 = 8;
887 break;
888 default:
889 break;
892 if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
893 temp = temp * temp2 + temp2 / 2;
894 else
895 temp *= temp2;
897 /* SetOffset */
898 DisplayUnit = temp;
899 temp2 = temp;
900 temp = temp >> 8; /* ah */
901 temp &= 0x0F;
902 i = xgifb_reg_get(pVBInfo->P3c4, 0x0E);
903 i &= 0xF0;
904 i |= temp;
905 xgifb_reg_set(pVBInfo->P3c4, 0x0E, i);
907 temp = (unsigned char) temp2;
908 temp &= 0xFF; /* al */
909 xgifb_reg_set(pVBInfo->P3d4, 0x13, temp);
911 /* SetDisplayUnit */
912 temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
913 temp2 &= InterlaceMode;
914 if (temp2)
915 DisplayUnit >>= 1;
917 DisplayUnit = DisplayUnit << 5;
918 ah = (DisplayUnit & 0xff00) >> 8;
919 al = DisplayUnit & 0x00ff;
920 if (al == 0)
921 ah += 1;
922 else
923 ah += 2;
925 if (HwDeviceExtension->jChipType >= XG20)
926 if ((ModeNo == 0x4A) | (ModeNo == 0x49))
927 ah -= 1;
929 xgifb_reg_set(pVBInfo->P3c4, 0x10, ah);
932 static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
933 unsigned short ModeIdIndex,
934 unsigned short RefreshRateTableIndex,
935 struct xgi_hw_device_info *HwDeviceExtension,
936 struct vb_device_info *pVBInfo)
938 unsigned short CRT2Index, VCLKIndex;
939 unsigned short modeflag, resinfo;
941 /* si+Ext_ResInfo */
942 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
943 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
944 CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
946 if (pVBInfo->IF_DEF_LVDS == 0) {
947 CRT2Index = CRT2Index >> 6; /* for LCD */
948 if (pVBInfo->VBInfo &
949 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /*301b*/
950 if (pVBInfo->LCDResInfo != Panel_1024x768)
951 /* LCDXlat2VCLK */
952 VCLKIndex = VCLK108_2_315 + 5;
953 else
954 VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */
955 } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
956 if (pVBInfo->SetFlag & RPLLDIV2XO)
957 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2;
958 else
959 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK;
961 if (pVBInfo->SetFlag & TVSimuMode) {
962 if (modeflag & Charx8Dot) {
963 VCLKIndex = TVCLKBASE_315_25 +
964 HiTVSimuVCLK;
965 } else {
966 VCLKIndex = TVCLKBASE_315_25 +
967 HiTVTextVCLK;
971 /* 301lv */
972 if ((pVBInfo->VBType & VB_SIS301LV) &&
973 !(pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
974 if (pVBInfo->VBExtInfo == YPbPr750p)
975 VCLKIndex = XGI_YPbPr750pVCLK;
976 else if (pVBInfo->VBExtInfo == YPbPr525p)
977 VCLKIndex = YPbPr525pVCLK;
978 else if (pVBInfo->SetFlag & RPLLDIV2XO)
979 VCLKIndex = YPbPr525iVCLK_2;
980 else
981 VCLKIndex = YPbPr525iVCLK;
983 } else if (pVBInfo->VBInfo & SetCRT2ToTV) {
984 if (pVBInfo->SetFlag & RPLLDIV2XO)
985 VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2;
986 else
987 VCLKIndex = TVCLKBASE_315_25 + TVVCLK;
988 } else { /* for CRT2 */
989 /* di+Ext_CRTVCLK */
990 VCLKIndex = pVBInfo->RefIndex[RefreshRateTableIndex].
991 Ext_CRTVCLK;
992 VCLKIndex &= IndexMask;
994 } else { /* LVDS */
995 if ((pVBInfo->LCDResInfo == Panel_800x600) ||
996 (pVBInfo->LCDResInfo == Panel_320x480))
997 VCLKIndex = VCLK40; /* LVDSXlat1VCLK */
998 else
999 VCLKIndex = VCLK65_315 + 2; /* LVDSXlat2VCLK,
1000 LVDSXlat3VCLK */
1003 return VCLKIndex;
1006 static void XGI_SetCRT1VCLK(unsigned short ModeNo,
1007 unsigned short ModeIdIndex,
1008 struct xgi_hw_device_info *HwDeviceExtension,
1009 unsigned short RefreshRateTableIndex,
1010 struct vb_device_info *pVBInfo)
1012 unsigned char index, data;
1013 unsigned short vclkindex;
1015 if (pVBInfo->IF_DEF_LVDS == 1) {
1016 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1017 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
1018 xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
1019 xgifb_reg_set(pVBInfo->P3c4, 0x2B,
1020 pVBInfo->VCLKData[index].SR2B);
1021 xgifb_reg_set(pVBInfo->P3c4, 0x2C,
1022 pVBInfo->VCLKData[index].SR2C);
1023 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
1024 } else if ((pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
1025 | VB_SIS302LV | VB_XGI301C)) && (pVBInfo->VBInfo
1026 & XGI_SetCRT2ToLCDA)) {
1027 vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex,
1028 RefreshRateTableIndex, HwDeviceExtension,
1029 pVBInfo);
1030 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
1031 xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
1032 data = pVBInfo->VBVCLKData[vclkindex].Part4_A;
1033 xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
1034 data = pVBInfo->VBVCLKData[vclkindex].Part4_B;
1035 xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
1036 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
1037 } else {
1038 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1039 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
1040 xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
1041 xgifb_reg_set(pVBInfo->P3c4, 0x2B,
1042 pVBInfo->VCLKData[index].SR2B);
1043 xgifb_reg_set(pVBInfo->P3c4, 0x2C,
1044 pVBInfo->VCLKData[index].SR2C);
1045 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
1048 if (HwDeviceExtension->jChipType >= XG20) {
1049 if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag &
1050 HalfDCLK) {
1051 data = xgifb_reg_get(pVBInfo->P3c4, 0x2B);
1052 xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
1053 data = xgifb_reg_get(pVBInfo->P3c4, 0x2C);
1054 index = data;
1055 index &= 0xE0;
1056 data &= 0x1F;
1057 data = data << 1;
1058 data += 1;
1059 data |= index;
1060 xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
1065 static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
1067 unsigned char temp;
1069 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
1070 temp = (temp & 1) << 6;
1071 /* SR06[6] 18bit Dither */
1072 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp);
1073 /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
1074 xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
1078 static void XGI_SetCRT1FIFO(unsigned short ModeNo,
1079 struct xgi_hw_device_info *HwDeviceExtension,
1080 struct vb_device_info *pVBInfo)
1082 unsigned short data;
1084 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
1085 data &= 0xfe;
1086 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
1088 xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34);
1089 data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
1090 data &= 0xC0;
1091 xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30);
1092 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
1093 data |= 0x01;
1094 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data);
1096 if (HwDeviceExtension->jChipType == XG21)
1097 XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
1100 static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
1101 unsigned short ModeNo, unsigned short RefreshRateTableIndex,
1102 struct vb_device_info *pVBInfo)
1104 unsigned short data, data2 = 0;
1105 short VCLK;
1107 unsigned char index;
1109 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1110 index &= IndexMask;
1111 VCLK = pVBInfo->VCLKData[index].CLOCK;
1113 data = xgifb_reg_get(pVBInfo->P3c4, 0x32);
1114 data &= 0xf3;
1115 if (VCLK >= 200)
1116 data |= 0x0c; /* VCLK > 200 */
1118 if (HwDeviceExtension->jChipType >= XG20)
1119 data &= ~0x04; /* 2 pixel mode */
1121 xgifb_reg_set(pVBInfo->P3c4, 0x32, data);
1123 if (HwDeviceExtension->jChipType < XG20) {
1124 data = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
1125 data &= 0xE7;
1126 if (VCLK < 200)
1127 data |= 0x10;
1128 xgifb_reg_set(pVBInfo->P3c4, 0x1F, data);
1131 data2 = 0x00;
1133 xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2);
1134 if (HwDeviceExtension->jChipType >= XG27)
1135 xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
1139 static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
1140 unsigned short ModeNo, unsigned short ModeIdIndex,
1141 unsigned short RefreshRateTableIndex,
1142 struct vb_device_info *pVBInfo)
1144 unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
1145 xres;
1147 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1148 infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1150 if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01)
1151 xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
1153 data = infoflag;
1154 data2 = 0;
1155 data2 |= 0x02;
1156 data3 = pVBInfo->ModeType - ModeVGA;
1157 data3 = data3 << 2;
1158 data2 |= data3;
1159 data &= InterlaceMode;
1161 if (data)
1162 data2 |= 0x20;
1164 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2);
1165 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
1166 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
1168 data = 0x0000;
1169 if (infoflag & InterlaceMode) {
1170 if (xres == 1024)
1171 data = 0x0035;
1172 else if (xres == 1280)
1173 data = 0x0048;
1176 data2 = data & 0x00FF;
1177 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data2);
1178 data2 = (data & 0xFF00) >> 8;
1179 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, data2);
1181 if (modeflag & HalfDCLK)
1182 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08);
1184 data2 = 0;
1186 if (modeflag & LineCompareOff)
1187 data2 |= 0x08;
1189 xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2);
1190 data = 0x60;
1191 data = data ^ 0x60;
1192 data = data ^ 0xA0;
1193 xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data);
1195 XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
1196 pVBInfo);
1198 data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
1200 if (HwDeviceExtension->jChipType == XG27) {
1201 if (data & 0x40)
1202 data = 0x2c;
1203 else
1204 data = 0x6c;
1205 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1206 xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10);
1207 } else if (HwDeviceExtension->jChipType >= XG20) {
1208 if (data & 0x40)
1209 data = 0x33;
1210 else
1211 data = 0x73;
1212 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1213 xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02);
1214 } else {
1215 if (data & 0x40)
1216 data = 0x2c;
1217 else
1218 data = 0x6c;
1219 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1224 static void XGI_WriteDAC(unsigned short dl,
1225 unsigned short ah,
1226 unsigned short al,
1227 unsigned short dh,
1228 struct vb_device_info *pVBInfo)
1230 unsigned short temp, bh, bl;
1232 bh = ah;
1233 bl = al;
1235 if (dl != 0) {
1236 temp = bh;
1237 bh = dh;
1238 dh = temp;
1239 if (dl == 1) {
1240 temp = bl;
1241 bl = dh;
1242 dh = temp;
1243 } else {
1244 temp = bl;
1245 bl = bh;
1246 bh = temp;
1249 outb((unsigned short) dh, pVBInfo->P3c9);
1250 outb((unsigned short) bh, pVBInfo->P3c9);
1251 outb((unsigned short) bl, pVBInfo->P3c9);
1254 static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex,
1255 struct vb_device_info *pVBInfo)
1257 unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh;
1258 const unsigned short *table = XGINew_VGA_DAC;
1260 outb(0xFF, pVBInfo->P3c6);
1261 outb(0x00, pVBInfo->P3c8);
1263 for (i = 0; i < 16; i++) {
1264 data = table[i];
1266 for (k = 0; k < 3; k++) {
1267 data2 = 0;
1269 if (data & 0x01)
1270 data2 = 0x2A;
1272 if (data & 0x02)
1273 data2 += 0x15;
1275 outb(data2, pVBInfo->P3c9);
1276 data = data >> 2;
1280 for (i = 16; i < 32; i++) {
1281 data = table[i];
1283 for (k = 0; k < 3; k++)
1284 outb(data, pVBInfo->P3c9);
1287 si = 32;
1289 for (m = 0; m < 9; m++) {
1290 di = si;
1291 bx = si + 0x04;
1292 dl = 0;
1294 for (n = 0; n < 3; n++) {
1295 for (o = 0; o < 5; o++) {
1296 dh = table[si];
1297 ah = table[di];
1298 al = table[bx];
1299 si++;
1300 XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1303 si -= 2;
1305 for (o = 0; o < 3; o++) {
1306 dh = table[bx];
1307 ah = table[di];
1308 al = table[si];
1309 si--;
1310 XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1313 dl++;
1316 si += 5;
1320 static void XGI_GetLVDSResInfo(unsigned short ModeNo,
1321 unsigned short ModeIdIndex,
1322 struct vb_device_info *pVBInfo)
1324 unsigned short resindex, xres, yres, modeflag;
1326 /* si+Ext_ResInfo */
1327 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
1329 /* si+Ext_ResInfo */
1330 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
1332 xres = pVBInfo->ModeResInfo[resindex].HTotal;
1333 yres = pVBInfo->ModeResInfo[resindex].VTotal;
1335 if (modeflag & HalfDCLK)
1336 xres = xres << 1;
1338 if (modeflag & DoubleScanMode)
1339 yres = yres << 1;
1341 if (xres == 720)
1342 xres = 640;
1344 pVBInfo->VGAHDE = xres;
1345 pVBInfo->HDE = xres;
1346 pVBInfo->VGAVDE = yres;
1347 pVBInfo->VDE = yres;
1350 static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
1351 unsigned short ModeIdIndex,
1352 unsigned short RefreshRateTableIndex,
1353 struct vb_device_info *pVBInfo)
1355 unsigned short i, tempdx, tempcx, tempbx, tempal, modeflag, table;
1357 struct XGI330_LCDDataTablStruct *tempdi = NULL;
1359 tempbx = BX;
1361 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1362 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1364 tempal = tempal & 0x0f;
1366 if (tempbx <= 1) { /* ExpLink */
1367 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1369 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
1370 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].
1371 Ext_CRT2CRTC2;
1374 if (tempbx & 0x01)
1375 tempal = (tempal >> 4);
1377 tempal = (tempal & 0x0f);
1380 tempcx = LCDLenList[tempbx];
1382 if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
1383 if ((tempbx == 5) || (tempbx) == 7)
1384 tempcx = LCDDesDataLen2;
1385 else if ((tempbx == 3) || (tempbx == 8))
1386 tempcx = LVDSDesDataLen2;
1389 switch (tempbx) {
1390 case 0:
1391 case 1:
1392 tempdi = xgifb_epllcd_crt1;
1393 break;
1394 case 2:
1395 tempdi = XGI_EPLLCDDataPtr;
1396 break;
1397 case 3:
1398 tempdi = XGI_EPLLCDDesDataPtr;
1399 break;
1400 case 4:
1401 tempdi = XGI_LCDDataTable;
1402 break;
1403 case 5:
1404 tempdi = XGI_LCDDesDataTable;
1405 break;
1406 case 6:
1407 tempdi = XGI_EPLCHLCDRegPtr;
1408 break;
1409 case 7:
1410 case 8:
1411 case 9:
1412 tempdi = NULL;
1413 break;
1414 default:
1415 break;
1418 if (tempdi == NULL) /* OEMUtil */
1419 return NULL;
1421 table = tempbx;
1422 i = 0;
1424 while (tempdi[i].PANELID != 0xff) {
1425 tempdx = pVBInfo->LCDResInfo;
1426 if (tempbx & 0x0080) { /* OEMUtil */
1427 tempbx &= (~0x0080);
1428 tempdx = pVBInfo->LCDTypeInfo;
1431 if (pVBInfo->LCDInfo & EnableScalingLCD)
1432 tempdx &= (~PanelResInfo);
1434 if (tempdi[i].PANELID == tempdx) {
1435 tempbx = tempdi[i].MASK;
1436 tempdx = pVBInfo->LCDInfo;
1438 if (modeflag & HalfDCLK)
1439 tempdx |= SetLCDLowResolution;
1441 tempbx &= tempdx;
1442 if (tempbx == tempdi[i].CAP)
1443 break;
1445 i++;
1448 if (table == 0) {
1449 switch (tempdi[i].DATAPTR) {
1450 case 0:
1451 return &XGI_LVDSCRT11024x768_1_H[tempal];
1452 break;
1453 case 1:
1454 return &XGI_LVDSCRT11024x768_2_H[tempal];
1455 break;
1456 case 2:
1457 return &XGI_LVDSCRT11280x1024_1_H[tempal];
1458 break;
1459 case 3:
1460 return &XGI_LVDSCRT11280x1024_2_H[tempal];
1461 break;
1462 case 4:
1463 return &XGI_LVDSCRT11400x1050_1_H[tempal];
1464 break;
1465 case 5:
1466 return &XGI_LVDSCRT11400x1050_2_H[tempal];
1467 break;
1468 case 6:
1469 return &XGI_LVDSCRT11600x1200_1_H[tempal];
1470 break;
1471 case 7:
1472 return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
1473 break;
1474 case 8:
1475 return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
1476 break;
1477 case 9:
1478 return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
1479 break;
1480 case 10:
1481 return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
1482 break;
1483 default:
1484 break;
1486 } else if (table == 1) {
1487 switch (tempdi[i].DATAPTR) {
1488 case 0:
1489 return &XGI_LVDSCRT11024x768_1_V[tempal];
1490 break;
1491 case 1:
1492 return &XGI_LVDSCRT11024x768_2_V[tempal];
1493 break;
1494 case 2:
1495 return &XGI_LVDSCRT11280x1024_1_V[tempal];
1496 break;
1497 case 3:
1498 return &XGI_LVDSCRT11280x1024_2_V[tempal];
1499 break;
1500 case 4:
1501 return &XGI_LVDSCRT11400x1050_1_V[tempal];
1502 break;
1503 case 5:
1504 return &XGI_LVDSCRT11400x1050_2_V[tempal];
1505 break;
1506 case 6:
1507 return &XGI_LVDSCRT11600x1200_1_V[tempal];
1508 break;
1509 case 7:
1510 return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
1511 break;
1512 case 8:
1513 return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
1514 break;
1515 case 9:
1516 return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
1517 break;
1518 case 10:
1519 return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
1520 break;
1521 default:
1522 break;
1524 } else if (table == 2) {
1525 switch (tempdi[i].DATAPTR) {
1526 case 0:
1527 return &XGI_LVDS1024x768Data_1[tempal];
1528 break;
1529 case 1:
1530 return &XGI_LVDS1024x768Data_2[tempal];
1531 break;
1532 case 2:
1533 return &XGI_LVDS1280x1024Data_1[tempal];
1534 break;
1535 case 3:
1536 return &XGI_LVDS1280x1024Data_2[tempal];
1537 break;
1538 case 4:
1539 return &XGI_LVDS1400x1050Data_1[tempal];
1540 break;
1541 case 5:
1542 return &XGI_LVDS1400x1050Data_2[tempal];
1543 break;
1544 case 6:
1545 return &XGI_LVDS1600x1200Data_1[tempal];
1546 break;
1547 case 7:
1548 return &XGI_LVDSNoScalingData[tempal];
1549 break;
1550 case 8:
1551 return &XGI_LVDS1024x768Data_1x75[tempal];
1552 break;
1553 case 9:
1554 return &XGI_LVDS1024x768Data_2x75[tempal];
1555 break;
1556 case 10:
1557 return &XGI_LVDS1280x1024Data_1x75[tempal];
1558 break;
1559 case 11:
1560 return &XGI_LVDS1280x1024Data_2x75[tempal];
1561 break;
1562 case 12:
1563 return &XGI_LVDSNoScalingDatax75[tempal];
1564 break;
1565 default:
1566 break;
1568 } else if (table == 3) {
1569 switch (tempdi[i].DATAPTR) {
1570 case 0:
1571 return &XGI_LVDS1024x768Des_1[tempal];
1572 break;
1573 case 1:
1574 return &XGI_LVDS1024x768Des_3[tempal];
1575 break;
1576 case 2:
1577 return &XGI_LVDS1024x768Des_2[tempal];
1578 break;
1579 case 3:
1580 return &XGI_LVDS1280x1024Des_1[tempal];
1581 break;
1582 case 4:
1583 return &XGI_LVDS1280x1024Des_2[tempal];
1584 break;
1585 case 5:
1586 return &XGI_LVDS1400x1050Des_1[tempal];
1587 break;
1588 case 6:
1589 return &XGI_LVDS1400x1050Des_2[tempal];
1590 break;
1591 case 7:
1592 return &XGI_LVDS1600x1200Des_1[tempal];
1593 break;
1594 case 8:
1595 return &XGI_LVDSNoScalingDesData[tempal];
1596 break;
1597 case 9:
1598 return &XGI_LVDS1024x768Des_1x75[tempal];
1599 break;
1600 case 10:
1601 return &XGI_LVDS1024x768Des_3x75[tempal];
1602 break;
1603 case 11:
1604 return &XGI_LVDS1024x768Des_2x75[tempal];
1605 break;
1606 case 12:
1607 return &XGI_LVDS1280x1024Des_1x75[tempal];
1608 break;
1609 case 13:
1610 return &XGI_LVDS1280x1024Des_2x75[tempal];
1611 break;
1612 case 14:
1613 return &XGI_LVDSNoScalingDesDatax75[tempal];
1614 break;
1615 default:
1616 break;
1618 } else if (table == 4) {
1619 switch (tempdi[i].DATAPTR) {
1620 case 0:
1621 return &XGI_ExtLCD1024x768Data[tempal];
1622 break;
1623 case 1:
1624 return &XGI_StLCD1024x768Data[tempal];
1625 break;
1626 case 2:
1627 return &XGI_CetLCD1024x768Data[tempal];
1628 break;
1629 case 3:
1630 return &XGI_ExtLCD1280x1024Data[tempal];
1631 break;
1632 case 4:
1633 return &XGI_StLCD1280x1024Data[tempal];
1634 break;
1635 case 5:
1636 return &XGI_CetLCD1280x1024Data[tempal];
1637 break;
1638 case 6:
1639 case 7:
1640 return &xgifb_lcd_1400x1050[tempal];
1641 break;
1642 case 8:
1643 return &XGI_CetLCD1400x1050Data[tempal];
1644 break;
1645 case 9:
1646 return &XGI_ExtLCD1600x1200Data[tempal];
1647 break;
1648 case 10:
1649 return &XGI_StLCD1600x1200Data[tempal];
1650 break;
1651 case 11:
1652 return &XGI_NoScalingData[tempal];
1653 break;
1654 case 12:
1655 return &XGI_ExtLCD1024x768x75Data[tempal];
1656 break;
1657 case 13:
1658 return &XGI_ExtLCD1024x768x75Data[tempal];
1659 break;
1660 case 14:
1661 return &XGI_CetLCD1024x768x75Data[tempal];
1662 break;
1663 case 15:
1664 case 16:
1665 return &xgifb_lcd_1280x1024x75[tempal];
1666 break;
1667 case 17:
1668 return &XGI_CetLCD1280x1024x75Data[tempal];
1669 break;
1670 case 18:
1671 return &XGI_NoScalingDatax75[tempal];
1672 break;
1673 default:
1674 break;
1676 } else if (table == 5) {
1677 switch (tempdi[i].DATAPTR) {
1678 case 0:
1679 return &XGI_ExtLCDDes1024x768Data[tempal];
1680 break;
1681 case 1:
1682 return &XGI_StLCDDes1024x768Data[tempal];
1683 break;
1684 case 2:
1685 return &XGI_CetLCDDes1024x768Data[tempal];
1686 break;
1687 case 3:
1688 if ((pVBInfo->VBType & VB_SIS301LV) ||
1689 (pVBInfo->VBType & VB_SIS302LV))
1690 return &XGI_ExtLCDDLDes1280x1024Data[tempal];
1691 else
1692 return &XGI_ExtLCDDes1280x1024Data[tempal];
1693 break;
1694 case 4:
1695 if ((pVBInfo->VBType & VB_SIS301LV) ||
1696 (pVBInfo->VBType & VB_SIS302LV))
1697 return &XGI_StLCDDLDes1280x1024Data[tempal];
1698 else
1699 return &XGI_StLCDDes1280x1024Data[tempal];
1700 break;
1701 case 5:
1702 if ((pVBInfo->VBType & VB_SIS301LV) ||
1703 (pVBInfo->VBType & VB_SIS302LV))
1704 return &XGI_CetLCDDLDes1280x1024Data[tempal];
1705 else
1706 return &XGI_CetLCDDes1280x1024Data[tempal];
1707 break;
1708 case 6:
1709 case 7:
1710 if ((pVBInfo->VBType & VB_SIS301LV) ||
1711 (pVBInfo->VBType & VB_SIS302LV))
1712 return &xgifb_lcddldes_1400x1050[tempal];
1713 else
1714 return &xgifb_lcddes_1400x1050[tempal];
1715 break;
1716 case 8:
1717 return &XGI_CetLCDDes1400x1050Data[tempal];
1718 break;
1719 case 9:
1720 return &XGI_CetLCDDes1400x1050Data2[tempal];
1721 break;
1722 case 10:
1723 if ((pVBInfo->VBType & VB_SIS301LV) ||
1724 (pVBInfo->VBType & VB_SIS302LV))
1725 return &XGI_ExtLCDDLDes1600x1200Data[tempal];
1726 else
1727 return &XGI_ExtLCDDes1600x1200Data[tempal];
1728 break;
1729 case 11:
1730 if ((pVBInfo->VBType & VB_SIS301LV) ||
1731 (pVBInfo->VBType & VB_SIS302LV))
1732 return &XGI_StLCDDLDes1600x1200Data[tempal];
1733 else
1734 return &XGI_StLCDDes1600x1200Data[tempal];
1735 break;
1736 case 12:
1737 return &XGI_NoScalingDesData[tempal];
1738 break;
1739 case 13:
1740 case 14:
1741 return &xgifb_lcddes_1024x768x75[tempal];
1742 break;
1743 case 15:
1744 return &XGI_CetLCDDes1024x768x75Data[tempal];
1745 break;
1746 case 16:
1747 case 17:
1748 if ((pVBInfo->VBType & VB_SIS301LV) ||
1749 (pVBInfo->VBType & VB_SIS302LV))
1750 return &xgifb_lcddldes_1280x1024x75[tempal];
1751 else
1752 return &xgifb_lcddes_1280x1024x75[tempal];
1753 break;
1754 case 18:
1755 if ((pVBInfo->VBType & VB_SIS301LV) ||
1756 (pVBInfo->VBType & VB_SIS302LV))
1757 return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
1758 else
1759 return &XGI_CetLCDDes1280x1024x75Data[tempal];
1760 break;
1761 case 19:
1762 return &XGI_NoScalingDesDatax75[tempal];
1763 break;
1764 default:
1765 break;
1767 } else if (table == 6) {
1768 switch (tempdi[i].DATAPTR) {
1769 case 0:
1770 return &XGI_CH7017LV1024x768[tempal];
1771 break;
1772 case 1:
1773 return &XGI_CH7017LV1400x1050[tempal];
1774 break;
1775 default:
1776 break;
1779 return NULL;
1782 static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo,
1783 unsigned short ModeIdIndex,
1784 unsigned short RefreshRateTableIndex,
1785 struct vb_device_info *pVBInfo)
1787 unsigned short i, tempdx, tempbx, tempal, modeflag, table;
1788 struct XGI330_TVDataTablStruct *tempdi = NULL;
1790 tempbx = BX;
1791 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1792 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1793 tempal = tempal & 0x3f;
1794 table = tempbx;
1796 switch (tempbx) {
1797 case 0:
1798 tempdi = NULL;
1799 break;
1800 case 1:
1801 tempdi = NULL;
1802 break;
1803 case 2:
1804 case 6:
1805 tempdi = xgifb_chrontel_tv;
1806 break;
1807 case 3:
1808 tempdi = NULL;
1809 break;
1810 case 4:
1811 tempdi = XGI_TVDataTable;
1812 break;
1813 case 5:
1814 tempdi = NULL;
1815 break;
1816 default:
1817 break;
1820 if (tempdi == NULL) /* OEMUtil */
1821 return NULL;
1823 tempdx = pVBInfo->TVInfo;
1825 if (pVBInfo->VBInfo & SetInSlaveMode)
1826 tempdx = tempdx | SetTVLockMode;
1828 if (modeflag & HalfDCLK)
1829 tempdx = tempdx | SetTVLowResolution;
1831 i = 0;
1833 while (tempdi[i].MASK != 0xffff) {
1834 if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
1835 break;
1836 i++;
1839 if (table == 0x04) {
1840 switch (tempdi[i].DATAPTR) {
1841 case 0:
1842 return &XGI_ExtPALData[tempal];
1843 break;
1844 case 1:
1845 return &XGI_ExtNTSCData[tempal];
1846 break;
1847 case 2:
1848 return &XGI_StPALData[tempal];
1849 break;
1850 case 3:
1851 return &XGI_StNTSCData[tempal];
1852 break;
1853 case 4:
1854 return &XGI_ExtHiTVData[tempal];
1855 break;
1856 case 5:
1857 return &XGI_St2HiTVData[tempal];
1858 break;
1859 case 6:
1860 return &XGI_ExtYPbPr525iData[tempal];
1861 break;
1862 case 7:
1863 return &XGI_ExtYPbPr525pData[tempal];
1864 break;
1865 case 8:
1866 return &XGI_ExtYPbPr750pData[tempal];
1867 break;
1868 case 9:
1869 return &XGI_StYPbPr525iData[tempal];
1870 break;
1871 case 10:
1872 return &XGI_StYPbPr525pData[tempal];
1873 break;
1874 case 11:
1875 return &XGI_StYPbPr750pData[tempal];
1876 break;
1877 case 12: /* avoid system hang */
1878 return &XGI_ExtNTSCData[tempal];
1879 break;
1880 case 13:
1881 return &XGI_St1HiTVData[tempal];
1882 break;
1883 default:
1884 break;
1886 } else if (table == 0x02) {
1887 switch (tempdi[i].DATAPTR) {
1888 case 0:
1889 return &XGI_CHTVUNTSCData[tempal];
1890 break;
1891 case 1:
1892 return &XGI_CHTVONTSCData[tempal];
1893 break;
1894 case 2:
1895 return &XGI_CHTVUPALData[tempal];
1896 break;
1897 case 3:
1898 return &XGI_CHTVOPALData[tempal];
1899 break;
1900 default:
1901 break;
1904 return NULL;
1907 static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
1908 unsigned short RefreshRateTableIndex,
1909 struct vb_device_info *pVBInfo)
1911 unsigned short tempbx;
1912 struct SiS_LVDSData *LCDPtr = NULL;
1914 tempbx = 2;
1916 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1917 LCDPtr = (struct SiS_LVDSData *)XGI_GetLcdPtr(tempbx,
1918 ModeNo, ModeIdIndex, RefreshRateTableIndex,
1919 pVBInfo);
1920 pVBInfo->VGAHT = LCDPtr->VGAHT;
1921 pVBInfo->VGAVT = LCDPtr->VGAVT;
1922 pVBInfo->HT = LCDPtr->LCDHT;
1923 pVBInfo->VT = LCDPtr->LCDVT;
1926 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1927 if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
1928 | EnableScalingLCD))) {
1929 if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
1930 (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
1931 pVBInfo->HDE = 1024;
1932 pVBInfo->VDE = 768;
1933 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
1934 (pVBInfo->LCDResInfo ==
1935 Panel_1280x1024x75)) {
1936 pVBInfo->HDE = 1280;
1937 pVBInfo->VDE = 1024;
1938 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
1939 pVBInfo->HDE = 1400;
1940 pVBInfo->VDE = 1050;
1941 } else {
1942 pVBInfo->HDE = 1600;
1943 pVBInfo->VDE = 1200;
1949 static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
1950 unsigned short RefreshRateTableIndex,
1951 struct xgi_hw_device_info *HwDeviceExtension,
1952 struct vb_device_info *pVBInfo)
1954 unsigned char index;
1955 unsigned short tempbx, i;
1956 struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
1957 struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
1959 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1960 index = index & IndexMask;
1962 tempbx = 0;
1964 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1965 LCDPtr = (struct XGI_LVDSCRT1HDataStruct *)
1966 XGI_GetLcdPtr(tempbx, ModeNo,
1967 ModeIdIndex,
1968 RefreshRateTableIndex,
1969 pVBInfo);
1971 for (i = 0; i < 8; i++)
1972 pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i];
1975 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
1977 tempbx = 1;
1979 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1980 LCDPtr1 = (struct XGI_LVDSCRT1VDataStruct *)
1981 XGI_GetLcdPtr(
1982 tempbx,
1983 ModeNo,
1984 ModeIdIndex,
1985 RefreshRateTableIndex,
1986 pVBInfo);
1987 for (i = 0; i < 7; i++)
1988 pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i];
1991 XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
1994 static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
1996 unsigned char tempal, tempah, tempbl, i;
1998 tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36);
1999 tempal = tempah & 0x0F;
2000 tempah = tempah & 0xF0;
2001 i = 0;
2002 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
2004 while (tempbl != 0xFF) {
2005 if (tempbl & 0x80) { /* OEMUtil */
2006 tempal = tempah;
2007 tempbl = tempbl & ~(0x80);
2010 if (tempal == tempbl)
2011 break;
2013 i++;
2015 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
2018 return i;
2021 static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
2023 unsigned short tempah, tempal, tempbl, i;
2025 tempal = pVBInfo->LCDResInfo;
2026 tempah = pVBInfo->LCDTypeInfo;
2028 i = 0;
2029 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
2031 while (tempbl != 0xFF) {
2032 if ((tempbl & 0x80) && (tempbl != 0x80)) {
2033 tempal = tempah;
2034 tempbl &= ~0x80;
2037 if (tempal == tempbl)
2038 break;
2040 i++;
2041 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
2044 if (tempbl == 0xFF) {
2045 pVBInfo->LCDResInfo = Panel_1024x768;
2046 pVBInfo->LCDTypeInfo = 0;
2047 i = 0;
2050 return i;
2053 static void XGI_GetLCDSync(unsigned short *HSyncWidth,
2054 unsigned short *VSyncWidth,
2055 struct vb_device_info *pVBInfo)
2057 unsigned short Index;
2059 Index = XGI_GetLCDCapPtr(pVBInfo);
2060 *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
2061 *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
2063 return;
2066 static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
2067 unsigned short RefreshRateTableIndex,
2068 struct vb_device_info *pVBInfo)
2070 unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
2071 unsigned long temp, temp1, temp2, temp3, push3;
2072 struct XGI_LCDDesStruct *LCDPtr = NULL;
2073 struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
2075 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2076 tempbx = 3;
2077 if (pVBInfo->LCDInfo & EnableScalingLCD)
2078 LCDPtr1 =
2079 (struct XGI330_LCDDataDesStruct2 *)
2080 XGI_GetLcdPtr(
2081 tempbx,
2082 ModeNo,
2083 ModeIdIndex,
2084 RefreshRateTableIndex,
2085 pVBInfo);
2086 else
2087 LCDPtr =
2088 (struct XGI_LCDDesStruct *)
2089 XGI_GetLcdPtr(
2090 tempbx,
2091 ModeNo,
2092 ModeIdIndex,
2093 RefreshRateTableIndex,
2094 pVBInfo);
2096 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
2097 push1 = tempbx;
2098 push2 = tempax;
2100 /* GetLCDResInfo */
2101 if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
2102 (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
2103 tempax = 1024;
2104 tempbx = 768;
2105 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
2106 (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
2107 tempax = 1280;
2108 tempbx = 1024;
2109 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
2110 tempax = 1400;
2111 tempbx = 1050;
2112 } else {
2113 tempax = 1600;
2114 tempbx = 1200;
2117 if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
2118 pVBInfo->HDE = tempax;
2119 pVBInfo->VDE = tempbx;
2120 pVBInfo->VGAHDE = tempax;
2121 pVBInfo->VGAVDE = tempbx;
2124 tempax = pVBInfo->HT;
2126 if (pVBInfo->LCDInfo & EnableScalingLCD)
2127 tempbx = LCDPtr1->LCDHDES;
2128 else
2129 tempbx = LCDPtr->LCDHDES;
2131 tempcx = pVBInfo->HDE;
2132 tempbx = tempbx & 0x0fff;
2133 tempcx += tempbx;
2135 if (tempcx >= tempax)
2136 tempcx -= tempax;
2138 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
2140 tempcx = tempcx >> 3;
2141 tempbx = tempbx >> 3;
2143 xgifb_reg_set(pVBInfo->Part1Port, 0x16,
2144 (unsigned short) (tempbx & 0xff));
2145 xgifb_reg_set(pVBInfo->Part1Port, 0x17,
2146 (unsigned short) (tempcx & 0xff));
2148 tempax = pVBInfo->HT;
2150 if (pVBInfo->LCDInfo & EnableScalingLCD)
2151 tempbx = LCDPtr1->LCDHRS;
2152 else
2153 tempbx = LCDPtr->LCDHRS;
2155 tempcx = push2;
2157 if (pVBInfo->LCDInfo & EnableScalingLCD)
2158 tempcx = LCDPtr1->LCDHSync;
2160 tempcx += tempbx;
2162 if (tempcx >= tempax)
2163 tempcx -= tempax;
2165 tempax = tempbx & 0x07;
2166 tempax = tempax >> 5;
2167 tempcx = tempcx >> 3;
2168 tempbx = tempbx >> 3;
2170 tempcx &= 0x1f;
2171 tempax |= tempcx;
2173 xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax);
2174 xgifb_reg_set(pVBInfo->Part1Port, 0x14,
2175 (unsigned short) (tempbx & 0xff));
2177 tempax = pVBInfo->VT;
2178 if (pVBInfo->LCDInfo & EnableScalingLCD)
2179 tempbx = LCDPtr1->LCDVDES;
2180 else
2181 tempbx = LCDPtr->LCDVDES;
2182 tempcx = pVBInfo->VDE;
2184 tempbx = tempbx & 0x0fff;
2185 tempcx += tempbx;
2186 if (tempcx >= tempax)
2187 tempcx -= tempax;
2189 xgifb_reg_set(pVBInfo->Part1Port, 0x1b,
2190 (unsigned short) (tempbx & 0xff));
2191 xgifb_reg_set(pVBInfo->Part1Port, 0x1c,
2192 (unsigned short) (tempcx & 0xff));
2194 tempbx = (tempbx >> 8) & 0x07;
2195 tempcx = (tempcx >> 8) & 0x07;
2197 xgifb_reg_set(pVBInfo->Part1Port, 0x1d,
2198 (unsigned short) ((tempcx << 3)
2199 | tempbx));
2201 tempax = pVBInfo->VT;
2202 if (pVBInfo->LCDInfo & EnableScalingLCD)
2203 tempbx = LCDPtr1->LCDVRS;
2204 else
2205 tempbx = LCDPtr->LCDVRS;
2207 tempcx = push1;
2209 if (pVBInfo->LCDInfo & EnableScalingLCD)
2210 tempcx = LCDPtr1->LCDVSync;
2212 tempcx += tempbx;
2213 if (tempcx >= tempax)
2214 tempcx -= tempax;
2216 xgifb_reg_set(pVBInfo->Part1Port, 0x18,
2217 (unsigned short) (tempbx & 0xff));
2218 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f,
2219 (unsigned short) (tempcx & 0x0f));
2221 tempax = ((tempbx >> 8) & 0x07) << 3;
2223 tempbx = pVBInfo->VGAVDE;
2224 if (tempbx != pVBInfo->VDE)
2225 tempax |= 0x40;
2227 if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA)
2228 tempax |= 0x40;
2230 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07,
2231 tempax);
2233 tempcx = pVBInfo->VGAVT;
2234 tempbx = pVBInfo->VDE;
2235 tempax = pVBInfo->VGAVDE;
2236 tempcx -= tempax;
2238 temp = tempax; /* 0430 ylshieh */
2239 temp1 = (temp << 18) / tempbx;
2241 tempdx = (unsigned short) ((temp << 18) % tempbx);
2243 if (tempdx != 0)
2244 temp1 += 1;
2246 temp2 = temp1;
2247 push3 = temp2;
2249 xgifb_reg_set(pVBInfo->Part1Port, 0x37,
2250 (unsigned short) (temp2 & 0xff));
2251 xgifb_reg_set(pVBInfo->Part1Port, 0x36,
2252 (unsigned short) ((temp2 >> 8) & 0xff));
2254 tempbx = (unsigned short) (temp2 >> 16);
2255 tempax = tempbx & 0x03;
2257 tempbx = pVBInfo->VGAVDE;
2258 if (tempbx == pVBInfo->VDE)
2259 tempax |= 0x04;
2261 xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax);
2263 if (pVBInfo->VBType & VB_XGI301C) {
2264 temp2 = push3;
2265 xgifb_reg_set(pVBInfo->Part4Port,
2266 0x3c,
2267 (unsigned short) (temp2 & 0xff));
2268 xgifb_reg_set(pVBInfo->Part4Port,
2269 0x3b,
2270 (unsigned short) ((temp2 >> 8) &
2271 0xff));
2272 tempbx = (unsigned short) (temp2 >> 16);
2273 xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a,
2274 ~0xc0,
2275 (unsigned short) ((tempbx &
2276 0xff) << 6));
2278 tempcx = pVBInfo->VGAVDE;
2279 if (tempcx == pVBInfo->VDE)
2280 xgifb_reg_and_or(pVBInfo->Part4Port,
2281 0x30, ~0x0c, 0x00);
2282 else
2283 xgifb_reg_and_or(pVBInfo->Part4Port,
2284 0x30, ~0x0c, 0x08);
2287 tempcx = pVBInfo->VGAHDE;
2288 tempbx = pVBInfo->HDE;
2290 temp1 = tempcx << 16;
2292 tempax = (unsigned short) (temp1 / tempbx);
2294 if ((tempbx & 0xffff) == (tempcx & 0xffff))
2295 tempax = 65535;
2297 temp3 = tempax;
2298 temp1 = pVBInfo->VGAHDE << 16;
2300 temp1 /= temp3;
2301 temp3 = temp3 << 16;
2302 temp1 -= 1;
2304 temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
2306 tempax = (unsigned short) (temp3 & 0xff);
2307 xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax);
2309 temp1 = pVBInfo->VGAVDE << 18;
2310 temp1 = temp1 / push3;
2311 tempbx = (unsigned short) (temp1 & 0xffff);
2313 if (pVBInfo->LCDResInfo == Panel_1024x768)
2314 tempbx -= 1;
2316 tempax = ((tempbx >> 8) & 0xff) << 3;
2317 tempax |= (unsigned short) ((temp3 >> 8) & 0x07);
2318 xgifb_reg_set(pVBInfo->Part1Port, 0x20,
2319 (unsigned short) (tempax & 0xff));
2320 xgifb_reg_set(pVBInfo->Part1Port, 0x21,
2321 (unsigned short) (tempbx & 0xff));
2323 temp3 = temp3 >> 16;
2325 if (modeflag & HalfDCLK)
2326 temp3 = temp3 >> 1;
2328 xgifb_reg_set(pVBInfo->Part1Port, 0x22,
2329 (unsigned short) ((temp3 >> 8) & 0xff));
2330 xgifb_reg_set(pVBInfo->Part1Port, 0x23,
2331 (unsigned short) (temp3 & 0xff));
2334 /* --------------------------------------------------------------------- */
2335 /* Function : XGI_GETLCDVCLKPtr */
2336 /* Input : */
2337 /* Output : al -> VCLK Index */
2338 /* Description : */
2339 /* --------------------------------------------------------------------- */
2340 static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
2341 struct vb_device_info *pVBInfo)
2343 unsigned short index;
2345 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
2346 index = XGI_GetLCDCapPtr1(pVBInfo);
2348 if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
2349 *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
2350 *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
2351 } else { /* LCDA */
2352 *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
2353 *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
2356 return;
2359 static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
2360 unsigned short ModeNo, unsigned short ModeIdIndex,
2361 struct vb_device_info *pVBInfo)
2364 unsigned short index, modeflag;
2365 unsigned char tempal;
2367 /* si+Ext_ResInfo */
2368 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2370 if ((pVBInfo->SetFlag & ProgrammingCRT2) &&
2371 (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
2372 index = XGI_GetLCDCapPtr(pVBInfo);
2373 tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
2375 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
2376 return tempal;
2378 /* {TV} */
2379 if (pVBInfo->VBType &
2380 (VB_SIS301B |
2381 VB_SIS302B |
2382 VB_SIS301LV |
2383 VB_SIS302LV |
2384 VB_XGI301C)) {
2385 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2386 tempal = TVCLKBASE_315 + HiTVVCLKDIV2;
2387 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
2388 tempal = TVCLKBASE_315 + HiTVVCLK;
2389 if (pVBInfo->TVInfo & TVSimuMode) {
2390 tempal = TVCLKBASE_315 + HiTVSimuVCLK;
2391 if (!(modeflag & Charx8Dot))
2392 tempal = TVCLKBASE_315 +
2393 HiTVTextVCLK;
2396 return tempal;
2399 if (pVBInfo->TVInfo & TVSetYPbPr750p) {
2400 tempal = XGI_YPbPr750pVCLK;
2401 return tempal;
2404 if (pVBInfo->TVInfo & TVSetYPbPr525p) {
2405 tempal = YPbPr525pVCLK;
2406 return tempal;
2409 tempal = NTSC1024VCLK;
2411 if (!(pVBInfo->TVInfo & NTSC1024x768)) {
2412 tempal = TVCLKBASE_315 + TVVCLKDIV2;
2413 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
2414 tempal = TVCLKBASE_315 + TVVCLK;
2417 if (pVBInfo->VBInfo & SetCRT2ToTV)
2418 return tempal;
2420 } /* {End of VB} */
2422 tempal = (unsigned char) inb((pVBInfo->P3ca + 0x02));
2423 tempal = tempal >> 2;
2424 tempal &= 0x03;
2426 /* for Dot8 Scaling LCD */
2427 if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot))
2428 tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */
2430 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2431 return tempal;
2434 static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
2435 unsigned char *di_1, struct vb_device_info *pVBInfo)
2437 if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B
2438 | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
2439 if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
2440 (pVBInfo->SetFlag & ProgrammingCRT2)) {
2441 *di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B;
2442 *di_1 = XGI_VBVCLKData[tempal].SR2C;
2444 } else {
2445 *di_0 = XGI_VCLKData[tempal].SR2B;
2446 *di_1 = XGI_VCLKData[tempal].SR2C;
2450 static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex,
2451 unsigned short RefreshRateTableIndex,
2452 struct vb_device_info *pVBInfo)
2454 unsigned char di_0, di_1, tempal;
2455 int i;
2457 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
2458 pVBInfo);
2459 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
2460 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
2462 for (i = 0; i < 4; i++) {
2463 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30,
2464 (unsigned short) (0x10 * i));
2465 if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
2466 && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
2467 xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0);
2468 xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1);
2469 } else {
2470 xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0);
2471 xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1);
2476 static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
2477 struct vb_device_info *pVBInfo)
2479 unsigned short tempcl, tempch, temp, tempbl, tempax;
2481 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
2482 | VB_SIS302LV | VB_XGI301C)) {
2483 tempcl = 0;
2484 tempch = 0;
2485 temp = xgifb_reg_get(pVBInfo->P3c4, 0x01);
2487 if (!(temp & 0x20)) {
2488 temp = xgifb_reg_get(pVBInfo->P3d4, 0x17);
2489 if (temp & 0x80) {
2490 temp = xgifb_reg_get(pVBInfo->P3d4, 0x53);
2491 if (!(temp & 0x40))
2492 tempcl |= ActiveCRT1;
2496 temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e);
2497 temp &= 0x0f;
2499 if (!(temp == 0x08)) {
2500 /* Check ChannelA */
2501 tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13);
2502 if (tempax & 0x04)
2503 tempcl = tempcl | ActiveLCD;
2505 temp &= 0x05;
2507 if (!(tempcl & ActiveLCD))
2508 if (temp == 0x01)
2509 tempcl |= ActiveCRT2;
2511 if (temp == 0x04)
2512 tempcl |= ActiveLCD;
2514 if (temp == 0x05) {
2515 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00);
2517 if (!(temp & 0x08))
2518 tempch |= ActiveAVideo;
2520 if (!(temp & 0x04))
2521 tempch |= ActiveSVideo;
2523 if (temp & 0x02)
2524 tempch |= ActiveSCART;
2526 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2527 if (temp & 0x01)
2528 tempch |= ActiveHiTV;
2531 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
2532 temp = xgifb_reg_get(
2533 pVBInfo->Part2Port,
2534 0x4d);
2536 if (temp & 0x10)
2537 tempch |= ActiveYPbPr;
2540 if (tempch != 0)
2541 tempcl |= ActiveTV;
2545 temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
2546 if (tempcl & ActiveLCD) {
2547 if ((pVBInfo->SetFlag & ReserveTVOption)) {
2548 if (temp & ActiveTV)
2549 tempcl |= ActiveTV;
2552 temp = tempcl;
2553 tempbl = ~XGI_ModeSwitchStatus;
2554 xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp);
2556 if (!(pVBInfo->SetFlag & ReserveTVOption))
2557 xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch);
2558 } else {
2559 return;
2563 void XGI_GetVBType(struct vb_device_info *pVBInfo)
2565 unsigned short flag, tempbx, tempah;
2567 if (pVBInfo->IF_DEF_LVDS != 0)
2568 return;
2570 tempbx = VB_SIS302B;
2571 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
2572 if (flag == 0x02)
2573 goto finish;
2575 tempbx = VB_SIS301;
2576 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01);
2577 if (flag < 0xB0)
2578 goto finish;
2580 tempbx = VB_SIS301B;
2581 if (flag < 0xC0)
2582 goto bigger_than_0xB0;
2584 tempbx = VB_XGI301C;
2585 if (flag < 0xD0)
2586 goto bigger_than_0xB0;
2588 tempbx = VB_SIS301LV;
2589 if (flag < 0xE0)
2590 goto bigger_than_0xB0;
2592 tempbx = VB_SIS302LV;
2593 tempah = xgifb_reg_get(pVBInfo->Part4Port, 0x39);
2594 if (tempah != 0xFF)
2595 tempbx = VB_XGI301C;
2597 bigger_than_0xB0:
2598 if (tempbx & (VB_SIS301B | VB_SIS302B)) {
2599 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x23);
2600 if (!(flag & 0x02))
2601 tempbx = tempbx | VB_NoLCD;
2604 finish:
2605 pVBInfo->VBType = tempbx;
2608 static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
2609 struct xgi_hw_device_info *HwDeviceExtension,
2610 struct vb_device_info *pVBInfo)
2612 unsigned short tempax, push, tempbx, temp, modeflag;
2614 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2615 pVBInfo->SetFlag = 0;
2616 pVBInfo->ModeType = modeflag & ModeTypeMask;
2617 tempbx = 0;
2619 if (!(pVBInfo->VBType & 0xFFFF))
2620 return;
2622 /* Check Display Device */
2623 temp = xgifb_reg_get(pVBInfo->P3d4, 0x30);
2624 tempbx = tempbx | temp;
2625 temp = xgifb_reg_get(pVBInfo->P3d4, 0x31);
2626 push = temp;
2627 push = push << 8;
2628 tempax = temp << 8;
2629 tempbx = tempbx | tempax;
2630 temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA
2631 | SetInSlaveMode | DisableCRT2Display);
2632 temp = 0xFFFF ^ temp;
2633 tempbx &= temp;
2635 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
2637 if (pVBInfo->IF_DEF_LCDA == 1) {
2639 if (((HwDeviceExtension->jChipType >= XG20) ||
2640 (HwDeviceExtension->jChipType >= XG40)) &&
2641 (pVBInfo->IF_DEF_LVDS == 0)) {
2642 if (pVBInfo->VBType &
2643 (VB_SIS302B |
2644 VB_SIS301LV |
2645 VB_SIS302LV |
2646 VB_XGI301C)) {
2647 if (temp & EnableDualEdge) {
2648 tempbx |= SetCRT2ToDualEdge;
2649 if (temp & SetToLCDA)
2650 tempbx |= XGI_SetCRT2ToLCDA;
2656 if (pVBInfo->IF_DEF_YPbPr == 1) {
2657 if (((pVBInfo->IF_DEF_LVDS == 0) &&
2658 ((pVBInfo->VBType & VB_SIS301LV) ||
2659 (pVBInfo->VBType & VB_SIS302LV) ||
2660 (pVBInfo->VBType & VB_XGI301C)))) {
2661 if (temp & SetYPbPr) {
2662 if (pVBInfo->IF_DEF_HiVision == 1) {
2663 /* shampoo add for new
2664 * scratch */
2665 temp = xgifb_reg_get(
2666 pVBInfo->P3d4,
2667 0x35);
2668 temp &= YPbPrMode;
2669 tempbx |= SetCRT2ToHiVision;
2671 if (temp != YPbPrMode1080i) {
2672 tempbx &=
2673 (~SetCRT2ToHiVision);
2674 tempbx |=
2675 SetCRT2ToYPbPr525750;
2682 tempax = push; /* restore CR31 */
2684 if (pVBInfo->IF_DEF_LVDS == 0) {
2685 if (pVBInfo->IF_DEF_YPbPr == 1) {
2686 if (pVBInfo->IF_DEF_HiVision == 1)
2687 temp = 0x09FC;
2688 else
2689 temp = 0x097C;
2690 } else {
2691 if (pVBInfo->IF_DEF_HiVision == 1)
2692 temp = 0x01FC;
2693 else
2694 temp = 0x017C;
2696 } else { /* 3nd party chip */
2697 temp = SetCRT2ToLCD;
2700 if (!(tempbx & temp)) {
2701 tempax |= DisableCRT2Display;
2702 tempbx = 0;
2705 if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
2706 if (!(pVBInfo->VBType & VB_NoLCD)) {
2707 if (tempbx & XGI_SetCRT2ToLCDA) {
2708 if (tempbx & SetSimuScanMode)
2709 tempbx &= (~(SetCRT2ToLCD |
2710 SetCRT2ToRAMDAC |
2711 SwitchCRT2));
2712 else
2713 tempbx &= (~(SetCRT2ToLCD |
2714 SetCRT2ToRAMDAC |
2715 SetCRT2ToTV |
2716 SwitchCRT2));
2721 /* shampoo add */
2722 /* for driver abnormal */
2723 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
2724 if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
2725 if (tempbx & SetCRT2ToRAMDAC) {
2726 tempbx &= (0xFF00 |
2727 SetCRT2ToRAMDAC |
2728 SwitchCRT2 |
2729 SetSimuScanMode);
2730 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2732 } else {
2733 tempbx &= (~(SetCRT2ToRAMDAC |
2734 SetCRT2ToLCD |
2735 SetCRT2ToTV));
2739 if (!(pVBInfo->VBType & VB_NoLCD)) {
2740 if (tempbx & SetCRT2ToLCD) {
2741 tempbx &= (0xFF00 |
2742 SetCRT2ToLCD |
2743 SwitchCRT2 |
2744 SetSimuScanMode);
2745 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2749 if (tempbx & SetCRT2ToSCART) {
2750 tempbx &= (0xFF00 |
2751 SetCRT2ToSCART |
2752 SwitchCRT2 |
2753 SetSimuScanMode);
2754 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2757 if (pVBInfo->IF_DEF_YPbPr == 1) {
2758 if (tempbx & SetCRT2ToYPbPr525750)
2759 tempbx &= (0xFF00 |
2760 SwitchCRT2 |
2761 SetSimuScanMode);
2764 if (pVBInfo->IF_DEF_HiVision == 1) {
2765 if (tempbx & SetCRT2ToHiVision)
2766 tempbx &= (0xFF00 |
2767 SetCRT2ToHiVision |
2768 SwitchCRT2 |
2769 SetSimuScanMode);
2772 if (tempax & DisableCRT2Display) { /* Set Display Device Info */
2773 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode)))
2774 tempbx = DisableCRT2Display;
2777 if (!(tempbx & DisableCRT2Display)) {
2778 if ((!(tempbx & DriverMode)) ||
2779 (!(modeflag & CRT2Mode))) {
2780 if (pVBInfo->IF_DEF_LCDA == 1) {
2781 if (!(tempbx & XGI_SetCRT2ToLCDA))
2782 tempbx |= (SetInSlaveMode |
2783 SetSimuScanMode);
2787 /* LCD+TV can't support in slave mode
2788 * (Force LCDA+TV->LCDB) */
2789 if ((tempbx & SetInSlaveMode) &&
2790 (tempbx & XGI_SetCRT2ToLCDA)) {
2791 tempbx ^= (SetCRT2ToLCD |
2792 XGI_SetCRT2ToLCDA |
2793 SetCRT2ToDualEdge);
2794 pVBInfo->SetFlag |= ReserveTVOption;
2798 pVBInfo->VBInfo = tempbx;
2801 static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
2802 struct vb_device_info *pVBInfo)
2804 unsigned short temp, tempbx = 0, resinfo = 0, modeflag, index1;
2806 tempbx = 0;
2807 resinfo = 0;
2809 if (pVBInfo->VBInfo & SetCRT2ToTV) {
2810 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2811 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
2813 if (pVBInfo->VBInfo & SetCRT2ToTV) {
2814 temp = xgifb_reg_get(pVBInfo->P3d4, 0x35);
2815 tempbx = temp;
2816 if (tempbx & TVSetPAL) {
2817 tempbx &= (SetCHTVOverScan |
2818 TVSetPALM |
2819 TVSetPALN |
2820 TVSetPAL);
2821 if (tempbx & TVSetPALM)
2822 /* set to NTSC if PAL-M */
2823 tempbx &= ~TVSetPAL;
2824 } else
2825 tempbx &= (SetCHTVOverScan |
2826 TVSetNTSCJ |
2827 TVSetPAL);
2830 if (pVBInfo->IF_DEF_LVDS == 0) {
2831 if (pVBInfo->VBInfo & SetCRT2ToSCART)
2832 tempbx |= TVSetPAL;
2835 if (pVBInfo->IF_DEF_YPbPr == 1) {
2836 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
2837 index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35);
2838 index1 &= YPbPrMode;
2840 if (index1 == YPbPrMode525i)
2841 tempbx |= TVSetYPbPr525i;
2843 if (index1 == YPbPrMode525p)
2844 tempbx = tempbx | TVSetYPbPr525p;
2845 if (index1 == YPbPrMode750p)
2846 tempbx = tempbx | TVSetYPbPr750p;
2850 if (pVBInfo->IF_DEF_HiVision == 1) {
2851 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
2852 tempbx = tempbx | TVSetHiVision | TVSetPAL;
2855 if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
2856 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
2857 (!(pVBInfo->VBInfo & SetNotSimuMode)))
2858 tempbx |= TVSimuMode;
2860 if (!(tempbx & TVSetPAL) &&
2861 (modeflag > 13) &&
2862 (resinfo == 8)) /* NTSC 1024x768, */
2863 tempbx |= NTSC1024x768;
2865 tempbx |= RPLLDIV2XO;
2867 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2868 if (pVBInfo->VBInfo & SetInSlaveMode)
2869 tempbx &= (~RPLLDIV2XO);
2870 } else {
2871 if (tempbx &
2872 (TVSetYPbPr525p | TVSetYPbPr750p))
2873 tempbx &= (~RPLLDIV2XO);
2874 else if (!(pVBInfo->VBType &
2875 (VB_SIS301B |
2876 VB_SIS302B |
2877 VB_SIS301LV |
2878 VB_SIS302LV |
2879 VB_XGI301C))) {
2880 if (tempbx & TVSimuMode)
2881 tempbx &= (~RPLLDIV2XO);
2886 pVBInfo->TVInfo = tempbx;
2889 static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
2890 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
2892 unsigned short temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
2894 pVBInfo->LCDResInfo = 0;
2895 pVBInfo->LCDTypeInfo = 0;
2896 pVBInfo->LCDInfo = 0;
2898 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2899 /* si+Ext_ResInfo // */
2900 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
2901 temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
2902 tempbx = temp & 0x0F;
2904 if (tempbx == 0)
2905 tempbx = Panel_1024x768; /* default */
2907 /* LCD75 */
2908 if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) {
2909 if (pVBInfo->VBInfo & DriverMode) {
2910 tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33);
2911 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
2912 tempax &= 0x0F;
2913 else
2914 tempax = tempax >> 4;
2916 if ((resinfo == 6) || (resinfo == 9)) {
2917 if (tempax >= 3)
2918 tempbx |= PanelRef75Hz;
2919 } else if ((resinfo == 7) || (resinfo == 8)) {
2920 if (tempax >= 4)
2921 tempbx |= PanelRef75Hz;
2926 pVBInfo->LCDResInfo = tempbx;
2928 /* End of LCD75 */
2930 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
2931 return 0;
2933 tempbx = 0;
2935 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
2937 temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
2939 tempbx |= temp;
2941 LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
2943 tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
2945 if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
2946 if (((pVBInfo->VBType & VB_SIS302LV) || (pVBInfo->VBType
2947 & VB_XGI301C)) && (tempax & XGI_LCDDualLink)) {
2948 tempbx |= SetLCDDualLink;
2952 if (pVBInfo->IF_DEF_LVDS == 0) {
2953 if ((pVBInfo->LCDResInfo == Panel_1400x1050) && (pVBInfo->VBInfo
2954 & SetCRT2ToLCD) && (resinfo == 9) &&
2955 (!(tempbx & EnableScalingLCD)))
2957 * set to center in 1280x1024 LCDB
2958 * for Panel_1400x1050
2960 tempbx |= SetLCDtoNonExpanding;
2963 if (pVBInfo->IF_DEF_ExpLink == 1) {
2964 if (modeflag & HalfDCLK) {
2965 if (!(tempbx & SetLCDtoNonExpanding)) {
2966 tempbx |= XGI_EnableLVDSDDA;
2967 } else {
2968 if (pVBInfo->LCDResInfo == Panel_1024x768) {
2969 if (resinfo == 4) {/* 512x384 */
2970 tempbx |= XGI_EnableLVDSDDA;
2977 if (pVBInfo->VBInfo & SetInSlaveMode) {
2978 if (pVBInfo->VBInfo & SetNotSimuMode)
2979 tempbx |= XGI_LCDVESATiming;
2980 } else {
2981 tempbx |= XGI_LCDVESATiming;
2984 pVBInfo->LCDInfo = tempbx;
2986 return 1;
2989 unsigned char XGI_SearchModeID(unsigned short ModeNo,
2990 unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo)
2992 for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
2993 if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
2994 break;
2995 if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
2996 return 0;
2999 return 1;
3002 static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
3004 unsigned char ujRet = 0;
3005 unsigned char i = 0;
3007 for (i = 0; i < 8; i++) {
3008 ujRet = ujRet << 1;
3009 ujRet |= (ujDate >> i) & 1;
3012 return ujRet;
3015 /*----------------------------------------------------------------------------*/
3016 /* output */
3017 /* bl[5] : LVDS signal */
3018 /* bl[1] : LVDS backlight */
3019 /* bl[0] : LVDS VDD */
3020 /*----------------------------------------------------------------------------*/
3021 static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
3023 unsigned char CR4A, temp;
3025 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
3026 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
3028 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
3030 temp = XG21GPIODataTransfer(temp);
3031 temp &= 0x23;
3032 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
3033 return temp;
3036 /*----------------------------------------------------------------------------*/
3037 /* output */
3038 /* bl[5] : LVDS signal */
3039 /* bl[1] : LVDS backlight */
3040 /* bl[0] : LVDS VDD */
3041 /*----------------------------------------------------------------------------*/
3042 static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
3044 unsigned char CR4A, CRB4, temp;
3046 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
3047 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
3049 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
3051 temp &= 0x0C;
3052 temp >>= 2;
3053 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
3054 CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4);
3055 temp |= ((CRB4 & 0x04) << 3);
3056 return temp;
3059 /*----------------------------------------------------------------------------*/
3060 /* input */
3061 /* bl[5] : 1;LVDS signal on */
3062 /* bl[1] : 1;LVDS backlight on */
3063 /* bl[0] : 1:LVDS VDD on */
3064 /* bh: 100000b : clear bit 5, to set bit5 */
3065 /* 000010b : clear bit 1, to set bit1 */
3066 /* 000001b : clear bit 0, to set bit0 */
3067 /*----------------------------------------------------------------------------*/
3068 static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
3069 struct vb_device_info *pVBInfo)
3071 unsigned char CR4A, temp;
3073 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
3074 tempbh &= 0x23;
3075 tempbl &= 0x23;
3076 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
3078 if (tempbh & 0x20) {
3079 temp = (tempbl >> 4) & 0x02;
3081 /* CR B4[1] */
3082 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
3086 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
3088 temp = XG21GPIODataTransfer(temp);
3089 temp &= ~tempbh;
3090 temp |= tempbl;
3091 xgifb_reg_set(pVBInfo->P3d4, 0x48, temp);
3094 static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
3095 struct vb_device_info *pVBInfo)
3097 unsigned char CR4A, temp;
3098 unsigned short tempbh0, tempbl0;
3100 tempbh0 = tempbh;
3101 tempbl0 = tempbl;
3102 tempbh0 &= 0x20;
3103 tempbl0 &= 0x20;
3104 tempbh0 >>= 3;
3105 tempbl0 >>= 3;
3107 if (tempbh & 0x20) {
3108 temp = (tempbl >> 4) & 0x02;
3110 /* CR B4[1] */
3111 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
3114 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
3116 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
3117 tempbh &= 0x03;
3118 tempbl &= 0x03;
3119 tempbh <<= 2;
3120 tempbl <<= 2; /* GPIOC,GPIOD */
3121 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
3122 xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
3125 /* --------------------------------------------------------------------- */
3126 /* Function : XGI_XG21SetPanelDelay */
3127 /* Input : */
3128 /* Output : */
3129 /* Description : */
3130 /* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
3131 /* : bl : 2 ; T2 : the duration signal on and Vdd on */
3132 /* : bl : 3 ; T3 : the duration between CPL off and signal off */
3133 /* : bl : 4 ; T4 : the duration signal off and Vdd off */
3134 /* --------------------------------------------------------------------- */
3135 static void XGI_XG21SetPanelDelay(struct xgifb_video_info *xgifb_info,
3136 unsigned short tempbl,
3137 struct vb_device_info *pVBInfo)
3139 if (tempbl == 1)
3140 mdelay(xgifb_info->lvds_data.PSC_S1);
3142 if (tempbl == 2)
3143 mdelay(xgifb_info->lvds_data.PSC_S2);
3145 if (tempbl == 3)
3146 mdelay(xgifb_info->lvds_data.PSC_S3);
3148 if (tempbl == 4)
3149 mdelay(xgifb_info->lvds_data.PSC_S4);
3152 static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
3153 struct xgi_hw_device_info *pXGIHWDE,
3154 struct vb_device_info *pVBInfo)
3157 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
3158 if (pXGIHWDE->jChipType == XG21) {
3159 if (pVBInfo->IF_DEF_LVDS == 1) {
3160 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
3161 /* LVDS VDD on */
3162 XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo);
3163 XGI_XG21SetPanelDelay(xgifb_info, 2, pVBInfo);
3165 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
3166 /* LVDS signal on */
3167 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
3168 XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo);
3169 /* LVDS backlight on */
3170 XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo);
3171 } else {
3172 /* DVO/DVI signal on */
3173 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
3178 if (pXGIHWDE->jChipType == XG27) {
3179 if (pVBInfo->IF_DEF_LVDS == 1) {
3180 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
3181 /* LVDS VDD on */
3182 XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo);
3183 XGI_XG21SetPanelDelay(xgifb_info, 2, pVBInfo);
3185 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
3186 /* LVDS signal on */
3187 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
3188 XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo);
3189 /* LVDS backlight on */
3190 XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo);
3191 } else {
3192 /* DVO/DVI signal on */
3193 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
3199 void XGI_DisplayOff(struct xgifb_video_info *xgifb_info,
3200 struct xgi_hw_device_info *pXGIHWDE,
3201 struct vb_device_info *pVBInfo)
3204 if (pXGIHWDE->jChipType == XG21) {
3205 if (pVBInfo->IF_DEF_LVDS == 1) {
3206 /* LVDS backlight off */
3207 XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo);
3208 XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo);
3209 } else {
3210 /* DVO/DVI signal off */
3211 XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo);
3215 if (pXGIHWDE->jChipType == XG27) {
3216 if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
3217 /* LVDS backlight off */
3218 XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo);
3219 XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo);
3222 if (pVBInfo->IF_DEF_LVDS == 0)
3223 /* DVO/DVI signal off */
3224 XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo);
3227 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
3230 static void XGI_WaitDisply(struct vb_device_info *pVBInfo)
3232 while ((inb(pVBInfo->P3da) & 0x01))
3233 break;
3235 while (!(inb(pVBInfo->P3da) & 0x01))
3236 break;
3239 static void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
3241 xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40);
3244 static void XGI_SaveCRT2Info(unsigned short ModeNo,
3245 struct vb_device_info *pVBInfo)
3247 unsigned short temp1, temp2;
3249 /* reserve CR34 for CRT1 Mode No */
3250 xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo);
3251 temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
3252 temp2 = ~(SetInSlaveMode >> 8);
3253 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1);
3256 static void XGI_GetCRT2ResInfo(unsigned short ModeNo,
3257 unsigned short ModeIdIndex,
3258 struct vb_device_info *pVBInfo)
3260 unsigned short xres, yres, modeflag, resindex;
3262 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3263 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
3264 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
3265 /* si+St_ModeFlag */
3266 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3268 if (modeflag & HalfDCLK)
3269 xres *= 2;
3271 if (modeflag & DoubleScanMode)
3272 yres *= 2;
3274 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
3275 goto exit;
3277 if (pVBInfo->IF_DEF_LVDS == 0) {
3278 if (pVBInfo->LCDResInfo == Panel_1600x1200) {
3279 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3280 if (yres == 1024)
3281 yres = 1056;
3285 if (pVBInfo->LCDResInfo == Panel_1280x1024) {
3286 if (yres == 400)
3287 yres = 405;
3288 else if (yres == 350)
3289 yres = 360;
3291 if (pVBInfo->LCDInfo & XGI_LCDVESATiming) {
3292 if (yres == 360)
3293 yres = 375;
3297 if (pVBInfo->LCDResInfo == Panel_1024x768) {
3298 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3299 if (!(pVBInfo->LCDInfo & LCDNonExpanding)) {
3300 if (yres == 350)
3301 yres = 357;
3302 else if (yres == 400)
3303 yres = 420;
3304 else if (yres == 480)
3305 yres = 525;
3311 if (xres == 720)
3312 xres = 640;
3314 exit:
3315 pVBInfo->VGAHDE = xres;
3316 pVBInfo->HDE = xres;
3317 pVBInfo->VGAVDE = yres;
3318 pVBInfo->VDE = yres;
3321 static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
3324 if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) &&
3325 (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
3326 return 1;
3328 return 0;
3331 static void XGI_GetRAMDAC2DATA(unsigned short ModeNo,
3332 unsigned short ModeIdIndex,
3333 unsigned short RefreshRateTableIndex,
3334 struct vb_device_info *pVBInfo)
3336 unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
3337 CRT1Index;
3339 pVBInfo->RVBHCMAX = 1;
3340 pVBInfo->RVBHCFACT = 1;
3341 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3342 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3343 CRT1Index &= IndexMask;
3344 temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
3345 temp2 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
3346 tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
3347 tempbx = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
3348 tempcx = (unsigned short)
3349 pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
3350 tempcx &= 0x0100;
3351 tempcx = tempcx << 2;
3352 tempbx |= tempcx;
3353 temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
3355 if (temp1 & 0x01)
3356 tempbx |= 0x0100;
3358 if (temp1 & 0x20)
3359 tempbx |= 0x0200;
3360 tempax += 5;
3362 if (modeflag & Charx8Dot)
3363 tempax *= 8;
3364 else
3365 tempax *= 9;
3367 pVBInfo->VGAHT = tempax;
3368 pVBInfo->HT = tempax;
3369 tempbx++;
3370 pVBInfo->VGAVT = tempbx;
3371 pVBInfo->VT = tempbx;
3374 static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
3375 unsigned short RefreshRateTableIndex,
3376 struct vb_device_info *pVBInfo)
3378 unsigned short tempax = 0, tempbx, modeflag, resinfo;
3380 struct SiS_LCDData *LCDPtr = NULL;
3381 struct SiS_TVData *TVPtr = NULL;
3383 /* si+Ext_ResInfo */
3384 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3385 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3386 pVBInfo->NewFlickerMode = 0;
3387 pVBInfo->RVBHRS = 50;
3389 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
3390 XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
3391 pVBInfo);
3392 return;
3395 tempbx = 4;
3397 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
3398 LCDPtr = (struct SiS_LCDData *) XGI_GetLcdPtr(tempbx,
3399 ModeNo, ModeIdIndex, RefreshRateTableIndex,
3400 pVBInfo);
3402 pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
3403 pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
3404 pVBInfo->VGAHT = LCDPtr->VGAHT;
3405 pVBInfo->VGAVT = LCDPtr->VGAVT;
3406 pVBInfo->HT = LCDPtr->LCDHT;
3407 pVBInfo->VT = LCDPtr->LCDVT;
3409 if (pVBInfo->LCDResInfo == Panel_1024x768) {
3410 tempax = 1024;
3411 tempbx = 768;
3413 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3414 if (pVBInfo->VGAVDE == 357)
3415 tempbx = 527;
3416 else if (pVBInfo->VGAVDE == 420)
3417 tempbx = 620;
3418 else if (pVBInfo->VGAVDE == 525)
3419 tempbx = 775;
3420 else if (pVBInfo->VGAVDE == 600)
3421 tempbx = 775;
3422 else
3423 tempbx = 768;
3424 } else
3425 tempbx = 768;
3426 } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) {
3427 tempax = 1024;
3428 tempbx = 768;
3429 } else if (pVBInfo->LCDResInfo == Panel_1280x1024) {
3430 tempax = 1280;
3431 if (pVBInfo->VGAVDE == 360)
3432 tempbx = 768;
3433 else if (pVBInfo->VGAVDE == 375)
3434 tempbx = 800;
3435 else if (pVBInfo->VGAVDE == 405)
3436 tempbx = 864;
3437 else
3438 tempbx = 1024;
3439 } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) {
3440 tempax = 1280;
3441 tempbx = 1024;
3442 } else if (pVBInfo->LCDResInfo == Panel_1280x960) {
3443 tempax = 1280;
3444 if (pVBInfo->VGAVDE == 350)
3445 tempbx = 700;
3446 else if (pVBInfo->VGAVDE == 400)
3447 tempbx = 800;
3448 else if (pVBInfo->VGAVDE == 1024)
3449 tempbx = 960;
3450 else
3451 tempbx = 960;
3452 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
3453 tempax = 1400;
3454 tempbx = 1050;
3456 if (pVBInfo->VGAVDE == 1024) {
3457 tempax = 1280;
3458 tempbx = 1024;
3460 } else if (pVBInfo->LCDResInfo == Panel_1600x1200) {
3461 tempax = 1600;
3462 tempbx = 1200; /* alan 10/14/2003 */
3463 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3464 if (pVBInfo->VGAVDE == 350)
3465 tempbx = 875;
3466 else if (pVBInfo->VGAVDE == 400)
3467 tempbx = 1000;
3471 if (pVBInfo->LCDInfo & LCDNonExpanding) {
3472 tempax = pVBInfo->VGAHDE;
3473 tempbx = pVBInfo->VGAVDE;
3476 pVBInfo->HDE = tempax;
3477 pVBInfo->VDE = tempbx;
3478 return;
3481 if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
3482 tempbx = 4;
3483 TVPtr = (struct SiS_TVData *) XGI_GetTVPtr(tempbx,
3484 ModeNo, ModeIdIndex, RefreshRateTableIndex,
3485 pVBInfo);
3487 pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
3488 pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
3489 pVBInfo->VGAHT = TVPtr->VGAHT;
3490 pVBInfo->VGAVT = TVPtr->VGAVT;
3491 pVBInfo->HDE = TVPtr->TVHDE;
3492 pVBInfo->VDE = TVPtr->TVVDE;
3493 pVBInfo->RVBHRS = TVPtr->RVBHRS;
3494 pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
3496 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3497 if (resinfo == 0x08)
3498 pVBInfo->NewFlickerMode = 0x40;
3499 else if (resinfo == 0x09)
3500 pVBInfo->NewFlickerMode = 0x40;
3501 else if (resinfo == 0x12)
3502 pVBInfo->NewFlickerMode = 0x40;
3504 if (pVBInfo->VGAVDE == 350)
3505 pVBInfo->TVInfo |= TVSimuMode;
3507 tempax = ExtHiTVHT;
3508 tempbx = ExtHiTVVT;
3510 if (pVBInfo->VBInfo & SetInSlaveMode) {
3511 if (pVBInfo->TVInfo & TVSimuMode) {
3512 tempax = StHiTVHT;
3513 tempbx = StHiTVVT;
3515 if (!(modeflag & Charx8Dot)) {
3516 tempax = StHiTextTVHT;
3517 tempbx = StHiTextTVVT;
3521 } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
3522 if (pVBInfo->TVInfo & TVSetYPbPr750p) {
3523 tempax = YPbPrTV750pHT; /* Ext750pTVHT */
3524 tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
3527 if (pVBInfo->TVInfo & TVSetYPbPr525p) {
3528 tempax = YPbPrTV525pHT; /* Ext525pTVHT */
3529 tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
3530 } else if (pVBInfo->TVInfo & TVSetYPbPr525i) {
3531 tempax = YPbPrTV525iHT; /* Ext525iTVHT */
3532 tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
3533 if (pVBInfo->TVInfo & NTSC1024x768)
3534 tempax = NTSC1024x768HT;
3536 } else {
3537 tempax = PALHT;
3538 tempbx = PALVT;
3539 if (!(pVBInfo->TVInfo & TVSetPAL)) {
3540 tempax = NTSCHT;
3541 tempbx = NTSCVT;
3542 if (pVBInfo->TVInfo & NTSC1024x768)
3543 tempax = NTSC1024x768HT;
3547 pVBInfo->HT = tempax;
3548 pVBInfo->VT = tempbx;
3549 return;
3553 static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
3554 unsigned short RefreshRateTableIndex,
3555 struct vb_device_info *pVBInfo)
3557 unsigned char di_0, di_1, tempal;
3559 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
3560 pVBInfo);
3561 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
3562 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
3564 if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */
3565 /* 301 */
3566 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10);
3567 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
3568 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
3569 } else { /* 301b/302b/301lv/302lv */
3570 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
3571 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
3574 xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12);
3576 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
3577 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28);
3578 else
3579 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08);
3582 static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
3583 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
3585 unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
3586 short index;
3587 unsigned short modeflag;
3589 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3590 index = (modeflag & ModeTypeMask) - ModeEGA;
3592 if (index < 0)
3593 index = 0;
3595 return ColorDepth[index];
3598 static unsigned short XGI_GetOffset(unsigned short ModeNo,
3599 unsigned short ModeIdIndex,
3600 unsigned short RefreshRateTableIndex,
3601 struct xgi_hw_device_info *HwDeviceExtension,
3602 struct vb_device_info *pVBInfo)
3604 unsigned short temp, colordepth, modeinfo, index, infoflag,
3605 ColorDepth[] = { 0x01, 0x02, 0x04 };
3607 modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
3608 infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
3610 index = (modeinfo >> 8) & 0xFF;
3612 temp = pVBInfo->ScreenOffset[index];
3614 if (infoflag & InterlaceMode)
3615 temp = temp << 1;
3617 colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
3619 if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
3620 temp = ModeNo - 0x7C;
3621 colordepth = ColorDepth[temp];
3622 temp = 0x6B;
3623 if (infoflag & InterlaceMode)
3624 temp = temp << 1;
3625 return temp * colordepth;
3626 } else {
3627 return temp * colordepth;
3631 static void XGI_SetCRT2Offset(unsigned short ModeNo,
3632 unsigned short ModeIdIndex,
3633 unsigned short RefreshRateTableIndex,
3634 struct xgi_hw_device_info *HwDeviceExtension,
3635 struct vb_device_info *pVBInfo)
3637 unsigned short offset;
3638 unsigned char temp;
3640 if (pVBInfo->VBInfo & SetInSlaveMode)
3641 return;
3643 offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
3644 HwDeviceExtension, pVBInfo);
3645 temp = (unsigned char) (offset & 0xFF);
3646 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
3647 temp = (unsigned char) ((offset & 0xFF00) >> 8);
3648 xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp);
3649 temp = (unsigned char) (((offset >> 3) & 0xFF) + 1);
3650 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
3653 static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
3655 /* threshold high ,disable auto threshold */
3656 xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B);
3657 /* threshold low default 04h */
3658 xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04);
3661 static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
3662 struct xgi_hw_device_info *HwDeviceExtension,
3663 unsigned short RefreshRateTableIndex,
3664 struct vb_device_info *pVBInfo)
3666 unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0;
3668 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3669 CRT1Index &= IndexMask;
3670 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3672 XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
3673 HwDeviceExtension, pVBInfo);
3674 XGI_SetCRT2FIFO(pVBInfo);
3676 for (tempcx = 4; tempcx < 7; tempcx++)
3677 xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0);
3679 xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00);
3680 xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
3683 static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
3684 struct xgi_hw_device_info *HwDeviceExtension,
3685 unsigned short RefreshRateTableIndex,
3686 struct vb_device_info *pVBInfo)
3688 unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
3689 pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
3691 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3692 CRT1Index &= IndexMask;
3693 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3694 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3696 /* bainy change table name */
3697 if (modeflag & HalfDCLK) {
3698 /* BTVGA2HT 0x08,0x09 */
3699 temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF;
3700 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
3701 temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
3702 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
3703 /* BTVGA2HDEE 0x0A,0x0C */
3704 temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF;
3705 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
3706 tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
3707 pushbx = pVBInfo->VGAHDE / 2 + 16;
3708 tempcx = tempcx >> 1;
3709 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
3710 tempcx += tempbx;
3712 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
3713 tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
3714 tempbx |= ((pVBInfo->
3715 XGINEWUB_CRT1Table[CRT1Index].CR[14] &
3716 0xC0) << 2);
3717 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
3718 tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
3719 tempcx &= 0x1F;
3720 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
3721 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
3722 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
3725 tempbx += 4;
3726 tempcx += 4;
3728 if (tempcx > (pVBInfo->VGAHT / 2))
3729 tempcx = pVBInfo->VGAHT / 2;
3731 temp = tempbx & 0x00FF;
3733 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
3734 } else {
3735 temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
3736 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
3737 temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
3738 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
3739 /* BTVGA2HDEE 0x0A,0x0C */
3740 temp = (pVBInfo->VGAHDE + 16) & 0x0FF;
3741 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
3742 tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
3743 pushbx = pVBInfo->VGAHDE + 16;
3744 tempcx = tempcx >> 1;
3745 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
3746 tempcx += tempbx;
3748 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
3749 tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
3750 tempbx |= ((pVBInfo->
3751 XGINEWUB_CRT1Table[CRT1Index].CR[5] &
3752 0xC0) << 2);
3753 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
3754 tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
3755 tempcx &= 0x1F;
3756 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
3757 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
3758 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
3759 tempbx += 16;
3760 tempcx += 16;
3763 if (tempcx > pVBInfo->VGAHT)
3764 tempcx = pVBInfo->VGAHT;
3766 temp = tempbx & 0x00FF;
3767 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
3770 tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
3771 tempbx = pushbx;
3772 tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
3773 tempax |= (tempbx & 0xFF00);
3774 temp = (tempax & 0xFF00) >> 8;
3775 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
3776 temp = tempcx & 0x00FF;
3777 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
3778 tempcx = (pVBInfo->VGAVT - 1);
3779 temp = tempcx & 0x00FF;
3781 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
3782 tempbx = pVBInfo->VGAVDE - 1;
3783 temp = tempbx & 0x00FF;
3784 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp);
3785 temp = ((tempbx & 0xFF00) << 3) >> 8;
3786 temp |= ((tempcx & 0xFF00) >> 8);
3787 xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp);
3789 tempax = pVBInfo->VGAVDE;
3790 tempbx = pVBInfo->VGAVDE;
3791 tempcx = pVBInfo->VGAVT;
3792 /* BTVGA2VRS 0x10,0x11 */
3793 tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1;
3794 /* BTVGA2VRE 0x11 */
3795 tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1;
3797 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
3798 tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
3799 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
3801 if (temp & 0x04)
3802 tempbx |= 0x0100;
3804 if (temp & 0x080)
3805 tempbx |= 0x0200;
3807 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
3809 if (temp & 0x08)
3810 tempbx |= 0x0400;
3812 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
3813 tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
3816 temp = tempbx & 0x00FF;
3817 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
3818 temp = ((tempbx & 0xFF00) >> 8) << 4;
3819 temp = ((tempcx & 0x000F) | (temp));
3820 xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp);
3821 tempax = 0;
3823 if (modeflag & DoubleScanMode)
3824 tempax |= 0x80;
3826 if (modeflag & HalfDCLK)
3827 tempax |= 0x40;
3829 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
3832 static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
3834 unsigned long tempax, tempbx;
3836 tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
3837 & 0xFFFF;
3838 tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
3839 tempax = (tempax * pVBInfo->HT) / tempbx;
3841 return (unsigned short) tempax;
3844 static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
3845 struct xgi_hw_device_info *HwDeviceExtension,
3846 unsigned short RefreshRateTableIndex,
3847 struct vb_device_info *pVBInfo)
3849 unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
3850 modeflag, CRT1Index;
3852 /* si+Ext_ResInfo */
3853 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3854 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
3855 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3856 CRT1Index &= IndexMask;
3858 if (!(pVBInfo->VBInfo & SetInSlaveMode))
3859 return;
3861 temp = 0xFF; /* set MAX HT */
3862 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
3863 tempcx = 0x08;
3865 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
3866 modeflag |= Charx8Dot;
3868 tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
3870 if (modeflag & HalfDCLK)
3871 tempax = tempax >> 1;
3873 tempax = (tempax / tempcx) - 1;
3874 tempbx |= ((tempax & 0x00FF) << 8);
3875 temp = tempax & 0x00FF;
3876 xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp);
3878 temp = (tempbx & 0xFF00) >> 8;
3880 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3881 if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3882 | VB_SIS302LV | VB_XGI301C)))
3883 temp += 2;
3885 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3886 if (pVBInfo->VBType & VB_SIS301LV) {
3887 if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
3888 if (resinfo == 7)
3889 temp -= 2;
3891 } else if (resinfo == 7) {
3892 temp -= 2;
3897 /* 0x05 Horizontal Display Start */
3898 xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp);
3899 /* 0x06 Horizontal Blank end */
3900 xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03);
3902 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
3903 if (pVBInfo->VBInfo & SetCRT2ToTV)
3904 tempax = pVBInfo->VGAHT;
3905 else
3906 tempax = XGI_GetVGAHT2(pVBInfo);
3909 if (tempax >= pVBInfo->VGAHT)
3910 tempax = pVBInfo->VGAHT;
3912 if (modeflag & HalfDCLK)
3913 tempax = tempax >> 1;
3915 tempax = (tempax / tempcx) - 5;
3916 tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
3917 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3918 temp = (tempbx & 0x00FF) - 1;
3919 if (!(modeflag & HalfDCLK)) {
3920 temp -= 6;
3921 if (pVBInfo->TVInfo & TVSimuMode) {
3922 temp -= 4;
3923 temp -= 10;
3926 } else {
3927 tempbx = (tempbx & 0xFF00) >> 8;
3928 tempcx = (tempcx + tempbx) >> 1;
3929 temp = (tempcx & 0x00FF) + 2;
3931 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3932 temp -= 1;
3933 if (!(modeflag & HalfDCLK)) {
3934 if ((modeflag & Charx8Dot)) {
3935 temp += 4;
3936 if (pVBInfo->VGAHDE >= 800)
3937 temp -= 6;
3940 } else if (!(modeflag & HalfDCLK)) {
3941 temp -= 4;
3942 if (pVBInfo->LCDResInfo != Panel_1280x960 &&
3943 pVBInfo->VGAHDE >= 800) {
3944 temp -= 7;
3945 if (pVBInfo->VGAHDE >= 1280 &&
3946 pVBInfo->LCDResInfo != Panel_1280x960 &&
3947 (pVBInfo->LCDInfo & LCDNonExpanding))
3948 temp += 28;
3953 /* 0x07 Horizontal Retrace Start */
3954 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
3955 /* 0x08 Horizontal Retrace End */
3956 xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0);
3958 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3959 if (pVBInfo->TVInfo & TVSimuMode) {
3960 if (ModeNo == 0x50) {
3961 if (pVBInfo->TVInfo & SetNTSCTV) {
3962 xgifb_reg_set(pVBInfo->Part1Port,
3963 0x07, 0x30);
3964 xgifb_reg_set(pVBInfo->Part1Port,
3965 0x08, 0x03);
3966 } else {
3967 xgifb_reg_set(pVBInfo->Part1Port,
3968 0x07, 0x2f);
3969 xgifb_reg_set(pVBInfo->Part1Port,
3970 0x08, 0x02);
3976 xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
3977 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
3978 xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
3980 tempbx = pVBInfo->VGAVT;
3981 push1 = tempbx;
3982 tempcx = 0x121;
3983 tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
3985 if (tempbx == 357)
3986 tempbx = 350;
3987 if (tempbx == 360)
3988 tempbx = 350;
3989 if (tempbx == 375)
3990 tempbx = 350;
3991 if (tempbx == 405)
3992 tempbx = 400;
3993 if (tempbx == 525)
3994 tempbx = 480;
3996 push2 = tempbx;
3998 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
3999 if (pVBInfo->LCDResInfo == Panel_1024x768) {
4000 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
4001 if (tempbx == 350)
4002 tempbx += 5;
4003 if (tempbx == 480)
4004 tempbx += 5;
4008 tempbx--;
4009 temp = tempbx & 0x00FF;
4010 tempbx--;
4011 temp = tempbx & 0x00FF;
4012 /* 0x10 vertical Blank Start */
4013 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
4014 tempbx = push2;
4015 tempbx--;
4016 temp = tempbx & 0x00FF;
4017 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
4019 if (tempbx & 0x0100)
4020 tempcx |= 0x0002;
4022 tempax = 0x000B;
4024 if (modeflag & DoubleScanMode)
4025 tempax |= 0x08000;
4027 if (tempbx & 0x0200)
4028 tempcx |= 0x0040;
4030 temp = (tempax & 0xFF00) >> 8;
4031 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
4033 if (tempbx & 0x0400)
4034 tempcx |= 0x0600;
4036 /* 0x11 Vertival Blank End */
4037 xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00);
4039 tempax = push1;
4040 tempax -= tempbx; /* 0x0C Vertical Retrace Start */
4041 tempax = tempax >> 2;
4042 push1 = tempax; /* push ax */
4044 if (resinfo != 0x09) {
4045 tempax = tempax << 1;
4046 tempbx += tempax;
4049 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
4050 if ((pVBInfo->VBType & VB_SIS301LV) &&
4051 !(pVBInfo->TVInfo & TVSetHiVision)) {
4052 if ((pVBInfo->TVInfo & TVSimuMode) &&
4053 (pVBInfo->TVInfo & TVSetPAL)) {
4054 if (!(pVBInfo->VBType & VB_SIS301LV) ||
4055 !(pVBInfo->TVInfo &
4056 (TVSetYPbPr525p |
4057 TVSetYPbPr750p |
4058 TVSetHiVision)))
4059 tempbx += 40;
4061 } else {
4062 tempbx -= 10;
4064 } else {
4065 if (pVBInfo->TVInfo & TVSimuMode) {
4066 if (pVBInfo->TVInfo & TVSetPAL) {
4067 if (pVBInfo->VBType & VB_SIS301LV) {
4068 if (!(pVBInfo->TVInfo &
4069 (TVSetYPbPr525p |
4070 TVSetYPbPr750p |
4071 TVSetHiVision)))
4072 tempbx += 40;
4073 } else {
4074 tempbx += 40;
4079 tempax = push1;
4080 tempax = tempax >> 2;
4081 tempax++;
4082 tempax += tempbx;
4083 push1 = tempax; /* push ax */
4085 if ((pVBInfo->TVInfo & TVSetPAL)) {
4086 if (tempbx <= 513) {
4087 if (tempax >= 513)
4088 tempbx = 513;
4092 temp = tempbx & 0x00FF;
4093 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
4094 tempbx--;
4095 temp = tempbx & 0x00FF;
4096 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
4098 if (tempbx & 0x0100)
4099 tempcx |= 0x0008;
4101 if (tempbx & 0x0200)
4102 xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
4104 tempbx++;
4106 if (tempbx & 0x0100)
4107 tempcx |= 0x0004;
4109 if (tempbx & 0x0200)
4110 tempcx |= 0x0080;
4112 if (tempbx & 0x0400)
4113 tempcx |= 0x0C00;
4115 tempbx = push1; /* pop ax */
4116 temp = tempbx & 0x00FF;
4117 temp &= 0x0F;
4118 /* 0x0D vertical Retrace End */
4119 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
4121 if (tempbx & 0x0010)
4122 tempcx |= 0x2000;
4124 temp = tempcx & 0x00FF;
4125 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
4126 temp = (tempcx & 0x0FF00) >> 8;
4127 xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
4128 tempax = modeflag;
4129 temp = (tempax & 0xFF00) >> 8;
4131 temp = (temp >> 1) & 0x09;
4133 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
4134 temp |= 0x01;
4136 xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
4137 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
4138 xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
4140 if (pVBInfo->LCDInfo & LCDRGB18Bit)
4141 temp = 0x80;
4142 else
4143 temp = 0x00;
4145 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
4147 return;
4150 static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
4151 unsigned short RefreshRateTableIndex,
4152 struct xgi_hw_device_info *HwDeviceExtension,
4153 struct vb_device_info *pVBInfo)
4155 unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
4156 modeflag, resinfo, crt2crtc;
4157 unsigned char *TimingPoint;
4159 unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
4161 /* si+Ext_ResInfo */
4162 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4163 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
4164 crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
4166 tempax = 0;
4168 if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
4169 tempax |= 0x0800;
4171 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
4172 tempax |= 0x0400;
4174 if (pVBInfo->VBInfo & SetCRT2ToSCART)
4175 tempax |= 0x0200;
4177 if (!(pVBInfo->TVInfo & TVSetPAL))
4178 tempax |= 0x1000;
4180 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
4181 tempax |= 0x0100;
4183 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
4184 tempax &= 0xfe00;
4186 tempax = (tempax & 0xff00) >> 8;
4188 xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax);
4189 TimingPoint = pVBInfo->NTSCTiming;
4191 if (pVBInfo->TVInfo & TVSetPAL)
4192 TimingPoint = pVBInfo->PALTiming;
4194 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
4195 TimingPoint = pVBInfo->HiTVExtTiming;
4197 if (pVBInfo->VBInfo & SetInSlaveMode)
4198 TimingPoint = pVBInfo->HiTVSt2Timing;
4200 if (pVBInfo->SetFlag & TVSimuMode)
4201 TimingPoint = pVBInfo->HiTVSt1Timing;
4203 if (!(modeflag & Charx8Dot))
4204 TimingPoint = pVBInfo->HiTVTextTiming;
4207 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
4208 if (pVBInfo->TVInfo & TVSetYPbPr525i)
4209 TimingPoint = pVBInfo->YPbPr525iTiming;
4211 if (pVBInfo->TVInfo & TVSetYPbPr525p)
4212 TimingPoint = pVBInfo->YPbPr525pTiming;
4214 if (pVBInfo->TVInfo & TVSetYPbPr750p)
4215 TimingPoint = pVBInfo->YPbPr750pTiming;
4218 for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
4219 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
4221 for (i = 0x39; i <= 0x45; i++, j++)
4222 /* di->temp2[j] */
4223 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
4225 if (pVBInfo->VBInfo & SetCRT2ToTV)
4226 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
4228 temp = pVBInfo->NewFlickerMode;
4229 temp &= 0x80;
4230 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
4232 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
4233 tempax = 950;
4235 if (pVBInfo->TVInfo & TVSetPAL)
4236 tempax = 520;
4237 else
4238 tempax = 440;
4240 if (pVBInfo->VDE <= tempax) {
4241 tempax -= pVBInfo->VDE;
4242 tempax = tempax >> 2;
4243 tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
4244 push1 = tempax;
4245 temp = (tempax & 0xFF00) >> 8;
4246 temp += (unsigned short) TimingPoint[0];
4248 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4249 | VB_SIS302LV | VB_XGI301C)) {
4250 if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
4251 | SetCRT2ToSVIDEO | SetCRT2ToSCART
4252 | SetCRT2ToYPbPr525750)) {
4253 tempcx = pVBInfo->VGAHDE;
4254 if (tempcx >= 1024) {
4255 temp = 0x17; /* NTSC */
4256 if (pVBInfo->TVInfo & TVSetPAL)
4257 temp = 0x19; /* PAL */
4262 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
4263 tempax = push1;
4264 temp = (tempax & 0xFF00) >> 8;
4265 temp += TimingPoint[1];
4267 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4268 | VB_SIS302LV | VB_XGI301C)) {
4269 if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
4270 | SetCRT2ToSVIDEO | SetCRT2ToSCART
4271 | SetCRT2ToYPbPr525750))) {
4272 tempcx = pVBInfo->VGAHDE;
4273 if (tempcx >= 1024) {
4274 temp = 0x1D; /* NTSC */
4275 if (pVBInfo->TVInfo & TVSetPAL)
4276 temp = 0x52; /* PAL */
4280 xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp);
4283 /* 301b */
4284 tempcx = pVBInfo->HT;
4286 if (XGI_IsLCDDualLink(pVBInfo))
4287 tempcx = tempcx >> 1;
4289 tempcx -= 2;
4290 temp = tempcx & 0x00FF;
4291 xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp);
4293 temp = (tempcx & 0xFF00) >> 8;
4294 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
4296 tempcx = pVBInfo->HT >> 1;
4297 push1 = tempcx; /* push cx */
4298 tempcx += 7;
4300 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
4301 tempcx -= 4;
4303 temp = tempcx & 0x00FF;
4304 temp = temp << 4;
4305 xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp);
4307 tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
4308 tempbx += tempcx;
4309 push2 = tempbx;
4310 temp = tempbx & 0x00FF;
4311 xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp);
4312 temp = (tempbx & 0xFF00) >> 8;
4313 temp = temp << 4;
4314 xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp);
4316 tempbx = push2;
4317 tempbx = tempbx + 8;
4318 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
4319 tempbx = tempbx - 4;
4320 tempcx = tempbx;
4323 temp = (tempbx & 0x00FF) << 4;
4324 xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp);
4326 j += 2;
4327 tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
4328 temp = tempcx & 0x00FF;
4329 xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp);
4330 temp = ((tempcx & 0xFF00) >> 8) << 4;
4331 xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp);
4333 tempcx += 8;
4334 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
4335 tempcx -= 4;
4337 temp = tempcx & 0xFF;
4338 temp = temp << 4;
4339 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
4341 tempcx = push1; /* pop cx */
4342 j += 2;
4343 temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
4344 tempcx -= temp;
4345 temp = tempcx & 0x00FF;
4346 temp = temp << 4;
4347 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
4349 tempcx -= 11;
4351 if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
4352 tempax = XGI_GetVGAHT2(pVBInfo);
4353 tempcx = tempax - 1;
4355 temp = tempcx & 0x00FF;
4356 xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp);
4358 tempbx = pVBInfo->VDE;
4360 if (pVBInfo->VGAVDE == 360)
4361 tempbx = 746;
4362 if (pVBInfo->VGAVDE == 375)
4363 tempbx = 746;
4364 if (pVBInfo->VGAVDE == 405)
4365 tempbx = 853;
4367 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4368 if (pVBInfo->VBType &
4369 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
4370 if (!(pVBInfo->TVInfo &
4371 (TVSetYPbPr525p | TVSetYPbPr750p)))
4372 tempbx = tempbx >> 1;
4373 } else
4374 tempbx = tempbx >> 1;
4377 tempbx -= 2;
4378 temp = tempbx & 0x00FF;
4380 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
4381 if (pVBInfo->VBType & VB_SIS301LV) {
4382 if (pVBInfo->TVInfo & TVSetHiVision) {
4383 if (pVBInfo->VBInfo & SetInSlaveMode) {
4384 if (ModeNo == 0x2f)
4385 temp += 1;
4388 } else {
4389 if (pVBInfo->VBInfo & SetInSlaveMode) {
4390 if (ModeNo == 0x2f)
4391 temp += 1;
4396 xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp);
4398 temp = (tempcx & 0xFF00) >> 8;
4399 temp |= ((tempbx & 0xFF00) >> 8) << 6;
4401 if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) {
4402 if (pVBInfo->VBType & VB_SIS301LV) {
4403 if (pVBInfo->TVInfo & TVSetHiVision) {
4404 temp |= 0x10;
4406 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
4407 temp |= 0x20;
4409 } else {
4410 temp |= 0x10;
4411 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
4412 temp |= 0x20;
4416 xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp);
4418 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4419 | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */
4420 tempbx = pVBInfo->VDE;
4421 tempcx = tempbx - 2;
4423 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4424 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p
4425 | TVSetYPbPr750p)))
4426 tempbx = tempbx >> 1;
4429 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
4430 temp = 0;
4431 if (tempcx & 0x0400)
4432 temp |= 0x20;
4434 if (tempbx & 0x0400)
4435 temp |= 0x40;
4437 xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp);
4440 temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
4441 xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp);
4442 temp = (tempbx - 3) & 0x00FF;
4443 xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp);
4446 tempbx = tempbx & 0x00FF;
4448 if (!(modeflag & HalfDCLK)) {
4449 tempcx = pVBInfo->VGAHDE;
4450 if (tempcx >= pVBInfo->HDE) {
4451 tempbx |= 0x2000;
4452 tempax &= 0x00FF;
4456 tempcx = 0x0101;
4458 if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/
4459 if (pVBInfo->VGAHDE >= 1024) {
4460 tempcx = 0x1920;
4461 if (pVBInfo->VGAHDE >= 1280) {
4462 tempcx = 0x1420;
4463 tempbx = tempbx & 0xDFFF;
4468 if (!(tempbx & 0x2000)) {
4469 if (modeflag & HalfDCLK)
4470 tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
4472 push1 = tempbx;
4473 tempeax = pVBInfo->VGAHDE;
4474 tempebx = (tempcx & 0xFF00) >> 8;
4475 longtemp = tempeax * tempebx;
4476 tempecx = tempcx & 0x00FF;
4477 longtemp = longtemp / tempecx;
4479 /* 301b */
4480 tempecx = 8 * 1024;
4482 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4483 | VB_SIS302LV | VB_XGI301C)) {
4484 tempecx = tempecx * 8;
4487 longtemp = longtemp * tempecx;
4488 tempecx = pVBInfo->HDE;
4489 temp2 = longtemp % tempecx;
4490 tempeax = longtemp / tempecx;
4491 if (temp2 != 0)
4492 tempeax += 1;
4494 tempax = (unsigned short) tempeax;
4496 /* 301b */
4497 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4498 | VB_SIS302LV | VB_XGI301C)) {
4499 tempcx = ((tempax & 0xFF00) >> 5) >> 8;
4501 /* end 301b */
4503 tempbx = push1;
4504 tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00)
4505 | (tempbx & 0x00FF));
4506 tempax = (unsigned short) (((tempeax & 0x000000FF) << 8)
4507 | (tempax & 0x00FF));
4508 temp = (tempax & 0xFF00) >> 8;
4509 } else {
4510 temp = (tempax & 0x00FF) >> 8;
4513 xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp);
4514 temp = (tempbx & 0xFF00) >> 8;
4515 xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
4516 temp = tempcx & 0x00FF;
4518 if (tempbx & 0x2000)
4519 temp = 0;
4521 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
4522 temp |= 0x18;
4524 xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
4525 if (pVBInfo->TVInfo & TVSetPAL) {
4526 tempbx = 0x0382;
4527 tempcx = 0x007e;
4528 } else {
4529 tempbx = 0x0369;
4530 tempcx = 0x0061;
4533 temp = tempbx & 0x00FF;
4534 xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp);
4535 temp = tempcx & 0x00FF;
4536 xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp);
4538 temp = ((tempcx & 0xFF00) >> 8) & 0x03;
4539 temp = temp << 2;
4540 temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
4542 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
4543 temp |= 0x10;
4545 if (pVBInfo->TVInfo & TVSetYPbPr525p)
4546 temp |= 0x20;
4548 if (pVBInfo->TVInfo & TVSetYPbPr750p)
4549 temp |= 0x60;
4552 xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp);
4553 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */
4554 xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
4556 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) {
4557 if (pVBInfo->TVInfo & NTSC1024x768) {
4558 TimingPoint = XGI_NTSC1024AdjTime;
4559 for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
4560 xgifb_reg_set(pVBInfo->Part2Port, i,
4561 TimingPoint[j]);
4563 xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72);
4567 /* Modify for 301C PALM Support */
4568 if (pVBInfo->VBType & VB_XGI301C) {
4569 if (pVBInfo->TVInfo & TVSetPALM)
4570 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08,
4571 0x08); /* PALM Mode */
4574 if (pVBInfo->TVInfo & TVSetPALM) {
4575 tempax = (unsigned char) xgifb_reg_get(pVBInfo->Part2Port,
4576 0x01);
4577 tempax--;
4578 xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax);
4580 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF);
4583 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
4584 if (!(pVBInfo->VBInfo & SetInSlaveMode))
4585 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00);
4588 if (pVBInfo->VBInfo & SetCRT2ToTV)
4589 return;
4592 static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
4593 struct xgi_hw_device_info *HwDeviceExtension,
4594 unsigned short RefreshRateTableIndex,
4595 struct vb_device_info *pVBInfo)
4597 unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp,
4598 tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
4600 struct XGI_LCDDesStruct *LCDBDesPtr = NULL;
4602 /* si+Ext_ResInfo */
4603 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4604 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
4605 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
4606 CRT1Index &= IndexMask;
4608 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
4609 return;
4611 tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
4613 if (XGI_IsLCDDualLink(pVBInfo))
4614 tempbx = tempbx >> 1;
4616 tempbx -= 1;
4617 temp = tempbx & 0x00FF;
4618 xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp);
4619 temp = (tempbx & 0xFF00) >> 8;
4620 temp = temp << 4;
4621 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
4622 temp = 0x01;
4624 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp);
4625 tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
4626 push1 = tempbx;
4627 tempbx--;
4628 temp = tempbx & 0x00FF;
4629 xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp);
4630 temp = ((tempbx & 0xFF00) >> 8) & 0x07;
4631 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
4633 tempcx = pVBInfo->VT - 1;
4634 push2 = tempcx + 1;
4635 temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
4636 xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp);
4637 temp = (tempcx & 0xFF00) >> 8;
4638 temp = temp << 5;
4639 xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp);
4640 xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
4641 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
4642 xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
4643 xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
4645 /* Customized LCDB Des no add */
4646 tempbx = 5;
4647 LCDBDesPtr = (struct XGI_LCDDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
4648 ModeIdIndex, RefreshRateTableIndex, pVBInfo);
4649 tempah = pVBInfo->LCDResInfo;
4650 tempah &= PanelResInfo;
4652 if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) {
4653 tempbx = 1024;
4654 tempcx = 768;
4655 } else if ((tempah == Panel_1280x1024) ||
4656 (tempah == Panel_1280x1024x75)) {
4657 tempbx = 1280;
4658 tempcx = 1024;
4659 } else if (tempah == Panel_1400x1050) {
4660 tempbx = 1400;
4661 tempcx = 1050;
4662 } else {
4663 tempbx = 1600;
4664 tempcx = 1200;
4667 if (pVBInfo->LCDInfo & EnableScalingLCD) {
4668 tempbx = pVBInfo->HDE;
4669 tempcx = pVBInfo->VDE;
4672 pushbx = tempbx;
4673 tempax = pVBInfo->VT;
4674 pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
4675 pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
4676 pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
4677 pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
4678 tempbx = pVBInfo->LCDVDES;
4679 tempcx += tempbx;
4681 if (tempcx >= tempax)
4682 tempcx -= tempax; /* lcdvdes */
4684 temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
4685 xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp);
4686 temp = tempcx & 0x00FF;
4687 xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp);
4688 tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
4689 tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
4690 tempah = tempch;
4691 tempah = tempah << 3;
4692 tempah |= tempbh;
4693 xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah);
4695 /* getlcdsync() */
4696 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
4697 tempcx = tempbx;
4698 tempax = pVBInfo->VT;
4699 tempbx = pVBInfo->LCDVRS;
4701 tempcx += tempbx;
4702 if (tempcx >= tempax)
4703 tempcx -= tempax;
4705 temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
4706 xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp);
4707 temp = (tempbx & 0xFF00) >> 8;
4708 temp = temp << 4;
4709 temp |= (tempcx & 0x000F);
4710 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
4711 tempcx = pushbx;
4712 tempax = pVBInfo->HT;
4713 tempbx = pVBInfo->LCDHDES;
4714 tempbx &= 0x0FFF;
4716 if (XGI_IsLCDDualLink(pVBInfo)) {
4717 tempax = tempax >> 1;
4718 tempbx = tempbx >> 1;
4719 tempcx = tempcx >> 1;
4722 if (pVBInfo->VBType & VB_SIS302LV)
4723 tempbx += 1;
4725 if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
4726 tempbx += 1;
4728 tempcx += tempbx;
4730 if (tempcx >= tempax)
4731 tempcx -= tempax;
4733 temp = tempbx & 0x00FF;
4734 xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
4735 temp = ((tempbx & 0xFF00) >> 8) << 4;
4736 xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp);
4737 temp = tempcx & 0x00FF;
4738 xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
4739 temp = (tempcx & 0xFF00) >> 8;
4740 xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp);
4742 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
4743 tempcx = tempax;
4744 tempax = pVBInfo->HT;
4745 tempbx = pVBInfo->LCDHRS;
4746 if (XGI_IsLCDDualLink(pVBInfo)) {
4747 tempax = tempax >> 1;
4748 tempbx = tempbx >> 1;
4749 tempcx = tempcx >> 1;
4752 if (pVBInfo->VBType & VB_SIS302LV)
4753 tempbx += 1;
4755 tempcx += tempbx;
4757 if (tempcx >= tempax)
4758 tempcx -= tempax;
4760 temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
4761 xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp);
4763 temp = (tempbx & 0xFF00) >> 8;
4764 temp = temp << 4;
4765 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
4766 temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
4767 xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp);
4769 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
4770 if (pVBInfo->VGAVDE == 525) {
4771 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
4772 | VB_SIS301LV | VB_SIS302LV
4773 | VB_XGI301C)) {
4774 temp = 0xC6;
4775 } else
4776 temp = 0xC4;
4778 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
4779 xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3);
4782 if (pVBInfo->VGAVDE == 420) {
4783 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
4784 | VB_SIS301LV | VB_SIS302LV
4785 | VB_XGI301C)) {
4786 temp = 0x4F;
4787 } else
4788 temp = 0x4E;
4789 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
4794 /* --------------------------------------------------------------------- */
4795 /* Function : XGI_GetTap4Ptr */
4796 /* Input : */
4797 /* Output : di -> Tap4 Reg. Setting Pointer */
4798 /* Description : */
4799 /* --------------------------------------------------------------------- */
4800 static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
4801 struct vb_device_info *pVBInfo)
4803 unsigned short tempax, tempbx, i;
4805 struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
4807 if (tempcx == 0) {
4808 tempax = pVBInfo->VGAHDE;
4809 tempbx = pVBInfo->HDE;
4810 } else {
4811 tempax = pVBInfo->VGAVDE;
4812 tempbx = pVBInfo->VDE;
4815 if (tempax <= tempbx)
4816 return &xgifb_tap4_timing[0];
4817 else
4818 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */
4820 if (pVBInfo->TVInfo & TVSetPAL)
4821 Tap4TimingPtr = PALTap4Timing;
4823 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
4824 if ((pVBInfo->TVInfo & TVSetYPbPr525i) ||
4825 (pVBInfo->TVInfo & TVSetYPbPr525p))
4826 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing;
4827 if (pVBInfo->TVInfo & TVSetYPbPr750p)
4828 Tap4TimingPtr = YPbPr750pTap4Timing;
4831 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
4832 Tap4TimingPtr = xgifb_tap4_timing;
4834 i = 0;
4835 while (Tap4TimingPtr[i].DE != 0xFFFF) {
4836 if (Tap4TimingPtr[i].DE == tempax)
4837 break;
4838 i++;
4840 return &Tap4TimingPtr[i];
4843 static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
4845 unsigned short i, j;
4847 struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
4849 if (!(pVBInfo->VBType & VB_XGI301C))
4850 return;
4852 Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
4853 for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
4854 xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
4856 if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
4857 (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) {
4858 /* Set Vertical Scaling */
4859 Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo);
4860 for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
4861 xgifb_reg_set(pVBInfo->Part2Port,
4863 Tap4TimingPtr->Reg[j]);
4866 if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
4867 (!(pVBInfo->VBInfo & SetCRT2ToHiVision)))
4868 /* Enable V.Scaling */
4869 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04);
4870 else
4871 /* Enable H.Scaling */
4872 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10);
4875 static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
4876 struct vb_device_info *pVBInfo)
4878 unsigned short i;
4879 unsigned char *tempdi;
4880 unsigned short modeflag;
4882 /* si+Ext_ResInfo */
4883 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4885 xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00);
4886 if (pVBInfo->TVInfo & TVSetPAL) {
4887 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
4888 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
4889 } else {
4890 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5);
4891 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7);
4894 if (!(pVBInfo->VBInfo & SetCRT2ToTV))
4895 return;
4897 if (pVBInfo->TVInfo & TVSetPALM) {
4898 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
4899 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
4900 xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8);
4903 if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo
4904 & SetCRT2ToYPbPr525750)) {
4905 if (pVBInfo->TVInfo & TVSetYPbPr525i)
4906 return;
4908 tempdi = pVBInfo->HiTVGroup3Data;
4909 if (pVBInfo->SetFlag & TVSimuMode) {
4910 tempdi = pVBInfo->HiTVGroup3Simu;
4911 if (!(modeflag & Charx8Dot))
4912 tempdi = pVBInfo->HiTVGroup3Text;
4915 if (pVBInfo->TVInfo & TVSetYPbPr525p)
4916 tempdi = pVBInfo->Ren525pGroup3;
4918 if (pVBInfo->TVInfo & TVSetYPbPr750p)
4919 tempdi = pVBInfo->Ren750pGroup3;
4921 for (i = 0; i <= 0x3E; i++)
4922 xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]);
4924 if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
4925 if (pVBInfo->TVInfo & TVSetYPbPr525p)
4926 xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f);
4929 return;
4930 } /* {end of XGI_SetGroup3} */
4932 static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
4933 unsigned short RefreshRateTableIndex,
4934 struct xgi_hw_device_info *HwDeviceExtension,
4935 struct vb_device_info *pVBInfo)
4937 unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
4939 unsigned long tempebx, tempeax, templong;
4941 /* si+Ext_ResInfo */
4942 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4943 temp = pVBInfo->RVBHCFACT;
4944 xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp);
4946 tempbx = pVBInfo->RVBHCMAX;
4947 temp = tempbx & 0x00FF;
4948 xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp);
4949 temp2 = ((tempbx & 0xFF00) >> 8) << 7;
4950 tempcx = pVBInfo->VGAHT - 1;
4951 temp = tempcx & 0x00FF;
4952 xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp);
4954 temp = ((tempcx & 0xFF00) >> 8) << 3;
4955 temp2 |= temp;
4957 tempcx = pVBInfo->VGAVT - 1;
4958 if (!(pVBInfo->VBInfo & SetCRT2ToTV))
4959 tempcx -= 5;
4961 temp = tempcx & 0x00FF;
4962 xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp);
4963 temp = temp2 | ((tempcx & 0xFF00) >> 8);
4964 xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp);
4965 xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08);
4966 tempcx = pVBInfo->VBInfo;
4967 tempbx = pVBInfo->VGAHDE;
4969 if (modeflag & HalfDCLK)
4970 tempbx = tempbx >> 1;
4972 if (XGI_IsLCDDualLink(pVBInfo))
4973 tempbx = tempbx >> 1;
4975 if (tempcx & SetCRT2ToHiVision) {
4976 temp = 0;
4977 if (tempbx <= 1024)
4978 temp = 0xA0;
4979 if (tempbx == 1280)
4980 temp = 0xC0;
4981 } else if (tempcx & SetCRT2ToTV) {
4982 temp = 0xA0;
4983 if (tempbx <= 800)
4984 temp = 0x80;
4985 } else {
4986 temp = 0x80;
4987 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4988 temp = 0;
4989 if (tempbx > 800)
4990 temp = 0x60;
4994 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) {
4995 temp = 0x00;
4996 if (pVBInfo->VGAHDE == 1280)
4997 temp = 0x40;
4998 if (pVBInfo->VGAHDE == 1024)
4999 temp = 0x20;
5001 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
5003 tempebx = pVBInfo->VDE;
5005 if (tempcx & SetCRT2ToHiVision) {
5006 if (!(temp & 0xE000))
5007 tempbx = tempbx >> 1;
5010 tempcx = pVBInfo->RVBHRS;
5011 temp = tempcx & 0x00FF;
5012 xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp);
5014 tempeax = pVBInfo->VGAVDE;
5015 tempcx |= 0x04000;
5017 if (tempeax <= tempebx) {
5018 tempcx = (tempcx & (~0x4000));
5019 tempeax = pVBInfo->VGAVDE;
5020 } else {
5021 tempeax -= tempebx;
5024 templong = (tempeax * 256 * 1024) % tempebx;
5025 tempeax = (tempeax * 256 * 1024) / tempebx;
5026 tempebx = tempeax;
5028 if (templong != 0)
5029 tempebx++;
5031 temp = (unsigned short) (tempebx & 0x000000FF);
5032 xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp);
5034 temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8);
5035 xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp);
5036 tempbx = (unsigned short) (tempebx >> 16);
5037 temp = tempbx & 0x00FF;
5038 temp = temp << 4;
5039 temp |= ((tempcx & 0xFF00) >> 8);
5040 xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp);
5042 /* 301b */
5043 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5044 | VB_SIS302LV | VB_XGI301C)) {
5045 temp = 0x0028;
5046 xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp);
5047 tempax = pVBInfo->VGAHDE;
5048 if (modeflag & HalfDCLK)
5049 tempax = tempax >> 1;
5051 if (XGI_IsLCDDualLink(pVBInfo))
5052 tempax = tempax >> 1;
5054 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
5055 if (tempax > 800)
5056 tempax -= 800;
5057 } else {
5058 if (pVBInfo->VGAHDE > 800) {
5059 if (pVBInfo->VGAHDE == 1024)
5060 tempax = (tempax * 25 / 32) - 1;
5061 else
5062 tempax = (tempax * 20 / 32) - 1;
5065 tempax -= 1;
5067 temp = (tempax & 0xFF00) >> 8;
5068 temp = ((temp & 0x0003) << 4);
5069 xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp);
5070 temp = (tempax & 0x00FF);
5071 xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp);
5073 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) {
5074 if (pVBInfo->VGAHDE > 800)
5075 xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08);
5078 temp = 0x0036;
5080 if (pVBInfo->VBInfo & SetCRT2ToTV) {
5081 if (!(pVBInfo->TVInfo & (NTSC1024x768
5082 | TVSetYPbPr525p | TVSetYPbPr750p
5083 | TVSetHiVision))) {
5084 temp |= 0x0001;
5085 if ((pVBInfo->VBInfo & SetInSlaveMode)
5086 && (!(pVBInfo->TVInfo
5087 & TVSimuMode)))
5088 temp &= (~0x0001);
5092 xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
5093 tempbx = pVBInfo->HT;
5094 if (XGI_IsLCDDualLink(pVBInfo))
5095 tempbx = tempbx >> 1;
5096 tempbx = (tempbx >> 1) - 2;
5097 temp = ((tempbx & 0x0700) >> 8) << 3;
5098 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
5099 temp = tempbx & 0x00FF;
5100 xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp);
5102 /* end 301b */
5104 if (pVBInfo->ISXPDOS == 0)
5105 XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5106 pVBInfo);
5109 static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
5111 xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
5114 static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex,
5115 struct vb_device_info *pVBInfo)
5117 unsigned short Pindex, Pdata;
5119 Pindex = pVBInfo->Part5Port;
5120 Pdata = pVBInfo->Part5Port + 1;
5121 if (pVBInfo->ModeType == ModeVGA) {
5122 if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
5123 | DisableCRT2Display))) {
5124 XGINew_EnableCRT2(pVBInfo);
5127 return;
5130 static void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
5131 struct vb_device_info *pVBInfo)
5133 xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x40);
5136 static void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
5137 struct vb_device_info *pVBInfo)
5140 xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00);
5143 static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info,
5144 unsigned short ModeNo, unsigned short ModeIdIndex,
5145 struct vb_device_info *pVBInfo)
5147 unsigned short xres, yres, colordepth, modeflag, resindex;
5149 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
5150 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
5151 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
5152 /* si+St_ModeFlag */
5153 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5155 if (!(modeflag & Charx8Dot)) {
5156 xres /= 9;
5157 xres *= 8;
5160 if ((ModeNo > 0x13) && (modeflag & HalfDCLK))
5161 xres *= 2;
5163 if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
5164 yres *= 2;
5166 if (xres > xgifb_info->lvds_data.LVDSHDE)
5167 return 0;
5169 if (yres > xgifb_info->lvds_data.LVDSVDE)
5170 return 0;
5172 if (xres != xgifb_info->lvds_data.LVDSHDE ||
5173 yres != xgifb_info->lvds_data.LVDSVDE) {
5174 colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
5175 if (colordepth > 2)
5176 return 0;
5178 return 1;
5181 static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
5182 int chip_id,
5183 unsigned short ModeNo,
5184 unsigned short ModeIdIndex,
5185 struct vb_device_info *pVBInfo)
5187 unsigned char temp, Miscdata;
5188 unsigned short xres, yres, modeflag, resindex;
5189 unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
5190 unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
5191 unsigned short value;
5193 temp = (unsigned char) ((xgifb_info->lvds_data.LVDS_Capability &
5194 (LCDPolarity << 8)) >> 8);
5195 temp &= LCDPolarity;
5196 Miscdata = (unsigned char) inb(pVBInfo->P3cc);
5198 outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2);
5200 temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity;
5201 /* SR35[7] FP VSync polarity */
5202 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80);
5203 /* SR30[5] FP HSync polarity */
5204 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1);
5206 if (chip_id == XG27)
5207 XGI_SetXG27FPBits(pVBInfo);
5208 else
5209 XGI_SetXG21FPBits(pVBInfo);
5211 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
5212 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
5213 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
5214 /* si+St_ModeFlag */
5215 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5217 if (!(modeflag & Charx8Dot))
5218 xres = xres * 8 / 9;
5220 LVDSHT = xgifb_info->lvds_data.LVDSHT;
5222 LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2;
5224 if (LVDSHBS > LVDSHT)
5225 LVDSHBS -= LVDSHT;
5227 LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP;
5228 if (LVDSHRS > LVDSHT)
5229 LVDSHRS -= LVDSHT;
5231 LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC;
5232 if (LVDSHRE > LVDSHT)
5233 LVDSHRE -= LVDSHT;
5235 LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE;
5237 LVDSVT = xgifb_info->lvds_data.LVDSVT;
5239 LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2;
5240 if (modeflag & DoubleScanMode)
5241 LVDSVBS += yres / 2;
5243 if (LVDSVBS > LVDSVT)
5244 LVDSVBS -= LVDSVT;
5246 LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP;
5247 if (LVDSVRS > LVDSVT)
5248 LVDSVRS -= LVDSVT;
5250 LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC;
5251 if (LVDSVRE > LVDSVT)
5252 LVDSVRE -= LVDSVT;
5254 LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE;
5256 temp = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
5257 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
5259 if (!(modeflag & Charx8Dot))
5260 xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1);
5262 /* HT SR0B[1:0] CR00 */
5263 value = (LVDSHT >> 3) - 5;
5264 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
5265 xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF));
5267 /* HBS SR0B[5:4] CR02 */
5268 value = (LVDSHBS >> 3) - 1;
5269 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
5270 xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF));
5272 /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
5273 value = (LVDSHBE >> 3) - 1;
5274 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
5275 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
5276 xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
5278 /* HRS SR0B[7:6] CR04 */
5279 value = (LVDSHRS >> 3) + 2;
5280 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
5281 xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF));
5283 /* Panel HRS SR2F[1:0] SR2E[7:0] */
5284 value--;
5285 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
5286 xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF));
5288 /* HRE SR0C[2] CR05[4:0] */
5289 value = (LVDSHRE >> 3) + 2;
5290 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
5291 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
5293 /* Panel HRE SR2F[7:2] */
5294 value--;
5295 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
5297 /* VT SR0A[0] CR07[5][0] CR06 */
5298 value = LVDSVT - 2;
5299 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
5300 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
5301 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
5302 xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF));
5304 /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
5305 value = LVDSVBS - 1;
5306 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
5307 xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
5308 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
5309 xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF));
5311 /* VBE SR0A[4] CR16 */
5312 value = LVDSVBE - 1;
5313 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
5314 xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF));
5316 /* VRS SR0A[3] CR7[7][2] CR10 */
5317 value = LVDSVRS - 1;
5318 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
5319 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
5320 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
5321 xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF));
5323 if (chip_id == XG27) {
5324 /* Panel VRS SR35[2:0] SR34[7:0] */
5325 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07,
5326 (value & 0x700) >> 8);
5327 xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF);
5328 } else {
5329 /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
5330 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03,
5331 (value & 0x600) >> 9);
5332 xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF);
5333 xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01);
5336 /* VRE SR0A[5] CR11[3:0] */
5337 value = LVDSVRE - 1;
5338 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
5339 xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
5341 /* Panel VRE SR3F[7:2] */
5342 if (chip_id == XG27)
5343 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
5344 (value << 2) & 0xFC);
5345 else
5346 /* SR3F[7] has to be 0, h/w bug */
5347 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
5348 (value << 2) & 0x7C);
5350 for (temp = 0, value = 0; temp < 3; temp++) {
5352 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
5353 xgifb_reg_set(pVBInfo->P3c4,
5354 0x2B, xgifb_info->lvds_data.VCLKData1);
5355 xgifb_reg_set(pVBInfo->P3c4,
5356 0x2C, xgifb_info->lvds_data.VCLKData2);
5357 value += 0x10;
5360 if (!(modeflag & Charx8Dot)) {
5361 inb(pVBInfo->P3da); /* reset 3da */
5362 outb(0x13, pVBInfo->P3c0); /* set index */
5363 /* set data, panning = 0, shift left 1 dot*/
5364 outb(0x00, pVBInfo->P3c0);
5366 inb(pVBInfo->P3da); /* Enable Attribute */
5367 outb(0x20, pVBInfo->P3c0);
5369 inb(pVBInfo->P3da); /* reset 3da */
5374 /* --------------------------------------------------------------------- */
5375 /* Function : XGI_IsLCDON */
5376 /* Input : */
5377 /* Output : 0 : Skip PSC Control */
5378 /* 1: Disable PSC */
5379 /* Description : */
5380 /* --------------------------------------------------------------------- */
5381 static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
5383 unsigned short tempax;
5385 tempax = pVBInfo->VBInfo;
5386 if (tempax & SetCRT2ToDualEdge)
5387 return 0;
5388 else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode))
5389 return 1;
5391 return 0;
5394 /* --------------------------------------------------------------------- */
5395 /* Function : XGI_DisableChISLCD */
5396 /* Input : */
5397 /* Output : 0 -> Not LCD Mode */
5398 /* Description : */
5399 /* --------------------------------------------------------------------- */
5400 static unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo)
5402 unsigned short tempbx, tempah;
5404 tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
5405 tempah = ~((unsigned short) xgifb_reg_get(pVBInfo->Part1Port, 0x2E));
5407 if (tempbx & (EnableChA | DisableChA)) {
5408 if (!(tempah & 0x08)) /* Chk LCDA Mode */
5409 return 0;
5412 if (!(tempbx & (EnableChB | DisableChB)))
5413 return 0;
5415 if (tempah & 0x01) /* Chk LCDB Mode */
5416 return 1;
5418 return 0;
5421 /* --------------------------------------------------------------------- */
5422 /* Function : XGI_EnableChISLCD */
5423 /* Input : */
5424 /* Output : 0 -> Not LCD mode */
5425 /* Description : */
5426 /* --------------------------------------------------------------------- */
5427 static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo)
5429 unsigned short tempbx, tempah;
5431 tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
5432 tempah = ~((unsigned short) xgifb_reg_get(pVBInfo->Part1Port, 0x2E));
5434 if (tempbx & (EnableChA | DisableChA)) {
5435 if (!(tempah & 0x08)) /* Chk LCDA Mode */
5436 return 0;
5439 if (!(tempbx & (EnableChB | DisableChB)))
5440 return 0;
5442 if (tempah & 0x01) /* Chk LCDB Mode */
5443 return 1;
5445 return 0;
5448 static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
5449 struct xgi_hw_device_info *HwDeviceExtension,
5450 struct vb_device_info *pVBInfo)
5452 unsigned short tempah = 0;
5454 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5455 | VB_SIS302LV | VB_XGI301C)) {
5456 tempah = 0x3F;
5457 if (!(pVBInfo->VBInfo &
5458 (DisableCRT2Display | SetSimuScanMode))) {
5459 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5460 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
5461 tempah = 0x7F; /* Disable Channel A */
5462 if (!(pVBInfo->VBInfo &
5463 XGI_SetCRT2ToLCDA))
5464 /* Disable Channel B */
5465 tempah = 0xBF;
5467 if (pVBInfo->SetFlag & DisableChB)
5468 /* force to disable Cahnnel */
5469 tempah &= 0xBF;
5471 if (pVBInfo->SetFlag & DisableChA)
5472 /* Force to disable Channel B */
5473 tempah &= 0x7F;
5478 /* disable part4_1f */
5479 xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah);
5481 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
5482 if (((pVBInfo->VBInfo &
5483 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
5484 || (XGI_DisableChISLCD(pVBInfo))
5485 || (XGI_IsLCDON(pVBInfo)))
5486 /* LVDS Driver power down */
5487 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80);
5490 if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
5491 & (DisableCRT2Display | XGI_SetCRT2ToLCDA
5492 | SetSimuScanMode))) {
5493 if (pVBInfo->SetFlag & GatingCRT)
5494 XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
5495 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
5498 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5499 if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
5500 & XGI_SetCRT2ToLCDA))
5501 /* Power down */
5502 xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf);
5505 /* disable TV as primary VGA swap */
5506 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf);
5508 if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
5509 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf);
5511 if ((pVBInfo->SetFlag & DisableChB) ||
5512 (pVBInfo->VBInfo &
5513 (DisableCRT2Display | SetSimuScanMode)) ||
5514 ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
5515 (pVBInfo->VBInfo &
5516 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
5517 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
5519 if ((pVBInfo->SetFlag & DisableChB) ||
5520 (pVBInfo->VBInfo &
5521 (DisableCRT2Display | SetSimuScanMode)) ||
5522 (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) ||
5523 (pVBInfo->VBInfo &
5524 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
5525 /* save Part1 index 0 */
5526 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
5527 /* BTDAC = 1, avoid VB reset */
5528 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10);
5529 /* disable CRT2 */
5530 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
5531 /* restore Part1 index 0 */
5532 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
5534 } else { /* {301} */
5535 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
5536 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
5537 /* Disable CRT2 */
5538 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
5539 /* Disable TV asPrimary VGA swap */
5540 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF);
5543 if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA
5544 | SetSimuScanMode))
5545 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
5549 /* --------------------------------------------------------------------- */
5550 /* Function : XGI_GetTVPtrIndex */
5551 /* Input : */
5552 /* Output : */
5553 /* Description : bx 0 : ExtNTSC */
5554 /* 1 : StNTSC */
5555 /* 2 : ExtPAL */
5556 /* 3 : StPAL */
5557 /* 4 : ExtHiTV */
5558 /* 5 : StHiTV */
5559 /* 6 : Ext525i */
5560 /* 7 : St525i */
5561 /* 8 : Ext525p */
5562 /* 9 : St525p */
5563 /* A : Ext750p */
5564 /* B : St750p */
5565 /* --------------------------------------------------------------------- */
5566 static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
5568 unsigned short tempbx = 0;
5570 if (pVBInfo->TVInfo & TVSetPAL)
5571 tempbx = 2;
5572 if (pVBInfo->TVInfo & TVSetHiVision)
5573 tempbx = 4;
5574 if (pVBInfo->TVInfo & TVSetYPbPr525i)
5575 tempbx = 6;
5576 if (pVBInfo->TVInfo & TVSetYPbPr525p)
5577 tempbx = 8;
5578 if (pVBInfo->TVInfo & TVSetYPbPr750p)
5579 tempbx = 10;
5580 if (pVBInfo->TVInfo & TVSimuMode)
5581 tempbx++;
5583 return tempbx;
5586 /* --------------------------------------------------------------------- */
5587 /* Function : XGI_GetTVPtrIndex2 */
5588 /* Input : */
5589 /* Output : bx 0 : NTSC */
5590 /* 1 : PAL */
5591 /* 2 : PALM */
5592 /* 3 : PALN */
5593 /* 4 : NTSC1024x768 */
5594 /* 5 : PAL-M 1024x768 */
5595 /* 6-7: reserved */
5596 /* cl 0 : YFilter1 */
5597 /* 1 : YFilter2 */
5598 /* ch 0 : 301A */
5599 /* 1 : 301B/302B/301LV/302LV */
5600 /* Description : */
5601 /* --------------------------------------------------------------------- */
5602 static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
5603 unsigned char *tempch, struct vb_device_info *pVBInfo)
5605 *tempbx = 0;
5606 *tempcl = 0;
5607 *tempch = 0;
5609 if (pVBInfo->TVInfo & TVSetPAL)
5610 *tempbx = 1;
5612 if (pVBInfo->TVInfo & TVSetPALM)
5613 *tempbx = 2;
5615 if (pVBInfo->TVInfo & TVSetPALN)
5616 *tempbx = 3;
5618 if (pVBInfo->TVInfo & NTSC1024x768) {
5619 *tempbx = 4;
5620 if (pVBInfo->TVInfo & TVSetPALM)
5621 *tempbx = 5;
5624 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5625 | VB_SIS302LV | VB_XGI301C)) {
5626 if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
5627 & TVSimuMode)) {
5628 *tempbx += 8;
5629 *tempcl += 1;
5633 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5634 | VB_SIS302LV | VB_XGI301C))
5635 (*tempch)++;
5638 static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
5640 unsigned char tempah, tempbl, tempbh;
5642 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5643 | VB_SIS302LV | VB_XGI301C)) {
5644 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA
5645 | SetCRT2ToTV | SetCRT2ToRAMDAC)) {
5646 tempbh = 0;
5647 tempbl = XGI301TVDelay;
5649 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5650 tempbl = tempbl >> 4;
5651 if (pVBInfo->VBInfo &
5652 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
5653 tempbh = XGI301LCDDelay;
5655 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
5656 tempbl = tempbh;
5659 tempbl &= 0x0F;
5660 tempbh &= 0xF0;
5661 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D);
5663 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
5664 | SetCRT2ToTV)) { /* Channel B */
5665 tempah &= 0xF0;
5666 tempah |= tempbl;
5669 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5670 /* Channel A */
5671 tempah &= 0x0F;
5672 tempah |= tempbh;
5674 xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah);
5676 } else if (pVBInfo->IF_DEF_LVDS == 1) {
5677 tempbl = 0;
5678 tempbh = 0;
5679 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
5680 tempah = XGI301LCDDelay;
5681 tempah &= 0x0f;
5682 tempah = tempah << 4;
5683 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2D, 0x0f,
5684 tempah);
5689 static void XGI_SetLCDCap_A(unsigned short tempcx,
5690 struct vb_device_info *pVBInfo)
5692 unsigned short temp;
5694 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
5696 if (temp & LCDRGB18Bit) {
5697 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
5698 /* Enable Dither */
5699 (unsigned short) (0x20 | (tempcx & 0x00C0)));
5700 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
5701 } else {
5702 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
5703 (unsigned short) (0x30 | (tempcx & 0x00C0)));
5704 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
5708 /* --------------------------------------------------------------------- */
5709 /* Function : XGI_SetLCDCap_B */
5710 /* Input : cx -> LCD Capability */
5711 /* Output : */
5712 /* Description : */
5713 /* --------------------------------------------------------------------- */
5714 static void XGI_SetLCDCap_B(unsigned short tempcx,
5715 struct vb_device_info *pVBInfo)
5717 if (tempcx & EnableLCD24bpp) /* 24bits */
5718 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
5719 (unsigned short) (((tempcx & 0x00ff) >> 6)
5720 | 0x0c));
5721 else
5722 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
5723 (unsigned short) (((tempcx & 0x00ff) >> 6)
5724 | 0x18)); /* Enable Dither */
5727 static void XGI_LongWait(struct vb_device_info *pVBInfo)
5729 unsigned short i;
5731 i = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
5733 if (!(i & 0xC0)) {
5734 for (i = 0; i < 0xFFFF; i++) {
5735 if (!(inb(pVBInfo->P3da) & 0x08))
5736 break;
5739 for (i = 0; i < 0xFFFF; i++) {
5740 if ((inb(pVBInfo->P3da) & 0x08))
5741 break;
5746 static void SetSpectrum(struct vb_device_info *pVBInfo)
5748 unsigned short index;
5750 index = XGI_GetLCDCapPtr(pVBInfo);
5752 /* disable down spectrum D[4] */
5753 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F);
5754 XGI_LongWait(pVBInfo);
5755 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
5756 XGI_LongWait(pVBInfo);
5758 xgifb_reg_set(pVBInfo->Part4Port, 0x31,
5759 pVBInfo->LCDCapList[index].Spectrum_31);
5760 xgifb_reg_set(pVBInfo->Part4Port, 0x32,
5761 pVBInfo->LCDCapList[index].Spectrum_32);
5762 xgifb_reg_set(pVBInfo->Part4Port, 0x33,
5763 pVBInfo->LCDCapList[index].Spectrum_33);
5764 xgifb_reg_set(pVBInfo->Part4Port, 0x34,
5765 pVBInfo->LCDCapList[index].Spectrum_34);
5766 XGI_LongWait(pVBInfo);
5767 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
5770 static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
5772 unsigned short tempcx;
5774 tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
5776 if (pVBInfo->VBType &
5777 (VB_SIS301B |
5778 VB_SIS302B |
5779 VB_SIS301LV |
5780 VB_SIS302LV |
5781 VB_XGI301C)) { /* 301LV/302LV only */
5782 if (pVBInfo->VBType &
5783 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
5784 /* Set 301LV Capability */
5785 xgifb_reg_set(pVBInfo->Part4Port, 0x24,
5786 (unsigned char) (tempcx & 0x1F));
5788 /* VB Driving */
5789 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D,
5790 ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
5791 (unsigned short) ((tempcx & (EnableVBCLKDRVLOW
5792 | EnablePLLSPLOW)) >> 8));
5795 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5796 | VB_SIS302LV | VB_XGI301C)) {
5797 if (pVBInfo->VBInfo & SetCRT2ToLCD)
5798 XGI_SetLCDCap_B(tempcx, pVBInfo);
5799 else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
5800 XGI_SetLCDCap_A(tempcx, pVBInfo);
5802 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
5803 if (tempcx & EnableSpectrum)
5804 SetSpectrum(pVBInfo);
5806 } else {
5807 /* LVDS,CH7017 */
5808 XGI_SetLCDCap_A(tempcx, pVBInfo);
5812 /* --------------------------------------------------------------------- */
5813 /* Function : XGI_SetAntiFlicker */
5814 /* Input : */
5815 /* Output : */
5816 /* Description : Set TV Customized Param. */
5817 /* --------------------------------------------------------------------- */
5818 static void XGI_SetAntiFlicker(unsigned short ModeNo,
5819 unsigned short ModeIdIndex,
5820 struct vb_device_info *pVBInfo)
5822 unsigned short tempbx;
5824 unsigned char tempah;
5826 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
5827 return;
5829 tempbx = XGI_GetTVPtrIndex(pVBInfo);
5830 tempbx &= 0xFE;
5831 tempah = TVAntiFlickList[tempbx];
5832 tempah = tempah << 4;
5834 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
5837 static void XGI_SetEdgeEnhance(unsigned short ModeNo,
5838 unsigned short ModeIdIndex,
5839 struct vb_device_info *pVBInfo)
5841 unsigned short tempbx;
5843 unsigned char tempah;
5845 tempbx = XGI_GetTVPtrIndex(pVBInfo);
5846 tempbx &= 0xFE;
5847 tempah = TVEdgeList[tempbx];
5848 tempah = tempah << 5;
5850 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
5853 static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
5855 unsigned short tempbx;
5857 unsigned char tempcl, tempch;
5859 unsigned long tempData;
5861 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
5862 tempData = TVPhaseList[tempbx];
5864 xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData
5865 & 0x000000FF));
5866 xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData
5867 & 0x0000FF00) >> 8));
5868 xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData
5869 & 0x00FF0000) >> 16));
5870 xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData
5871 & 0xFF000000) >> 24));
5874 static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
5875 struct vb_device_info *pVBInfo)
5877 unsigned short tempbx, index;
5879 unsigned char tempcl, tempch, tempal, *filterPtr;
5881 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
5883 switch (tempbx) {
5884 case 0x00:
5885 case 0x04:
5886 filterPtr = NTSCYFilter1;
5887 break;
5889 case 0x01:
5890 filterPtr = PALYFilter1;
5891 break;
5893 case 0x02:
5894 case 0x05:
5895 case 0x0D:
5896 case 0x03:
5897 filterPtr = xgifb_palmn_yfilter1;
5898 break;
5900 case 0x08:
5901 case 0x0C:
5902 case 0x0A:
5903 case 0x0B:
5904 case 0x09:
5905 filterPtr = xgifb_yfilter2;
5906 break;
5908 default:
5909 return;
5912 tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
5913 if (tempcl == 0)
5914 index = tempal * 4;
5915 else
5916 index = tempal * 7;
5918 if ((tempcl == 0) && (tempch == 1)) {
5919 xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0);
5920 xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0);
5921 xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0);
5922 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
5923 } else {
5924 xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
5925 xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
5926 xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
5927 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
5930 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5931 | VB_SIS302LV | VB_XGI301C)) {
5932 xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
5933 xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
5934 xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
5938 /* --------------------------------------------------------------------- */
5939 /* Function : XGI_OEM310Setting */
5940 /* Input : */
5941 /* Output : */
5942 /* Description : Customized Param. for 301 */
5943 /* --------------------------------------------------------------------- */
5944 static void XGI_OEM310Setting(unsigned short ModeNo,
5945 unsigned short ModeIdIndex,
5946 struct vb_device_info *pVBInfo)
5948 XGI_SetDelayComp(pVBInfo);
5950 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
5951 XGI_SetLCDCap(pVBInfo);
5953 if (pVBInfo->VBInfo & SetCRT2ToTV) {
5954 XGI_SetPhaseIncr(pVBInfo);
5955 XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
5956 XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
5958 if (pVBInfo->VBType & VB_SIS301)
5959 XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
5963 /* --------------------------------------------------------------------- */
5964 /* Function : XGI_SetCRT2ModeRegs */
5965 /* Input : */
5966 /* Output : */
5967 /* Description : Origin code for crt2group */
5968 /* --------------------------------------------------------------------- */
5969 static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
5970 struct xgi_hw_device_info *HwDeviceExtension,
5971 struct vb_device_info *pVBInfo)
5973 unsigned short tempbl;
5974 short tempcl;
5976 unsigned char tempah;
5978 tempah = 0;
5979 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5980 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
5981 tempah &= ~0x10; /* BTRAMDAC */
5982 tempah |= 0x40; /* BTRAM */
5984 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
5985 | SetCRT2ToLCD)) {
5986 tempah = 0x40; /* BTDRAM */
5987 tempcl = pVBInfo->ModeType;
5988 tempcl -= ModeVGA;
5989 if (tempcl >= 0) {
5990 /* BT Color */
5991 tempah = (0x008 >> tempcl);
5992 if (tempah == 0)
5993 tempah = 1;
5994 tempah |= 0x040;
5996 if (pVBInfo->VBInfo & SetInSlaveMode)
5997 tempah ^= 0x50; /* BTDAC */
6001 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
6002 tempah = 0x08;
6003 tempbl = 0xf0;
6005 if (pVBInfo->VBInfo & DisableCRT2Display)
6006 goto reg_and_or;
6008 tempah = 0x00;
6009 tempbl = 0xff;
6011 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV |
6012 SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
6013 goto reg_and_or;
6015 if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
6016 (!(pVBInfo->VBInfo & SetSimuScanMode))) {
6017 tempbl &= 0xf7;
6018 tempah |= 0x01;
6019 goto reg_and_or;
6022 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
6023 tempbl &= 0xf7;
6024 tempah |= 0x01;
6027 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)))
6028 goto reg_and_or;
6030 tempbl &= 0xf8;
6031 tempah = 0x01;
6033 if (!(pVBInfo->VBInfo & SetInSlaveMode))
6034 tempah |= 0x02;
6036 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
6037 tempah = tempah ^ 0x05;
6038 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
6039 tempah = tempah ^ 0x01;
6042 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
6043 tempah |= 0x08;
6045 reg_and_or:
6046 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
6048 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
6049 | XGI_SetCRT2ToLCDA)) {
6050 tempah &= (~0x08);
6051 if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
6052 & SetInSlaveMode))) {
6053 tempah |= 0x010;
6055 tempah |= 0x080;
6057 if (pVBInfo->VBInfo & SetCRT2ToTV) {
6058 tempah |= 0x020;
6059 if (pVBInfo->VBInfo & DriverMode)
6060 tempah = tempah ^ 0x20;
6063 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
6064 tempah = 0;
6066 if (pVBInfo->LCDInfo & SetLCDDualLink)
6067 tempah |= 0x40;
6069 if (pVBInfo->VBInfo & SetCRT2ToTV) {
6070 if (pVBInfo->TVInfo & RPLLDIV2XO)
6071 tempah |= 0x40;
6074 if ((pVBInfo->LCDResInfo == Panel_1280x1024)
6075 || (pVBInfo->LCDResInfo == Panel_1280x1024x75))
6076 tempah |= 0x80;
6078 if (pVBInfo->LCDResInfo == Panel_1280x960)
6079 tempah |= 0x80;
6081 xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah);
6084 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
6085 | VB_SIS302LV | VB_XGI301C)) {
6086 tempah = 0;
6087 tempbl = 0xfb;
6089 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
6090 tempbl = 0xff;
6091 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
6092 tempah |= 0x04; /* shampoo 0129 */
6095 xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah);
6096 tempah = 0x00;
6097 tempbl = 0xcf;
6098 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
6099 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
6100 tempah |= 0x30;
6103 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
6104 tempah = 0;
6105 tempbl = 0x3f;
6107 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
6108 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
6109 tempah |= 0xc0;
6111 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah);
6114 tempah = 0;
6115 tempbl = 0x7f;
6116 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) {
6117 tempbl = 0xff;
6118 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
6119 tempah |= 0x80;
6122 xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah);
6124 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
6125 if (pVBInfo->LCDInfo & SetLCDDualLink) {
6126 xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20);
6127 xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10);
6133 void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
6134 struct vb_device_info *pVBInfo)
6137 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
6141 void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
6142 struct vb_device_info *pVBInfo)
6145 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
6149 unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo)
6151 unsigned short flag;
6153 if (pVBInfo->IF_DEF_LVDS == 1) {
6154 return 1;
6155 } else {
6156 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
6157 if ((flag == 1) || (flag == 2))
6158 return 1; /* 301b */
6159 else
6160 return 0;
6164 unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
6165 unsigned short ModeNo, unsigned short ModeIdIndex,
6166 struct vb_device_info *pVBInfo)
6168 short LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 },
6169 LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01,
6170 0x01, 0x01 };
6172 unsigned short RefreshRateTableIndex, i, modeflag, index, temp;
6174 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6176 index = xgifb_reg_get(pVBInfo->P3d4, 0x33);
6177 index = index >> pVBInfo->SelectCRT2Rate;
6178 index &= 0x0F;
6180 if (pVBInfo->LCDInfo & LCDNonExpanding)
6181 index = 0;
6183 if (index > 0)
6184 index--;
6186 if (pVBInfo->SetFlag & ProgrammingCRT2) {
6187 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
6188 if (pVBInfo->IF_DEF_LVDS == 0) {
6189 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
6190 | VB_SIS301LV | VB_SIS302LV
6191 | VB_XGI301C))
6192 /* 301b */
6193 temp = LCDARefreshIndex[
6194 pVBInfo->LCDResInfo & 0x0F];
6195 else
6196 temp = LCDRefreshIndex[
6197 pVBInfo->LCDResInfo & 0x0F];
6199 if (index > temp)
6200 index = temp;
6201 } else {
6202 index = 0;
6207 RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
6208 ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
6209 if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
6210 if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800) &&
6211 (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 600)) {
6212 index++;
6214 /* do the similar adjustment like XGISearchCRT1Rate() */
6215 if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024) &&
6216 (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 768)) {
6217 index++;
6219 if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280) &&
6220 (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 1024)) {
6221 index++;
6225 i = 0;
6226 do {
6227 if (pVBInfo->RefIndex[RefreshRateTableIndex + i].
6228 ModeID != ModeNo)
6229 break;
6230 temp = pVBInfo->RefIndex[RefreshRateTableIndex + i].
6231 Ext_InfoFlag;
6232 temp &= ModeTypeMask;
6233 if (temp < pVBInfo->ModeType)
6234 break;
6235 i++;
6236 index--;
6238 } while (index != 0xFFFF);
6239 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
6240 if (pVBInfo->VBInfo & SetInSlaveMode) {
6241 temp = pVBInfo->RefIndex[RefreshRateTableIndex + i - 1].
6242 Ext_InfoFlag;
6243 if (temp & InterlaceMode)
6244 i++;
6247 i--;
6248 if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
6249 temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex,
6250 RefreshRateTableIndex, &i, pVBInfo);
6252 return RefreshRateTableIndex + i;
6255 static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
6256 struct xgi_hw_device_info *HwDeviceExtension,
6257 struct vb_device_info *pVBInfo)
6259 unsigned short RefreshRateTableIndex;
6261 pVBInfo->SetFlag |= ProgrammingCRT2;
6262 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
6263 ModeIdIndex, pVBInfo);
6264 XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
6265 XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6266 XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6267 HwDeviceExtension, pVBInfo);
6268 XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6269 XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6272 static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
6273 struct xgi_hw_device_info *HwDeviceExtension,
6274 struct vb_device_info *pVBInfo)
6276 unsigned short tempbx, ModeIdIndex, RefreshRateTableIndex;
6278 tempbx = pVBInfo->VBInfo;
6279 pVBInfo->SetFlag |= ProgrammingCRT2;
6280 XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
6281 pVBInfo->SelectCRT2Rate = 4;
6282 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
6283 ModeIdIndex, pVBInfo);
6284 XGI_SaveCRT2Info(ModeNo, pVBInfo);
6285 XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
6286 XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6287 XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
6288 RefreshRateTableIndex, pVBInfo);
6289 XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
6290 RefreshRateTableIndex, pVBInfo);
6291 XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
6292 RefreshRateTableIndex, pVBInfo);
6293 XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6294 HwDeviceExtension, pVBInfo);
6295 XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
6296 RefreshRateTableIndex, pVBInfo);
6297 XGI_SetTap4Regs(pVBInfo);
6298 XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
6299 XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6300 HwDeviceExtension, pVBInfo);
6301 XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
6302 XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
6303 XGI_AutoThreshold(pVBInfo);
6304 return 1;
6307 void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
6309 unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
6310 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
6311 0x05, 0x00 };
6313 unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
6315 unsigned char CR17, CR63, SR31;
6316 unsigned short temp;
6317 unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
6319 int i;
6320 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
6322 /* to fix XG42 single LCD sense to CRT+LCD */
6323 xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A);
6324 xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (xgifb_reg_get(
6325 pVBInfo->P3d4, 0x53) | 0x02));
6327 SR31 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x31);
6328 CR63 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x63);
6329 SR01 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x01);
6331 xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF));
6332 xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF));
6334 CR17 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x17);
6335 xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80));
6337 SR1F = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x1F);
6338 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04));
6340 SR07 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x07);
6341 xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB));
6342 SR06 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x06);
6343 xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3));
6345 xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00);
6347 for (i = 0; i < 8; i++)
6348 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]);
6350 for (i = 8; i < 11; i++)
6351 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 8),
6352 CRTCData[i]);
6354 for (i = 11; i < 13; i++)
6355 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 4),
6356 CRTCData[i]);
6358 for (i = 13; i < 16; i++)
6359 xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i - 3),
6360 CRTCData[i]);
6362 xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16]
6363 & 0xE0));
6365 xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00);
6366 xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B);
6367 xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1);
6369 outb(0x00, pVBInfo->P3c8);
6371 for (i = 0; i < 256; i++) {
6372 outb((unsigned char) DAC_TEST_PARMS[0], (pVBInfo->P3c8 + 1));
6373 outb((unsigned char) DAC_TEST_PARMS[1], (pVBInfo->P3c8 + 1));
6374 outb((unsigned char) DAC_TEST_PARMS[2], (pVBInfo->P3c8 + 1));
6377 mdelay(1);
6379 XGI_WaitDisply(pVBInfo);
6380 temp = inb(pVBInfo->P3c2);
6382 if (temp & 0x10)
6383 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
6384 else
6385 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
6387 /* avoid display something, set BLACK DAC if not restore DAC */
6388 outb(0x00, pVBInfo->P3c8);
6390 for (i = 0; i < 256; i++) {
6391 outb(0, (pVBInfo->P3c8 + 1));
6392 outb(0, (pVBInfo->P3c8 + 1));
6393 outb(0, (pVBInfo->P3c8 + 1));
6396 xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01);
6397 xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63);
6398 xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31);
6400 xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (xgifb_reg_get(
6401 pVBInfo->P3d4, 0x53) & 0xFD));
6402 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
6405 static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
6406 struct xgi_hw_device_info *HwDeviceExtension,
6407 struct vb_device_info *pVBInfo)
6409 unsigned short tempah;
6411 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
6412 | VB_SIS302LV | VB_XGI301C)) {
6413 if (!(pVBInfo->SetFlag & DisableChA)) {
6414 if (pVBInfo->SetFlag & EnableChA) {
6415 /* Power on */
6416 xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20);
6417 } else {
6418 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
6419 /* Power on */
6420 xgifb_reg_set(pVBInfo->Part1Port,
6421 0x1E, 0x20);
6426 if (!(pVBInfo->SetFlag & DisableChB)) {
6427 if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo
6428 & (SetCRT2ToLCD | SetCRT2ToTV
6429 | SetCRT2ToRAMDAC))) {
6430 tempah = (unsigned char) xgifb_reg_get(
6431 pVBInfo->P3c4, 0x32);
6432 tempah &= 0xDF;
6433 if (pVBInfo->VBInfo & SetInSlaveMode) {
6434 if (!(pVBInfo->VBInfo &
6435 SetCRT2ToRAMDAC))
6436 tempah |= 0x20;
6438 xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah);
6439 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20);
6441 tempah = (unsigned char) xgifb_reg_get(
6442 pVBInfo->Part1Port, 0x2E);
6444 if (!(tempah & 0x80))
6445 xgifb_reg_or(pVBInfo->Part1Port,
6446 0x2E, 0x80);
6447 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
6451 if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
6452 || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
6453 xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0,
6454 0x20); /* shampoo 0129 */
6455 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
6456 if (!XGI_DisableChISLCD(pVBInfo)) {
6457 if (XGI_EnableChISLCD(pVBInfo) ||
6458 (pVBInfo->VBInfo &
6459 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
6460 /* LVDS PLL power on */
6461 xgifb_reg_and(
6462 pVBInfo->Part4Port,
6463 0x2A,
6464 0x7F);
6466 /* LVDS Driver power on */
6467 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F);
6471 tempah = 0x00;
6473 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
6474 tempah = 0xc0;
6476 if (!(pVBInfo->VBInfo & SetSimuScanMode) &&
6477 (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
6478 (pVBInfo->VBInfo & SetCRT2ToDualEdge)) {
6479 tempah = tempah & 0x40;
6480 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
6481 tempah = tempah ^ 0xC0;
6483 if (pVBInfo->SetFlag & DisableChB)
6484 tempah &= 0xBF;
6486 if (pVBInfo->SetFlag & DisableChA)
6487 tempah &= 0x7F;
6489 if (pVBInfo->SetFlag & EnableChB)
6490 tempah |= 0x40;
6492 if (pVBInfo->SetFlag & EnableChA)
6493 tempah |= 0x80;
6497 /* EnablePart4_1F */
6498 xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah);
6500 if (!(pVBInfo->SetFlag & DisableChA)) {
6501 if (!(pVBInfo->SetFlag & GatingCRT)) {
6502 XGI_DisableGatingCRT(HwDeviceExtension,
6503 pVBInfo);
6504 XGI_DisplayOn(xgifb_info, HwDeviceExtension,
6505 pVBInfo);
6508 } /* 301 */
6509 else { /* LVDS */
6510 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
6511 | XGI_SetCRT2ToLCDA))
6512 /* enable CRT2 */
6513 xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20);
6515 tempah = (unsigned char) xgifb_reg_get(pVBInfo->Part1Port,
6516 0x2E);
6517 if (!(tempah & 0x80))
6518 xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
6520 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
6521 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
6522 } /* End of VB */
6525 static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
6526 struct xgi_hw_device_info *HwDeviceExtension,
6527 unsigned short ModeNo, unsigned short ModeIdIndex,
6528 struct vb_device_info *pVBInfo)
6530 unsigned short RefreshRateTableIndex, temp;
6532 XGI_SetSeqRegs(ModeNo, ModeIdIndex, pVBInfo);
6533 outb(pVBInfo->StandTable->MISC, pVBInfo->P3c2);
6534 XGI_SetCRTCRegs(HwDeviceExtension, pVBInfo);
6535 XGI_SetATTRegs(ModeNo, ModeIdIndex, pVBInfo);
6536 XGI_SetGRCRegs(pVBInfo);
6537 XGI_ClearExt1Regs(pVBInfo);
6539 if (HwDeviceExtension->jChipType == XG27) {
6540 if (pVBInfo->IF_DEF_LVDS == 0)
6541 XGI_SetDefaultVCLK(pVBInfo);
6544 temp = ~ProgrammingCRT2;
6545 pVBInfo->SetFlag &= temp;
6546 pVBInfo->SelectCRT2Rate = 0;
6548 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
6549 | VB_SIS302LV | VB_XGI301C)) {
6550 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA
6551 | SetInSlaveMode)) {
6552 pVBInfo->SetFlag |= ProgrammingCRT2;
6556 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
6557 ModeIdIndex, pVBInfo);
6558 if (RefreshRateTableIndex != 0xFFFF) {
6559 XGI_SetSync(RefreshRateTableIndex, pVBInfo);
6560 XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6561 pVBInfo, HwDeviceExtension);
6562 XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
6563 RefreshRateTableIndex, pVBInfo);
6564 XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6565 HwDeviceExtension, pVBInfo);
6566 XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
6567 RefreshRateTableIndex, pVBInfo);
6570 if (HwDeviceExtension->jChipType >= XG21) {
6571 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
6572 if (temp & 0xA0) {
6574 if (HwDeviceExtension->jChipType == XG27)
6575 XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
6576 RefreshRateTableIndex, pVBInfo);
6577 else
6578 XGI_SetXG21CRTC(ModeNo, ModeIdIndex,
6579 RefreshRateTableIndex, pVBInfo);
6581 XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
6582 RefreshRateTableIndex);
6584 xgifb_set_lcd(HwDeviceExtension->jChipType,
6585 pVBInfo, RefreshRateTableIndex, ModeNo);
6587 if (pVBInfo->IF_DEF_LVDS == 1)
6588 xgifb_set_lvds(xgifb_info,
6589 HwDeviceExtension->jChipType,
6590 ModeNo, ModeIdIndex, pVBInfo);
6594 pVBInfo->SetFlag &= (~ProgrammingCRT2);
6595 XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
6596 XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
6597 RefreshRateTableIndex, pVBInfo);
6598 XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
6601 unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
6602 struct xgi_hw_device_info *HwDeviceExtension,
6603 unsigned short ModeNo)
6605 unsigned short ModeIdIndex;
6606 struct vb_device_info VBINF;
6607 struct vb_device_info *pVBInfo = &VBINF;
6608 pVBInfo->BaseAddr = xgifb_info->vga_base;
6609 pVBInfo->IF_DEF_LVDS = 0;
6610 pVBInfo->IF_DEF_LCDA = 1;
6612 if (HwDeviceExtension->jChipType >= XG20) {
6613 pVBInfo->IF_DEF_YPbPr = 0;
6614 pVBInfo->IF_DEF_HiVision = 0;
6615 pVBInfo->IF_DEF_CRT2Monitor = 0;
6616 pVBInfo->VBType = 0; /*set VBType default 0*/
6617 } else {
6618 pVBInfo->IF_DEF_YPbPr = 1;
6619 pVBInfo->IF_DEF_HiVision = 1;
6620 pVBInfo->IF_DEF_CRT2Monitor = 1;
6623 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
6624 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
6625 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
6626 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
6627 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
6628 pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C;
6629 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
6630 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
6631 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
6632 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
6633 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
6634 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
6635 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
6636 pVBInfo->Part1Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_04;
6637 pVBInfo->Part2Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_10;
6638 pVBInfo->Part3Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_12;
6639 pVBInfo->Part4Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14;
6640 pVBInfo->Part5Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14 + 2;
6642 /* for x86 Linux, XG21 LVDS */
6643 if (HwDeviceExtension->jChipType == XG21) {
6644 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
6645 pVBInfo->IF_DEF_LVDS = 1;
6647 if (HwDeviceExtension->jChipType == XG27) {
6648 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
6649 if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20)
6650 pVBInfo->IF_DEF_LVDS = 1;
6654 if (HwDeviceExtension->jChipType < XG20)
6655 XGI_GetVBType(pVBInfo);
6657 InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
6658 if (ModeNo & 0x80)
6659 ModeNo = ModeNo & 0x7F;
6660 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
6662 if (HwDeviceExtension->jChipType < XG20)
6663 XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
6665 XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
6667 if (HwDeviceExtension->jChipType < XG20) {
6668 XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
6669 XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
6670 XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
6671 XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
6673 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA)) {
6674 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
6675 ModeIdIndex, pVBInfo);
6677 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
6678 XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
6679 HwDeviceExtension, pVBInfo);
6681 } else {
6682 if (!(pVBInfo->VBInfo & SwitchCRT2)) {
6683 XGI_SetCRT1Group(xgifb_info,
6684 HwDeviceExtension, ModeNo,
6685 ModeIdIndex, pVBInfo);
6686 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
6687 XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
6688 HwDeviceExtension,
6689 pVBInfo);
6694 if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) {
6695 switch (HwDeviceExtension->ujVBChipID) {
6696 case VB_CHIP_301:
6697 XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
6698 pVBInfo); /*add for CRT2 */
6699 break;
6701 case VB_CHIP_302:
6702 XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
6703 pVBInfo); /*add for CRT2 */
6704 break;
6706 default:
6707 break;
6711 XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
6712 XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/
6713 XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
6714 } /* !XG20 */
6715 else {
6716 if (pVBInfo->IF_DEF_LVDS == 1)
6717 if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo,
6718 ModeIdIndex,
6719 pVBInfo))
6720 return 0;
6722 pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex].
6723 Ext_ModeFlag & ModeTypeMask;
6725 pVBInfo->SetFlag = 0;
6726 pVBInfo->VBInfo = DisableCRT2Display;
6728 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
6730 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
6731 ModeIdIndex, pVBInfo);
6733 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
6736 XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
6738 if (HwDeviceExtension->jChipType < XG20)
6739 XGI_LockCRT2(HwDeviceExtension, pVBInfo);
6741 return 1;