]> Pileus Git - ~andy/linux/blob - drivers/staging/xgifb/vb_setmode.c
staging: xgifb: vb_setmode: move functions to avoid forward declarations
[~andy/linux] / drivers / staging / xgifb / vb_setmode.c
1
2 #include <asm/io.h>
3 #include <linux/delay.h>
4 #include <linux/types.h>
5 #include <linux/version.h>
6 #include "XGIfb.h"
7
8
9 #include "vb_def.h"
10 #include "vgatypes.h"
11 #include "vb_struct.h"
12 #include "vb_util.h"
13 #include "vb_table.h"
14 #include "vb_setmode.h"
15
16
17 #define  IndexMask 0xff
18 #ifndef XGI_MASK_DUAL_CHIP
19 #define XGI_MASK_DUAL_CHIP        0x04  /* SR3A */
20 #endif
21
22 static unsigned short XGINew_MDA_DAC[] = {
23         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24         0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
25         0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
26         0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
27         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28         0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
29         0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
30         0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F};
31
32 static unsigned short XGINew_CGA_DAC[] = {
33         0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
34         0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
35         0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
36         0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
37         0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
38         0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
39         0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
40         0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F};
41
42 static unsigned short XGINew_EGA_DAC[] = {
43         0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
44         0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
45         0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
46         0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D,
47         0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17,
48         0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37,
49         0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F,
50         0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F};
51
52 static unsigned short XGINew_VGA_DAC[] = {
53         0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
54         0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
55         0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
56         0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
57         0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
58         0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
59         0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
60         0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
61         0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
62         0x0B, 0x0C, 0x0D, 0x0F, 0x10};
63
64 void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
65 {
66         pVBInfo->SModeIDTable = (struct XGI_StStruct *) XGI330_SModeIDTable;
67         pVBInfo->StandTable = (struct XGI_StandTableStruct *) XGI330_StandTable;
68         pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable;
69         pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex;
70         pVBInfo->XGINEWUB_CRT1Table
71                         = (struct XGI_CRT1TableStruct *) XGI_CRT1Table;
72
73         /* add for new UNIVGABIOS */
74         /* XGINew_UBLCDDataTable = (struct XGI_LCDDataTablStruct *) XGI_LCDDataTable; */
75         /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable; */
76
77         if (ChipType >= XG40) {
78                 pVBInfo->MCLKData
79                         = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData;
80                 pVBInfo->ECLKData
81                         = (struct XGI_ECLKDataStruct *) XGI340_ECLKData;
82         } else {
83                 pVBInfo->MCLKData
84                         = (struct XGI_MCLKDataStruct *) XGI330New_MCLKData;
85                 pVBInfo->ECLKData
86                         = (struct XGI_ECLKDataStruct *) XGI330_ECLKData;
87         }
88
89         pVBInfo->VCLKData = (struct XGI_VCLKDataStruct *) XGI_VCLKData;
90         pVBInfo->VBVCLKData = (struct XGI_VBVCLKDataStruct *) XGI_VBVCLKData;
91         pVBInfo->ScreenOffset = XGI330_ScreenOffset;
92         pVBInfo->StResInfo = (struct XGI_StResInfoStruct *) XGI330_StResInfo;
93         pVBInfo->ModeResInfo
94                         = (struct XGI_ModeResInfoStruct *) XGI330_ModeResInfo;
95
96         pVBInfo->pOutputSelect = &XGI330_OutputSelect;
97         pVBInfo->pSoftSetting = &XGI330_SoftSetting;
98         pVBInfo->pSR07 = &XGI330_SR07;
99         pVBInfo->LCDResInfo = 0;
100         pVBInfo->LCDTypeInfo = 0;
101         pVBInfo->LCDInfo = 0;
102         pVBInfo->VBInfo = 0;
103         pVBInfo->TVInfo = 0;
104
105         pVBInfo->SR15 = XGI340_SR13;
106         pVBInfo->CR40 = XGI340_cr41;
107         pVBInfo->SR25 = XGI330_sr25;
108         pVBInfo->pSR31 = &XGI330_sr31;
109         pVBInfo->pSR32 = &XGI330_sr32;
110         pVBInfo->CR6B = XGI340_CR6B;
111         pVBInfo->CR6E = XGI340_CR6E;
112         pVBInfo->CR6F = XGI340_CR6F;
113         pVBInfo->CR89 = XGI340_CR89;
114         pVBInfo->AGPReg = XGI340_AGPReg;
115         pVBInfo->SR16 = XGI340_SR16;
116         pVBInfo->pCRCF = &XG40_CRCF;
117         pVBInfo->pXGINew_DRAMTypeDefinition = &XG40_DRAMTypeDefinition;
118
119         pVBInfo->CR49 = XGI330_CR49;
120         pVBInfo->pSR1F = &XGI330_SR1F;
121         pVBInfo->pSR21 = &XGI330_SR21;
122         pVBInfo->pSR22 = &XGI330_SR22;
123         pVBInfo->pSR23 = &XGI330_SR23;
124         pVBInfo->pSR24 = &XGI330_SR24;
125         pVBInfo->pSR33 = &XGI330_SR33;
126
127         pVBInfo->pCRT2Data_1_2 = &XGI330_CRT2Data_1_2;
128         pVBInfo->pCRT2Data_4_D = &XGI330_CRT2Data_4_D;
129         pVBInfo->pCRT2Data_4_E = &XGI330_CRT2Data_4_E;
130         pVBInfo->pCRT2Data_4_10 = &XGI330_CRT2Data_4_10;
131         pVBInfo->pRGBSenseData = &XGI330_RGBSenseData;
132         pVBInfo->pVideoSenseData = &XGI330_VideoSenseData;
133         pVBInfo->pYCSenseData = &XGI330_YCSenseData;
134         pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2;
135         pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2;
136         pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2;
137
138         pVBInfo->NTSCTiming = XGI330_NTSCTiming;
139         pVBInfo->PALTiming = XGI330_PALTiming;
140         pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming;
141         pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing;
142         pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing;
143         pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming;
144         pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming;
145         pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming;
146         pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming;
147         pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data;
148         pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu;
149         pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text;
150         pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3;
151         pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3;
152
153         pVBInfo->TimingH = (struct XGI_TimingHStruct *) XGI_TimingH;
154         pVBInfo->TimingV = (struct XGI_TimingVStruct *) XGI_TimingV;
155         pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table;
156
157         pVBInfo->CHTVVCLKUNTSC = XGI330_CHTVVCLKUNTSC;
158         pVBInfo->CHTVVCLKONTSC = XGI330_CHTVVCLKONTSC;
159         pVBInfo->CHTVVCLKUPAL = XGI330_CHTVVCLKUPAL;
160         pVBInfo->CHTVVCLKOPAL = XGI330_CHTVVCLKOPAL;
161
162         /* 310 customization related */
163         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV))
164                 pVBInfo->LCDCapList = XGI_LCDDLCapList;
165         else
166                 pVBInfo->LCDCapList = XGI_LCDCapList;
167
168         if ((ChipType == XG21) || (ChipType == XG27))
169                 pVBInfo->XG21_LVDSCapList = XGI21_LCDCapList;
170
171         pVBInfo->XGI_TVDelayList = XGI301TVDelayList;
172         pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2;
173
174         pVBInfo->pXGINew_I2CDefinition = &XG40_I2CDefinition;
175
176         if (ChipType >= XG20)
177                 pVBInfo->pXGINew_CR97 = &XG20_CR97;
178
179         if (ChipType == XG27) {
180                 pVBInfo->MCLKData
181                         = (struct XGI_MCLKDataStruct *) XGI27New_MCLKData;
182                 pVBInfo->CR40 = XGI27_cr41;
183                 pVBInfo->pXGINew_CR97 = &XG27_CR97;
184                 pVBInfo->pSR36 = &XG27_SR36;
185                 pVBInfo->pCR8F = &XG27_CR8F;
186                 pVBInfo->pCRD0 = XG27_CRD0;
187                 pVBInfo->pCRDE = XG27_CRDE;
188                 pVBInfo->pSR40 = &XG27_SR40;
189                 pVBInfo->pSR41 = &XG27_SR41;
190
191         }
192
193         if (ChipType >= XG20) {
194                 pVBInfo->pDVOSetting = &XG21_DVOSetting;
195                 pVBInfo->pCR2E = &XG21_CR2E;
196                 pVBInfo->pCR2F = &XG21_CR2F;
197                 pVBInfo->pCR46 = &XG21_CR46;
198                 pVBInfo->pCR47 = &XG21_CR47;
199         }
200
201 }
202
203 static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex,
204                 struct vb_device_info *pVBInfo)
205 {
206         unsigned char index;
207
208         if (ModeNo <= 0x13)
209                 index = pVBInfo->SModeIDTable[ModeIdIndex].St_StTableIndex;
210         else {
211                 if (pVBInfo->ModeType <= 0x02)
212                         index = 0x1B; /* 02 -> ModeEGA */
213                 else
214                         index = 0x0F;
215         }
216         return index; /* Get pVBInfo->StandTable index */
217 }
218
219 /*
220 unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex) {
221         return (0);
222 }
223 */
224
225 /* unsigned char XGI_ClearBankRegs(unsigned short ModeNo, unsigned short ModeIdIndex) {
226         return( 0 ) ;
227 }
228 */
229
230 static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex,
231                 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
232 {
233         unsigned char tempah, SRdata;
234
235         unsigned short i, modeflag;
236
237         if (ModeNo <= 0x13)
238                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
239         else
240                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
241
242         XGINew_SetReg1(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
243         tempah = pVBInfo->StandTable[StandTableIndex].SR[0];
244
245         i = SetCRT2ToLCDA;
246         if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
247                 tempah |= 0x01;
248         } else {
249                 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
250                         if (pVBInfo->VBInfo & SetInSlaveMode)
251                                 tempah |= 0x01;
252                 }
253         }
254
255         tempah |= 0x20; /* screen off */
256         XGINew_SetReg1(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */
257
258         for (i = 02; i <= 04; i++) {
259                 SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; /* Get SR2,3,4 from file */
260                 XGINew_SetReg1(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */
261         }
262 }
263
264 static void XGI_SetMiscRegs(unsigned short StandTableIndex,
265                 struct vb_device_info *pVBInfo)
266 {
267         unsigned char Miscdata;
268
269         Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */
270         /*
271         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
272                 if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
273                         Miscdata |= 0x0C;
274                 }
275         }
276         */
277
278         XGINew_SetReg3(pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */
279 }
280
281 static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
282                 unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
283 {
284         unsigned char CRTCdata;
285         unsigned short i;
286
287         CRTCdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
288         CRTCdata &= 0x7f;
289         XGINew_SetReg1(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
290
291         for (i = 0; i <= 0x18; i++) {
292                 CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; /* Get CRTC from file */
293                 XGINew_SetReg1(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
294         }
295         /*
296         if ((HwDeviceExtension->jChipType == XGI_630) && (HwDeviceExtension->jChipRevision == 0x30)) {
297                 if (pVBInfo->VBInfo & SetInSlaveMode) {
298                         if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
299                                 XGINew_SetReg1(pVBInfo->P3d4, 0x18, 0xFE);
300                         }
301                 }
302         }
303         */
304 }
305
306 static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex,
307                 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
308 {
309         unsigned char ARdata;
310         unsigned short i, modeflag;
311
312         if (ModeNo <= 0x13)
313                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
314         else
315                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
316
317         for (i = 0; i <= 0x13; i++) {
318                 ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
319                 if (modeflag & Charx8Dot) { /* ifndef Dot9 */
320                         if (i == 0x13) {
321                                 if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
322                                         ARdata = 0;
323                                 } else {
324                                         if (pVBInfo->VBInfo & (SetCRT2ToTV
325                                                         | SetCRT2ToLCD)) {
326                                                 if (pVBInfo->VBInfo
327                                                                 & SetInSlaveMode)
328                                                         ARdata = 0;
329                                         }
330                                 }
331                         }
332                 }
333
334                 XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
335                 XGINew_SetReg3(pVBInfo->P3c0, i); /* set index */
336                 XGINew_SetReg3(pVBInfo->P3c0, ARdata); /* set data */
337         }
338
339         XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
340         XGINew_SetReg3(pVBInfo->P3c0, 0x14); /* set index */
341         XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data */
342         XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */
343         XGINew_SetReg3(pVBInfo->P3c0, 0x20);
344 }
345
346 static void XGI_SetGRCRegs(unsigned short StandTableIndex,
347                 struct vb_device_info *pVBInfo)
348 {
349         unsigned char GRdata;
350         unsigned short i;
351
352         for (i = 0; i <= 0x08; i++) {
353                 GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; /* Get GR from file */
354                 XGINew_SetReg1(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
355         }
356
357         if (pVBInfo->ModeType > ModeVGA) {
358                 GRdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3ce, 0x05);
359                 GRdata &= 0xBF; /* 256 color disable */
360                 XGINew_SetReg1(pVBInfo->P3ce, 0x05, GRdata);
361         }
362 }
363
364 static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
365 {
366         unsigned short i;
367
368         for (i = 0x0A; i <= 0x0E; i++)
369                 XGINew_SetReg1(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
370 }
371
372 static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
373 {
374
375         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
376         XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B);
377         XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C);
378
379         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
380         XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B);
381         XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C);
382
383         XGINew_SetRegAND(pVBInfo->P3c4, 0x31, ~0x30);
384         return 0;
385 }
386
387 static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
388                 unsigned short ModeIdIndex,
389                 unsigned short RefreshRateTableIndex, unsigned short *i,
390                 struct vb_device_info *pVBInfo)
391 {
392         unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
393
394         if (ModeNo <= 0x13)
395                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
396         else
397                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
398
399         resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
400         tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
401         tempax = 0;
402
403         if (pVBInfo->IF_DEF_LVDS == 0) {
404                 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
405                         tempax |= SupportRAMDAC2;
406
407                         if (pVBInfo->VBType & VB_XGI301C)
408                                 tempax |= SupportCRT2in301C;
409                 }
410
411                 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */
412                         tempax |= SupportLCD;
413
414                         if (pVBInfo->LCDResInfo != Panel1280x1024) {
415                                 if (pVBInfo->LCDResInfo != Panel1280x960) {
416                                         if (pVBInfo->LCDInfo & LCDNonExpanding) {
417                                                 if (resinfo >= 9) {
418                                                         tempax = 0;
419                                                         return 0;
420                                                 }
421                                         }
422                                 }
423                         }
424                 }
425
426                 if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
427                         if ((pVBInfo->VBType & VB_XGI301LV)
428                                         && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
429                                 tempax |= SupportYPbPr;
430                                 if (pVBInfo->VBInfo & SetInSlaveMode) {
431                                         if (resinfo == 4)
432                                                 return 0;
433
434                                         if (resinfo == 3)
435                                                 return 0;
436
437                                         if (resinfo > 7)
438                                                 return 0;
439                                 }
440                         } else {
441                                 tempax |= SupportHiVisionTV;
442                                 if (pVBInfo->VBInfo & SetInSlaveMode) {
443                                         if (resinfo == 4)
444                                                 return 0;
445
446                                         if (resinfo == 3) {
447                                                 if (pVBInfo->SetFlag
448                                                                 & TVSimuMode)
449                                                         return 0;
450                                         }
451
452                                         if (resinfo > 7)
453                                                 return 0;
454                                 }
455                         }
456                 } else {
457                         if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
458                                         | SetCRT2ToSVIDEO | SetCRT2ToSCART
459                                         | SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) {
460                                 tempax |= SupportTV;
461
462                                 if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
463                                                 | VB_XGI301LV | VB_XGI302LV
464                                                 | VB_XGI301C)) {
465                                         tempax |= SupportTV1024;
466                                 }
467
468                                 if (!(pVBInfo->VBInfo & SetPALTV)) {
469                                         if (modeflag & NoSupportSimuTV) {
470                                                 if (pVBInfo->VBInfo
471                                                                 & SetInSlaveMode) {
472                                                         if (!(pVBInfo->VBInfo
473                                                                         & SetNotSimuMode)) {
474                                                                 return 0;
475                                                         }
476                                                 }
477                                         }
478                                 }
479                         }
480                 }
481         } else { /* for LVDS */
482                 if (pVBInfo->IF_DEF_CH7005 == 1) {
483                         if (pVBInfo->VBInfo & SetCRT2ToTV)
484                                 tempax |= SupportCHTV;
485                 }
486
487                 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
488                         tempax |= SupportLCD;
489
490                         if (resinfo > 0x08)
491                                 return 0; /* 1024x768 */
492
493                         if (pVBInfo->LCDResInfo < Panel1024x768) {
494                                 if (resinfo > 0x07)
495                                         return 0; /* 800x600 */
496
497                                 if (resinfo == 0x04)
498                                         return 0; /* 512x384 */
499                         }
500                 }
501         }
502
503         for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx; (*i)--) {
504                 infoflag
505                                 = pVBInfo->RefIndex[RefreshRateTableIndex
506                                                 + (*i)].Ext_InfoFlag;
507                 if (infoflag & tempax)
508                         return 1;
509
510                 if ((*i) == 0)
511                         break;
512         }
513
514         for ((*i) = 0;; (*i)++) {
515                 infoflag
516                                 = pVBInfo->RefIndex[RefreshRateTableIndex
517                                                 + (*i)].Ext_InfoFlag;
518                 if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID
519                                 != tempbx) {
520                         return 0;
521                 }
522
523                 if (infoflag & tempax)
524                         return 1;
525         }
526         return 1;
527 }
528
529 static void XGI_SetSync(unsigned short RefreshRateTableIndex,
530                 struct vb_device_info *pVBInfo)
531 {
532         unsigned short sync, temp;
533
534         sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; /* di+0x00 */
535         sync &= 0xC0;
536         temp = 0x2F;
537         temp |= sync;
538         XGINew_SetReg3(pVBInfo->P3c2, temp); /* Set Misc(3c2) */
539 }
540
541 static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
542                 struct xgi_hw_device_info *HwDeviceExtension)
543 {
544         unsigned char data, data1, pushax;
545         unsigned short i, j;
546
547         /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */
548         /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */
549         /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
550
551         data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
552         data &= 0x7F;
553         XGINew_SetReg1(pVBInfo->P3d4, 0x11, data);
554
555         data = pVBInfo->TimingH[0].data[0];
556         XGINew_SetReg1(pVBInfo->P3d4, 0, data);
557
558         for (i = 0x01; i <= 0x04; i++) {
559                 data = pVBInfo->TimingH[0].data[i];
560                 XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 1), data);
561         }
562
563         for (i = 0x05; i <= 0x06; i++) {
564                 data = pVBInfo->TimingH[0].data[i];
565                 XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i + 6), data);
566         }
567
568         j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
569         j &= 0x1F;
570         data = pVBInfo->TimingH[0].data[7];
571         data &= 0xE0;
572         data |= j;
573         XGINew_SetReg1(pVBInfo->P3c4, 0x0e, data);
574
575         if (HwDeviceExtension->jChipType >= XG20) {
576                 data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x04);
577                 data = data - 1;
578                 XGINew_SetReg1(pVBInfo->P3d4, 0x04, data);
579                 data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x05);
580                 data1 = data;
581                 data1 &= 0xE0;
582                 data &= 0x1F;
583                 if (data == 0) {
584                         pushax = data;
585                         data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4,
586                                         0x0c);
587                         data &= 0xFB;
588                         XGINew_SetReg1(pVBInfo->P3c4, 0x0c, data);
589                         data = pushax;
590                 }
591                 data = data - 1;
592                 data |= data1;
593                 XGINew_SetReg1(pVBInfo->P3d4, 0x05, data);
594                 data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
595                 data = data >> 5;
596                 data = data + 3;
597                 if (data > 7)
598                         data = data - 7;
599                 data = data << 5;
600                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0e, ~0xE0, data);
601         }
602 }
603
604 static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo,
605                 struct vb_device_info *pVBInfo)
606 {
607         unsigned char data;
608         unsigned short i, j;
609
610         /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */
611         /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */
612         /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
613
614         for (i = 0x00; i <= 0x01; i++) {
615                 data = pVBInfo->TimingV[0].data[i];
616                 XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 6), data);
617         }
618
619         for (i = 0x02; i <= 0x03; i++) {
620                 data = pVBInfo->TimingV[0].data[i];
621                 XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
622         }
623
624         for (i = 0x04; i <= 0x05; i++) {
625                 data = pVBInfo->TimingV[0].data[i];
626                 XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
627         }
628
629         j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0a);
630         j &= 0xC0;
631         data = pVBInfo->TimingV[0].data[6];
632         data &= 0x3F;
633         data |= j;
634         XGINew_SetReg1(pVBInfo->P3c4, 0x0a, data);
635
636         data = pVBInfo->TimingV[0].data[6];
637         data &= 0x80;
638         data = data >> 2;
639
640         if (ModeNo <= 0x13)
641                 i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
642         else
643                 i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
644
645         i &= DoubleScanMode;
646         if (i)
647                 data |= 0x80;
648
649         j = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x09);
650         j &= 0x5F;
651         data |= j;
652         XGINew_SetReg1(pVBInfo->P3d4, 0x09, data);
653 }
654
655 static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
656                 unsigned short RefreshRateTableIndex,
657                 struct vb_device_info *pVBInfo,
658                 struct xgi_hw_device_info *HwDeviceExtension)
659 {
660         unsigned char index, data;
661         unsigned short i;
662
663         index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
664         index = index & IndexMask;
665
666         data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
667         data &= 0x7F;
668         XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
669
670         for (i = 0; i < 8; i++)
671                 pVBInfo->TimingH[0].data[i]
672                                 = pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
673
674         for (i = 0; i < 7; i++)
675                 pVBInfo->TimingV[0].data[i]
676                                 = pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
677
678         XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
679
680         XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
681
682         if (pVBInfo->ModeType > 0x03)
683                 XGINew_SetReg1(pVBInfo->P3d4, 0x14, 0x4F);
684 }
685
686 /* --------------------------------------------------------------------- */
687 /* Function : XGI_SetXG21CRTC */
688 /* Input : Stand or enhance CRTC table */
689 /* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
690 /* Description : Set LCD timing */
691 /* --------------------------------------------------------------------- */
692 static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
693                 unsigned short RefreshRateTableIndex,
694                 struct vb_device_info *pVBInfo)
695 {
696         unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
697         unsigned short Temp1, Temp2, Temp3;
698
699         if (ModeNo <= 0x13) {
700                 StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
701                 Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
702                 XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
703                 Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
704                 Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
705                 Tempcx = Tempax;
706                 Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
707                 Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
708                 if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
709                         Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
710                 Tempdx <<= 2; /* Tempdx << 2 */
711                 XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
712                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
713
714                 Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */
715                 Tempbx = Tempax; /* Tempbx=Tempax */
716                 Tempax &= 0x01; /* Tempax: VRS[0] */
717                 XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */
718                 Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax: CR7 VRS */
719                 Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */
720                 Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */
721                 Tempcx <<= 5; /* Tempcx[7]: VRS[8] */
722                 Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */
723                 XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempdx); /* SR34[7:0]: VRS[8:1] */
724
725                 Temp1 = Tempcx << 1; /* Temp1[8]: VRS[8] unsigned char -> unsigned short */
726                 Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
727                 Tempax &= 0x80; /* Tempax[7]: CR7[7] */
728                 Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
729                 Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
730
731                 Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR16 VRE */
732                 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
733                 Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */
734                 Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */
735                 Temp3 = Temp1 & 0x0F; /* Temp3[3:0]: VRS[3:0] */
736                 if (Tempax < Temp3) /* VRE[3:0]<VRS[3:0] */
737                         Temp2 |= 0x10; /* Temp2: VRE + 0x10 */
738                 Temp2 &= 0xFF; /* Temp2[7:0]: VRE[7:0] */
739                 Tempax = (unsigned char) Temp2; /* Tempax[7:0]: VRE[7:0] */
740                 Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
741                 Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
742                 Temp1 >>= 9; /* [10:9]->[1:0] */
743                 Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */
744                 Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */
745                 Tempax &= 0x7F;
746                 XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
747         } else {
748                 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
749                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
750                 Tempcx = Tempax; /* Tempcx: HRS */
751                 XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
752
753                 Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */
754                 Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
755                 Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
756                 Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
757                 Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
758
759                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
760                 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
761
762                 Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
763                 Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
764                 Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
765                 Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
766
767                 Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
768                 Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
769
770                 Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
771                 if (Tempax < Tempcx) /* HRE < HRS */
772                         Temp2 |= 0x40; /* Temp2 + 0x40 */
773
774                 Temp2 &= 0xFF;
775                 Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
776                 Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
777                 Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
778                 Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
779                 XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */
780                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
781
782                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
783                 Tempbx = Tempax; /* Tempbx: VRS */
784                 Tempax &= 0x01; /* Tempax[0]: VRS[0] */
785                 XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
786                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[2][7] VRE */
787                 Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
788                 Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
789                 Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
790                 Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
791                 XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
792
793                 Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
794                 Temp1 <<= 1; /* Temp1[8]: VRS[8] */
795                 Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
796                 Tempax &= 0x80;
797                 Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
798                 Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
799                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SRA */
800                 Tempax &= 0x08; /* Tempax[3]: VRS[3] */
801                 Temp2 = Tempax;
802                 Temp2 <<= 7; /* Temp2[10]: VRS[10] */
803                 Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
804
805                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
806                 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
807                 Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SRA */
808                 Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
809                 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
810                 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
811                 Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
812                 Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
813
814                 Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
815                 if (Tempax < Temp3) /* VRE < VRS */
816                         Temp2 |= 0x20; /* VRE + 0x20 */
817
818                 Temp2 &= 0xFF;
819                 Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
820                 Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
821                 Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
822                 Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
823                 Tempbx = (unsigned char) Temp1;
824                 Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
825                 Tempax &= 0x7F;
826                 XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
827         }
828 }
829
830 static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
831                 unsigned short RefreshRateTableIndex,
832                 struct vb_device_info *pVBInfo)
833 {
834         unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
835
836         if (ModeNo <= 0x13) {
837                 StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
838                 Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
839                 XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
840                 Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
841                 Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
842                 Tempcx = Tempax;
843                 Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
844                 Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
845                 if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
846                         Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
847                 Tempdx <<= 2; /* Tempdx << 2 */
848                 XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
849                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
850
851                 Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR10 VRS */
852                 XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */
853                 Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */
854                 Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */
855                 Tempbx = Tempax; /* Tempbx=CR07 */
856                 Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */
857                 Tempax >>= 2;
858                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35 D[0]->VRS D[8] */
859                 Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */
860                 Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */
861
862                 Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR11 VRE */
863                 Tempax &= 0x0F; /* Tempax: VRE[3:0] */
864                 Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */
865                 Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */
866                 Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */
867                 if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */
868                         Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */
869                 Tempax = (unsigned char) Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */
870                 Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
871                 Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */
872                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F D[7:2]->VRE D[5:0] */
873                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); /* SR35 D[2:1]->VRS[10:9] */
874         } else {
875                 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
876                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
877                 Tempbx = Tempax; /* Tempbx: HRS[7:0] */
878                 XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
879
880                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
881                 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
882                 Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
883
884                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
885                 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
886                 Tempcx = Tempax; /* Tempcx: HRE[4:0] */
887
888                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
889                 Tempax &= 0x04; /* Tempax[2]: HRE[5] */
890                 Tempax <<= 3; /* Tempax[5]: HRE[5] */
891                 Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
892
893                 Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
894                 Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
895
896                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
897                 Tempax &= 0x3F; /* Tempax: HRS[5:0] */
898                 if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
899                         Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
900
901                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
902                 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
903                 Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
904                 Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
905                 XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
906                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
907
908                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
909                 XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */
910
911                 Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
912                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[7][2] VRS[9][8] */
913                 Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
914                 Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
915                 Tempax >>= 2; /* Tempax[0]: VRS[8] */
916                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35[0]: VRS[8] */
917                 Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
918                 Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
919                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SR0A */
920                 Tempax &= 0x08; /* SR0A[3] VRS[10] */
921                 Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
922
923                 Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
924                 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
925                 Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SR0A */
926                 Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
927                 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
928                 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
929                 Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
930                 Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
931                 Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
932
933                 if (Tempbx <= Tempcx) /* VRE <= VRS */
934                         Tempbx |= 0x20; /* VRE + 0x20 */
935
936                 Tempax = (Tempbx << 2) & 0xFF; /* Tempax: Tempax[7:0]; VRE[5:0]00 */
937                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F[7:2]:VRE[5:0] */
938                 Tempax = Tempcx >> 8;
939                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, Tempax); /* SR35[2:0]:VRS[10:8] */
940         }
941 }
942
943 /* --------------------------------------------------------------------- */
944 /* Function : XGI_SetXG21LCD */
945 /* Input : */
946 /* Output : FCLK duty cycle, FCLK delay compensation */
947 /* Description : All values set zero */
948 /* --------------------------------------------------------------------- */
949 static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo,
950                 unsigned short RefreshRateTableIndex, unsigned short ModeNo)
951 {
952         unsigned short Data, Temp, b3CC;
953         unsigned short XGI_P3cc;
954
955         XGI_P3cc = pVBInfo->P3cc;
956
957         XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00);
958         XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00);
959         XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00);
960         XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00);
961         if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) {
962                 XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E);
963                 XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F);
964                 XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46);
965                 XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47);
966         }
967
968         Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
969
970         if (Temp & 0x01) {
971                 XGINew_SetRegOR(pVBInfo->P3c4, 0x06, 0x40); /* 18 bits FP */
972                 XGINew_SetRegOR(pVBInfo->P3c4, 0x09, 0x40);
973         }
974
975         XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
976
977         XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20);
978         XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80);
979
980         if (ModeNo <= 0x13) {
981                 b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
982                 if (b3CC & 0x40)
983                         XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
984                 if (b3CC & 0x80)
985                         XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
986         } else {
987                 Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
988                 if (Data & 0x4000)
989                         XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
990                 if (Data & 0x8000)
991                         XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
992         }
993 }
994
995 static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo,
996                 unsigned short RefreshRateTableIndex, unsigned short ModeNo)
997 {
998         unsigned short Data, Temp, b3CC;
999         unsigned short XGI_P3cc;
1000
1001         XGI_P3cc = pVBInfo->P3cc;
1002
1003         XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00);
1004         XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00);
1005         XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00);
1006         XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00);
1007
1008         Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
1009         if ((Temp & 0x03) == 0) { /* dual 12 */
1010                 XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x13);
1011                 XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x13);
1012         }
1013
1014         if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) {
1015                 XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E);
1016                 XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F);
1017                 XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46);
1018                 XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47);
1019         }
1020
1021         XGI_SetXG27FPBits(pVBInfo);
1022
1023         XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
1024
1025         XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
1026         XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
1027
1028         if (ModeNo <= 0x13) {
1029                 b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
1030                 if (b3CC & 0x40)
1031                         XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
1032                 if (b3CC & 0x80)
1033                         XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
1034         } else {
1035                 Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1036                 if (Data & 0x4000)
1037                         XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
1038                 if (Data & 0x8000)
1039                         XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
1040         }
1041 }
1042
1043 /* --------------------------------------------------------------------- */
1044 /* Function : XGI_UpdateXG21CRTC */
1045 /* Input : */
1046 /* Output : CRT1 CRTC */
1047 /* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
1048 /* --------------------------------------------------------------------- */
1049 static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo,
1050                 unsigned short RefreshRateTableIndex)
1051 {
1052         int i, index = -1;
1053
1054         XGINew_SetRegAND(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
1055         if (ModeNo <= 0x13) {
1056                 for (i = 0; i < 12; i++) {
1057                         if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID)
1058                                 index = i;
1059                 }
1060         } else {
1061                 if (ModeNo == 0x2E
1062                                 && (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
1063                                                 == RES640x480x60))
1064                         index = 12;
1065                 else if (ModeNo == 0x2E
1066                                 && (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
1067                                                 == RES640x480x72))
1068                         index = 13;
1069                 else if (ModeNo == 0x2F)
1070                         index = 14;
1071                 else if (ModeNo == 0x50)
1072                         index = 15;
1073                 else if (ModeNo == 0x59)
1074                         index = 16;
1075         }
1076
1077         if (index != -1) {
1078                 XGINew_SetReg1(pVBInfo->P3d4, 0x02,
1079                                 pVBInfo->UpdateCRT1[index].CR02);
1080                 XGINew_SetReg1(pVBInfo->P3d4, 0x03,
1081                                 pVBInfo->UpdateCRT1[index].CR03);
1082                 XGINew_SetReg1(pVBInfo->P3d4, 0x15,
1083                                 pVBInfo->UpdateCRT1[index].CR15);
1084                 XGINew_SetReg1(pVBInfo->P3d4, 0x16,
1085                                 pVBInfo->UpdateCRT1[index].CR16);
1086         }
1087 }
1088
1089 static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
1090                 unsigned short ModeNo, unsigned short ModeIdIndex,
1091                 unsigned short RefreshRateTableIndex,
1092                 struct vb_device_info *pVBInfo)
1093 {
1094         unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
1095
1096         unsigned char data;
1097
1098         resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
1099
1100         if (ModeNo <= 0x13) {
1101                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
1102                 tempax = pVBInfo->StResInfo[resindex].HTotal;
1103                 tempbx = pVBInfo->StResInfo[resindex].VTotal;
1104         } else {
1105                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1106                 tempax = pVBInfo->ModeResInfo[resindex].HTotal;
1107                 tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
1108         }
1109
1110         if (modeflag & HalfDCLK)
1111                 tempax = tempax >> 1;
1112
1113         if (ModeNo > 0x13) {
1114                 if (modeflag & HalfDCLK)
1115                         tempax = tempax << 1;
1116
1117                 temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1118
1119                 if (temp & InterlaceMode)
1120                         tempbx = tempbx >> 1;
1121
1122                 if (modeflag & DoubleScanMode)
1123                         tempbx = tempbx << 1;
1124         }
1125
1126         tempcx = 8;
1127
1128         /* if (!(modeflag & Charx8Dot)) */
1129         /* tempcx = 9; */
1130
1131         tempax /= tempcx;
1132         tempax -= 1;
1133         tempbx -= 1;
1134         tempcx = tempax;
1135         temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
1136         data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
1137         data &= 0x7F;
1138         XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
1139         XGINew_SetReg1(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
1140         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c,
1141                         (unsigned short) ((tempcx & 0x0ff00) >> 10));
1142         XGINew_SetReg1(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
1143         tempax = 0;
1144         tempbx = tempbx >> 8;
1145
1146         if (tempbx & 0x01)
1147                 tempax |= 0x02;
1148
1149         if (tempbx & 0x02)
1150                 tempax |= 0x40;
1151
1152         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x42, tempax);
1153         data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x07);
1154         data &= 0xFF;
1155         tempax = 0;
1156
1157         if (tempbx & 0x04)
1158                 tempax |= 0x02;
1159
1160         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
1161         XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp);
1162 }
1163
1164 unsigned short XGI_GetResInfo(unsigned short ModeNo,
1165                 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
1166 {
1167         unsigned short resindex;
1168
1169         if (ModeNo <= 0x13)
1170                 resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
1171         else
1172                 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
1173         return resindex;
1174 }
1175
1176 static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex,
1177                 unsigned short RefreshRateTableIndex,
1178                 struct xgi_hw_device_info *HwDeviceExtension,
1179                 struct vb_device_info *pVBInfo)
1180 {
1181         unsigned short temp, ah, al, temp2, i, DisplayUnit;
1182
1183         /* GetOffset */
1184         temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
1185         temp = temp >> 8;
1186         temp = pVBInfo->ScreenOffset[temp];
1187
1188         temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1189         temp2 &= InterlaceMode;
1190
1191         if (temp2)
1192                 temp = temp << 1;
1193
1194         temp2 = pVBInfo->ModeType - ModeEGA;
1195
1196         switch (temp2) {
1197         case 0:
1198                 temp2 = 1;
1199                 break;
1200         case 1:
1201                 temp2 = 2;
1202                 break;
1203         case 2:
1204                 temp2 = 4;
1205                 break;
1206         case 3:
1207                 temp2 = 4;
1208                 break;
1209         case 4:
1210                 temp2 = 6;
1211                 break;
1212         case 5:
1213                 temp2 = 8;
1214                 break;
1215         default:
1216                 break;
1217         }
1218
1219         if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
1220                 temp = temp * temp2 + temp2 / 2;
1221         else
1222                 temp *= temp2;
1223
1224         /* SetOffset */
1225         DisplayUnit = temp;
1226         temp2 = temp;
1227         temp = temp >> 8; /* ah */
1228         temp &= 0x0F;
1229         i = XGINew_GetReg1(pVBInfo->P3c4, 0x0E);
1230         i &= 0xF0;
1231         i |= temp;
1232         XGINew_SetReg1(pVBInfo->P3c4, 0x0E, i);
1233
1234         temp = (unsigned char) temp2;
1235         temp &= 0xFF; /* al */
1236         XGINew_SetReg1(pVBInfo->P3d4, 0x13, temp);
1237
1238         /* SetDisplayUnit */
1239         temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1240         temp2 &= InterlaceMode;
1241         if (temp2)
1242                 DisplayUnit >>= 1;
1243
1244         DisplayUnit = DisplayUnit << 5;
1245         ah = (DisplayUnit & 0xff00) >> 8;
1246         al = DisplayUnit & 0x00ff;
1247         if (al == 0)
1248                 ah += 1;
1249         else
1250                 ah += 2;
1251
1252         if (HwDeviceExtension->jChipType >= XG20)
1253                 if ((ModeNo == 0x4A) | (ModeNo == 0x49))
1254                         ah -= 1;
1255
1256         XGINew_SetReg1(pVBInfo->P3c4, 0x10, ah);
1257 }
1258
1259 static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
1260                 unsigned short ModeIdIndex,
1261                 unsigned short RefreshRateTableIndex,
1262                 struct xgi_hw_device_info *HwDeviceExtension,
1263                 struct vb_device_info *pVBInfo)
1264 {
1265         unsigned short tempbx;
1266
1267         unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
1268                         VCLK65 + 2 };
1269         unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5, VCLK108_2 + 5,
1270                         VCLK108_2 + 5, VCLK108_2 + 5 };
1271         unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 };
1272         unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
1273                         VCLK65 + 2 };
1274         unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
1275                         VCLK65 + 2 };
1276
1277         unsigned short CRT2Index, VCLKIndex;
1278         unsigned short modeflag, resinfo;
1279         unsigned char *CHTVVCLKPtr = NULL;
1280
1281         if (ModeNo <= 0x13) {
1282                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
1283                 resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
1284                 CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
1285         } else {
1286                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
1287                 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
1288                 CRT2Index
1289                                 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1290         }
1291
1292         if (pVBInfo->IF_DEF_LVDS == 0) {
1293                 CRT2Index = CRT2Index >> 6; /*  for LCD */
1294                 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/
1295                         if (pVBInfo->LCDResInfo != Panel1024x768)
1296                                 VCLKIndex = LCDXlat2VCLK[CRT2Index];
1297                         else
1298                                 VCLKIndex = LCDXlat1VCLK[CRT2Index];
1299                 } else { /* for TV */
1300                         if (pVBInfo->VBInfo & SetCRT2ToTV) {
1301                                 if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
1302                                         if (pVBInfo->SetFlag & RPLLDIV2XO) {
1303                                                 VCLKIndex = HiTVVCLKDIV2;
1304
1305                                                 VCLKIndex += 25;
1306
1307                                         } else {
1308                                                 VCLKIndex = HiTVVCLK;
1309
1310                                                 VCLKIndex += 25;
1311
1312                                         }
1313
1314                                         if (pVBInfo->SetFlag & TVSimuMode) {
1315                                                 if (modeflag & Charx8Dot) {
1316                                                         VCLKIndex
1317                                                                         = HiTVSimuVCLK;
1318
1319                                                         VCLKIndex += 25;
1320
1321                                                 } else {
1322                                                         VCLKIndex
1323                                                                         = HiTVTextVCLK;
1324
1325                                                         VCLKIndex += 25;
1326
1327                                                 }
1328                                         }
1329
1330                                         if (pVBInfo->VBType & VB_XGI301LV) { /* 301lv */
1331                                                 if (!(pVBInfo->VBExtInfo
1332                                                                 == VB_YPbPr1080i)) {
1333                                                         VCLKIndex
1334                                                                         = YPbPr750pVCLK;
1335                                                         if (!(pVBInfo->VBExtInfo
1336                                                                         == VB_YPbPr750p)) {
1337                                                                 VCLKIndex
1338                                                                                 = YPbPr525pVCLK;
1339                                                                 if (!(pVBInfo->VBExtInfo
1340                                                                                 == VB_YPbPr525p)) {
1341                                                                         VCLKIndex
1342                                                                                         = YPbPr525iVCLK_2;
1343                                                                         if (!(pVBInfo->SetFlag
1344                                                                                         & RPLLDIV2XO))
1345                                                                                 VCLKIndex
1346                                                                                                 = YPbPr525iVCLK;
1347                                                                 }
1348                                                         }
1349                                                 }
1350                                         }
1351                                 } else {
1352                                         if (pVBInfo->VBInfo & SetCRT2ToTV) {
1353                                                 if (pVBInfo->SetFlag
1354                                                                 & RPLLDIV2XO) {
1355                                                         VCLKIndex = TVVCLKDIV2;
1356
1357                                                         VCLKIndex += 25;
1358
1359                                                 } else {
1360                                                         VCLKIndex = TVVCLK;
1361
1362                                                         VCLKIndex += 25;
1363
1364                                                 }
1365                                         }
1366                                 }
1367                         } else { /* for CRT2 */
1368                                 VCLKIndex = (unsigned char) XGINew_GetReg2(
1369                                                 (pVBInfo->P3ca + 0x02)); /* Port 3cch */
1370                                 VCLKIndex = ((VCLKIndex >> 2) & 0x03);
1371                                 if (ModeNo > 0x13) {
1372                                         VCLKIndex
1373                                                         = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; /* di+Ext_CRTVCLK */
1374                                         VCLKIndex &= IndexMask;
1375                                 }
1376                         }
1377                 }
1378         } else { /* LVDS */
1379                 if (ModeNo <= 0x13)
1380                         VCLKIndex = CRT2Index;
1381                 else
1382                         VCLKIndex = CRT2Index;
1383
1384                 if (pVBInfo->IF_DEF_CH7005 == 1) {
1385                         if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) {
1386                                 VCLKIndex &= 0x1f;
1387                                 tempbx = 0;
1388
1389                                 if (pVBInfo->VBInfo & SetPALTV)
1390                                         tempbx += 2;
1391
1392                                 if (pVBInfo->VBInfo & SetCHTVOverScan)
1393                                         tempbx += 1;
1394
1395                                 switch (tempbx) {
1396                                 case 0:
1397                                         CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC;
1398                                         break;
1399                                 case 1:
1400                                         CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC;
1401                                         break;
1402                                 case 2:
1403                                         CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL;
1404                                         break;
1405                                 case 3:
1406                                         CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL;
1407                                         break;
1408                                 default:
1409                                         break;
1410                                 }
1411
1412                                 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
1413                         }
1414                 } else {
1415                         VCLKIndex = VCLKIndex >> 6;
1416                         if ((pVBInfo->LCDResInfo == Panel800x600)
1417                                         || (pVBInfo->LCDResInfo == Panel320x480))
1418                                 VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
1419                         else if ((pVBInfo->LCDResInfo == Panel1024x768)
1420                                         || (pVBInfo->LCDResInfo
1421                                                         == Panel1024x768x75))
1422                                 VCLKIndex = LVDSXlat2VCLK[VCLKIndex];
1423                         else
1424                                 VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
1425                 }
1426         }
1427         /* VCLKIndex = VCLKIndex&IndexMask; */
1428
1429         return VCLKIndex;
1430 }
1431
1432 static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
1433                 struct xgi_hw_device_info *HwDeviceExtension,
1434                 unsigned short RefreshRateTableIndex,
1435                 struct vb_device_info *pVBInfo)
1436 {
1437         unsigned char index, data;
1438         unsigned short vclkindex;
1439
1440         if (pVBInfo->IF_DEF_LVDS == 1) {
1441                 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1442                 data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF;
1443                 XGINew_SetReg1(pVBInfo->P3c4, 0x31, data);
1444                 XGINew_SetReg1(pVBInfo->P3c4, 0x2B,
1445                                 pVBInfo->VCLKData[index].SR2B);
1446                 XGINew_SetReg1(pVBInfo->P3c4, 0x2C,
1447                                 pVBInfo->VCLKData[index].SR2C);
1448                 XGINew_SetReg1(pVBInfo->P3c4, 0x2D, 0x01);
1449         } else if ((pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
1450                         | VB_XGI302LV | VB_XGI301C)) && (pVBInfo->VBInfo
1451                         & SetCRT2ToLCDA)) {
1452                 vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex,
1453                                 RefreshRateTableIndex, HwDeviceExtension,
1454                                 pVBInfo);
1455                 data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF;
1456                 XGINew_SetReg1(pVBInfo->P3c4, 0x31, data);
1457                 data = pVBInfo->VBVCLKData[vclkindex].Part4_A;
1458                 XGINew_SetReg1(pVBInfo->P3c4, 0x2B, data);
1459                 data = pVBInfo->VBVCLKData[vclkindex].Part4_B;
1460                 XGINew_SetReg1(pVBInfo->P3c4, 0x2C, data);
1461                 XGINew_SetReg1(pVBInfo->P3c4, 0x2D, 0x01);
1462         } else {
1463                 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1464                 data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF;
1465                 XGINew_SetReg1(pVBInfo->P3c4, 0x31, data);
1466                 XGINew_SetReg1(pVBInfo->P3c4, 0x2B,
1467                                 pVBInfo->VCLKData[index].SR2B);
1468                 XGINew_SetReg1(pVBInfo->P3c4, 0x2C,
1469                                 pVBInfo->VCLKData[index].SR2C);
1470                 XGINew_SetReg1(pVBInfo->P3c4, 0x2D, 0x01);
1471         }
1472
1473         if (HwDeviceExtension->jChipType >= XG20) {
1474                 if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK) {
1475                         data = XGINew_GetReg1(pVBInfo->P3c4, 0x2B);
1476                         XGINew_SetReg1(pVBInfo->P3c4, 0x2B, data);
1477                         data = XGINew_GetReg1(pVBInfo->P3c4, 0x2C);
1478                         index = data;
1479                         index &= 0xE0;
1480                         data &= 0x1F;
1481                         data = data << 1;
1482                         data += 1;
1483                         data |= index;
1484                         XGINew_SetReg1(pVBInfo->P3c4, 0x2C, data);
1485                 }
1486         }
1487 }
1488
1489 static void XGI_SetCRT1FIFO(unsigned short ModeNo,
1490                 struct xgi_hw_device_info *HwDeviceExtension,
1491                 struct vb_device_info *pVBInfo)
1492 {
1493         unsigned short data;
1494
1495         data = XGINew_GetReg1(pVBInfo->P3c4, 0x3D);
1496         data &= 0xfe;
1497         XGINew_SetReg1(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
1498
1499         if (ModeNo > 0x13) {
1500                 XGINew_SetReg1(pVBInfo->P3c4, 0x08, 0x34);
1501                 data = XGINew_GetReg1(pVBInfo->P3c4, 0x09);
1502                 data &= 0xC0;
1503                 XGINew_SetReg1(pVBInfo->P3c4, 0x09, data | 0x30);
1504                 data = XGINew_GetReg1(pVBInfo->P3c4, 0x3D);
1505                 data |= 0x01;
1506                 XGINew_SetReg1(pVBInfo->P3c4, 0x3D, data);
1507         } else {
1508                 if (HwDeviceExtension->jChipType == XG27) {
1509                         XGINew_SetReg1(pVBInfo->P3c4, 0x08, 0x0E);
1510                         data = XGINew_GetReg1(pVBInfo->P3c4, 0x09);
1511                         data &= 0xC0;
1512                         XGINew_SetReg1(pVBInfo->P3c4, 0x09, data | 0x20);
1513                 } else {
1514                         XGINew_SetReg1(pVBInfo->P3c4, 0x08, 0xAE);
1515                         data = XGINew_GetReg1(pVBInfo->P3c4, 0x09);
1516                         data &= 0xF0;
1517                         XGINew_SetReg1(pVBInfo->P3c4, 0x09, data);
1518                 }
1519         }
1520
1521         if (HwDeviceExtension->jChipType == XG21)
1522                 XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
1523 }
1524
1525 static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
1526                 unsigned short ModeNo, unsigned short RefreshRateTableIndex,
1527                 struct vb_device_info *pVBInfo)
1528 {
1529         unsigned short data, data2 = 0;
1530         short VCLK;
1531
1532         unsigned char index;
1533
1534         if (ModeNo <= 0x13)
1535                 VCLK = 0;
1536         else {
1537                 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1538                 index &= IndexMask;
1539                 VCLK = pVBInfo->VCLKData[index].CLOCK;
1540         }
1541
1542         data = XGINew_GetReg1(pVBInfo->P3c4, 0x32);
1543         data &= 0xf3;
1544         if (VCLK >= 200)
1545                 data |= 0x0c; /* VCLK > 200 */
1546
1547         if (HwDeviceExtension->jChipType >= XG20)
1548                 data &= ~0x04; /* 2 pixel mode */
1549
1550         XGINew_SetReg1(pVBInfo->P3c4, 0x32, data);
1551
1552         if (HwDeviceExtension->jChipType < XG20) {
1553                 data = XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
1554                 data &= 0xE7;
1555                 if (VCLK < 200)
1556                         data |= 0x10;
1557                 XGINew_SetReg1(pVBInfo->P3c4, 0x1F, data);
1558         }
1559
1560         /*  Jong for Adavantech LCD ripple issue
1561         if ((VCLK >= 0) && (VCLK < 135))
1562                 data2 = 0x03;
1563         else if ((VCLK >= 135) && (VCLK < 160))
1564                 data2 = 0x02;
1565         else if ((VCLK >= 160) && (VCLK < 260))
1566                 data2 = 0x01;
1567         else if (VCLK > 260)
1568                 data2 = 0x00;
1569         */
1570         data2 = 0x00;
1571
1572         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x07, 0xFC, data2);
1573         if (HwDeviceExtension->jChipType >= XG27)
1574                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
1575
1576 }
1577
1578 static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
1579                 unsigned short ModeNo, unsigned short ModeIdIndex,
1580                 unsigned short RefreshRateTableIndex,
1581                 struct vb_device_info *pVBInfo)
1582 {
1583         unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
1584                         xres;
1585
1586         if (ModeNo > 0x13) {
1587                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1588                 infoflag
1589                                 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1590         } else
1591                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
1592
1593         if (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & 0x01)
1594                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
1595
1596         if (ModeNo > 0x13)
1597                 data = infoflag;
1598         else
1599                 data = 0;
1600
1601         data2 = 0;
1602
1603         if (ModeNo > 0x13) {
1604                 if (pVBInfo->ModeType > 0x02) {
1605                         data2 |= 0x02;
1606                         data3 = pVBInfo->ModeType - ModeVGA;
1607                         data3 = data3 << 2;
1608                         data2 |= data3;
1609                 }
1610         }
1611
1612         data &= InterlaceMode;
1613
1614         if (data)
1615                 data2 |= 0x20;
1616
1617         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0x3F, data2);
1618         /* XGINew_SetReg1(pVBInfo->P3c4,0x06,data2); */
1619         resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
1620         if (ModeNo <= 0x13)
1621                 xres = pVBInfo->StResInfo[resindex].HTotal;
1622         else
1623                 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
1624
1625         data = 0x0000;
1626         if (infoflag & InterlaceMode) {
1627                 if (xres == 1024)
1628                         data = 0x0035;
1629                 else if (xres == 1280)
1630                         data = 0x0048;
1631         }
1632
1633         data2 = data & 0x00FF;
1634         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x19, 0xFF, data2);
1635         data2 = (data & 0xFF00) >> 8;
1636         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x19, 0xFC, data2);
1637
1638         if (modeflag & HalfDCLK)
1639                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xF7, 0x08);
1640
1641         data2 = 0;
1642
1643         if (modeflag & LineCompareOff)
1644                 data2 |= 0x08;
1645
1646         if (ModeNo > 0x13) {
1647                 if (pVBInfo->ModeType == ModeEGA)
1648                         data2 |= 0x40;
1649         }
1650
1651         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0F, ~0x48, data2);
1652         data = 0x60;
1653         if (pVBInfo->ModeType != ModeText) {
1654                 data = data ^ 0x60;
1655                 if (pVBInfo->ModeType != ModeEGA)
1656                         data = data ^ 0xA0;
1657         }
1658         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x21, 0x1F, data);
1659
1660         XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
1661                         pVBInfo);
1662
1663         /* if (modeflag&HalfDCLK) //030305 fix lowresolution bug */
1664         /* if (XGINew_IF_DEF_NEW_LOWRES) */
1665         /* XGI_VesaLowResolution(ModeNo, ModeIdIndex); //030305 fix lowresolution bug */
1666
1667         data = XGINew_GetReg1(pVBInfo->P3d4, 0x31);
1668
1669         if (HwDeviceExtension->jChipType == XG27) {
1670                 if (data & 0x40)
1671                         data = 0x2c;
1672                 else
1673                         data = 0x6c;
1674                 XGINew_SetReg1(pVBInfo->P3d4, 0x52, data);
1675                 XGINew_SetRegOR(pVBInfo->P3d4, 0x51, 0x10);
1676         } else if (HwDeviceExtension->jChipType >= XG20) {
1677                 if (data & 0x40)
1678                         data = 0x33;
1679                 else
1680                         data = 0x73;
1681                 XGINew_SetReg1(pVBInfo->P3d4, 0x52, data);
1682                 XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0x02);
1683         } else {
1684                 if (data & 0x40)
1685                         data = 0x2c;
1686                 else
1687                         data = 0x6c;
1688                 XGINew_SetReg1(pVBInfo->P3d4, 0x52, data);
1689         }
1690
1691 }
1692
1693 /*
1694 void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
1695 {
1696         unsigned short modeflag;
1697
1698         if (ModeNo > 0x13)
1699                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1700         else
1701                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
1702
1703         if (ModeNo > 0x13) {
1704                 if (modeflag & DoubleScanMode) {
1705                         if (modeflag & HalfDCLK) {
1706                                 if (pVBInfo->VBType & VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
1707                                         if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
1708                                                 if (pVBInfo->VBInfo & SetInSlaveMode) {
1709                                                         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xf7, 0x00);
1710                                                         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0f, 0x7f, 0x00);
1711                                                         return;
1712                                                 }
1713                                         }
1714                                 }
1715                                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0f, 0xff, 0x80);
1716                                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xf7, 0x00);
1717                                 return;
1718                         }
1719                 }
1720         }
1721         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0f, 0x7f, 0x00);
1722 }
1723 */
1724
1725 static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al,
1726                 unsigned short dh, struct vb_device_info *pVBInfo)
1727 {
1728         unsigned short temp, bh, bl;
1729
1730         bh = ah;
1731         bl = al;
1732
1733         if (dl != 0) {
1734                 temp = bh;
1735                 bh = dh;
1736                 dh = temp;
1737                 if (dl == 1) {
1738                         temp = bl;
1739                         bl = dh;
1740                         dh = temp;
1741                 } else {
1742                         temp = bl;
1743                         bl = bh;
1744                         bh = temp;
1745                 }
1746         }
1747         XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) dh);
1748         XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bh);
1749         XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bl);
1750 }
1751
1752 static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex,
1753                 struct vb_device_info *pVBInfo)
1754 {
1755         unsigned short data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al,
1756                         ah, dh, *table = NULL;
1757
1758         if (ModeNo <= 0x13)
1759                 data = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
1760         else
1761                 data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1762
1763         data &= DACInfoFlag;
1764         time = 64;
1765
1766         if (data == 0x00)
1767                 table = XGINew_MDA_DAC;
1768         else if (data == 0x08)
1769                 table = XGINew_CGA_DAC;
1770         else if (data == 0x10)
1771                 table = XGINew_EGA_DAC;
1772         else if (data == 0x18) {
1773                 time = 256;
1774                 table = XGINew_VGA_DAC;
1775         }
1776
1777         if (time == 256)
1778                 j = 16;
1779         else
1780                 j = time;
1781
1782         XGINew_SetReg3(pVBInfo->P3c6, 0xFF);
1783         XGINew_SetReg3(pVBInfo->P3c8, 0x00);
1784
1785         for (i = 0; i < j; i++) {
1786                 data = table[i];
1787
1788                 for (k = 0; k < 3; k++) {
1789                         data2 = 0;
1790
1791                         if (data & 0x01)
1792                                 data2 = 0x2A;
1793
1794                         if (data & 0x02)
1795                                 data2 += 0x15;
1796
1797                         XGINew_SetReg3(pVBInfo->P3c9, data2);
1798                         data = data >> 2;
1799                 }
1800         }
1801
1802         if (time == 256) {
1803                 for (i = 16; i < 32; i++) {
1804                         data = table[i];
1805
1806                         for (k = 0; k < 3; k++)
1807                                 XGINew_SetReg3(pVBInfo->P3c9, data);
1808                 }
1809
1810                 si = 32;
1811
1812                 for (m = 0; m < 9; m++) {
1813                         di = si;
1814                         bx = si + 0x04;
1815                         dl = 0;
1816
1817                         for (n = 0; n < 3; n++) {
1818                                 for (o = 0; o < 5; o++) {
1819                                         dh = table[si];
1820                                         ah = table[di];
1821                                         al = table[bx];
1822                                         si++;
1823                                         XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1824                                 }
1825
1826                                 si -= 2;
1827
1828                                 for (o = 0; o < 3; o++) {
1829                                         dh = table[bx];
1830                                         ah = table[di];
1831                                         al = table[si];
1832                                         si--;
1833                                         XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1834                                 }
1835
1836                                 dl++;
1837                         }
1838
1839                         si += 5;
1840                 }
1841         }
1842 }
1843
1844 static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
1845                 struct vb_device_info *pVBInfo)
1846 {
1847         unsigned short resindex, xres, yres, modeflag;
1848
1849         if (ModeNo <= 0x13)
1850                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
1851         else
1852                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
1853
1854         /* if (ModeNo > 0x13) */
1855         /*      modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; */
1856         /* else */
1857         /*      modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; */
1858
1859         if (ModeNo <= 0x13)
1860                 resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
1861         else
1862                 resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
1863
1864         /* resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); */
1865
1866         if (ModeNo <= 0x13) {
1867                 xres = pVBInfo->StResInfo[resindex].HTotal;
1868                 yres = pVBInfo->StResInfo[resindex].VTotal;
1869         } else {
1870                 xres = pVBInfo->ModeResInfo[resindex].HTotal;
1871                 yres = pVBInfo->ModeResInfo[resindex].VTotal;
1872         }
1873         if (ModeNo > 0x13) {
1874                 if (modeflag & HalfDCLK)
1875                         xres = xres << 1;
1876
1877                 if (modeflag & DoubleScanMode)
1878                         yres = yres << 1;
1879         }
1880         /* if (modeflag & Charx8Dot) */
1881         /* { */
1882
1883         if (xres == 720)
1884                 xres = 640;
1885
1886         /* } */
1887         pVBInfo->VGAHDE = xres;
1888         pVBInfo->HDE = xres;
1889         pVBInfo->VGAVDE = yres;
1890         pVBInfo->VDE = yres;
1891 }
1892
1893 static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
1894                 unsigned short ModeIdIndex,
1895                 unsigned short RefreshRateTableIndex,
1896                 struct vb_device_info *pVBInfo)
1897 {
1898         unsigned short i, tempdx, tempcx, tempbx, tempal, modeflag, table;
1899
1900         struct XGI330_LCDDataTablStruct *tempdi = NULL;
1901
1902         tempbx = BX;
1903
1904         if (ModeNo <= 0x13) {
1905                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
1906                 tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
1907         } else {
1908                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1909                 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1910         }
1911
1912         tempal = tempal & 0x0f;
1913
1914         if (tempbx <= 1) { /* ExpLink */
1915                 if (ModeNo <= 0x13) {
1916                         tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */
1917                 } else {
1918                         tempal
1919                                         = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1920                 }
1921
1922                 if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
1923                         if (ModeNo <= 0x13)
1924                                 tempal
1925                                                 = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2;
1926                         else
1927                                 tempal
1928                                                 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2;
1929                 }
1930
1931                 if (tempbx & 0x01)
1932                         tempal = (tempal >> 4);
1933
1934                 tempal = (tempal & 0x0f);
1935         }
1936
1937         tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
1938
1939         if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
1940                 if ((tempbx == 5) || (tempbx) == 7)
1941                         tempcx = LCDDesDataLen2;
1942                 else if ((tempbx == 3) || (tempbx == 8))
1943                         tempcx = LVDSDesDataLen2;
1944         }
1945         /* mov di, word ptr cs:LCDDataList[bx] */
1946         /* tempdi = pVideoMemory[LCDDataList + tempbx * 2] | (pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */
1947
1948         switch (tempbx) {
1949         case 0:
1950                 tempdi = XGI_EPLLCDCRT1Ptr_H;
1951                 break;
1952         case 1:
1953                 tempdi = XGI_EPLLCDCRT1Ptr_V;
1954                 break;
1955         case 2:
1956                 tempdi = XGI_EPLLCDDataPtr;
1957                 break;
1958         case 3:
1959                 tempdi = XGI_EPLLCDDesDataPtr;
1960                 break;
1961         case 4:
1962                 tempdi = XGI_LCDDataTable;
1963                 break;
1964         case 5:
1965                 tempdi = XGI_LCDDesDataTable;
1966                 break;
1967         case 6:
1968                 tempdi = XGI_EPLCHLCDRegPtr;
1969                 break;
1970         case 7:
1971         case 8:
1972         case 9:
1973                 tempdi = NULL;
1974                 break;
1975         default:
1976                 break;
1977         }
1978
1979         if (tempdi == NULL) /* OEMUtil */
1980                 return NULL;
1981
1982         table = tempbx;
1983         i = 0;
1984
1985         while (tempdi[i].PANELID != 0xff) {
1986                 tempdx = pVBInfo->LCDResInfo;
1987                 if (tempbx & 0x0080) { /* OEMUtil */
1988                         tempbx &= (~0x0080);
1989                         tempdx = pVBInfo->LCDTypeInfo;
1990                 }
1991
1992                 if (pVBInfo->LCDInfo & EnableScalingLCD)
1993                         tempdx &= (~PanelResInfo);
1994
1995                 if (tempdi[i].PANELID == tempdx) {
1996                         tempbx = tempdi[i].MASK;
1997                         tempdx = pVBInfo->LCDInfo;
1998
1999                         if (ModeNo <= 0x13) /* alan 09/10/2003 */
2000                                 tempdx |= SetLCDStdMode;
2001
2002                         if (modeflag & HalfDCLK)
2003                                 tempdx |= SetLCDLowResolution;
2004
2005                         tempbx &= tempdx;
2006                         if (tempbx == tempdi[i].CAP)
2007                                 break;
2008                 }
2009                 i++;
2010         }
2011
2012         if (table == 0) {
2013                 switch (tempdi[i].DATAPTR) {
2014                 case 0:
2015                         return &XGI_LVDSCRT11024x768_1_H[tempal];
2016                         break;
2017                 case 1:
2018                         return &XGI_LVDSCRT11024x768_2_H[tempal];
2019                         break;
2020                 case 2:
2021                         return &XGI_LVDSCRT11280x1024_1_H[tempal];
2022                         break;
2023                 case 3:
2024                         return &XGI_LVDSCRT11280x1024_2_H[tempal];
2025                         break;
2026                 case 4:
2027                         return &XGI_LVDSCRT11400x1050_1_H[tempal];
2028                         break;
2029                 case 5:
2030                         return &XGI_LVDSCRT11400x1050_2_H[tempal];
2031                         break;
2032                 case 6:
2033                         return &XGI_LVDSCRT11600x1200_1_H[tempal];
2034                         break;
2035                 case 7:
2036                         return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
2037                         break;
2038                 case 8:
2039                         return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
2040                         break;
2041                 case 9:
2042                         return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
2043                         break;
2044                 case 10:
2045                         return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
2046                         break;
2047                 default:
2048                         break;
2049                 }
2050         } else if (table == 1) {
2051                 switch (tempdi[i].DATAPTR) {
2052                 case 0:
2053                         return &XGI_LVDSCRT11024x768_1_V[tempal];
2054                         break;
2055                 case 1:
2056                         return &XGI_LVDSCRT11024x768_2_V[tempal];
2057                         break;
2058                 case 2:
2059                         return &XGI_LVDSCRT11280x1024_1_V[tempal];
2060                         break;
2061                 case 3:
2062                         return &XGI_LVDSCRT11280x1024_2_V[tempal];
2063                         break;
2064                 case 4:
2065                         return &XGI_LVDSCRT11400x1050_1_V[tempal];
2066                         break;
2067                 case 5:
2068                         return &XGI_LVDSCRT11400x1050_2_V[tempal];
2069                         break;
2070                 case 6:
2071                         return &XGI_LVDSCRT11600x1200_1_V[tempal];
2072                         break;
2073                 case 7:
2074                         return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
2075                         break;
2076                 case 8:
2077                         return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
2078                         break;
2079                 case 9:
2080                         return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
2081                         break;
2082                 case 10:
2083                         return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
2084                         break;
2085                 default:
2086                         break;
2087                 }
2088         } else if (table == 2) {
2089                 switch (tempdi[i].DATAPTR) {
2090                 case 0:
2091                         return &XGI_LVDS1024x768Data_1[tempal];
2092                         break;
2093                 case 1:
2094                         return &XGI_LVDS1024x768Data_2[tempal];
2095                         break;
2096                 case 2:
2097                         return &XGI_LVDS1280x1024Data_1[tempal];
2098                         break;
2099                 case 3:
2100                         return &XGI_LVDS1280x1024Data_2[tempal];
2101                         break;
2102                 case 4:
2103                         return &XGI_LVDS1400x1050Data_1[tempal];
2104                         break;
2105                 case 5:
2106                         return &XGI_LVDS1400x1050Data_2[tempal];
2107                         break;
2108                 case 6:
2109                         return &XGI_LVDS1600x1200Data_1[tempal];
2110                         break;
2111                 case 7:
2112                         return &XGI_LVDSNoScalingData[tempal];
2113                         break;
2114                 case 8:
2115                         return &XGI_LVDS1024x768Data_1x75[tempal];
2116                         break;
2117                 case 9:
2118                         return &XGI_LVDS1024x768Data_2x75[tempal];
2119                         break;
2120                 case 10:
2121                         return &XGI_LVDS1280x1024Data_1x75[tempal];
2122                         break;
2123                 case 11:
2124                         return &XGI_LVDS1280x1024Data_2x75[tempal];
2125                         break;
2126                 case 12:
2127                         return &XGI_LVDSNoScalingDatax75[tempal];
2128                         break;
2129                 default:
2130                         break;
2131                 }
2132         } else if (table == 3) {
2133                 switch (tempdi[i].DATAPTR) {
2134                 case 0:
2135                         return &XGI_LVDS1024x768Des_1[tempal];
2136                         break;
2137                 case 1:
2138                         return &XGI_LVDS1024x768Des_3[tempal];
2139                         break;
2140                 case 2:
2141                         return &XGI_LVDS1024x768Des_2[tempal];
2142                         break;
2143                 case 3:
2144                         return &XGI_LVDS1280x1024Des_1[tempal];
2145                         break;
2146                 case 4:
2147                         return &XGI_LVDS1280x1024Des_2[tempal];
2148                         break;
2149                 case 5:
2150                         return &XGI_LVDS1400x1050Des_1[tempal];
2151                         break;
2152                 case 6:
2153                         return &XGI_LVDS1400x1050Des_2[tempal];
2154                         break;
2155                 case 7:
2156                         return &XGI_LVDS1600x1200Des_1[tempal];
2157                         break;
2158                 case 8:
2159                         return &XGI_LVDSNoScalingDesData[tempal];
2160                         break;
2161                 case 9:
2162                         return &XGI_LVDS1024x768Des_1x75[tempal];
2163                         break;
2164                 case 10:
2165                         return &XGI_LVDS1024x768Des_3x75[tempal];
2166                         break;
2167                 case 11:
2168                         return &XGI_LVDS1024x768Des_2x75[tempal];
2169                         break;
2170                 case 12:
2171                         return &XGI_LVDS1280x1024Des_1x75[tempal];
2172                         break;
2173                 case 13:
2174                         return &XGI_LVDS1280x1024Des_2x75[tempal];
2175                         break;
2176                 case 14:
2177                         return &XGI_LVDSNoScalingDesDatax75[tempal];
2178                         break;
2179                 default:
2180                         break;
2181                 }
2182         } else if (table == 4) {
2183                 switch (tempdi[i].DATAPTR) {
2184                 case 0:
2185                         return &XGI_ExtLCD1024x768Data[tempal];
2186                         break;
2187                 case 1:
2188                         return &XGI_StLCD1024x768Data[tempal];
2189                         break;
2190                 case 2:
2191                         return &XGI_CetLCD1024x768Data[tempal];
2192                         break;
2193                 case 3:
2194                         return &XGI_ExtLCD1280x1024Data[tempal];
2195                         break;
2196                 case 4:
2197                         return &XGI_StLCD1280x1024Data[tempal];
2198                         break;
2199                 case 5:
2200                         return &XGI_CetLCD1280x1024Data[tempal];
2201                         break;
2202                 case 6:
2203                         return &XGI_ExtLCD1400x1050Data[tempal];
2204                         break;
2205                 case 7:
2206                         return &XGI_StLCD1400x1050Data[tempal];
2207                         break;
2208                 case 8:
2209                         return &XGI_CetLCD1400x1050Data[tempal];
2210                         break;
2211                 case 9:
2212                         return &XGI_ExtLCD1600x1200Data[tempal];
2213                         break;
2214                 case 10:
2215                         return &XGI_StLCD1600x1200Data[tempal];
2216                         break;
2217                 case 11:
2218                         return &XGI_NoScalingData[tempal];
2219                         break;
2220                 case 12:
2221                         return &XGI_ExtLCD1024x768x75Data[tempal];
2222                         break;
2223                 case 13:
2224                         return &XGI_ExtLCD1024x768x75Data[tempal];
2225                         break;
2226                 case 14:
2227                         return &XGI_CetLCD1024x768x75Data[tempal];
2228                         break;
2229                 case 15:
2230                         return &XGI_ExtLCD1280x1024x75Data[tempal];
2231                         break;
2232                 case 16:
2233                         return &XGI_StLCD1280x1024x75Data[tempal];
2234                         break;
2235                 case 17:
2236                         return &XGI_CetLCD1280x1024x75Data[tempal];
2237                         break;
2238                 case 18:
2239                         return &XGI_NoScalingDatax75[tempal];
2240                         break;
2241                 default:
2242                         break;
2243                 }
2244         } else if (table == 5) {
2245                 switch (tempdi[i].DATAPTR) {
2246                 case 0:
2247                         return &XGI_ExtLCDDes1024x768Data[tempal];
2248                         break;
2249                 case 1:
2250                         return &XGI_StLCDDes1024x768Data[tempal];
2251                         break;
2252                 case 2:
2253                         return &XGI_CetLCDDes1024x768Data[tempal];
2254                         break;
2255                 case 3:
2256                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2257                                         & VB_XGI302LV))
2258                                 return &XGI_ExtLCDDLDes1280x1024Data[tempal];
2259                         else
2260                                 return &XGI_ExtLCDDes1280x1024Data[tempal];
2261                         break;
2262                 case 4:
2263                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2264                                         & VB_XGI302LV))
2265                                 return &XGI_StLCDDLDes1280x1024Data[tempal];
2266                         else
2267                                 return &XGI_StLCDDes1280x1024Data[tempal];
2268                         break;
2269                 case 5:
2270                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2271                                         & VB_XGI302LV))
2272                                 return &XGI_CetLCDDLDes1280x1024Data[tempal];
2273                         else
2274                                 return &XGI_CetLCDDes1280x1024Data[tempal];
2275                         break;
2276                 case 6:
2277                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2278                                         & VB_XGI302LV))
2279                                 return &XGI_ExtLCDDLDes1400x1050Data[tempal];
2280                         else
2281                                 return &XGI_ExtLCDDes1400x1050Data[tempal];
2282                         break;
2283                 case 7:
2284                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2285                                         & VB_XGI302LV))
2286                                 return &XGI_StLCDDLDes1400x1050Data[tempal];
2287                         else
2288                                 return &XGI_StLCDDes1400x1050Data[tempal];
2289                         break;
2290                 case 8:
2291                         return &XGI_CetLCDDes1400x1050Data[tempal];
2292                         break;
2293                 case 9:
2294                         return &XGI_CetLCDDes1400x1050Data2[tempal];
2295                         break;
2296                 case 10:
2297                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2298                                         & VB_XGI302LV))
2299                                 return &XGI_ExtLCDDLDes1600x1200Data[tempal];
2300                         else
2301                                 return &XGI_ExtLCDDes1600x1200Data[tempal];
2302                         break;
2303                 case 11:
2304                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2305                                         & VB_XGI302LV))
2306                                 return &XGI_StLCDDLDes1600x1200Data[tempal];
2307                         else
2308                                 return &XGI_StLCDDes1600x1200Data[tempal];
2309                         break;
2310                 case 12:
2311                         return &XGI_NoScalingDesData[tempal];
2312                         break;
2313                 case 13:
2314                         return &XGI_ExtLCDDes1024x768x75Data[tempal];
2315                         break;
2316                 case 14:
2317                         return &XGI_StLCDDes1024x768x75Data[tempal];
2318                         break;
2319                 case 15:
2320                         return &XGI_CetLCDDes1024x768x75Data[tempal];
2321                         break;
2322                 case 16:
2323                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2324                                         & VB_XGI302LV))
2325                                 return &XGI_ExtLCDDLDes1280x1024x75Data[tempal];
2326                         else
2327                                 return &XGI_ExtLCDDes1280x1024x75Data[tempal];
2328                         break;
2329                 case 17:
2330                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2331                                         & VB_XGI302LV))
2332                                 return &XGI_StLCDDLDes1280x1024x75Data[tempal];
2333                         else
2334                                 return &XGI_StLCDDes1280x1024x75Data[tempal];
2335                         break;
2336                 case 18:
2337                         if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
2338                                         & VB_XGI302LV))
2339                                 return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
2340                         else
2341                                 return &XGI_CetLCDDes1280x1024x75Data[tempal];
2342                         break;
2343                 case 19:
2344                         return &XGI_NoScalingDesDatax75[tempal];
2345                         break;
2346                 default:
2347                         break;
2348                 }
2349         } else if (table == 6) {
2350                 switch (tempdi[i].DATAPTR) {
2351                 case 0:
2352                         return &XGI_CH7017LV1024x768[tempal];
2353                         break;
2354                 case 1:
2355                         return &XGI_CH7017LV1400x1050[tempal];
2356                         break;
2357                 default:
2358                         break;
2359                 }
2360         }
2361         return NULL;
2362 }
2363
2364 static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo,
2365                 unsigned short ModeIdIndex,
2366                 unsigned short RefreshRateTableIndex,
2367                 struct vb_device_info *pVBInfo)
2368 {
2369         unsigned short i, tempdx, tempbx, tempal, modeflag, table;
2370         struct XGI330_TVDataTablStruct *tempdi = NULL;
2371
2372         tempbx = BX;
2373
2374         if (ModeNo <= 0x13) {
2375                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
2376                 tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2377         } else {
2378                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2379                 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2380         }
2381
2382         tempal = tempal & 0x3f;
2383         table = tempbx;
2384
2385         switch (tempbx) {
2386         case 0:
2387                 tempdi = NULL; /*EPLCHTVCRT1Ptr_H;*/
2388                 if (pVBInfo->IF_DEF_CH7007 == 1)
2389                         tempdi = XGI_EPLCHTVCRT1Ptr;
2390
2391                 break;
2392         case 1:
2393                 tempdi = NULL; /*EPLCHTVCRT1Ptr_V;*/
2394                 if (pVBInfo->IF_DEF_CH7007 == 1)
2395                         tempdi = XGI_EPLCHTVCRT1Ptr;
2396
2397                 break;
2398         case 2:
2399                 tempdi = XGI_EPLCHTVDataPtr;
2400                 break;
2401         case 3:
2402                 tempdi = NULL;
2403                 break;
2404         case 4:
2405                 tempdi = XGI_TVDataTable;
2406                 break;
2407         case 5:
2408                 tempdi = NULL;
2409                 break;
2410         case 6:
2411                 tempdi = XGI_EPLCHTVRegPtr;
2412                 break;
2413         default:
2414                 break;
2415         }
2416
2417         if (tempdi == NULL) /* OEMUtil */
2418                 return NULL;
2419
2420         tempdx = pVBInfo->TVInfo;
2421
2422         if (pVBInfo->VBInfo & SetInSlaveMode)
2423                 tempdx = tempdx | SetTVLockMode;
2424
2425         if (modeflag & HalfDCLK)
2426                 tempdx = tempdx | SetTVLowResolution;
2427
2428         i = 0;
2429
2430         while (tempdi[i].MASK != 0xffff) {
2431                 if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
2432                         break;
2433                 i++;
2434         }
2435
2436         if (table == 0x00) { /* 07/05/22 */
2437         } else if (table == 0x01) {
2438         } else if (table == 0x04) {
2439                 switch (tempdi[i].DATAPTR) {
2440                 case 0:
2441                         return &XGI_ExtPALData[tempal];
2442                         break;
2443                 case 1:
2444                         return &XGI_ExtNTSCData[tempal];
2445                         break;
2446                 case 2:
2447                         return &XGI_StPALData[tempal];
2448                         break;
2449                 case 3:
2450                         return &XGI_StNTSCData[tempal];
2451                         break;
2452                 case 4:
2453                         return &XGI_ExtHiTVData[tempal];
2454                         break;
2455                 case 5:
2456                         return &XGI_St2HiTVData[tempal];
2457                         break;
2458                 case 6:
2459                         return &XGI_ExtYPbPr525iData[tempal];
2460                         break;
2461                 case 7:
2462                         return &XGI_ExtYPbPr525pData[tempal];
2463                         break;
2464                 case 8:
2465                         return &XGI_ExtYPbPr750pData[tempal];
2466                         break;
2467                 case 9:
2468                         return &XGI_StYPbPr525iData[tempal];
2469                         break;
2470                 case 10:
2471                         return &XGI_StYPbPr525pData[tempal];
2472                         break;
2473                 case 11:
2474                         return &XGI_StYPbPr750pData[tempal];
2475                         break;
2476                 case 12: /* avoid system hang */
2477                         return &XGI_ExtNTSCData[tempal];
2478                         break;
2479                 case 13:
2480                         return &XGI_St1HiTVData[tempal];
2481                         break;
2482                 default:
2483                         break;
2484                 }
2485         } else if (table == 0x02) {
2486                 switch (tempdi[i].DATAPTR) {
2487                 case 0:
2488                         return &XGI_CHTVUNTSCData[tempal];
2489                         break;
2490                 case 1:
2491                         return &XGI_CHTVONTSCData[tempal];
2492                         break;
2493                 case 2:
2494                         return &XGI_CHTVUPALData[tempal];
2495                         break;
2496                 case 3:
2497                         return &XGI_CHTVOPALData[tempal];
2498                         break;
2499                 default:
2500                         break;
2501                 }
2502         } else if (table == 0x06) {
2503         }
2504         return NULL;
2505 }
2506
2507 static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
2508                 unsigned short RefreshRateTableIndex,
2509                 struct vb_device_info *pVBInfo)
2510 {
2511         unsigned short tempbx;
2512         struct XGI330_LVDSDataStruct *LCDPtr = NULL;
2513         struct XGI330_CHTVDataStruct *TVPtr = NULL;
2514
2515         tempbx = 2;
2516
2517         if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
2518                 LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx,
2519                                 ModeNo, ModeIdIndex, RefreshRateTableIndex,
2520                                 pVBInfo);
2521                 pVBInfo->VGAHT = LCDPtr->VGAHT;
2522                 pVBInfo->VGAVT = LCDPtr->VGAVT;
2523                 pVBInfo->HT = LCDPtr->LCDHT;
2524                 pVBInfo->VT = LCDPtr->LCDVT;
2525         }
2526         if (pVBInfo->IF_DEF_CH7017 == 1) {
2527                 if (pVBInfo->VBInfo & SetCRT2ToTV) {
2528                         TVPtr = (struct XGI330_CHTVDataStruct *) XGI_GetTVPtr(
2529                                         tempbx, ModeNo, ModeIdIndex,
2530                                         RefreshRateTableIndex, pVBInfo);
2531                         pVBInfo->VGAHT = TVPtr->VGAHT;
2532                         pVBInfo->VGAVT = TVPtr->VGAVT;
2533                         pVBInfo->HT = TVPtr->LCDHT;
2534                         pVBInfo->VT = TVPtr->LCDVT;
2535                 }
2536         }
2537
2538         if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
2539                 if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
2540                                 | EnableScalingLCD))) {
2541                         if ((pVBInfo->LCDResInfo == Panel1024x768)
2542                                         || (pVBInfo->LCDResInfo
2543                                                         == Panel1024x768x75)) {
2544                                 pVBInfo->HDE = 1024;
2545                                 pVBInfo->VDE = 768;
2546                         } else if ((pVBInfo->LCDResInfo == Panel1280x1024)
2547                                         || (pVBInfo->LCDResInfo
2548                                                         == Panel1280x1024x75)) {
2549                                 pVBInfo->HDE = 1280;
2550                                 pVBInfo->VDE = 1024;
2551                         } else if (pVBInfo->LCDResInfo == Panel1400x1050) {
2552                                 pVBInfo->HDE = 1400;
2553                                 pVBInfo->VDE = 1050;
2554                         } else {
2555                                 pVBInfo->HDE = 1600;
2556                                 pVBInfo->VDE = 1200;
2557                         }
2558                 }
2559         }
2560 }
2561
2562 static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
2563                 unsigned short RefreshRateTableIndex,
2564                 struct xgi_hw_device_info *HwDeviceExtension,
2565                 struct vb_device_info *pVBInfo)
2566 {
2567         unsigned char index;
2568         unsigned short tempbx, i;
2569         struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
2570         struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
2571         /* struct XGI330_CHTVDataStruct *TVPtr = NULL; */
2572         struct XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL;
2573         struct XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL;
2574
2575         if (ModeNo <= 0x13)
2576                 index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2577         else
2578                 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2579
2580         index = index & IndexMask;
2581
2582         if ((pVBInfo->IF_DEF_ScaleLCD == 0) || ((pVBInfo->IF_DEF_ScaleLCD == 1)
2583                         && (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
2584                 tempbx = 0;
2585
2586                 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
2587                         LCDPtr
2588                                         = (struct XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(
2589                                                         tempbx, ModeNo,
2590                                                         ModeIdIndex,
2591                                                         RefreshRateTableIndex,
2592                                                         pVBInfo);
2593
2594                         for (i = 0; i < 8; i++)
2595                                 pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i];
2596                 }
2597
2598                 if (pVBInfo->IF_DEF_CH7007 == 1) {
2599                         if (pVBInfo->VBInfo & SetCRT2ToTV) {
2600                                 CH7007TV_TimingHPtr
2601                                                 = (struct XGI_CH7007TV_TimingHStruct *) XGI_GetTVPtr(
2602                                                                 tempbx,
2603                                                                 ModeNo,
2604                                                                 ModeIdIndex,
2605                                                                 RefreshRateTableIndex,
2606                                                                 pVBInfo);
2607
2608                                 for (i = 0; i < 8; i++)
2609                                         pVBInfo->TimingH[0].data[i]
2610                                                         = CH7007TV_TimingHPtr[0].data[i];
2611                         }
2612                 }
2613
2614                 /* if (pVBInfo->IF_DEF_CH7017 == 1) {
2615                         if (pVBInfo->VBInfo & SetCRT2ToTV)
2616                                 TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
2617                 }
2618                 */
2619
2620                 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
2621
2622                 if (pVBInfo->IF_DEF_CH7007 == 1) {
2623                         XGINew_SetReg1(pVBInfo->P3c4, 0x2E,
2624                                         CH7007TV_TimingHPtr[0].data[8]);
2625                         XGINew_SetReg1(pVBInfo->P3c4, 0x2F,
2626                                         CH7007TV_TimingHPtr[0].data[9]);
2627                 }
2628
2629                 tempbx = 1;
2630
2631                 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
2632                         LCDPtr1
2633                                         = (struct XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr(
2634                                                         tempbx, ModeNo,
2635                                                         ModeIdIndex,
2636                                                         RefreshRateTableIndex,
2637                                                         pVBInfo);
2638                         for (i = 0; i < 7; i++)
2639                                 pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i];
2640                 }
2641
2642                 if (pVBInfo->IF_DEF_CH7007 == 1) {
2643                         if (pVBInfo->VBInfo & SetCRT2ToTV) {
2644                                 CH7007TV_TimingVPtr
2645                                                 = (struct XGI_CH7007TV_TimingVStruct *) XGI_GetTVPtr(
2646                                                                 tempbx,
2647                                                                 ModeNo,
2648                                                                 ModeIdIndex,
2649                                                                 RefreshRateTableIndex,
2650                                                                 pVBInfo);
2651
2652                                 for (i = 0; i < 7; i++)
2653                                         pVBInfo->TimingV[0].data[i]
2654                                                         = CH7007TV_TimingVPtr[0].data[i];
2655                         }
2656                 }
2657                 /* if (pVBInfo->IF_DEF_CH7017 == 1) {
2658                         if (pVBInfo->VBInfo & SetCRT2ToTV)
2659                                 TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
2660                 }
2661                 */
2662
2663                 XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
2664
2665                 if (pVBInfo->IF_DEF_CH7007 == 1) {
2666                         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x33, ~0x01,
2667                                         CH7007TV_TimingVPtr[0].data[7] & 0x01);
2668                         XGINew_SetReg1(pVBInfo->P3c4, 0x34,
2669                                         CH7007TV_TimingVPtr[0].data[8]);
2670                         XGINew_SetReg1(pVBInfo->P3c4, 0x3F,
2671                                         CH7007TV_TimingVPtr[0].data[9]);
2672
2673                 }
2674         }
2675 }
2676
2677 static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
2678 {
2679         unsigned char tempal, tempah, tempbl, i;
2680
2681         tempah = XGINew_GetReg1(pVBInfo->P3d4, 0x36);
2682         tempal = tempah & 0x0F;
2683         tempah = tempah & 0xF0;
2684         i = 0;
2685         tempbl = pVBInfo->LCDCapList[i].LCD_ID;
2686
2687         while (tempbl != 0xFF) {
2688                 if (tempbl & 0x80) { /* OEMUtil */
2689                         tempal = tempah;
2690                         tempbl = tempbl & ~(0x80);
2691                 }
2692
2693                 if (tempal == tempbl)
2694                         break;
2695
2696                 i++;
2697
2698                 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
2699         }
2700
2701         return i;
2702 }
2703
2704 static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
2705 {
2706         unsigned short tempah, tempal, tempbl, i;
2707
2708         tempal = pVBInfo->LCDResInfo;
2709         tempah = pVBInfo->LCDTypeInfo;
2710
2711         i = 0;
2712         tempbl = pVBInfo->LCDCapList[i].LCD_ID;
2713
2714         while (tempbl != 0xFF) {
2715                 if ((tempbl & 0x80) && (tempbl != 0x80)) {
2716                         tempal = tempah;
2717                         tempbl &= ~0x80;
2718                 }
2719
2720                 if (tempal == tempbl)
2721                         break;
2722
2723                 i++;
2724                 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
2725         }
2726
2727         if (tempbl == 0xFF) {
2728                 pVBInfo->LCDResInfo = Panel1024x768;
2729                 pVBInfo->LCDTypeInfo = 0;
2730                 i = 0;
2731         }
2732
2733         return i;
2734 }
2735
2736 static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth,
2737                 struct vb_device_info *pVBInfo)
2738 {
2739         unsigned short Index;
2740
2741         Index = XGI_GetLCDCapPtr(pVBInfo);
2742         *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
2743         *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
2744
2745         return;
2746 }
2747
2748 static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
2749                 unsigned short RefreshRateTableIndex,
2750                 struct vb_device_info *pVBInfo)
2751 {
2752         unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
2753         unsigned long temp, temp1, temp2, temp3, push3;
2754         struct XGI330_LCDDataDesStruct *LCDPtr = NULL;
2755         struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
2756
2757         if (ModeNo > 0x13)
2758                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2759         else
2760                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
2761
2762         if (!(pVBInfo->SetFlag & Win9xDOSMode)) {
2763                 if ((pVBInfo->IF_DEF_CH7017 == 0) || (pVBInfo->VBInfo
2764                                 & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
2765                         if (pVBInfo->IF_DEF_OEMUtil == 1) {
2766                                 tempbx = 8;
2767                                 LCDPtr
2768                                                 = (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
2769                                                                 tempbx,
2770                                                                 ModeNo,
2771                                                                 ModeIdIndex,
2772                                                                 RefreshRateTableIndex,
2773                                                                 pVBInfo);
2774                         }
2775
2776                         if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == NULL)) {
2777                                 tempbx = 3;
2778                                 if (pVBInfo->LCDInfo & EnableScalingLCD)
2779                                         LCDPtr1
2780                                                         = (struct XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(
2781                                                                         tempbx,
2782                                                                         ModeNo,
2783                                                                         ModeIdIndex,
2784                                                                         RefreshRateTableIndex,
2785                                                                         pVBInfo);
2786                                 else
2787                                         LCDPtr
2788                                                         = (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
2789                                                                         tempbx,
2790                                                                         ModeNo,
2791                                                                         ModeIdIndex,
2792                                                                         RefreshRateTableIndex,
2793                                                                         pVBInfo);
2794                         }
2795
2796                         XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
2797                         push1 = tempbx;
2798                         push2 = tempax;
2799
2800                         /* GetLCDResInfo */
2801                         if ((pVBInfo->LCDResInfo == Panel1024x768)
2802                                         || (pVBInfo->LCDResInfo
2803                                                         == Panel1024x768x75)) {
2804                                 tempax = 1024;
2805                                 tempbx = 768;
2806                         } else if ((pVBInfo->LCDResInfo == Panel1280x1024)
2807                                         || (pVBInfo->LCDResInfo
2808                                                         == Panel1280x1024x75)) {
2809                                 tempax = 1280;
2810                                 tempbx = 1024;
2811                         } else if (pVBInfo->LCDResInfo == Panel1400x1050) {
2812                                 tempax = 1400;
2813                                 tempbx = 1050;
2814                         } else {
2815                                 tempax = 1600;
2816                                 tempbx = 1200;
2817                         }
2818
2819                         if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
2820                                 pVBInfo->HDE = tempax;
2821                                 pVBInfo->VDE = tempbx;
2822                                 pVBInfo->VGAHDE = tempax;
2823                                 pVBInfo->VGAVDE = tempbx;
2824                         }
2825
2826                         if ((pVBInfo->IF_DEF_ScaleLCD == 1)
2827                                         && (pVBInfo->LCDInfo & EnableScalingLCD)) {
2828                                 tempax = pVBInfo->HDE;
2829                                 tempbx = pVBInfo->VDE;
2830                         }
2831
2832                         tempax = pVBInfo->HT;
2833
2834                         if (pVBInfo->LCDInfo & EnableScalingLCD)
2835                                 tempbx = LCDPtr1->LCDHDES;
2836                         else
2837                                 tempbx = LCDPtr->LCDHDES;
2838
2839                         tempcx = pVBInfo->HDE;
2840                         tempbx = tempbx & 0x0fff;
2841                         tempcx += tempbx;
2842
2843                         if (tempcx >= tempax)
2844                                 tempcx -= tempax;
2845
2846                         XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
2847
2848                         tempcx = tempcx >> 3;
2849                         tempbx = tempbx >> 3;
2850
2851                         XGINew_SetReg1(pVBInfo->Part1Port, 0x16,
2852                                         (unsigned short) (tempbx & 0xff));
2853                         XGINew_SetReg1(pVBInfo->Part1Port, 0x17,
2854                                         (unsigned short) (tempcx & 0xff));
2855
2856                         tempax = pVBInfo->HT;
2857
2858                         if (pVBInfo->LCDInfo & EnableScalingLCD)
2859                                 tempbx = LCDPtr1->LCDHRS;
2860                         else
2861                                 tempbx = LCDPtr->LCDHRS;
2862
2863                         tempcx = push2;
2864
2865                         if (pVBInfo->LCDInfo & EnableScalingLCD)
2866                                 tempcx = LCDPtr1->LCDHSync;
2867
2868                         tempcx += tempbx;
2869
2870                         if (tempcx >= tempax)
2871                                 tempcx -= tempax;
2872
2873                         tempax = tempbx & 0x07;
2874                         tempax = tempax >> 5;
2875                         tempcx = tempcx >> 3;
2876                         tempbx = tempbx >> 3;
2877
2878                         tempcx &= 0x1f;
2879                         tempax |= tempcx;
2880
2881                         XGINew_SetReg1(pVBInfo->Part1Port, 0x15, tempax);
2882                         XGINew_SetReg1(pVBInfo->Part1Port, 0x14,
2883                                         (unsigned short) (tempbx & 0xff));
2884
2885                         tempax = pVBInfo->VT;
2886                         if (pVBInfo->LCDInfo & EnableScalingLCD)
2887                                 tempbx = LCDPtr1->LCDVDES;
2888                         else
2889                                 tempbx = LCDPtr->LCDVDES;
2890                         tempcx = pVBInfo->VDE;
2891
2892                         tempbx = tempbx & 0x0fff;
2893                         tempcx += tempbx;
2894                         if (tempcx >= tempax)
2895                                 tempcx -= tempax;
2896
2897                         XGINew_SetReg1(pVBInfo->Part1Port, 0x1b,
2898                                         (unsigned short) (tempbx & 0xff));
2899                         XGINew_SetReg1(pVBInfo->Part1Port, 0x1c,
2900                                         (unsigned short) (tempcx & 0xff));
2901
2902                         tempbx = (tempbx >> 8) & 0x07;
2903                         tempcx = (tempcx >> 8) & 0x07;
2904
2905                         XGINew_SetReg1(pVBInfo->Part1Port, 0x1d,
2906                                         (unsigned short) ((tempcx << 3)
2907                                                         | tempbx));
2908
2909                         tempax = pVBInfo->VT;
2910                         if (pVBInfo->LCDInfo & EnableScalingLCD)
2911                                 tempbx = LCDPtr1->LCDVRS;
2912                         else
2913                                 tempbx = LCDPtr->LCDVRS;
2914
2915                         /* tempbx = tempbx >> 4; */
2916                         tempcx = push1;
2917
2918                         if (pVBInfo->LCDInfo & EnableScalingLCD)
2919                                 tempcx = LCDPtr1->LCDVSync;
2920
2921                         tempcx += tempbx;
2922                         if (tempcx >= tempax)
2923                                 tempcx -= tempax;
2924
2925                         XGINew_SetReg1(pVBInfo->Part1Port, 0x18,
2926                                         (unsigned short) (tempbx & 0xff));
2927                         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f,
2928                                         (unsigned short) (tempcx & 0x0f));
2929
2930                         tempax = ((tempbx >> 8) & 0x07) << 3;
2931
2932                         tempbx = pVBInfo->VGAVDE;
2933                         if (tempbx != pVBInfo->VDE)
2934                                 tempax |= 0x40;
2935
2936                         if (pVBInfo->LCDInfo & EnableLVDSDDA)
2937                                 tempax |= 0x40;
2938
2939                         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1a, 0x07,
2940                                         tempax);
2941
2942                         tempcx = pVBInfo->VGAVT;
2943                         tempbx = pVBInfo->VDE;
2944                         tempax = pVBInfo->VGAVDE;
2945                         tempcx -= tempax;
2946
2947                         temp = tempax; /* 0430 ylshieh */
2948                         temp1 = (temp << 18) / tempbx;
2949
2950                         tempdx = (unsigned short) ((temp << 18) % tempbx);
2951
2952                         if (tempdx != 0)
2953                                 temp1 += 1;
2954
2955                         temp2 = temp1;
2956                         push3 = temp2;
2957
2958                         XGINew_SetReg1(pVBInfo->Part1Port, 0x37,
2959                                         (unsigned short) (temp2 & 0xff));
2960                         XGINew_SetReg1(pVBInfo->Part1Port, 0x36,
2961                                         (unsigned short) ((temp2 >> 8) & 0xff));
2962
2963                         tempbx = (unsigned short) (temp2 >> 16);
2964                         tempax = tempbx & 0x03;
2965
2966                         tempbx = pVBInfo->VGAVDE;
2967                         if (tempbx == pVBInfo->VDE)
2968                                 tempax |= 0x04;
2969
2970                         XGINew_SetReg1(pVBInfo->Part1Port, 0x35, tempax);
2971
2972                         if (pVBInfo->VBType & VB_XGI301C) {
2973                                 temp2 = push3;
2974                                 XGINew_SetReg1(pVBInfo->Part4Port, 0x3c,
2975                                                 (unsigned short) (temp2 & 0xff));
2976                                 XGINew_SetReg1(pVBInfo->Part4Port, 0x3b,
2977                                                 (unsigned short) ((temp2 >> 8)
2978                                                                 & 0xff));
2979                                 tempbx = (unsigned short) (temp2 >> 16);
2980                                 XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x3a,
2981                                                 ~0xc0,
2982                                                 (unsigned short) ((tempbx
2983                                                                 & 0xff) << 6));
2984
2985                                 tempcx = pVBInfo->VGAVDE;
2986                                 if (tempcx == pVBInfo->VDE)
2987                                         XGINew_SetRegANDOR(pVBInfo->Part4Port,
2988                                                         0x30, ~0x0c, 0x00);
2989                                 else
2990                                         XGINew_SetRegANDOR(pVBInfo->Part4Port,
2991                                                         0x30, ~0x0c, 0x08);
2992                         }
2993
2994                         tempcx = pVBInfo->VGAHDE;
2995                         tempbx = pVBInfo->HDE;
2996
2997                         temp1 = tempcx << 16;
2998
2999                         tempax = (unsigned short) (temp1 / tempbx);
3000
3001                         if ((tempbx & 0xffff) == (tempcx & 0xffff))
3002                                 tempax = 65535;
3003
3004                         temp3 = tempax;
3005                         temp1 = pVBInfo->VGAHDE << 16;
3006
3007                         temp1 /= temp3;
3008                         temp3 = temp3 << 16;
3009                         temp1 -= 1;
3010
3011                         temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
3012
3013                         tempax = (unsigned short) (temp3 & 0xff);
3014                         XGINew_SetReg1(pVBInfo->Part1Port, 0x1f, tempax);
3015
3016                         temp1 = pVBInfo->VGAVDE << 18;
3017                         temp1 = temp1 / push3;
3018                         tempbx = (unsigned short) (temp1 & 0xffff);
3019
3020                         if (pVBInfo->LCDResInfo == Panel1024x768)
3021                                 tempbx -= 1;
3022
3023                         tempax = ((tempbx >> 8) & 0xff) << 3;
3024                         tempax |= (unsigned short) ((temp3 >> 8) & 0x07);
3025                         XGINew_SetReg1(pVBInfo->Part1Port, 0x20,
3026                                         (unsigned short) (tempax & 0xff));
3027                         XGINew_SetReg1(pVBInfo->Part1Port, 0x21,
3028                                         (unsigned short) (tempbx & 0xff));
3029
3030                         temp3 = temp3 >> 16;
3031
3032                         if (modeflag & HalfDCLK)
3033                                 temp3 = temp3 >> 1;
3034
3035                         XGINew_SetReg1(pVBInfo->Part1Port, 0x22,
3036                                         (unsigned short) ((temp3 >> 8) & 0xff));
3037                         XGINew_SetReg1(pVBInfo->Part1Port, 0x23,
3038                                         (unsigned short) (temp3 & 0xff));
3039                 }
3040         }
3041 }
3042
3043 /* --------------------------------------------------------------------- */
3044 /* Function : XGI_GETLCDVCLKPtr */
3045 /* Input : */
3046 /* Output : al -> VCLK Index */
3047 /* Description : */
3048 /* --------------------------------------------------------------------- */
3049 static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
3050                 struct vb_device_info *pVBInfo)
3051 {
3052         unsigned short index;
3053
3054         if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
3055                 if (pVBInfo->IF_DEF_ScaleLCD == 1) {
3056                         if (pVBInfo->LCDInfo & EnableScalingLCD)
3057                                 return;
3058                 }
3059
3060                 /* index = XGI_GetLCDCapPtr(pVBInfo); */
3061                 index = XGI_GetLCDCapPtr1(pVBInfo);
3062
3063                 if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
3064                         *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
3065                         *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
3066                 } else { /* LCDA */
3067                         *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
3068                         *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
3069                 }
3070         }
3071         return;
3072 }
3073
3074 static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
3075                 unsigned short ModeNo, unsigned short ModeIdIndex,
3076                 struct vb_device_info *pVBInfo)
3077 {
3078
3079         unsigned short index, modeflag;
3080         unsigned short tempbx;
3081         unsigned char tempal;
3082         unsigned char *CHTVVCLKPtr = NULL;
3083
3084         if (ModeNo <= 0x13)
3085                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
3086         else
3087                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
3088
3089         if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo
3090                         & EnableScalingLCD))) { /* {LCDA/LCDB} */
3091                 index = XGI_GetLCDCapPtr(pVBInfo);
3092                 tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
3093
3094                 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
3095                         return tempal;
3096
3097                 /* {TV} */
3098                 if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
3099                                 | VB_XGI302LV | VB_XGI301C)) {
3100                         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
3101                                 tempal = HiTVVCLKDIV2;
3102                                 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
3103                                         tempal = HiTVVCLK;
3104                                 if (pVBInfo->TVInfo & TVSimuMode) {
3105                                         tempal = HiTVSimuVCLK;
3106                                         if (!(modeflag & Charx8Dot))
3107                                                 tempal = HiTVTextVCLK;
3108
3109                                 }
3110                                 return tempal;
3111                         }
3112
3113                         if (pVBInfo->TVInfo & SetYPbPrMode750p) {
3114                                 tempal = YPbPr750pVCLK;
3115                                 return tempal;
3116                         }
3117
3118                         if (pVBInfo->TVInfo & SetYPbPrMode525p) {
3119                                 tempal = YPbPr525pVCLK;
3120                                 return tempal;
3121                         }
3122
3123                         tempal = NTSC1024VCLK;
3124
3125                         if (!(pVBInfo->TVInfo & NTSC1024x768)) {
3126                                 tempal = TVVCLKDIV2;
3127                                 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
3128                                         tempal = TVVCLK;
3129                         }
3130
3131                         if (pVBInfo->VBInfo & SetCRT2ToTV)
3132                                 return tempal;
3133                 }
3134                 /* else if ((pVBInfo->IF_DEF_CH7017==1)&&(pVBInfo->VBType&VB_CH7017)) {
3135                         if (ModeNo<=0x13)
3136                                 *tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3137                         else
3138                                 *tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3139                         *tempal = *tempal & 0x1F;
3140                         tempbx = 0;
3141                         if (pVBInfo->TVInfo & SetPALTV)
3142                                 tempbx = tempbx + 2;
3143                         if (pVBInfo->TVInfo & SetCHTVOverScan)
3144                                 tempbx++;
3145                         tempbx = tempbx << 1;
3146                 } */
3147         } /* {End of VB} */
3148
3149         if ((pVBInfo->IF_DEF_CH7007 == 1) && (pVBInfo->VBType & VB_CH7007)) { /* [Billy] 07/05/08 CH7007 */
3150                 /* VideoDebugPrint((0, "XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
3151                 if ((pVBInfo->VBInfo & SetCRT2ToTV)) {
3152                         if (ModeNo <= 0x13) {
3153                                 tempal
3154                                                 = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3155                         } else {
3156                                 tempal
3157                                                 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3158                         }
3159
3160                         tempal = tempal & 0x0F;
3161                         tempbx = 0;
3162
3163                         if (pVBInfo->TVInfo & SetPALTV)
3164                                 tempbx = tempbx + 2;
3165
3166                         if (pVBInfo->TVInfo & SetCHTVOverScan)
3167                                 tempbx++;
3168
3169                         /** tempbx = tempbx << 1; CH7007 ? **/
3170
3171                         /* [Billy]07/05/29 CH7007 */
3172                         if (pVBInfo->IF_DEF_CH7007 == 1) {
3173                                 switch (tempbx) {
3174                                 case 0:
3175                                         CHTVVCLKPtr = XGI7007_CHTVVCLKUNTSC;
3176                                         break;
3177                                 case 1:
3178                                         CHTVVCLKPtr = XGI7007_CHTVVCLKONTSC;
3179                                         break;
3180                                 case 2:
3181                                         CHTVVCLKPtr = XGI7007_CHTVVCLKUPAL;
3182                                         break;
3183                                 case 3:
3184                                         CHTVVCLKPtr = XGI7007_CHTVVCLKOPAL;
3185                                         break;
3186                                 default:
3187                                         break;
3188
3189                                 }
3190                         }
3191                         /* else {
3192                                 switch(tempbx) {
3193                                 case 0:
3194                                         CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC;
3195                                         break;
3196                                 case 1:
3197                                         CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC;
3198                                         break;
3199                                 case 2:
3200                                         CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL;
3201                                         break;
3202                                 case 3:
3203                                         CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL;
3204                                         break;
3205                                 default:
3206                                         break;
3207                                 }
3208                         }
3209                         */
3210
3211                         tempal = CHTVVCLKPtr[tempal];
3212                         return tempal;
3213                 }
3214
3215         }
3216
3217         tempal = (unsigned char) XGINew_GetReg2((pVBInfo->P3ca + 0x02));
3218         tempal = tempal >> 2;
3219         tempal &= 0x03;
3220
3221         if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) /* for Dot8 Scaling LCD */
3222                 tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */
3223
3224         if (ModeNo <= 0x13)
3225                 return tempal;
3226
3227         tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
3228         return tempal;
3229 }
3230
3231 static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
3232                 unsigned char *di_1, struct vb_device_info *pVBInfo)
3233 {
3234         if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 2007/05/16 */
3235                 /* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */
3236                 *di_0 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2B;
3237                 *di_1 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2C;
3238         } else if (pVBInfo->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B
3239                         | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
3240                 if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (pVBInfo->SetFlag
3241                                 & ProgrammingCRT2)) {
3242                         *di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B;
3243                         *di_1 = XGI_VBVCLKData[tempal].SR2C;
3244                 }
3245         } else {
3246                 *di_0 = XGI_VCLKData[tempal].SR2B;
3247                 *di_1 = XGI_VCLKData[tempal].SR2C;
3248         }
3249 }
3250
3251 static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex,
3252                 unsigned short RefreshRateTableIndex,
3253                 struct vb_device_info *pVBInfo)
3254 {
3255         unsigned char di_0, di_1, tempal;
3256         int i;
3257
3258         tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
3259                         pVBInfo);
3260         XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
3261         XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
3262
3263         for (i = 0; i < 4; i++) {
3264                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30,
3265                                 (unsigned short) (0x10 * i));
3266                 if (pVBInfo->IF_DEF_CH7007 == 1) {
3267                         XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0);
3268                         XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1);
3269                 } else if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
3270                                 && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
3271                         XGINew_SetReg1(pVBInfo->P3c4, 0x2e, di_0);
3272                         XGINew_SetReg1(pVBInfo->P3c4, 0x2f, di_1);
3273                 } else {
3274                         XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0);
3275                         XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1);
3276                 }
3277         }
3278 }
3279
3280 static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
3281                 struct vb_device_info *pVBInfo)
3282 {
3283         unsigned short tempcl, tempch, temp, tempbl, tempax;
3284
3285         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
3286                         | VB_XGI302LV | VB_XGI301C)) {
3287                 tempcl = 0;
3288                 tempch = 0;
3289                 temp = XGINew_GetReg1(pVBInfo->P3c4, 0x01);
3290
3291                 if (!(temp & 0x20)) {
3292                         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x17);
3293                         if (temp & 0x80) {
3294                                 if ((HwDeviceExtension->jChipType >= XG20)
3295                                                 || (HwDeviceExtension->jChipType
3296                                                                 >= XG40))
3297                                         temp = XGINew_GetReg1(pVBInfo->P3d4,
3298                                                         0x53);
3299                                 else
3300                                         temp = XGINew_GetReg1(pVBInfo->P3d4,
3301                                                         0x63);
3302
3303                                 if (!(temp & 0x40))
3304                                         tempcl |= ActiveCRT1;
3305                         }
3306                 }
3307
3308                 temp = XGINew_GetReg1(pVBInfo->Part1Port, 0x2e);
3309                 temp &= 0x0f;
3310
3311                 if (!(temp == 0x08)) {
3312                         tempax = XGINew_GetReg1(pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */
3313                         if (tempax & 0x04)
3314                                 tempcl = tempcl | ActiveLCD;
3315
3316                         temp &= 0x05;
3317
3318                         if (!(tempcl & ActiveLCD))
3319                                 if (temp == 0x01)
3320                                         tempcl |= ActiveCRT2;
3321
3322                         if (temp == 0x04)
3323                                 tempcl |= ActiveLCD;
3324
3325                         if (temp == 0x05) {
3326                                 temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x00);
3327
3328                                 if (!(temp & 0x08))
3329                                         tempch |= ActiveAVideo;
3330
3331                                 if (!(temp & 0x04))
3332                                         tempch |= ActiveSVideo;
3333
3334                                 if (temp & 0x02)
3335                                         tempch |= ActiveSCART;
3336
3337                                 if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
3338                                         if (temp & 0x01)
3339                                                 tempch |= ActiveHiTV;
3340                                 }
3341
3342                                 if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
3343                                         temp = XGINew_GetReg1(
3344                                                         pVBInfo->Part2Port,
3345                                                         0x4d);
3346
3347                                         if (temp & 0x10)
3348                                                 tempch |= ActiveYPbPr;
3349                                 }
3350
3351                                 if (tempch != 0)
3352                                         tempcl |= ActiveTV;
3353                         }
3354                 }
3355
3356                 temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
3357                 if (tempcl & ActiveLCD) {
3358                         if ((pVBInfo->SetFlag & ReserveTVOption)) {
3359                                 if (temp & ActiveTV)
3360                                         tempcl |= ActiveTV;
3361                         }
3362                 }
3363                 temp = tempcl;
3364                 tempbl = ~ModeSwitchStatus;
3365                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x3d, tempbl, temp);
3366
3367                 if (!(pVBInfo->SetFlag & ReserveTVOption))
3368                         XGINew_SetReg1(pVBInfo->P3d4, 0x3e, tempch);
3369         } else {
3370                 return;
3371         }
3372 }
3373
3374 void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension,
3375                 struct vb_device_info *pVBInfo)
3376 {
3377         /*
3378         if ( HwDeviceExtension->jChipType >= XG20 ) {
3379                 pVBInfo->Set_VGAType = XG20;
3380         } else if (HwDeviceExtension->jChipType >= XG40) {
3381                 pVBInfo->Set_VGAType = VGA_XGI340;
3382         }
3383         */
3384         pVBInfo->Set_VGAType = HwDeviceExtension->jChipType;
3385 }
3386
3387 void XGI_GetVBType(struct vb_device_info *pVBInfo)
3388 {
3389         unsigned short flag, tempbx, tempah;
3390
3391         if (pVBInfo->IF_DEF_CH7007 == 1) {
3392                 pVBInfo->VBType = VB_CH7007;
3393                 return;
3394         }
3395         if (pVBInfo->IF_DEF_LVDS == 0) {
3396                 tempbx = VB_XGI302B;
3397                 flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00);
3398                 if (flag != 0x02) {
3399                         tempbx = VB_XGI301;
3400                         flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01);
3401                         if (flag >= 0xB0) {
3402                                 tempbx = VB_XGI301B;
3403                                 if (flag >= 0xC0) {
3404                                         tempbx = VB_XGI301C;
3405                                         if (flag >= 0xD0) {
3406                                                 tempbx = VB_XGI301LV;
3407                                                 if (flag >= 0xE0) {
3408                                                         tempbx = VB_XGI302LV;
3409                                                         tempah
3410                                                                         = XGINew_GetReg1(
3411                                                                                         pVBInfo->Part4Port,
3412                                                                                         0x39);
3413                                                         if (tempah != 0xFF)
3414                                                                 tempbx
3415                                                                                 = VB_XGI301C;
3416                                                 }
3417                                         }
3418                                 }
3419
3420                                 if (tempbx & (VB_XGI301B | VB_XGI302B)) {
3421                                         flag = XGINew_GetReg1(
3422                                                         pVBInfo->Part4Port,
3423                                                         0x23);
3424
3425                                         if (!(flag & 0x02))
3426                                                 tempbx = tempbx | VB_NoLCD;
3427                                 }
3428                         }
3429                 }
3430                 pVBInfo->VBType = tempbx;
3431         }
3432         /*
3433         else if (pVBInfo->IF_DEF_CH7017 == 1)
3434                 pVBInfo->VBType = VB_CH7017;
3435         else //LVDS
3436                 pVBInfo->VBType = VB_LVDS_NS;
3437          */
3438
3439 }
3440
3441 void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
3442                 struct xgi_hw_device_info *HwDeviceExtension,
3443                 struct vb_device_info *pVBInfo)
3444 {
3445         unsigned short tempax, push, tempbx, temp, modeflag;
3446
3447         if (ModeNo <= 0x13)
3448                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
3449         else
3450                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3451
3452         pVBInfo->SetFlag = 0;
3453         pVBInfo->ModeType = modeflag & ModeInfoFlag;
3454         tempbx = 0;
3455
3456         if (pVBInfo->VBType & 0xFFFF) {
3457                 temp = XGINew_GetReg1(pVBInfo->P3d4, 0x30); /* Check Display Device */
3458                 tempbx = tempbx | temp;
3459                 temp = XGINew_GetReg1(pVBInfo->P3d4, 0x31);
3460                 push = temp;
3461                 push = push << 8;
3462                 tempax = temp << 8;
3463                 tempbx = tempbx | tempax;
3464                 temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA
3465                                 | SetInSlaveMode | DisableCRT2Display);
3466                 temp = 0xFFFF ^ temp;
3467                 tempbx &= temp;
3468
3469                 temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
3470
3471                 if (pVBInfo->IF_DEF_LCDA == 1) {
3472
3473                         if ((pVBInfo->Set_VGAType >= XG20)
3474                                         || (pVBInfo->Set_VGAType >= XG40)) {
3475                                 if (pVBInfo->IF_DEF_LVDS == 0) {
3476                                         /* if ((pVBInfo->VBType & VB_XGI302B) || (pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C)) */
3477                                         if (pVBInfo->VBType & (VB_XGI302B
3478                                                         | VB_XGI301LV
3479                                                         | VB_XGI302LV
3480                                                         | VB_XGI301C)) {
3481                                                 if (temp & EnableDualEdge) {
3482                                                         tempbx
3483                                                                         |= SetCRT2ToDualEdge;
3484
3485                                                         if (temp & SetToLCDA)
3486                                                                 tempbx
3487                                                                                 |= SetCRT2ToLCDA;
3488                                                 }
3489                                         }
3490                                 } else if (pVBInfo->IF_DEF_CH7017 == 1) {
3491                                         if (pVBInfo->VBType & VB_CH7017) {
3492                                                 if (temp & EnableDualEdge) {
3493                                                         tempbx
3494                                                                         |= SetCRT2ToDualEdge;
3495
3496                                                         if (temp & SetToLCDA)
3497                                                                 tempbx
3498                                                                                 |= SetCRT2ToLCDA;
3499                                                 }
3500                                         }
3501                                 }
3502                         }
3503                 }
3504
3505                 if (pVBInfo->IF_DEF_YPbPr == 1) {
3506                         if (((pVBInfo->IF_DEF_LVDS == 0) && ((pVBInfo->VBType
3507                                         & VB_XGI301LV) || (pVBInfo->VBType
3508                                         & VB_XGI302LV) || (pVBInfo->VBType
3509                                         & VB_XGI301C)))
3510                                         || ((pVBInfo->IF_DEF_CH7017 == 1)
3511                                                         && (pVBInfo->VBType
3512                                                                         & VB_CH7017))
3513                                         || ((pVBInfo->IF_DEF_CH7007 == 1)
3514                                                         && (pVBInfo->VBType
3515                                                                         & VB_CH7007))) { /* [Billy] 07/05/04 */
3516                                 if (temp & SetYPbPr) { /* temp = CR38 */
3517                                         if (pVBInfo->IF_DEF_HiVision == 1) {
3518                                                 temp = XGINew_GetReg1(
3519                                                                 pVBInfo->P3d4,
3520                                                                 0x35); /* shampoo add for new scratch */
3521                                                 temp &= YPbPrMode;
3522                                                 tempbx |= SetCRT2ToHiVisionTV;
3523
3524                                                 if (temp != YPbPrMode1080i) {
3525                                                         tempbx
3526                                                                         &= (~SetCRT2ToHiVisionTV);
3527                                                         tempbx
3528                                                                         |= SetCRT2ToYPbPr;
3529                                                 }
3530                                         }
3531
3532                                         /* tempbx |= SetCRT2ToYPbPr; */
3533                                 }
3534                         }
3535                 }
3536
3537                 tempax = push; /* restore CR31 */
3538
3539                 if (pVBInfo->IF_DEF_LVDS == 0) {
3540                         if (pVBInfo->IF_DEF_YPbPr == 1) {
3541                                 if (pVBInfo->IF_DEF_HiVision == 1)
3542                                         temp = 0x09FC;
3543                                 else
3544                                         temp = 0x097C;
3545                         } else {
3546                                 if (pVBInfo->IF_DEF_HiVision == 1)
3547                                         temp = 0x01FC;
3548                                 else
3549                                         temp = 0x017C;
3550                         }
3551                 } else { /* 3nd party chip */
3552                         if (pVBInfo->IF_DEF_CH7017 == 1)
3553                                 temp = (SetCRT2ToTV | SetCRT2ToLCD
3554                                                 | SetCRT2ToLCDA);
3555                         else if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/03 */
3556                                 temp = SetCRT2ToTV;
3557                         } else
3558                                 temp = SetCRT2ToLCD;
3559                 }
3560
3561                 if (!(tempbx & temp)) {
3562                         tempax |= DisableCRT2Display;
3563                         tempbx = 0;
3564                 }
3565
3566                 if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
3567                         if (!(pVBInfo->VBType & VB_NoLCD)) {
3568                                 if (tempbx & SetCRT2ToLCDA) {
3569                                         if (tempbx & SetSimuScanMode)
3570                                                 tempbx
3571                                                                 &= (~(SetCRT2ToLCD
3572                                                                                 | SetCRT2ToRAMDAC
3573                                                                                 | SwitchToCRT2));
3574                                         else
3575                                                 tempbx
3576                                                                 &= (~(SetCRT2ToLCD
3577                                                                                 | SetCRT2ToRAMDAC
3578                                                                                 | SetCRT2ToTV
3579                                                                                 | SwitchToCRT2));
3580                                 }
3581                         }
3582                 }
3583
3584                 /* shampoo add */
3585                 if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */
3586                         if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
3587                                 if (tempbx & SetCRT2ToRAMDAC) {
3588                                         tempbx &= (0xFF00 | SetCRT2ToRAMDAC
3589                                                         | SwitchToCRT2
3590                                                         | SetSimuScanMode);
3591                                         tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
3592                                 }
3593                         } else {
3594                                 tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD
3595                                                 | SetCRT2ToTV));
3596                         }
3597                 }
3598
3599                 if (!(pVBInfo->VBType & VB_NoLCD)) {
3600                         if (tempbx & SetCRT2ToLCD) {
3601                                 tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchToCRT2
3602                                                 | SetSimuScanMode);
3603                                 tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
3604                         }
3605                 }
3606
3607                 if (tempbx & SetCRT2ToSCART) {
3608                         tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchToCRT2
3609                                         | SetSimuScanMode);
3610                         tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
3611                 }
3612
3613                 if (pVBInfo->IF_DEF_YPbPr == 1) {
3614                         if (tempbx & SetCRT2ToYPbPr)
3615                                 tempbx &= (0xFF00 | SwitchToCRT2
3616                                                 | SetSimuScanMode);
3617                 }
3618
3619                 if (pVBInfo->IF_DEF_HiVision == 1) {
3620                         if (tempbx & SetCRT2ToHiVisionTV)
3621                                 tempbx &= (0xFF00 | SetCRT2ToHiVisionTV
3622                                                 | SwitchToCRT2
3623                                                 | SetSimuScanMode);
3624                 }
3625
3626                 if (tempax & DisableCRT2Display) { /* Set Display Device Info */
3627                         if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode)))
3628                                 tempbx = DisableCRT2Display;
3629                 }
3630
3631                 if (!(tempbx & DisableCRT2Display)) {
3632                         if ((!(tempbx & DriverMode))
3633                                         || (!(modeflag & CRT2Mode))) {
3634                                 if (pVBInfo->IF_DEF_LCDA == 1) {
3635                                         if (!(tempbx & SetCRT2ToLCDA))
3636                                                 tempbx
3637                                                                 |= (SetInSlaveMode
3638                                                                                 | SetSimuScanMode);
3639                                 }
3640
3641                                 if (pVBInfo->IF_DEF_VideoCapture == 1) {
3642                                         if (((HwDeviceExtension->jChipType
3643                                                         == XG40)
3644                                                         && (pVBInfo->Set_VGAType
3645                                                                         == XG40))
3646                                                         || ((HwDeviceExtension->jChipType
3647                                                                         == XG41)
3648                                                                         && (pVBInfo->Set_VGAType
3649                                                                                         == XG41))
3650                                                         || ((HwDeviceExtension->jChipType
3651                                                                         == XG42)
3652                                                                         && (pVBInfo->Set_VGAType
3653                                                                                         == XG42))
3654                                                         || ((HwDeviceExtension->jChipType
3655                                                                         == XG45)
3656                                                                         && (pVBInfo->Set_VGAType
3657                                                                                         == XG45))) {
3658                                                 if (ModeNo <= 13) {
3659                                                         if (!(tempbx
3660                                                                         & SetCRT2ToRAMDAC)) { /*CRT2 not need to support*/
3661                                                                 tempbx
3662                                                                                 &= (0x00FF
3663                                                                                                 | (~SetInSlaveMode));
3664                                                                 pVBInfo->SetFlag
3665                                                                                 |= EnableVCMode;
3666                                                         }
3667                                                 }
3668                                         }
3669                                 }
3670                         }
3671
3672                         /* LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */
3673                         if ((tempbx & SetInSlaveMode) && (tempbx
3674                                         & SetCRT2ToLCDA)) {
3675                                 tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA
3676                                                 | SetCRT2ToDualEdge);
3677                                 pVBInfo->SetFlag |= ReserveTVOption;
3678                         }
3679                 }
3680         }
3681
3682         pVBInfo->VBInfo = tempbx;
3683 }
3684
3685 void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
3686                 struct vb_device_info *pVBInfo)
3687 {
3688         unsigned short temp, tempbx = 0, resinfo = 0, modeflag, index1;
3689
3690         tempbx = 0;
3691         resinfo = 0;
3692
3693         if (pVBInfo->VBInfo & SetCRT2ToTV) {
3694                 if (ModeNo <= 0x13) {
3695                         modeflag
3696                                         = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
3697                         resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
3698                 } else {
3699                         modeflag
3700                                         = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3701                         resinfo
3702                                         = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
3703                 }
3704
3705                 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3706                         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
3707                         tempbx = temp;
3708                         if (tempbx & SetPALTV) {
3709                                 tempbx &= (SetCHTVOverScan | SetPALMTV
3710                                                 | SetPALNTV | SetPALTV);
3711                                 if (tempbx & SetPALMTV)
3712                                         tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */
3713                         } else
3714                                 tempbx &= (SetCHTVOverScan | SetNTSCJ
3715                                                 | SetPALTV);
3716                         /*
3717                         if (pVBInfo->IF_DEF_LVDS == 0) {
3718                                 index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); //PAL-M/PAL-N Info
3719                                 temp2 = (index1 & 0xC0) >> 5; //00:PAL, 01:PAL-M, 10:PAL-N
3720                                 tempbx |= temp2;
3721                                 if (temp2 & 0x02)          //PAL-M
3722                                         tempbx &= (~SetPALTV);
3723                         }
3724                         */
3725                 }
3726
3727                 if (pVBInfo->IF_DEF_CH7017 == 1) {
3728                         tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
3729
3730                         if (tempbx & TVOverScan)
3731                                 tempbx |= SetCHTVOverScan;
3732                 }
3733
3734                 if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/04 */
3735                         tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
3736
3737                         if (tempbx & TVOverScan)
3738                                 tempbx |= SetCHTVOverScan;
3739                 }
3740
3741                 if (pVBInfo->IF_DEF_LVDS == 0) {
3742                         if (pVBInfo->VBInfo & SetCRT2ToSCART)
3743                                 tempbx |= SetPALTV;
3744                 }
3745
3746                 if (pVBInfo->IF_DEF_YPbPr == 1) {
3747                         if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
3748                                 index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
3749                                 index1 &= YPbPrMode;
3750
3751                                 if (index1 == YPbPrMode525i)
3752                                         tempbx |= SetYPbPrMode525i;
3753
3754                                 if (index1 == YPbPrMode525p)
3755                                         tempbx = tempbx | SetYPbPrMode525p;
3756                                 if (index1 == YPbPrMode750p)
3757                                         tempbx = tempbx | SetYPbPrMode750p;
3758                         }
3759                 }
3760
3761                 if (pVBInfo->IF_DEF_HiVision == 1) {
3762                         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
3763                                 tempbx = tempbx | SetYPbPrMode1080i | SetPALTV;
3764                 }
3765
3766                 if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
3767                         if ((pVBInfo->VBInfo & SetInSlaveMode)
3768                                         && (!(pVBInfo->VBInfo & SetNotSimuMode)))
3769                                 tempbx |= TVSimuMode;
3770
3771                         if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo
3772                                         == 8)) /* NTSC 1024x768, */
3773                                 tempbx |= NTSC1024x768;
3774
3775                         tempbx |= RPLLDIV2XO;
3776
3777                         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
3778                                 if (pVBInfo->VBInfo & SetInSlaveMode)
3779                                         tempbx &= (~RPLLDIV2XO);
3780                         } else {
3781                                 if (tempbx & (SetYPbPrMode525p
3782                                                 | SetYPbPrMode750p))
3783                                         tempbx &= (~RPLLDIV2XO);
3784                                 else if (!(pVBInfo->VBType & (VB_XGI301B
3785                                                 | VB_XGI302B | VB_XGI301LV
3786                                                 | VB_XGI302LV | VB_XGI301C))) {
3787                                         if (tempbx & TVSimuMode)
3788                                                 tempbx &= (~RPLLDIV2XO);
3789                                 }
3790                         }
3791                 }
3792         }
3793         pVBInfo->TVInfo = tempbx;
3794 }
3795
3796 unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
3797                 struct vb_device_info *pVBInfo)
3798 {
3799         unsigned short temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
3800
3801         pVBInfo->LCDResInfo = 0;
3802         pVBInfo->LCDTypeInfo = 0;
3803         pVBInfo->LCDInfo = 0;
3804
3805         if (ModeNo <= 0x13) {
3806                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */
3807         } else {
3808                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3809                 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo // */
3810         }
3811
3812         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
3813         tempbx = temp & 0x0F;
3814
3815         if (tempbx == 0)
3816                 tempbx = Panel1024x768; /* default */
3817
3818         /* LCD75 [2003/8/22] Vicent */
3819         if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) {
3820                 if (pVBInfo->VBInfo & DriverMode) {
3821                         tempax = XGINew_GetReg1(pVBInfo->P3d4, 0x33);
3822                         if (pVBInfo->VBInfo & SetCRT2ToLCDA)
3823                                 tempax &= 0x0F;
3824                         else
3825                                 tempax = tempax >> 4;
3826
3827                         if ((resinfo == 6) || (resinfo == 9)) {
3828                                 if (tempax >= 3)
3829                                         tempbx |= PanelRef75Hz;
3830                         } else if ((resinfo == 7) || (resinfo == 8)) {
3831                                 if (tempax >= 4)
3832                                         tempbx |= PanelRef75Hz;
3833                         }
3834                 }
3835         }
3836
3837         pVBInfo->LCDResInfo = tempbx;
3838
3839         /* End of LCD75 */
3840
3841         if (pVBInfo->IF_DEF_OEMUtil == 1)
3842                 pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4;
3843
3844         if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
3845                 return 0;
3846
3847         tempbx = 0;
3848
3849         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
3850
3851         temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
3852
3853         if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding))
3854                 temp &= ~EnableScalingLCD;
3855
3856         tempbx |= temp;
3857
3858         LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
3859
3860         tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
3861
3862         if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
3863                 if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
3864                                 & VB_XGI301C)) && (tempax & LCDDualLink)) {
3865                         tempbx |= SetLCDDualLink;
3866                 }
3867         }
3868
3869         if (pVBInfo->IF_DEF_CH7017 == 1) {
3870                 if (tempax & LCDDualLink)
3871                         tempbx |= SetLCDDualLink;
3872         }
3873
3874         if (pVBInfo->IF_DEF_LVDS == 0) {
3875                 if ((pVBInfo->LCDResInfo == Panel1400x1050) && (pVBInfo->VBInfo
3876                                 & SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo
3877                                 == 9) && (!(tempbx & EnableScalingLCD)))
3878                         tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
3879         }
3880
3881         /*
3882         if (tempax & LCDBToA) {
3883                 tempbx |= SetLCDBToA;
3884         }
3885         */
3886
3887         if (pVBInfo->IF_DEF_ExpLink == 1) {
3888                 if (modeflag & HalfDCLK) {
3889                         /* if (!(pVBInfo->LCDInfo&LCDNonExpanding)) */
3890                         if (!(tempbx & SetLCDtoNonExpanding)) {
3891                                 tempbx |= EnableLVDSDDA;
3892                         } else {
3893                                 if (ModeNo > 0x13) {
3894                                         if (pVBInfo->LCDResInfo
3895                                                         == Panel1024x768) {
3896                                                 if (resinfo == 4) { /* 512x384  */
3897                                                         tempbx |= EnableLVDSDDA;
3898                                                 }
3899                                         }
3900                                 }
3901                         }
3902                 }
3903         }
3904
3905         if (pVBInfo->VBInfo & SetInSlaveMode) {
3906                 if (pVBInfo->VBInfo & SetNotSimuMode)
3907                         tempbx |= LCDVESATiming;
3908         } else {
3909                 tempbx |= LCDVESATiming;
3910         }
3911
3912         pVBInfo->LCDInfo = tempbx;
3913
3914         if (pVBInfo->IF_DEF_PWD == 1) {
3915                 if (pVBInfo->LCDInfo & SetPWDEnable) {
3916                         if ((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
3917                                         & VB_XGI301C)) {
3918                                 if (!(tempax & PWDEnable))
3919                                         pVBInfo->LCDInfo &= ~SetPWDEnable;
3920                         }
3921                 }
3922         }
3923
3924         if (pVBInfo->IF_DEF_LVDS == 0) {
3925                 if (tempax & (LockLCDBToA | StLCDBToA)) {
3926                         if (pVBInfo->VBInfo & SetInSlaveMode) {
3927                                 if (!(tempax & LockLCDBToA)) {
3928                                         if (ModeNo <= 0x13) {
3929                                                 pVBInfo->VBInfo
3930                                                                 &= ~(SetSimuScanMode
3931                                                                                 | SetInSlaveMode
3932                                                                                 | SetCRT2ToLCD);
3933                                                 pVBInfo->VBInfo
3934                                                                 |= SetCRT2ToLCDA
3935                                                                                 | SetCRT2ToDualEdge;
3936                                         }
3937                                 }
3938                         }
3939                 }
3940         }
3941
3942         /*
3943         if (pVBInfo->IF_DEF_LVDS == 0) {
3944                 if (tempax & (LockLCDBToA | StLCDBToA)) {
3945                         if (pVBInfo->VBInfo & SetInSlaveMode) {
3946                                 if (!((!(tempax & LockLCDBToA)) && (ModeNo > 0x13))) {
3947                                         pVBInfo->VBInfo&=~(SetSimuScanMode|SetInSlaveMode|SetCRT2ToLCD);
3948                                         pVBInfo->VBInfo|=SetCRT2ToLCDA|SetCRT2ToDualEdge;
3949                                 }
3950                         }
3951                 }
3952         }
3953         */
3954
3955         return 1;
3956 }
3957
3958 unsigned char XGI_SearchModeID(unsigned short ModeNo,
3959                 unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo)
3960 {
3961         if (ModeNo <= 5)
3962                 ModeNo |= 1;
3963         if (ModeNo <= 0x13) {
3964                 /* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->SModeIDTable) / sizeof(struct XGI_StStruct); (*ModeIdIndex)++) */
3965                 for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
3966                         if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo)
3967                                 break;
3968                         if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
3969                                 return 0;
3970                 }
3971
3972                 if (ModeNo == 0x07)
3973                         (*ModeIdIndex)++; /* 400 lines */
3974                 if (ModeNo <= 3)
3975                         (*ModeIdIndex) += 2; /* 400 lines */
3976                 /* else 350 lines */
3977         } else {
3978                 /* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->EModeIDTable) / sizeof(struct XGI_ExtStruct); (*ModeIdIndex)++) */
3979                 for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
3980                         if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
3981                                 break;
3982                         if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
3983                                 return 0;
3984                 }
3985         }
3986
3987         return 1;
3988 }
3989
3990 /* win2000 MM adapter not support standard mode! */
3991
3992 #if 0
3993 static unsigned char XGINew_CheckMemorySize(
3994                 struct xgi_hw_device_info *HwDeviceExtension,
3995                 unsigned short ModeNo,
3996                 unsigned short ModeIdIndex,
3997                 struct vb_device_info *pVBInfo)
3998 {
3999         unsigned short memorysize, modeflag, temp, temp1, tmp;
4000
4001         /*
4002         if ((HwDeviceExtension->jChipType == XGI_650) ||
4003         (HwDeviceExtension->jChipType == XGI_650M)) {
4004                 return 1;
4005         }
4006         */
4007
4008         if (ModeNo <= 0x13)
4009                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
4010         else
4011                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4012
4013         /* ModeType = modeflag&ModeInfoFlag; // Get mode type */
4014
4015         memorysize = modeflag & MemoryInfoFlag;
4016         memorysize = memorysize > MemorySizeShift;
4017         memorysize++; /* Get memory size */
4018
4019         temp = XGINew_GetReg1(pVBInfo->P3c4, 0x14); /* Get DRAM Size */
4020         tmp = temp;
4021
4022         if (HwDeviceExtension->jChipType == XG40) {
4023                 temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
4024                 if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
4025                         temp <<= 2;
4026                 } else if ((tmp & 0x0c) == 0x08) { /* Dual channels */
4027                         temp <<= 1;
4028                 }
4029         } else if (HwDeviceExtension->jChipType == XG42) {
4030                 temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
4031                 if ((tmp & 0x04) == 0x04) { /* Dual channels */
4032                         temp <<= 1;
4033                 }
4034         } else if (HwDeviceExtension->jChipType == XG45) {
4035                 temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
4036                 if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
4037                         temp <<= 2;
4038                 } else if ((tmp & 0x0c) == 0x08) { /* triple channels */
4039                         temp1 = temp;
4040                         temp <<= 1;
4041                         temp += temp1;
4042                 } else if ((tmp & 0x0c) == 0x04) { /* Dual channels */
4043                         temp <<= 1;
4044                 }
4045         }
4046         if (temp < memorysize)
4047                 return 0;
4048         else
4049                 return 1;
4050 }
4051 #endif
4052
4053 /*
4054 void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
4055 {
4056         unsigned short data ;
4057         unsigned short ModeFlag ;
4058
4059         data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F);
4060         data &= 0x7F;
4061         XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data);
4062
4063         if (ModeNo > 0x13) {
4064                 ModeFlag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4065                 if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
4066                         data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F);
4067                         data |= 0x80;
4068                         XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data);
4069                         data = XGINew_GetReg1(pVBInfo->P3c4, 0x01);
4070                         data &= 0xF7;
4071                         XGINew_SetReg1(pVBInfo->P3c4, 0x01, data);
4072                 }
4073         }
4074 }
4075 */
4076
4077 static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
4078 {
4079         unsigned char ujRet = 0;
4080         unsigned char i = 0;
4081
4082         for (i = 0; i < 8; i++) {
4083                 ujRet = ujRet << 1;
4084                 /* ujRet |= GETBITS(ujDate >> i, 0:0); */
4085                 ujRet |= (ujDate >> i) & 1;
4086         }
4087
4088         return ujRet;
4089 }
4090
4091 /*----------------------------------------------------------------------------*/
4092 /* output                                                                     */
4093 /*      bl[5] : LVDS signal                                                   */
4094 /*      bl[1] : LVDS backlight                                                */
4095 /*      bl[0] : LVDS VDD                                                      */
4096 /*----------------------------------------------------------------------------*/
4097 static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
4098 {
4099         unsigned char CR4A, temp;
4100
4101         CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
4102         XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
4103
4104         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
4105
4106         temp = XG21GPIODataTransfer(temp);
4107         temp &= 0x23;
4108         XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
4109         return temp;
4110 }
4111
4112 /*----------------------------------------------------------------------------*/
4113 /* output                                                                     */
4114 /*      bl[5] : LVDS signal                                                   */
4115 /*      bl[1] : LVDS backlight                                                */
4116 /*      bl[0] : LVDS VDD                                                      */
4117 /*----------------------------------------------------------------------------*/
4118 static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
4119 {
4120         unsigned char CR4A, CRB4, temp;
4121
4122         CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
4123         XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
4124
4125         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
4126
4127         temp &= 0x0C;
4128         temp >>= 2;
4129         XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
4130         CRB4 = XGINew_GetReg1(pVBInfo->P3d4, 0xB4);
4131         temp |= ((CRB4 & 0x04) << 3);
4132         return temp;
4133 }
4134
4135 void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE,
4136                 struct vb_device_info *pVBInfo)
4137 {
4138
4139         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
4140         if (pXGIHWDE->jChipType == XG21) {
4141                 if (pVBInfo->IF_DEF_LVDS == 1) {
4142                         if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
4143                                 XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
4144                                 XGI_XG21SetPanelDelay(2, pVBInfo);
4145                         }
4146                         if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
4147                                 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
4148                         XGI_XG21SetPanelDelay(3, pVBInfo);
4149                         XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
4150                 } else {
4151                         XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
4152                 }
4153
4154         }
4155
4156         if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */
4157
4158         }
4159
4160         if (pXGIHWDE->jChipType == XG27) {
4161                 if (pVBInfo->IF_DEF_LVDS == 1) {
4162                         if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
4163                                 XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
4164                                 XGI_XG21SetPanelDelay(2, pVBInfo);
4165                         }
4166                         if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
4167                                 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
4168                         XGI_XG21SetPanelDelay(3, pVBInfo);
4169                         XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
4170                 } else {
4171                         XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
4172                 }
4173
4174         }
4175 }
4176
4177 void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE,
4178                 struct vb_device_info *pVBInfo)
4179 {
4180
4181         if (pXGIHWDE->jChipType == XG21) {
4182                 if (pVBInfo->IF_DEF_LVDS == 1) {
4183                         XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
4184                         XGI_XG21SetPanelDelay(3, pVBInfo);
4185                 } else {
4186                         XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
4187                 }
4188         }
4189
4190         if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */
4191                 /* if (IsCH7007TVMode(pVBInfo) == 0) */
4192                 {
4193                 }
4194         }
4195
4196         if (pXGIHWDE->jChipType == XG27) {
4197                 if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
4198                         XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
4199                         XGI_XG21SetPanelDelay(3, pVBInfo);
4200                 }
4201
4202                 if (pVBInfo->IF_DEF_LVDS == 0)
4203                         XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
4204         }
4205
4206         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
4207 }
4208
4209 static void XGI_WaitDisply(struct vb_device_info *pVBInfo)
4210 {
4211         while ((XGINew_GetReg2(pVBInfo->P3da) & 0x01))
4212                 break;
4213
4214         while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01))
4215                 break;
4216 }
4217
4218 #if 0
4219 static void XGI_WaitDisplay(struct vb_device_info *pVBInfo)
4220 {
4221         while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01));
4222         while (XGINew_GetReg2(pVBInfo->P3da) & 0x01);
4223 }
4224 #endif
4225
4226 static void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
4227 {
4228         if (!(pVBInfo->SetFlag & Win9xDOSMode))
4229                 XGINew_SetRegOR(pVBInfo->Part1Port, 0x01, 0x40);
4230 }
4231
4232 static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo)
4233 {
4234         unsigned short temp1, temp2;
4235
4236         XGINew_SetReg1(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */
4237         temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
4238         temp2 = ~(SetInSlaveMode >> 8);
4239         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, temp2, temp1);
4240 }
4241
4242 static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
4243                 struct vb_device_info *pVBInfo)
4244 {
4245         unsigned short xres, yres, modeflag, resindex;
4246
4247         resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
4248         if (ModeNo <= 0x13) {
4249                 xres = pVBInfo->StResInfo[resindex].HTotal;
4250                 yres = pVBInfo->StResInfo[resindex].VTotal;
4251                 /* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; si+St_ResInfo */
4252         } else {
4253                 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
4254                 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
4255                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
4256
4257                 /*
4258                 if (pVBInfo->IF_DEF_FSTN) {
4259                         xres *= 2;
4260                         yres *= 2;
4261                  } else {
4262                 */
4263                 if (modeflag & HalfDCLK)
4264                         xres *= 2;
4265
4266                 if (modeflag & DoubleScanMode)
4267                         yres *= 2;
4268                 /* } */
4269         }
4270
4271         if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4272                 if (pVBInfo->IF_DEF_LVDS == 0) {
4273                         if (pVBInfo->LCDResInfo == Panel1600x1200) {
4274                                 if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
4275                                         if (yres == 1024)
4276                                                 yres = 1056;
4277                                 }
4278                         }
4279
4280                         if (pVBInfo->LCDResInfo == Panel1280x1024) {
4281                                 if (yres == 400)
4282                                         yres = 405;
4283                                 else if (yres == 350)
4284                                         yres = 360;
4285
4286                                 if (pVBInfo->LCDInfo & LCDVESATiming) {
4287                                         if (yres == 360)
4288                                                 yres = 375;
4289                                 }
4290                         }
4291
4292                         if (pVBInfo->LCDResInfo == Panel1024x768) {
4293                                 if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
4294                                         if (!(pVBInfo->LCDInfo
4295                                                         & LCDNonExpanding)) {
4296                                                 if (yres == 350)
4297                                                         yres = 357;
4298                                                 else if (yres == 400)
4299                                                         yres = 420;
4300                                                 else if (yres == 480)
4301                                                         yres = 525;
4302                                         }
4303                                 }
4304                         }
4305                 }
4306
4307                 if (xres == 720)
4308                         xres = 640;
4309         }
4310
4311         pVBInfo->VGAHDE = xres;
4312         pVBInfo->HDE = xres;
4313         pVBInfo->VGAVDE = yres;
4314         pVBInfo->VDE = yres;
4315 }
4316
4317 static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
4318 {
4319
4320         if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
4321                         (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
4322                 return 1;
4323
4324         return 0;
4325 }
4326
4327 static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex,
4328                 unsigned short RefreshRateTableIndex,
4329                 struct vb_device_info *pVBInfo)
4330 {
4331         unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
4332                         StandTableIndex, CRT1Index;
4333
4334         pVBInfo->RVBHCMAX = 1;
4335         pVBInfo->RVBHCFACT = 1;
4336
4337         if (ModeNo <= 0x13) {
4338                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
4339                 StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
4340                 tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0];
4341                 tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6];
4342                 temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7];
4343         } else {
4344                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4345                 CRT1Index
4346                                 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
4347                 CRT1Index &= IndexMask;
4348                 temp1
4349                                 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
4350                 temp2
4351                                 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
4352                 tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
4353                 tempbx
4354                                 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
4355                 tempcx
4356                                 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
4357                                                 << 8;
4358                 tempcx &= 0x0100;
4359                 tempcx = tempcx << 2;
4360                 tempbx |= tempcx;
4361                 temp1
4362                                 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
4363         }
4364
4365         if (temp1 & 0x01)
4366                 tempbx |= 0x0100;
4367
4368         if (temp1 & 0x20)
4369                 tempbx |= 0x0200;
4370         tempax += 5;
4371
4372         if (modeflag & Charx8Dot)
4373                 tempax *= 8;
4374         else
4375                 tempax *= 9;
4376
4377         pVBInfo->VGAHT = tempax;
4378         pVBInfo->HT = tempax;
4379         tempbx++;
4380         pVBInfo->VGAVT = tempbx;
4381         pVBInfo->VT = tempbx;
4382 }
4383
4384 static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
4385                 unsigned short RefreshRateTableIndex,
4386                 struct vb_device_info *pVBInfo)
4387 {
4388         unsigned short tempax = 0, tempbx, modeflag, resinfo;
4389
4390         struct XGI_LCDDataStruct *LCDPtr = NULL;
4391         struct XGI_TVDataStruct *TVPtr = NULL;
4392
4393         if (ModeNo <= 0x13) {
4394                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
4395                 resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
4396         } else {
4397                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
4398                 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
4399         }
4400
4401         pVBInfo->NewFlickerMode = 0;
4402         pVBInfo->RVBHRS = 50;
4403
4404         if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
4405                 XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
4406                                 pVBInfo);
4407                 return;
4408         }
4409
4410         tempbx = 4;
4411
4412         if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4413                 LCDPtr = (struct XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx,
4414                                 ModeNo, ModeIdIndex, RefreshRateTableIndex,
4415                                 pVBInfo);
4416
4417                 pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
4418                 pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
4419                 pVBInfo->VGAHT = LCDPtr->VGAHT;
4420                 pVBInfo->VGAVT = LCDPtr->VGAVT;
4421                 pVBInfo->HT = LCDPtr->LCDHT;
4422                 pVBInfo->VT = LCDPtr->LCDVT;
4423
4424                 if (pVBInfo->LCDResInfo == Panel1024x768) {
4425                         tempax = 1024;
4426                         tempbx = 768;
4427
4428                         if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
4429                                 if (pVBInfo->VGAVDE == 357)
4430                                         tempbx = 527;
4431                                 else if (pVBInfo->VGAVDE == 420)
4432                                         tempbx = 620;
4433                                 else if (pVBInfo->VGAVDE == 525)
4434                                         tempbx = 775;
4435                                 else if (pVBInfo->VGAVDE == 600)
4436                                         tempbx = 775;
4437                                 /* else if (pVBInfo->VGAVDE==350) tempbx=560; */
4438                                 /* else if (pVBInfo->VGAVDE==400) tempbx=640; */
4439                                 else
4440                                         tempbx = 768;
4441                         } else
4442                                 tempbx = 768;
4443                 } else if (pVBInfo->LCDResInfo == Panel1024x768x75) {
4444                         tempax = 1024;
4445                         tempbx = 768;
4446                 } else if (pVBInfo->LCDResInfo == Panel1280x1024) {
4447                         tempax = 1280;
4448                         if (pVBInfo->VGAVDE == 360)
4449                                 tempbx = 768;
4450                         else if (pVBInfo->VGAVDE == 375)
4451                                 tempbx = 800;
4452                         else if (pVBInfo->VGAVDE == 405)
4453                                 tempbx = 864;
4454                         else
4455                                 tempbx = 1024;
4456                 } else if (pVBInfo->LCDResInfo == Panel1280x1024x75) {
4457                         tempax = 1280;
4458                         tempbx = 1024;
4459                 } else if (pVBInfo->LCDResInfo == Panel1280x960) {
4460                         tempax = 1280;
4461                         if (pVBInfo->VGAVDE == 350)
4462                                 tempbx = 700;
4463                         else if (pVBInfo->VGAVDE == 400)
4464                                 tempbx = 800;
4465                         else if (pVBInfo->VGAVDE == 1024)
4466                                 tempbx = 960;
4467                         else
4468                                 tempbx = 960;
4469                 } else if (pVBInfo->LCDResInfo == Panel1400x1050) {
4470                         tempax = 1400;
4471                         tempbx = 1050;
4472
4473                         if (pVBInfo->VGAVDE == 1024) {
4474                                 tempax = 1280;
4475                                 tempbx = 1024;
4476                         }
4477                 } else if (pVBInfo->LCDResInfo == Panel1600x1200) {
4478                         tempax = 1600;
4479                         tempbx = 1200; /* alan 10/14/2003 */
4480                         if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
4481                                 if (pVBInfo->VGAVDE == 350)
4482                                         tempbx = 875;
4483                                 else if (pVBInfo->VGAVDE == 400)
4484                                         tempbx = 1000;
4485                         }
4486                 }
4487
4488                 if (pVBInfo->LCDInfo & LCDNonExpanding) {
4489                         tempax = pVBInfo->VGAHDE;
4490                         tempbx = pVBInfo->VGAVDE;
4491                 }
4492
4493                 pVBInfo->HDE = tempax;
4494                 pVBInfo->VDE = tempbx;
4495                 return;
4496         }
4497
4498         if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
4499                 tempbx = 4;
4500                 TVPtr = (struct XGI_TVDataStruct *) XGI_GetTVPtr(tempbx,
4501                                 ModeNo, ModeIdIndex, RefreshRateTableIndex,
4502                                 pVBInfo);
4503
4504                 pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
4505                 pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
4506                 pVBInfo->VGAHT = TVPtr->VGAHT;
4507                 pVBInfo->VGAVT = TVPtr->VGAVT;
4508                 pVBInfo->HDE = TVPtr->TVHDE;
4509                 pVBInfo->VDE = TVPtr->TVVDE;
4510                 pVBInfo->RVBHRS = TVPtr->RVBHRS;
4511                 pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
4512
4513                 if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
4514                         if (resinfo == 0x08)
4515                                 pVBInfo->NewFlickerMode = 0x40;
4516                         else if (resinfo == 0x09)
4517                                 pVBInfo->NewFlickerMode = 0x40;
4518                         else if (resinfo == 0x12)
4519                                 pVBInfo->NewFlickerMode = 0x40;
4520
4521                         if (pVBInfo->VGAVDE == 350)
4522                                 pVBInfo->TVInfo |= TVSimuMode;
4523
4524                         tempax = ExtHiTVHT;
4525                         tempbx = ExtHiTVVT;
4526
4527                         if (pVBInfo->VBInfo & SetInSlaveMode) {
4528                                 if (pVBInfo->TVInfo & TVSimuMode) {
4529                                         tempax = StHiTVHT;
4530                                         tempbx = StHiTVVT;
4531
4532                                         if (!(modeflag & Charx8Dot)) {
4533                                                 tempax = StHiTextTVHT;
4534                                                 tempbx = StHiTextTVVT;
4535                                         }
4536                                 }
4537                         }
4538                 } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
4539                         if (pVBInfo->TVInfo & SetYPbPrMode750p) {
4540                                 tempax = YPbPrTV750pHT; /* Ext750pTVHT */
4541                                 tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
4542                         }
4543
4544                         if (pVBInfo->TVInfo & SetYPbPrMode525p) {
4545                                 tempax = YPbPrTV525pHT; /* Ext525pTVHT */
4546                                 tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
4547                         } else if (pVBInfo->TVInfo & SetYPbPrMode525i) {
4548                                 tempax = YPbPrTV525iHT; /* Ext525iTVHT */
4549                                 tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
4550                                 if (pVBInfo->TVInfo & NTSC1024x768)
4551                                         tempax = NTSC1024x768HT;
4552                         }
4553                 } else {
4554                         tempax = PALHT;
4555                         tempbx = PALVT;
4556                         if (!(pVBInfo->TVInfo & SetPALTV)) {
4557                                 tempax = NTSCHT;
4558                                 tempbx = NTSCVT;
4559                                 if (pVBInfo->TVInfo & NTSC1024x768)
4560                                         tempax = NTSC1024x768HT;
4561                         }
4562                 }
4563
4564                 pVBInfo->HT = tempax;
4565                 pVBInfo->VT = tempbx;
4566                 return;
4567         }
4568 }
4569
4570 static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
4571                 unsigned short RefreshRateTableIndex,
4572                 struct vb_device_info *pVBInfo)
4573 {
4574         unsigned char di_0, di_1, tempal;
4575
4576         tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
4577                         pVBInfo);
4578         XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
4579         XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
4580
4581         if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 */
4582                 /* 301 */
4583                 XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, 0x10);
4584                 XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1);
4585                 XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0);
4586         } else { /* 301b/302b/301lv/302lv */
4587                 XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0);
4588                 XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1);
4589         }
4590
4591         XGINew_SetReg1(pVBInfo->Part4Port, 0x00, 0x12);
4592
4593         if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
4594                 XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x28);
4595         else
4596                 XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x08);
4597 }
4598
4599 static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
4600                 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
4601 {
4602         unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
4603         short index;
4604         unsigned short modeflag;
4605
4606         if (ModeNo <= 0x13)
4607                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
4608         else
4609                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4610
4611         index = (modeflag & ModeInfoFlag) - ModeEGA;
4612
4613         if (index < 0)
4614                 index = 0;
4615
4616         return ColorDepth[index];
4617 }
4618
4619 static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex,
4620                 unsigned short RefreshRateTableIndex,
4621                 struct xgi_hw_device_info *HwDeviceExtension,
4622                 struct vb_device_info *pVBInfo)
4623 {
4624         unsigned short temp, colordepth, modeinfo, index, infoflag,
4625                         ColorDepth[] = { 0x01, 0x02, 0x04 };
4626
4627         modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
4628         if (ModeNo <= 0x14)
4629                 infoflag = 0;
4630         else
4631                 infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4632
4633         index = (modeinfo >> 8) & 0xFF;
4634
4635         temp = pVBInfo->ScreenOffset[index];
4636
4637         if (infoflag & InterlaceMode)
4638                 temp = temp << 1;
4639
4640         colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
4641
4642         if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
4643                 temp = ModeNo - 0x7C;
4644                 colordepth = ColorDepth[temp];
4645                 temp = 0x6B;
4646                 if (infoflag & InterlaceMode)
4647                         temp = temp << 1;
4648                 return temp * colordepth;
4649         } else {
4650                 return temp * colordepth;
4651         }
4652 }
4653
4654 static void XGI_SetCRT2Offset(unsigned short ModeNo,
4655                 unsigned short ModeIdIndex,
4656                 unsigned short RefreshRateTableIndex,
4657                 struct xgi_hw_device_info *HwDeviceExtension,
4658                 struct vb_device_info *pVBInfo)
4659 {
4660         unsigned short offset;
4661         unsigned char temp;
4662
4663         if (pVBInfo->VBInfo & SetInSlaveMode)
4664                 return;
4665
4666         offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
4667                         HwDeviceExtension, pVBInfo);
4668         temp = (unsigned char) (offset & 0xFF);
4669         XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp);
4670         temp = (unsigned char) ((offset & 0xFF00) >> 8);
4671         XGINew_SetReg1(pVBInfo->Part1Port, 0x09, temp);
4672         temp = (unsigned char) (((offset >> 3) & 0xFF) + 1);
4673         XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
4674 }
4675
4676 static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
4677 {
4678         XGINew_SetReg1(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */
4679         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */
4680 }
4681
4682 static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
4683                 struct xgi_hw_device_info *HwDeviceExtension,
4684                 unsigned short RefreshRateTableIndex,
4685                 struct vb_device_info *pVBInfo)
4686 {
4687         unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0;
4688
4689         if (ModeNo > 0x13) {
4690                 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
4691                 CRT1Index &= IndexMask;
4692                 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
4693         }
4694
4695         XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
4696                         HwDeviceExtension, pVBInfo);
4697         XGI_SetCRT2FIFO(pVBInfo);
4698         /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
4699
4700         for (tempcx = 4; tempcx < 7; tempcx++)
4701                 XGINew_SetReg1(pVBInfo->Part1Port, tempcx, 0x0);
4702
4703         XGINew_SetReg1(pVBInfo->Part1Port, 0x50, 0x00);
4704         XGINew_SetReg1(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
4705 }
4706
4707 static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
4708                 struct xgi_hw_device_info *HwDeviceExtension,
4709                 unsigned short RefreshRateTableIndex,
4710                 struct vb_device_info *pVBInfo)
4711 {
4712         unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
4713                         pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
4714
4715         if (ModeNo > 0x13) {
4716                 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
4717                 CRT1Index &= IndexMask;
4718                 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
4719         }
4720
4721         if (ModeNo <= 0x13)
4722                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
4723         else
4724                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4725
4726         /* bainy change table name */
4727         if (modeflag & HalfDCLK) {
4728                 temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
4729                 XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp);
4730                 temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
4731                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
4732                 temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
4733                 XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp);
4734                 tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
4735                 pushbx = pVBInfo->VGAHDE / 2 + 16;
4736                 tempcx = tempcx >> 1;
4737                 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
4738                 tempcx += tempbx;
4739
4740                 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
4741                         tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
4742                         tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
4743                                                         & 0xC0) << 2);
4744                         tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
4745                         tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
4746                         tempcx &= 0x1F;
4747                         temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
4748                         temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
4749                         tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
4750                 }
4751
4752                 tempbx += 4;
4753                 tempcx += 4;
4754
4755                 if (tempcx > (pVBInfo->VGAHT / 2))
4756                         tempcx = pVBInfo->VGAHT / 2;
4757
4758                 temp = tempbx & 0x00FF;
4759
4760                 XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
4761         } else {
4762                 temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
4763                 XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp);
4764                 temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
4765                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
4766                 temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
4767                 XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp);
4768                 tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
4769                 pushbx = pVBInfo->VGAHDE + 16;
4770                 tempcx = tempcx >> 1;
4771                 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
4772                 tempcx += tempbx;
4773
4774                 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
4775                         tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
4776                         tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]
4777                                                         & 0xC0) << 2);
4778                         tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
4779                         tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
4780                         tempcx &= 0x1F;
4781                         temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
4782                         temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
4783                         tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
4784                         tempbx += 16;
4785                         tempcx += 16;
4786                 }
4787
4788                 if (tempcx > pVBInfo->VGAHT)
4789                         tempcx = pVBInfo->VGAHT;
4790
4791                 temp = tempbx & 0x00FF;
4792                 XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
4793         }
4794
4795         tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
4796         tempbx = pushbx;
4797         tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
4798         tempax |= (tempbx & 0xFF00);
4799         temp = (tempax & 0xFF00) >> 8;
4800         XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp);
4801         temp = tempcx & 0x00FF;
4802         XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp);
4803         tempcx = (pVBInfo->VGAVT - 1);
4804         temp = tempcx & 0x00FF;
4805
4806         if (pVBInfo->IF_DEF_CH7005 == 1) {
4807                 if (pVBInfo->VBInfo & 0x0C)
4808                         temp--;
4809         }
4810
4811         XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp);
4812         tempbx = pVBInfo->VGAVDE - 1;
4813         temp = tempbx & 0x00FF;
4814         XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, temp);
4815         temp = ((tempbx & 0xFF00) << 3) >> 8;
4816         temp |= ((tempcx & 0xFF00) >> 8);
4817         XGINew_SetReg1(pVBInfo->Part1Port, 0x12, temp);
4818
4819         tempax = pVBInfo->VGAVDE;
4820         tempbx = pVBInfo->VGAVDE;
4821         tempcx = pVBInfo->VGAVT;
4822         tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
4823         tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
4824
4825         if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
4826                 tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
4827                 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
4828
4829                 if (temp & 0x04)
4830                         tempbx |= 0x0100;
4831
4832                 if (temp & 0x080)
4833                         tempbx |= 0x0200;
4834
4835                 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
4836
4837                 if (temp & 0x08)
4838                         tempbx |= 0x0400;
4839
4840                 temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
4841                 tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
4842         }
4843
4844         temp = tempbx & 0x00FF;
4845         XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp);
4846         temp = ((tempbx & 0xFF00) >> 8) << 4;
4847         temp = ((tempcx & 0x000F) | (temp));
4848         XGINew_SetReg1(pVBInfo->Part1Port, 0x11, temp);
4849         tempax = 0;
4850
4851         if (modeflag & DoubleScanMode)
4852                 tempax |= 0x80;
4853
4854         if (modeflag & HalfDCLK)
4855                 tempax |= 0x40;
4856
4857         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
4858 }
4859
4860 static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
4861 {
4862         unsigned long tempax, tempbx;
4863
4864         tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
4865                         & 0xFFFF;
4866         tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
4867         tempax = (tempax * pVBInfo->HT) / tempbx;
4868
4869         return (unsigned short) tempax;
4870 }
4871
4872 static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
4873                 struct xgi_hw_device_info *HwDeviceExtension,
4874                 unsigned short RefreshRateTableIndex,
4875                 struct vb_device_info *pVBInfo)
4876 {
4877         unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
4878                         modeflag, CRT1Index;
4879
4880         if (ModeNo <= 0x13) {
4881                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
4882                 resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
4883         } else {
4884                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
4885                 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
4886                 CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
4887                 CRT1Index &= IndexMask;
4888         }
4889
4890         if (!(pVBInfo->VBInfo & SetInSlaveMode))
4891                 return;
4892
4893         temp = 0xFF; /* set MAX HT */
4894         XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
4895         /* if (modeflag & Charx8Dot) */
4896         /*      tempcx = 0x08; */
4897         /* else */
4898         tempcx = 0x08;
4899
4900         if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
4901                 modeflag |= Charx8Dot;
4902
4903         tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
4904
4905         if (modeflag & HalfDCLK)
4906                 tempax = tempax >> 1;
4907
4908         tempax = (tempax / tempcx) - 1;
4909         tempbx |= ((tempax & 0x00FF) << 8);
4910         temp = tempax & 0x00FF;
4911         XGINew_SetReg1(pVBInfo->Part1Port, 0x04, temp);
4912
4913         temp = (tempbx & 0xFF00) >> 8;
4914
4915         if (pVBInfo->VBInfo & SetCRT2ToTV) {
4916                 if (!(pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
4917                                 | VB_XGI302LV | VB_XGI301C)))
4918                         temp += 2;
4919
4920                 if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
4921                         if (pVBInfo->VBType & VB_XGI301LV) {
4922                                 if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
4923                                         if (resinfo == 7)
4924                                                 temp -= 2;
4925                                 }
4926                         } else if (resinfo == 7) {
4927                                 temp -= 2;
4928                         }
4929                 }
4930         }
4931
4932         XGINew_SetReg1(pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */
4933         XGINew_SetReg1(pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */
4934
4935         if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
4936                 if (pVBInfo->VBInfo & SetCRT2ToTV)
4937                         tempax = pVBInfo->VGAHT;
4938                 else
4939                         tempax = XGI_GetVGAHT2(pVBInfo);
4940         }
4941
4942         if (tempax >= pVBInfo->VGAHT)
4943                 tempax = pVBInfo->VGAHT;
4944
4945         if (modeflag & HalfDCLK)
4946                 tempax = tempax >> 1;
4947
4948         tempax = (tempax / tempcx) - 5;
4949         tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
4950         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
4951                 temp = (tempbx & 0x00FF) - 1;
4952                 if (!(modeflag & HalfDCLK)) {
4953                         temp -= 6;
4954                         if (pVBInfo->TVInfo & TVSimuMode) {
4955                                 temp -= 4;
4956                                 if (ModeNo > 0x13)
4957                                         temp -= 10;
4958                         }
4959                 }
4960         } else {
4961                 /* tempcx = tempbx & 0x00FF ; */
4962                 tempbx = (tempbx & 0xFF00) >> 8;
4963                 tempcx = (tempcx + tempbx) >> 1;
4964                 temp = (tempcx & 0x00FF) + 2;
4965
4966                 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4967                         temp -= 1;
4968                         if (!(modeflag & HalfDCLK)) {
4969                                 if ((modeflag & Charx8Dot)) {
4970                                         temp += 4;
4971                                         if (pVBInfo->VGAHDE >= 800)
4972                                                 temp -= 6;
4973                                 }
4974                         }
4975                 } else {
4976                         if (!(modeflag & HalfDCLK)) {
4977                                 temp -= 4;
4978                                 if (pVBInfo->LCDResInfo != Panel1280x960) {
4979                                         if (pVBInfo->VGAHDE >= 800) {
4980                                                 temp -= 7;
4981                                                 if (pVBInfo->ModeType
4982                                                                 == ModeEGA) {
4983                                                         if (pVBInfo->VGAVDE
4984                                                                         == 1024) {
4985                                                                 temp += 15;
4986                                                                 if (pVBInfo->LCDResInfo
4987                                                                                 != Panel1280x1024) {
4988                                                                         temp
4989                                                                                         += 7;
4990                                                                 }
4991                                                         }
4992                                                 }
4993
4994                                                 if (pVBInfo->VGAHDE >= 1280) {
4995                                                         if (pVBInfo->LCDResInfo
4996                                                                         != Panel1280x960) {
4997                                                                 if (pVBInfo->LCDInfo
4998                                                                                 & LCDNonExpanding) {
4999                                                                         temp
5000                                                                                         += 28;
5001                                                                 }
5002                                                         }
5003                                                 }
5004                                         }
5005                                 }
5006                         }
5007                 }
5008         }
5009
5010         XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */
5011         XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */
5012
5013         if (pVBInfo->VBInfo & SetCRT2ToTV) {
5014                 if (pVBInfo->TVInfo & TVSimuMode) {
5015                         if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo
5016                                         == 0x11) || (ModeNo == 0x13) || (ModeNo
5017                                         == 0x0F)) {
5018                                 XGINew_SetReg1(pVBInfo->Part1Port, 0x07, 0x5b);
5019                                 XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0x03);
5020                         }
5021
5022                         if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
5023                                 if (pVBInfo->TVInfo & SetNTSCTV) {
5024                                         XGINew_SetReg1(pVBInfo->Part1Port,
5025                                                         0x07, 0x2A);
5026                                         XGINew_SetReg1(pVBInfo->Part1Port,
5027                                                         0x08, 0x61);
5028                                 } else {
5029                                         XGINew_SetReg1(pVBInfo->Part1Port,
5030                                                         0x07, 0x2A);
5031                                         XGINew_SetReg1(pVBInfo->Part1Port,
5032                                                         0x08, 0x41);
5033                                         XGINew_SetReg1(pVBInfo->Part1Port,
5034                                                         0x0C, 0xF0);
5035                                 }
5036                         }
5037
5038                         if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo
5039                                         == 0x07)) {
5040                                 if (pVBInfo->TVInfo & SetNTSCTV) {
5041                                         XGINew_SetReg1(pVBInfo->Part1Port,
5042                                                         0x07, 0x54);
5043                                         XGINew_SetReg1(pVBInfo->Part1Port,
5044                                                         0x08, 0x00);
5045                                 } else {
5046                                         XGINew_SetReg1(pVBInfo->Part1Port,
5047                                                         0x07, 0x55);
5048                                         XGINew_SetReg1(pVBInfo->Part1Port,
5049                                                         0x08, 0x00);
5050                                         XGINew_SetReg1(pVBInfo->Part1Port,
5051                                                         0x0C, 0xF0);
5052                                 }
5053                         }
5054
5055                         if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo
5056                                         == 0x0D) || (ModeNo == 0x50)) {
5057                                 if (pVBInfo->TVInfo & SetNTSCTV) {
5058                                         XGINew_SetReg1(pVBInfo->Part1Port,
5059                                                         0x07, 0x30);
5060                                         XGINew_SetReg1(pVBInfo->Part1Port,
5061                                                         0x08, 0x03);
5062                                 } else {
5063                                         XGINew_SetReg1(pVBInfo->Part1Port,
5064                                                         0x07, 0x2f);
5065                                         XGINew_SetReg1(pVBInfo->Part1Port,
5066                                                         0x08, 0x02);
5067                                 }
5068                         }
5069                 }
5070         }
5071
5072         XGINew_SetReg1(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
5073         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
5074         XGINew_SetReg1(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
5075
5076         tempbx = pVBInfo->VGAVT;
5077         push1 = tempbx;
5078         tempcx = 0x121;
5079         tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
5080
5081         if (tempbx == 357)
5082                 tempbx = 350;
5083         if (tempbx == 360)
5084                 tempbx = 350;
5085         if (tempbx == 375)
5086                 tempbx = 350;
5087         if (tempbx == 405)
5088                 tempbx = 400;
5089         if (tempbx == 525)
5090                 tempbx = 480;
5091
5092         push2 = tempbx;
5093
5094         if (pVBInfo->VBInfo & SetCRT2ToLCD) {
5095                 if (pVBInfo->LCDResInfo == Panel1024x768) {
5096                         if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
5097                                 if (tempbx == 350)
5098                                         tempbx += 5;
5099                                 if (tempbx == 480)
5100                                         tempbx += 5;
5101                         }
5102                 }
5103         }
5104         tempbx--;
5105         temp = tempbx & 0x00FF;
5106         tempbx--;
5107         temp = tempbx & 0x00FF;
5108         XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */
5109         tempbx = push2;
5110         tempbx--;
5111         temp = tempbx & 0x00FF;
5112         XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp);
5113
5114         if (tempbx & 0x0100)
5115                 tempcx |= 0x0002;
5116
5117         tempax = 0x000B;
5118
5119         if (modeflag & DoubleScanMode)
5120                 tempax |= 0x08000;
5121
5122         if (tempbx & 0x0200)
5123                 tempcx |= 0x0040;
5124
5125         temp = (tempax & 0xFF00) >> 8;
5126         XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
5127
5128         if (tempbx & 0x0400)
5129                 tempcx |= 0x0600;
5130
5131         XGINew_SetReg1(pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */
5132
5133         tempax = push1;
5134         tempax -= tempbx; /* 0x0C Vertical Retrace Start */
5135         tempax = tempax >> 2;
5136         push1 = tempax; /* push ax */
5137
5138         if (resinfo != 0x09) {
5139                 tempax = tempax << 1;
5140                 tempbx += tempax;
5141         }
5142
5143         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
5144                 if (pVBInfo->VBType & VB_XGI301LV) {
5145                         if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
5146                                 tempbx -= 10;
5147                         } else {
5148                                 if (pVBInfo->TVInfo & TVSimuMode) {
5149                                         if (pVBInfo->TVInfo & SetPALTV) {
5150                                                 if (pVBInfo->VBType
5151                                                                 & VB_XGI301LV) {
5152                                                         if (!(pVBInfo->TVInfo
5153                                                                         & (SetYPbPrMode525p
5154                                                                                         | SetYPbPrMode750p
5155                                                                                         | SetYPbPrMode1080i)))
5156                                                                 tempbx += 40;
5157                                                 } else {
5158                                                         tempbx += 40;
5159                                                 }
5160                                         }
5161                                 }
5162                         }
5163                 } else {
5164                         tempbx -= 10;
5165                 }
5166         } else {
5167                 if (pVBInfo->TVInfo & TVSimuMode) {
5168                         if (pVBInfo->TVInfo & SetPALTV) {
5169                                 if (pVBInfo->VBType & VB_XGI301LV) {
5170                                         if (!(pVBInfo->TVInfo
5171                                                         & (SetYPbPrMode525p
5172                                                                         | SetYPbPrMode750p
5173                                                                         | SetYPbPrMode1080i)))
5174                                                 tempbx += 40;
5175                                 } else {
5176                                         tempbx += 40;
5177                                 }
5178                         }
5179                 }
5180         }
5181         tempax = push1;
5182         tempax = tempax >> 2;
5183         tempax++;
5184         tempax += tempbx;
5185         push1 = tempax; /* push ax */
5186
5187         if ((pVBInfo->TVInfo & SetPALTV)) {
5188                 if (tempbx <= 513) {
5189                         if (tempax >= 513)
5190                                 tempbx = 513;
5191                 }
5192         }
5193
5194         temp = tempbx & 0x00FF;
5195         XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp);
5196         tempbx--;
5197         temp = tempbx & 0x00FF;
5198         XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp);
5199
5200         if (tempbx & 0x0100)
5201                 tempcx |= 0x0008;
5202
5203         if (tempbx & 0x0200)
5204                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
5205
5206         tempbx++;
5207
5208         if (tempbx & 0x0100)
5209                 tempcx |= 0x0004;
5210
5211         if (tempbx & 0x0200)
5212                 tempcx |= 0x0080;
5213
5214         if (tempbx & 0x0400)
5215                 tempcx |= 0x0C00;
5216
5217         tempbx = push1; /* pop ax */
5218         temp = tempbx & 0x00FF;
5219         temp &= 0x0F;
5220         XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */
5221
5222         if (tempbx & 0x0010)
5223                 tempcx |= 0x2000;
5224
5225         temp = tempcx & 0x00FF;
5226         XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
5227         temp = (tempcx & 0x0FF00) >> 8;
5228         XGINew_SetReg1(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
5229         tempax = modeflag;
5230         temp = (tempax & 0xFF00) >> 8;
5231
5232         temp = (temp >> 1) & 0x09;
5233
5234         if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
5235                 temp |= 0x01;
5236
5237         XGINew_SetReg1(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
5238         XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
5239         XGINew_SetReg1(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
5240
5241         if (pVBInfo->LCDInfo & LCDRGB18Bit)
5242                 temp = 0x80;
5243         else
5244                 temp = 0x00;
5245
5246         XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
5247
5248         return;
5249 }
5250
5251 static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
5252                 unsigned short RefreshRateTableIndex,
5253                 struct xgi_hw_device_info *HwDeviceExtension,
5254                 struct vb_device_info *pVBInfo)
5255 {
5256         unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
5257                         modeflag, resinfo, crt2crtc;
5258         unsigned char *TimingPoint;
5259
5260         unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
5261
5262         if (ModeNo <= 0x13) {
5263                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
5264                 resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
5265                 crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5266         } else {
5267                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
5268                 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
5269                 crt2crtc
5270                                 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5271         }
5272
5273         tempax = 0;
5274
5275         if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
5276                 tempax |= 0x0800;
5277
5278         if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
5279                 tempax |= 0x0400;
5280
5281         if (pVBInfo->VBInfo & SetCRT2ToSCART)
5282                 tempax |= 0x0200;
5283
5284         if (!(pVBInfo->TVInfo & SetPALTV))
5285                 tempax |= 0x1000;
5286
5287         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
5288                 tempax |= 0x0100;
5289
5290         if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
5291                 tempax &= 0xfe00;
5292
5293         tempax = (tempax & 0xff00) >> 8;
5294
5295         XGINew_SetReg1(pVBInfo->Part2Port, 0x0, tempax);
5296         TimingPoint = pVBInfo->NTSCTiming;
5297
5298         if (pVBInfo->TVInfo & SetPALTV)
5299                 TimingPoint = pVBInfo->PALTiming;
5300
5301         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
5302                 TimingPoint = pVBInfo->HiTVExtTiming;
5303
5304                 if (pVBInfo->VBInfo & SetInSlaveMode)
5305                         TimingPoint = pVBInfo->HiTVSt2Timing;
5306
5307                 if (pVBInfo->SetFlag & TVSimuMode)
5308                         TimingPoint = pVBInfo->HiTVSt1Timing;
5309
5310                 if (!(modeflag & Charx8Dot))
5311                         TimingPoint = pVBInfo->HiTVTextTiming;
5312         }
5313
5314         if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
5315                 if (pVBInfo->TVInfo & SetYPbPrMode525i)
5316                         TimingPoint = pVBInfo->YPbPr525iTiming;
5317
5318                 if (pVBInfo->TVInfo & SetYPbPrMode525p)
5319                         TimingPoint = pVBInfo->YPbPr525pTiming;
5320
5321                 if (pVBInfo->TVInfo & SetYPbPrMode750p)
5322                         TimingPoint = pVBInfo->YPbPr750pTiming;
5323         }
5324
5325         for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
5326                 XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]);
5327
5328         for (i = 0x39; i <= 0x45; i++, j++)
5329                 XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */
5330
5331         if (pVBInfo->VBInfo & SetCRT2ToTV)
5332                 XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
5333
5334         temp = pVBInfo->NewFlickerMode;
5335         temp &= 0x80;
5336         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
5337
5338         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
5339                 tempax = 950;
5340
5341         if (pVBInfo->TVInfo & SetPALTV)
5342                 tempax = 520;
5343         else
5344                 tempax = 440;
5345
5346         if (pVBInfo->VDE <= tempax) {
5347                 tempax -= pVBInfo->VDE;
5348                 tempax = tempax >> 2;
5349                 tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
5350                 push1 = tempax;
5351                 temp = (tempax & 0xFF00) >> 8;
5352                 temp += (unsigned short) TimingPoint[0];
5353
5354                 if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
5355                                 | VB_XGI302LV | VB_XGI301C)) {
5356                         if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
5357                                         | SetCRT2ToSVIDEO | SetCRT2ToSCART
5358                                         | SetCRT2ToYPbPr)) {
5359                                 tempcx = pVBInfo->VGAHDE;
5360                                 if (tempcx >= 1024) {
5361                                         temp = 0x17; /* NTSC */
5362                                         if (pVBInfo->TVInfo & SetPALTV)
5363                                                 temp = 0x19; /* PAL */
5364                                 }
5365                         }
5366                 }
5367
5368                 XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp);
5369                 tempax = push1;
5370                 temp = (tempax & 0xFF00) >> 8;
5371                 temp += TimingPoint[1];
5372
5373                 if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
5374                                 | VB_XGI302LV | VB_XGI301C)) {
5375                         if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
5376                                         | SetCRT2ToSVIDEO | SetCRT2ToSCART
5377                                         | SetCRT2ToYPbPr))) {
5378                                 tempcx = pVBInfo->VGAHDE;
5379                                 if (tempcx >= 1024) {
5380                                         temp = 0x1D; /* NTSC */
5381                                         if (pVBInfo->TVInfo & SetPALTV)
5382                                                 temp = 0x52; /* PAL */
5383                                 }
5384                         }
5385                 }
5386                 XGINew_SetReg1(pVBInfo->Part2Port, 0x02, temp);
5387         }
5388
5389         /* 301b */
5390         tempcx = pVBInfo->HT;
5391
5392         if (XGI_IsLCDDualLink(pVBInfo))
5393                 tempcx = tempcx >> 1;
5394
5395         tempcx -= 2;
5396         temp = tempcx & 0x00FF;
5397         XGINew_SetReg1(pVBInfo->Part2Port, 0x1B, temp);
5398
5399         temp = (tempcx & 0xFF00) >> 8;
5400         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
5401
5402         tempcx = pVBInfo->HT >> 1;
5403         push1 = tempcx; /* push cx */
5404         tempcx += 7;
5405
5406         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
5407                 tempcx -= 4;
5408
5409         temp = tempcx & 0x00FF;
5410         temp = temp << 4;
5411         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x22, 0x0F, temp);
5412
5413         tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
5414         tempbx += tempcx;
5415         push2 = tempbx;
5416         temp = tempbx & 0x00FF;
5417         XGINew_SetReg1(pVBInfo->Part2Port, 0x24, temp);
5418         temp = (tempbx & 0xFF00) >> 8;
5419         temp = temp << 4;
5420         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x25, 0x0F, temp);
5421
5422         tempbx = push2;
5423         tempbx = tempbx + 8;
5424         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
5425                 tempbx = tempbx - 4;
5426                 tempcx = tempbx;
5427         }
5428
5429         temp = (tempbx & 0x00FF) << 4;
5430         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x29, 0x0F, temp);
5431
5432         j += 2;
5433         tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
5434         temp = tempcx & 0x00FF;
5435         XGINew_SetReg1(pVBInfo->Part2Port, 0x27, temp);
5436         temp = ((tempcx & 0xFF00) >> 8) << 4;
5437         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x28, 0x0F, temp);
5438
5439         tempcx += 8;
5440         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
5441                 tempcx -= 4;
5442
5443         temp = tempcx & 0xFF;
5444         temp = temp << 4;
5445         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
5446
5447         tempcx = push1; /* pop cx */
5448         j += 2;
5449         temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
5450         tempcx -= temp;
5451         temp = tempcx & 0x00FF;
5452         temp = temp << 4;
5453         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
5454
5455         tempcx -= 11;
5456
5457         if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
5458                 tempax = XGI_GetVGAHT2(pVBInfo);
5459                 tempcx = tempax - 1;
5460         }
5461         temp = tempcx & 0x00FF;
5462         XGINew_SetReg1(pVBInfo->Part2Port, 0x2E, temp);
5463
5464         tempbx = pVBInfo->VDE;
5465
5466         if (pVBInfo->VGAVDE == 360)
5467                 tempbx = 746;
5468         if (pVBInfo->VGAVDE == 375)
5469                 tempbx = 746;
5470         if (pVBInfo->VGAVDE == 405)
5471                 tempbx = 853;
5472
5473         if (pVBInfo->VBInfo & SetCRT2ToTV) {
5474                 if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
5475                         if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
5476                                         | SetYPbPrMode750p)))
5477                                 tempbx = tempbx >> 1;
5478                 } else
5479                         tempbx = tempbx >> 1;
5480         }
5481
5482         tempbx -= 2;
5483         temp = tempbx & 0x00FF;
5484
5485         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
5486                 if (pVBInfo->VBType & VB_XGI301LV) {
5487                         if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
5488                                 if (pVBInfo->VBInfo & SetInSlaveMode) {
5489                                         if (ModeNo == 0x2f)
5490                                                 temp += 1;
5491                                 }
5492                         }
5493                 } else {
5494                         if (pVBInfo->VBInfo & SetInSlaveMode) {
5495                                 if (ModeNo == 0x2f)
5496                                         temp += 1;
5497                         }
5498                 }
5499         }
5500
5501         XGINew_SetReg1(pVBInfo->Part2Port, 0x2F, temp);
5502
5503         temp = (tempcx & 0xFF00) >> 8;
5504         temp |= ((tempbx & 0xFF00) >> 8) << 6;
5505
5506         if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) {
5507                 if (pVBInfo->VBType & VB_XGI301LV) {
5508                         if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
5509                                 temp |= 0x10;
5510
5511                                 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
5512                                         temp |= 0x20;
5513                         }
5514                 } else {
5515                         temp |= 0x10;
5516                         if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
5517                                 temp |= 0x20;
5518                 }
5519         }
5520
5521         XGINew_SetReg1(pVBInfo->Part2Port, 0x30, temp);
5522
5523         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
5524                         | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */
5525                 tempbx = pVBInfo->VDE;
5526                 tempcx = tempbx - 2;
5527
5528                 if (pVBInfo->VBInfo & SetCRT2ToTV) {
5529                         if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
5530                                         | SetYPbPrMode750p)))
5531                                 tempbx = tempbx >> 1;
5532                 }
5533
5534                 if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
5535                         temp = 0;
5536                         if (tempcx & 0x0400)
5537                                 temp |= 0x20;
5538
5539                         if (tempbx & 0x0400)
5540                                 temp |= 0x40;
5541
5542                         XGINew_SetReg1(pVBInfo->Part4Port, 0x10, temp);
5543                 }
5544
5545                 temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
5546                 XGINew_SetReg1(pVBInfo->Part2Port, 0x46, temp);
5547                 temp = (tempbx - 3) & 0x00FF;
5548                 XGINew_SetReg1(pVBInfo->Part2Port, 0x47, temp);
5549         }
5550
5551         tempbx = tempbx & 0x00FF;
5552
5553         if (!(modeflag & HalfDCLK)) {
5554                 tempcx = pVBInfo->VGAHDE;
5555                 if (tempcx >= pVBInfo->HDE) {
5556                         tempbx |= 0x2000;
5557                         tempax &= 0x00FF;
5558                 }
5559         }
5560
5561         tempcx = 0x0101;
5562
5563         if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/
5564                 if (pVBInfo->VGAHDE >= 1024) {
5565                         tempcx = 0x1920;
5566                         if (pVBInfo->VGAHDE >= 1280) {
5567                                 tempcx = 0x1420;
5568                                 tempbx = tempbx & 0xDFFF;
5569                         }
5570                 }
5571         }
5572
5573         if (!(tempbx & 0x2000)) {
5574                 if (modeflag & HalfDCLK)
5575                         tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
5576
5577                 push1 = tempbx;
5578                 tempeax = pVBInfo->VGAHDE;
5579                 tempebx = (tempcx & 0xFF00) >> 8;
5580                 longtemp = tempeax * tempebx;
5581                 tempecx = tempcx & 0x00FF;
5582                 longtemp = longtemp / tempecx;
5583
5584                 /* 301b */
5585                 tempecx = 8 * 1024;
5586
5587                 if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
5588                                 | VB_XGI302LV | VB_XGI301C)) {
5589                         tempecx = tempecx * 8;
5590                 }
5591
5592                 longtemp = longtemp * tempecx;
5593                 tempecx = pVBInfo->HDE;
5594                 temp2 = longtemp % tempecx;
5595                 tempeax = longtemp / tempecx;
5596                 if (temp2 != 0)
5597                         tempeax += 1;
5598
5599                 tempax = (unsigned short) tempeax;
5600
5601                 /* 301b */
5602                 if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
5603                                 | VB_XGI302LV | VB_XGI301C)) {
5604                         tempcx = ((tempax & 0xFF00) >> 5) >> 8;
5605                 }
5606                 /* end 301b */
5607
5608                 tempbx = push1;
5609                 tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00)
5610                                 | (tempbx & 0x00FF));
5611                 tempax = (unsigned short) (((tempeax & 0x000000FF) << 8)
5612                                 | (tempax & 0x00FF));
5613                 temp = (tempax & 0xFF00) >> 8;
5614         } else {
5615                 temp = (tempax & 0x00FF) >> 8;
5616         }
5617
5618         XGINew_SetReg1(pVBInfo->Part2Port, 0x44, temp);
5619         temp = (tempbx & 0xFF00) >> 8;
5620         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
5621         temp = tempcx & 0x00FF;
5622
5623         if (tempbx & 0x2000)
5624                 temp = 0;
5625
5626         if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
5627                 temp |= 0x18;
5628
5629         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
5630         if (pVBInfo->TVInfo & SetPALTV) {
5631                 tempbx = 0x0382;
5632                 tempcx = 0x007e;
5633         } else {
5634                 tempbx = 0x0369;
5635                 tempcx = 0x0061;
5636         }
5637
5638         temp = tempbx & 0x00FF;
5639         XGINew_SetReg1(pVBInfo->Part2Port, 0x4b, temp);
5640         temp = tempcx & 0x00FF;
5641         XGINew_SetReg1(pVBInfo->Part2Port, 0x4c, temp);
5642
5643         temp = ((tempcx & 0xFF00) >> 8) & 0x03;
5644         temp = temp << 2;
5645         temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
5646
5647         if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
5648                 temp |= 0x10;
5649
5650                 if (pVBInfo->TVInfo & SetYPbPrMode525p)
5651                         temp |= 0x20;
5652
5653                 if (pVBInfo->TVInfo & SetYPbPrMode750p)
5654                         temp |= 0x60;
5655         }
5656
5657         XGINew_SetReg1(pVBInfo->Part2Port, 0x4d, temp);
5658         temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x43); /* 301b change */
5659         XGINew_SetReg1(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
5660
5661         if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) {
5662                 if (pVBInfo->TVInfo & NTSC1024x768) {
5663                         TimingPoint = XGI_NTSC1024AdjTime;
5664                         for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
5665                                 XGINew_SetReg1(pVBInfo->Part2Port, i,
5666                                                 TimingPoint[j]);
5667                         }
5668                         XGINew_SetReg1(pVBInfo->Part2Port, 0x43, 0x72);
5669                 }
5670         }
5671
5672         /* [ycchen] 01/14/03 Modify for 301C PALM Support */
5673         if (pVBInfo->VBType & VB_XGI301C) {
5674                 if (pVBInfo->TVInfo & SetPALMTV)
5675                         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x08,
5676                                         0x08); /* PALM Mode */
5677         }
5678
5679         if (pVBInfo->TVInfo & SetPALMTV) {
5680                 tempax = (unsigned char) XGINew_GetReg1(pVBInfo->Part2Port,
5681                                 0x01);
5682                 tempax--;
5683                 XGINew_SetRegAND(pVBInfo->Part2Port, 0x01, tempax);
5684
5685                 /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
5686                 XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xEF);
5687         }
5688
5689         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
5690                 if (!(pVBInfo->VBInfo & SetInSlaveMode))
5691                         XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, 0x00);
5692         }
5693
5694         if (pVBInfo->VBInfo & SetCRT2ToTV)
5695                 return;
5696 }
5697
5698 static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
5699                 struct xgi_hw_device_info *HwDeviceExtension,
5700                 unsigned short RefreshRateTableIndex,
5701                 struct vb_device_info *pVBInfo)
5702 {
5703         unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp,
5704                         tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
5705
5706         struct XGI_LCDDesStruct *LCDBDesPtr = NULL;
5707
5708         if (ModeNo <= 0x13) {
5709                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
5710                 resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
5711         } else {
5712                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
5713                 resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
5714                 CRT1Index
5715                                 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
5716                 CRT1Index &= IndexMask;
5717         }
5718
5719         if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
5720                 return;
5721
5722         tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
5723
5724         if (XGI_IsLCDDualLink(pVBInfo))
5725                 tempbx = tempbx >> 1;
5726
5727         tempbx -= 1;
5728         temp = tempbx & 0x00FF;
5729         XGINew_SetReg1(pVBInfo->Part2Port, 0x2C, temp);
5730         temp = (tempbx & 0xFF00) >> 8;
5731         temp = temp << 4;
5732         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
5733         temp = 0x01;
5734
5735         if (pVBInfo->LCDResInfo == Panel1280x1024) {
5736                 if (pVBInfo->ModeType == ModeEGA) {
5737                         if (pVBInfo->VGAHDE >= 1024) {
5738                                 temp = 0x02;
5739                                 if (pVBInfo->LCDInfo & LCDVESATiming)
5740                                         temp = 0x01;
5741                         }
5742                 }
5743         }
5744
5745         XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, temp);
5746         tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
5747         push1 = tempbx;
5748         tempbx--;
5749         temp = tempbx & 0x00FF;
5750         XGINew_SetReg1(pVBInfo->Part2Port, 0x03, temp);
5751         temp = ((tempbx & 0xFF00) >> 8) & 0x07;
5752         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
5753
5754         tempcx = pVBInfo->VT - 1;
5755         push2 = tempcx + 1;
5756         temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
5757         XGINew_SetReg1(pVBInfo->Part2Port, 0x19, temp);
5758         temp = (tempcx & 0xFF00) >> 8;
5759         temp = temp << 5;
5760         XGINew_SetReg1(pVBInfo->Part2Port, 0x1A, temp);
5761         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
5762         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
5763         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
5764         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
5765
5766         /* Customized LCDB Des no add */
5767         tempbx = 5;
5768         LCDBDesPtr = (struct XGI_LCDDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
5769                         ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5770         tempah = pVBInfo->LCDResInfo;
5771         tempah &= PanelResInfo;
5772
5773         if ((tempah == Panel1024x768) || (tempah == Panel1024x768x75)) {
5774                 tempbx = 1024;
5775                 tempcx = 768;
5776         } else if ((tempah == Panel1280x1024) || (tempah == Panel1280x1024x75)) {
5777                 tempbx = 1280;
5778                 tempcx = 1024;
5779         } else if (tempah == Panel1400x1050) {
5780                 tempbx = 1400;
5781                 tempcx = 1050;
5782         } else {
5783                 tempbx = 1600;
5784                 tempcx = 1200;
5785         }
5786
5787         if (pVBInfo->LCDInfo & EnableScalingLCD) {
5788                 tempbx = pVBInfo->HDE;
5789                 tempcx = pVBInfo->VDE;
5790         }
5791
5792         pushbx = tempbx;
5793         tempax = pVBInfo->VT;
5794         pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
5795         pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
5796         pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
5797         pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
5798         tempbx = pVBInfo->LCDVDES;
5799         tempcx += tempbx;
5800
5801         if (tempcx >= tempax)
5802                 tempcx -= tempax; /* lcdvdes */
5803
5804         temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
5805         XGINew_SetReg1(pVBInfo->Part2Port, 0x05, temp);
5806         temp = tempcx & 0x00FF;
5807         XGINew_SetReg1(pVBInfo->Part2Port, 0x06, temp);
5808         tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
5809         tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
5810         tempah = tempch;
5811         tempah = tempah << 3;
5812         tempah |= tempbh;
5813         XGINew_SetReg1(pVBInfo->Part2Port, 0x02, tempah);
5814
5815         /* getlcdsync() */
5816         XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
5817         tempcx = tempbx;
5818         tempax = pVBInfo->VT;
5819         tempbx = pVBInfo->LCDVRS;
5820
5821         /* if (SetLCD_Info & EnableScalingLCD) */
5822         tempcx += tempbx;
5823         if (tempcx >= tempax)
5824                 tempcx -= tempax;
5825
5826         temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
5827         XGINew_SetReg1(pVBInfo->Part2Port, 0x04, temp);
5828         temp = (tempbx & 0xFF00) >> 8;
5829         temp = temp << 4;
5830         temp |= (tempcx & 0x000F);
5831         XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp);
5832         tempcx = pushbx;
5833         tempax = pVBInfo->HT;
5834         tempbx = pVBInfo->LCDHDES;
5835         tempbx &= 0x0FFF;
5836
5837         if (XGI_IsLCDDualLink(pVBInfo)) {
5838                 tempax = tempax >> 1;
5839                 tempbx = tempbx >> 1;
5840                 tempcx = tempcx >> 1;
5841         }
5842
5843         if (pVBInfo->VBType & VB_XGI302LV)
5844                 tempbx += 1;
5845
5846         if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
5847                 tempbx += 1;
5848
5849         tempcx += tempbx;
5850
5851         if (tempcx >= tempax)
5852                 tempcx -= tempax;
5853
5854         temp = tempbx & 0x00FF;
5855         XGINew_SetReg1(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
5856         temp = ((tempbx & 0xFF00) >> 8) << 4;
5857         XGINew_SetReg1(pVBInfo->Part2Port, 0x20, temp);
5858         temp = tempcx & 0x00FF;
5859         XGINew_SetReg1(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
5860         temp = (tempcx & 0xFF00) >> 8;
5861         XGINew_SetReg1(pVBInfo->Part2Port, 0x25, temp);
5862
5863         /* getlcdsync() */
5864         XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
5865         tempcx = tempax;
5866         tempax = pVBInfo->HT;
5867         tempbx = pVBInfo->LCDHRS;
5868         /* if ( SetLCD_Info & EnableScalingLCD) */
5869         if (XGI_IsLCDDualLink(pVBInfo)) {
5870                 tempax = tempax >> 1;
5871                 tempbx = tempbx >> 1;
5872                 tempcx = tempcx >> 1;
5873         }
5874
5875         if (pVBInfo->VBType & VB_XGI302LV)
5876                 tempbx += 1;
5877
5878         tempcx += tempbx;
5879
5880         if (tempcx >= tempax)
5881                 tempcx -= tempax;
5882
5883         temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
5884         XGINew_SetReg1(pVBInfo->Part2Port, 0x1C, temp);
5885
5886         temp = (tempbx & 0xFF00) >> 8;
5887         temp = temp << 4;
5888         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
5889         temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
5890         XGINew_SetReg1(pVBInfo->Part2Port, 0x21, temp);
5891
5892         if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
5893                 if (pVBInfo->VGAVDE == 525) {
5894                         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
5895                                         | VB_XGI301LV | VB_XGI302LV
5896                                         | VB_XGI301C)) {
5897                                 temp = 0xC6;
5898                         } else
5899                                 temp = 0xC4;
5900
5901                         XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp);
5902                         XGINew_SetReg1(pVBInfo->Part2Port, 0x30, 0xB3);
5903                 }
5904
5905                 if (pVBInfo->VGAVDE == 420) {
5906                         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
5907                                         | VB_XGI301LV | VB_XGI302LV
5908                                         | VB_XGI301C)) {
5909                                 temp = 0x4F;
5910                         } else
5911                                 temp = 0x4E;
5912                         XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp);
5913                 }
5914         }
5915 }
5916
5917 /* --------------------------------------------------------------------- */
5918 /* Function : XGI_GetTap4Ptr */
5919 /* Input : */
5920 /* Output : di -> Tap4 Reg. Setting Pointer */
5921 /* Description : */
5922 /* --------------------------------------------------------------------- */
5923 static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
5924                 struct vb_device_info *pVBInfo)
5925 {
5926         unsigned short tempax, tempbx, i;
5927
5928         struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
5929
5930         if (tempcx == 0) {
5931                 tempax = pVBInfo->VGAHDE;
5932                 tempbx = pVBInfo->HDE;
5933         } else {
5934                 tempax = pVBInfo->VGAVDE;
5935                 tempbx = pVBInfo->VDE;
5936         }
5937
5938         if (tempax < tempbx)
5939                 return &EnlargeTap4Timing[0];
5940         else if (tempax == tempbx)
5941                 return &NoScaleTap4Timing[0]; /* 1:1 */
5942         else
5943                 Tap4TimingPtr = NTSCTap4Timing; /* NTSC */
5944
5945         if (pVBInfo->TVInfo & SetPALTV)
5946                 Tap4TimingPtr = PALTap4Timing;
5947
5948         if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
5949                 if (pVBInfo->TVInfo & SetYPbPrMode525i)
5950                         Tap4TimingPtr = YPbPr525iTap4Timing;
5951                 if (pVBInfo->TVInfo & SetYPbPrMode525p)
5952                         Tap4TimingPtr = YPbPr525pTap4Timing;
5953                 if (pVBInfo->TVInfo & SetYPbPrMode750p)
5954                         Tap4TimingPtr = YPbPr750pTap4Timing;
5955         }
5956
5957         if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
5958                 Tap4TimingPtr = HiTVTap4Timing;
5959
5960         i = 0;
5961         while (Tap4TimingPtr[i].DE != 0xFFFF) {
5962                 if (Tap4TimingPtr[i].DE == tempax)
5963                         break;
5964                 i++;
5965         }
5966         return &Tap4TimingPtr[i];
5967 }
5968
5969 static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
5970 {
5971         unsigned short i, j;
5972
5973         struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
5974
5975         if (!(pVBInfo->VBType & VB_XGI301C))
5976                 return;
5977
5978 #ifndef Tap4
5979         XGINew_SetRegAND(pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */
5980 #else            /* Tap4 Setting */
5981
5982         Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
5983         for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
5984                 XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
5985
5986         if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
5987                 Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */
5988                 for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
5989                         XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
5990         }
5991
5992         if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
5993                 XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */
5994         else
5995                 XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */
5996 #endif
5997 }
5998
5999 static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
6000                 struct vb_device_info *pVBInfo)
6001 {
6002         unsigned short i;
6003         unsigned char *tempdi;
6004         unsigned short modeflag;
6005
6006         if (ModeNo <= 0x13)
6007                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
6008         else
6009                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
6010
6011         XGINew_SetReg1(pVBInfo->Part3Port, 0x00, 0x00);
6012         if (pVBInfo->TVInfo & SetPALTV) {
6013                 XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA);
6014                 XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8);
6015         } else {
6016                 XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xF5);
6017                 XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xB7);
6018         }
6019
6020         if (!(pVBInfo->VBInfo & SetCRT2ToTV))
6021                 return;
6022
6023         if (pVBInfo->TVInfo & SetPALMTV) {
6024                 XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA);
6025                 XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8);
6026                 XGINew_SetReg1(pVBInfo->Part3Port, 0x3D, 0xA8);
6027         }
6028
6029         if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV) || (pVBInfo->VBInfo
6030                         & SetCRT2ToYPbPr)) {
6031                 if (pVBInfo->TVInfo & SetYPbPrMode525i)
6032                         return;
6033
6034                 tempdi = pVBInfo->HiTVGroup3Data;
6035                 if (pVBInfo->SetFlag & TVSimuMode) {
6036                         tempdi = pVBInfo->HiTVGroup3Simu;
6037                         if (!(modeflag & Charx8Dot))
6038                                 tempdi = pVBInfo->HiTVGroup3Text;
6039                 }
6040
6041                 if (pVBInfo->TVInfo & SetYPbPrMode525p)
6042                         tempdi = pVBInfo->Ren525pGroup3;
6043
6044                 if (pVBInfo->TVInfo & SetYPbPrMode750p)
6045                         tempdi = pVBInfo->Ren750pGroup3;
6046
6047                 for (i = 0; i <= 0x3E; i++)
6048                         XGINew_SetReg1(pVBInfo->Part3Port, i, tempdi[i]);
6049
6050                 if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
6051                         if (pVBInfo->TVInfo & SetYPbPrMode525p)
6052                                 XGINew_SetReg1(pVBInfo->Part3Port, 0x28, 0x3f);
6053                 }
6054         }
6055         return;
6056 } /* {end of XGI_SetGroup3} */
6057
6058 static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
6059                 unsigned short RefreshRateTableIndex,
6060                 struct xgi_hw_device_info *HwDeviceExtension,
6061                 struct vb_device_info *pVBInfo)
6062 {
6063         unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
6064
6065         unsigned long tempebx, tempeax, templong;
6066
6067         if (ModeNo <= 0x13)
6068                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
6069         else
6070                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
6071
6072         temp = pVBInfo->RVBHCFACT;
6073         XGINew_SetReg1(pVBInfo->Part4Port, 0x13, temp);
6074
6075         tempbx = pVBInfo->RVBHCMAX;
6076         temp = tempbx & 0x00FF;
6077         XGINew_SetReg1(pVBInfo->Part4Port, 0x14, temp);
6078         temp2 = ((tempbx & 0xFF00) >> 8) << 7;
6079         tempcx = pVBInfo->VGAHT - 1;
6080         temp = tempcx & 0x00FF;
6081         XGINew_SetReg1(pVBInfo->Part4Port, 0x16, temp);
6082
6083         temp = ((tempcx & 0xFF00) >> 8) << 3;
6084         temp2 |= temp;
6085
6086         tempcx = pVBInfo->VGAVT - 1;
6087         if (!(pVBInfo->VBInfo & SetCRT2ToTV))
6088                 tempcx -= 5;
6089
6090         temp = tempcx & 0x00FF;
6091         XGINew_SetReg1(pVBInfo->Part4Port, 0x17, temp);
6092         temp = temp2 | ((tempcx & 0xFF00) >> 8);
6093         XGINew_SetReg1(pVBInfo->Part4Port, 0x15, temp);
6094         XGINew_SetRegOR(pVBInfo->Part4Port, 0x0D, 0x08);
6095         tempcx = pVBInfo->VBInfo;
6096         tempbx = pVBInfo->VGAHDE;
6097
6098         if (modeflag & HalfDCLK)
6099                 tempbx = tempbx >> 1;
6100
6101         if (XGI_IsLCDDualLink(pVBInfo))
6102                 tempbx = tempbx >> 1;
6103
6104         if (tempcx & SetCRT2ToHiVisionTV) {
6105                 temp = 0;
6106                 if (tempbx <= 1024)
6107                         temp = 0xA0;
6108                 if (tempbx == 1280)
6109                         temp = 0xC0;
6110         } else if (tempcx & SetCRT2ToTV) {
6111                 temp = 0xA0;
6112                 if (tempbx <= 800)
6113                         temp = 0x80;
6114         } else {
6115                 temp = 0x80;
6116                 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
6117                         temp = 0;
6118                         if (tempbx > 800)
6119                                 temp = 0x60;
6120                 }
6121         }
6122
6123         if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) {
6124                 temp = 0x00;
6125                 if (pVBInfo->VGAHDE == 1280)
6126                         temp = 0x40;
6127                 if (pVBInfo->VGAHDE == 1024)
6128                         temp = 0x20;
6129         }
6130         XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
6131
6132         tempebx = pVBInfo->VDE;
6133
6134         if (tempcx & SetCRT2ToHiVisionTV) {
6135                 if (!(temp & 0xE000))
6136                         tempbx = tempbx >> 1;
6137         }
6138
6139         tempcx = pVBInfo->RVBHRS;
6140         temp = tempcx & 0x00FF;
6141         XGINew_SetReg1(pVBInfo->Part4Port, 0x18, temp);
6142
6143         tempeax = pVBInfo->VGAVDE;
6144         tempcx |= 0x04000;
6145
6146         if (tempeax <= tempebx) {
6147                 tempcx = (tempcx & (~0x4000));
6148                 tempeax = pVBInfo->VGAVDE;
6149         } else {
6150                 tempeax -= tempebx;
6151         }
6152
6153         templong = (tempeax * 256 * 1024) % tempebx;
6154         tempeax = (tempeax * 256 * 1024) / tempebx;
6155         tempebx = tempeax;
6156
6157         if (templong != 0)
6158                 tempebx++;
6159
6160         temp = (unsigned short) (tempebx & 0x000000FF);
6161         XGINew_SetReg1(pVBInfo->Part4Port, 0x1B, temp);
6162
6163         temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8);
6164         XGINew_SetReg1(pVBInfo->Part4Port, 0x1A, temp);
6165         tempbx = (unsigned short) (tempebx >> 16);
6166         temp = tempbx & 0x00FF;
6167         temp = temp << 4;
6168         temp |= ((tempcx & 0xFF00) >> 8);
6169         XGINew_SetReg1(pVBInfo->Part4Port, 0x19, temp);
6170
6171         /* 301b */
6172         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
6173                         | VB_XGI302LV | VB_XGI301C)) {
6174                 temp = 0x0028;
6175                 XGINew_SetReg1(pVBInfo->Part4Port, 0x1C, temp);
6176                 tempax = pVBInfo->VGAHDE;
6177                 if (modeflag & HalfDCLK)
6178                         tempax = tempax >> 1;
6179
6180                 if (XGI_IsLCDDualLink(pVBInfo))
6181                         tempax = tempax >> 1;
6182
6183                 /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
6184                 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
6185                         if (tempax > 800)
6186                                 tempax -= 800;
6187                 } else {
6188                         if (pVBInfo->VGAHDE > 800) {
6189                                 if (pVBInfo->VGAHDE == 1024)
6190                                         tempax = (tempax * 25 / 32) - 1;
6191                                 else
6192                                         tempax = (tempax * 20 / 32) - 1;
6193                         }
6194                 }
6195                 tempax -= 1;
6196
6197                 /*
6198                 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
6199                         if (pVBInfo->VBType & VB_XGI301LV) {
6200                                 if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i))) {
6201                                         if (pVBInfo->VGAHDE > 800) {
6202                                                 if (pVBInfo->VGAHDE == 1024)
6203                                                         tempax = (tempax * 25 / 32) - 1;
6204                                                 else
6205                                                         tempax = (tempax * 20 / 32) - 1;
6206                                         }
6207                                 }
6208                         } else {
6209                                 if (pVBInfo->VGAHDE > 800) {
6210                                         if (pVBInfo->VGAHDE == 1024)
6211                                                 tempax = (tempax * 25 / 32) - 1;
6212                                         else
6213                                                 tempax = (tempax * 20 / 32) - 1;
6214                                 }
6215                         }
6216                 }
6217                 */
6218
6219                 temp = (tempax & 0xFF00) >> 8;
6220                 temp = ((temp & 0x0003) << 4);
6221                 XGINew_SetReg1(pVBInfo->Part4Port, 0x1E, temp);
6222                 temp = (tempax & 0x00FF);
6223                 XGINew_SetReg1(pVBInfo->Part4Port, 0x1D, temp);
6224
6225                 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
6226                         if (pVBInfo->VGAHDE > 800)
6227                                 XGINew_SetRegOR(pVBInfo->Part4Port, 0x1E, 0x08);
6228
6229                 }
6230                 temp = 0x0036;
6231
6232                 if (pVBInfo->VBInfo & SetCRT2ToTV) {
6233                         if (!(pVBInfo->TVInfo & (NTSC1024x768
6234                                         | SetYPbPrMode525p | SetYPbPrMode750p
6235                                         | SetYPbPrMode1080i))) {
6236                                 temp |= 0x0001;
6237                                 if ((pVBInfo->VBInfo & SetInSlaveMode)
6238                                                 && (!(pVBInfo->TVInfo
6239                                                                 & TVSimuMode)))
6240                                         temp &= (~0x0001);
6241                         }
6242                 }
6243
6244                 XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
6245                 tempbx = pVBInfo->HT;
6246                 if (XGI_IsLCDDualLink(pVBInfo))
6247                         tempbx = tempbx >> 1;
6248                 tempbx = (tempbx >> 1) - 2;
6249                 temp = ((tempbx & 0x0700) >> 8) << 3;
6250                 XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
6251                 temp = tempbx & 0x00FF;
6252                 XGINew_SetReg1(pVBInfo->Part4Port, 0x22, temp);
6253         }
6254         /* end 301b */
6255
6256         if (pVBInfo->ISXPDOS == 0)
6257                 XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex,
6258                                 pVBInfo);
6259 }
6260
6261 static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
6262 {
6263         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
6264 }
6265
6266 static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex,
6267                 struct vb_device_info *pVBInfo)
6268 {
6269         unsigned short Pindex, Pdata;
6270
6271         Pindex = pVBInfo->Part5Port;
6272         Pdata = pVBInfo->Part5Port + 1;
6273         if (pVBInfo->ModeType == ModeVGA) {
6274                 if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
6275                                 | CRT2DisplayFlag))) {
6276                         XGINew_EnableCRT2(pVBInfo);
6277                         /* LoadDAC2(pVBInfo->Part5Port, ModeNo, ModeIdIndex); */
6278                 }
6279         }
6280         return;
6281 }
6282
6283 /* --------------------------------------------------------------------- */
6284 /* Function : XGI_BacklightByDrv */
6285 /* Input : */
6286 /* Output : 1 -> Skip backlight control */
6287 /* Description : */
6288 /* --------------------------------------------------------------------- */
6289 static unsigned char XGI_BacklightByDrv(struct vb_device_info *pVBInfo)
6290 {
6291         unsigned char tempah;
6292
6293         tempah = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x3A);
6294         if (tempah & BacklightControlBit)
6295                 return 1;
6296         else
6297                 return 0;
6298 }
6299
6300 /* --------------------------------------------------------------------- */
6301 /* Function : XGI_FirePWDDisable */
6302 /* Input : */
6303 /* Output : */
6304 /* Description : Turn off VDD & Backlight : Fire disable procedure */
6305 /* --------------------------------------------------------------------- */
6306 /*
6307 void XGI_FirePWDDisable(struct vb_device_info *pVBInfo)
6308 {
6309         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x26, 0x00, 0xFC);
6310 }
6311 */
6312
6313 /* --------------------------------------------------------------------- */
6314 /* Function : XGI_FirePWDEnable */
6315 /* Input : */
6316 /* Output : */
6317 /* Description : Turn on VDD & Backlight : Fire enable procedure */
6318 /* --------------------------------------------------------------------- */
6319 static void XGI_FirePWDEnable(struct vb_device_info *pVBInfo)
6320 {
6321         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x26, 0x03, 0xFC);
6322 }
6323
6324 static void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
6325                 struct vb_device_info *pVBInfo)
6326 {
6327         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x63, 0xBF, 0x40);
6328 }
6329
6330 static void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
6331                 struct vb_device_info *pVBInfo)
6332 {
6333
6334         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x63, 0xBF, 0x00);
6335 }
6336
6337 /* --------------------------------------------------------------------- */
6338 /* Function : XGI_SetPanelDelay */
6339 /* Input : */
6340 /* Output : */
6341 /* Description : */
6342 /* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
6343 /* : bl : 2 ; T2 : the duration signal on and Vdd on */
6344 /* : bl : 3 ; T3 : the duration between CPL off and signal off */
6345 /* : bl : 4 ; T4 : the duration signal off and Vdd off */
6346 /* --------------------------------------------------------------------- */
6347 static void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo)
6348 {
6349         unsigned short index;
6350
6351         index = XGI_GetLCDCapPtr(pVBInfo);
6352
6353         if (tempbl == 1)
6354                 mdelay(pVBInfo->LCDCapList[index].PSC_S1);
6355
6356         if (tempbl == 2)
6357                 mdelay(pVBInfo->LCDCapList[index].PSC_S2);
6358
6359         if (tempbl == 3)
6360                 mdelay(pVBInfo->LCDCapList[index].PSC_S3);
6361
6362         if (tempbl == 4)
6363                 mdelay(pVBInfo->LCDCapList[index].PSC_S4);
6364 }
6365
6366 /* --------------------------------------------------------------------- */
6367 /* Function : XGI_SetPanelPower */
6368 /* Input : */
6369 /* Output : */
6370 /* Description : */
6371 /* I/O : ah = 0011b = 03h ; Backlight on, Power on */
6372 /* = 0111b = 07h ; Backlight on, Power off */
6373 /* = 1011b = 0Bh ; Backlight off, Power on */
6374 /* = 1111b = 0Fh ; Backlight off, Power off */
6375 /* --------------------------------------------------------------------- */
6376 static void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl,
6377                 struct vb_device_info *pVBInfo)
6378 {
6379         if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
6380                 XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x26, tempbl, tempah);
6381         else
6382                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x11, tempbl, tempah);
6383 }
6384
6385 /*----------------------------------------------------------------------------*/
6386 /* input                                                                      */
6387 /*      bl[5] : 1;LVDS signal on                                              */
6388 /*      bl[1] : 1;LVDS backlight on                                           */
6389 /*      bl[0] : 1:LVDS VDD on                                                 */
6390 /*      bh: 100000b : clear bit 5, to set bit5                                */
6391 /*          000010b : clear bit 1, to set bit1                                */
6392 /*          000001b : clear bit 0, to set bit0                                */
6393 /*----------------------------------------------------------------------------*/
6394 void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
6395                 struct vb_device_info *pVBInfo)
6396 {
6397         unsigned char CR4A, temp;
6398
6399         CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
6400         tempbh &= 0x23;
6401         tempbl &= 0x23;
6402         XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
6403
6404         if (tempbh & 0x20) {
6405                 temp = (tempbl >> 4) & 0x02;
6406
6407                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */
6408
6409         }
6410
6411         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
6412
6413         temp = XG21GPIODataTransfer(temp);
6414         temp &= ~tempbh;
6415         temp |= tempbl;
6416         XGINew_SetReg1(pVBInfo->P3d4, 0x48, temp);
6417 }
6418
6419 void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
6420                 struct vb_device_info *pVBInfo)
6421 {
6422         unsigned char CR4A, temp;
6423         unsigned short tempbh0, tempbl0;
6424
6425         tempbh0 = tempbh;
6426         tempbl0 = tempbl;
6427         tempbh0 &= 0x20;
6428         tempbl0 &= 0x20;
6429         tempbh0 >>= 3;
6430         tempbl0 >>= 3;
6431
6432         if (tempbh & 0x20) {
6433                 temp = (tempbl >> 4) & 0x02;
6434
6435                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */
6436
6437         }
6438         XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
6439
6440         CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
6441         tempbh &= 0x03;
6442         tempbl &= 0x03;
6443         tempbh <<= 2;
6444         tempbl <<= 2; /* GPIOC,GPIOD */
6445         XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
6446         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
6447 }
6448
6449 /* --------------------------------------------------------------------- */
6450 unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo)
6451 {
6452         unsigned short index;
6453
6454         index = XGINew_GetReg1(pVBInfo->P3d4, 0x36);
6455         if (index < sizeof(XGI21_LCDCapList)
6456                         / sizeof(struct XGI21_LVDSCapStruct))
6457                 return index;
6458         return 0;
6459 }
6460
6461 /* --------------------------------------------------------------------- */
6462 /* Function : XGI_XG21SetPanelDelay */
6463 /* Input : */
6464 /* Output : */
6465 /* Description : */
6466 /* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
6467 /* : bl : 2 ; T2 : the duration signal on and Vdd on */
6468 /* : bl : 3 ; T3 : the duration between CPL off and signal off */
6469 /* : bl : 4 ; T4 : the duration signal off and Vdd off */
6470 /* --------------------------------------------------------------------- */
6471 void XGI_XG21SetPanelDelay(unsigned short tempbl,
6472                 struct vb_device_info *pVBInfo)
6473 {
6474         unsigned short index;
6475
6476         index = XGI_GetLVDSOEMTableIndex(pVBInfo);
6477         if (tempbl == 1)
6478                 mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S1);
6479
6480         if (tempbl == 2)
6481                 mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S2);
6482
6483         if (tempbl == 3)
6484                 mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S3);
6485
6486         if (tempbl == 4)
6487                 mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S4);
6488 }
6489
6490 unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo,
6491                 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
6492 {
6493         unsigned short xres, yres, colordepth, modeflag, resindex,
6494                         lvdstableindex;
6495
6496         resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
6497         if (ModeNo <= 0x13) {
6498                 xres = pVBInfo->StResInfo[resindex].HTotal;
6499                 yres = pVBInfo->StResInfo[resindex].VTotal;
6500                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
6501         } else {
6502                 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
6503                 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
6504                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
6505         }
6506
6507         if (!(modeflag & Charx8Dot)) {
6508                 xres /= 9;
6509                 xres *= 8;
6510         }
6511
6512         if (ModeNo > 0x13) {
6513                 if ((ModeNo > 0x13) && (modeflag & HalfDCLK))
6514                         xres *= 2;
6515
6516                 if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
6517                         yres *= 2;
6518
6519         }
6520
6521         lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
6522         if (xres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE))
6523                 return 0;
6524
6525         if (yres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE))
6526                 return 0;
6527
6528         if (ModeNo > 0x13) {
6529                 if ((xres
6530                                 != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE))
6531                                 || (yres
6532                                                 != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE))) {
6533                         colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex,
6534                                         pVBInfo);
6535                         if (colordepth > 2)
6536                                 return 0;
6537
6538                 }
6539         }
6540         return 1;
6541 }
6542
6543 void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
6544 {
6545         unsigned char temp;
6546
6547         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
6548         temp = (temp & 1) << 6;
6549         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0x40, temp); /* SR06[6] 18bit Dither */
6550         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
6551
6552 }
6553
6554 void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
6555 {
6556         unsigned char temp;
6557
6558         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
6559         temp = (temp & 3) << 6;
6560         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80); /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
6561         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
6562
6563 }
6564
6565 static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex,
6566                 struct vb_device_info *pVBInfo)
6567 {
6568         unsigned char temp, Miscdata;
6569         unsigned short xres, yres, modeflag, resindex, lvdstableindex;
6570         unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
6571         unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
6572         unsigned short value;
6573
6574         lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
6575
6576         temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
6577                                         & (LCDPolarity << 8)) >> 8);
6578         temp &= LCDPolarity;
6579         Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc);
6580
6581         XGINew_SetReg3(pVBInfo->P3c2, (Miscdata & 0x3F) | temp);
6582
6583         temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
6584                                         & LCDPolarity);
6585         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */
6586         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */
6587
6588         XGI_SetXG21FPBits(pVBInfo);
6589         resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
6590         if (ModeNo <= 0x13) {
6591                 xres = pVBInfo->StResInfo[resindex].HTotal;
6592                 yres = pVBInfo->StResInfo[resindex].VTotal;
6593                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
6594         } else {
6595                 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
6596                 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
6597                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
6598         }
6599
6600         if (!(modeflag & Charx8Dot))
6601                 xres = xres * 8 / 9;
6602
6603         LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
6604
6605         LVDSHBS = xres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE
6606                         - xres) / 2;
6607         if ((ModeNo <= 0x13) && (modeflag & HalfDCLK))
6608                 LVDSHBS -= xres / 4;
6609
6610         if (LVDSHBS > LVDSHT)
6611                 LVDSHBS -= LVDSHT;
6612
6613         LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP;
6614         if (LVDSHRS > LVDSHT)
6615                 LVDSHRS -= LVDSHT;
6616
6617         LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC;
6618         if (LVDSHRE > LVDSHT)
6619                 LVDSHRE -= LVDSHT;
6620
6621         LVDSHBE = LVDSHBS + LVDSHT
6622                         - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE;
6623
6624         LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
6625
6626         LVDSVBS = yres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE
6627                         - yres) / 2;
6628         if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
6629                 LVDSVBS += yres / 2;
6630
6631         if (LVDSVBS > LVDSVT)
6632                 LVDSVBS -= LVDSVT;
6633
6634         LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP;
6635         if (LVDSVRS > LVDSVT)
6636                 LVDSVRS -= LVDSVT;
6637
6638         LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC;
6639         if (LVDSVRE > LVDSVT)
6640                 LVDSVRE -= LVDSVT;
6641
6642         LVDSVBE = LVDSVBS + LVDSVT
6643                         - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE;
6644
6645         temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
6646         XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
6647
6648         if (!(modeflag & Charx8Dot))
6649                 XGINew_SetRegOR(pVBInfo->P3c4, 0x1, 0x1);
6650
6651         /* HT SR0B[1:0] CR00 */
6652         value = (LVDSHT >> 3) - 5;
6653         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
6654         XGINew_SetReg1(pVBInfo->P3d4, 0x0, (value & 0xFF));
6655
6656         /* HBS SR0B[5:4] CR02 */
6657         value = (LVDSHBS >> 3) - 1;
6658         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
6659         XGINew_SetReg1(pVBInfo->P3d4, 0x2, (value & 0xFF));
6660
6661         /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
6662         value = (LVDSHBE >> 3) - 1;
6663         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
6664         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
6665         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
6666
6667         /* HRS SR0B[7:6] CR04 */
6668         value = (LVDSHRS >> 3) + 2;
6669         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
6670         XGINew_SetReg1(pVBInfo->P3d4, 0x4, (value & 0xFF));
6671
6672         /* Panel HRS SR2F[1:0] SR2E[7:0]  */
6673         value--;
6674         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
6675         XGINew_SetReg1(pVBInfo->P3c4, 0x2E, (value & 0xFF));
6676
6677         /* HRE SR0C[2] CR05[4:0] */
6678         value = (LVDSHRE >> 3) + 2;
6679         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
6680         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
6681
6682         /* Panel HRE SR2F[7:2]  */
6683         value--;
6684         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
6685
6686         /* VT SR0A[0] CR07[5][0] CR06 */
6687         value = LVDSVT - 2;
6688         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
6689         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
6690         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
6691         XGINew_SetReg1(pVBInfo->P3d4, 0x06, (value & 0xFF));
6692
6693         /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
6694         value = LVDSVBS - 1;
6695         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
6696         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
6697         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
6698         XGINew_SetReg1(pVBInfo->P3d4, 0x15, (value & 0xFF));
6699
6700         /* VBE SR0A[4] CR16 */
6701         value = LVDSVBE - 1;
6702         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
6703         XGINew_SetReg1(pVBInfo->P3d4, 0x16, (value & 0xFF));
6704
6705         /* VRS SR0A[3] CR7[7][2] CR10 */
6706         value = LVDSVRS - 1;
6707         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
6708         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
6709         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
6710         XGINew_SetReg1(pVBInfo->P3d4, 0x10, (value & 0xFF));
6711
6712         /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
6713         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0x03, (value & 0x600) >> 9);
6714         XGINew_SetReg1(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF);
6715         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01);
6716
6717         /* VRE SR0A[5] CR11[3:0] */
6718         value = LVDSVRE - 1;
6719         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
6720         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
6721
6722         /* Panel VRE SR3F[7:2] *//* SR3F[7] has to be 0, h/w bug */
6723         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, (value << 2) & 0x7C);
6724
6725         for (temp = 0, value = 0; temp < 3; temp++) {
6726
6727                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, value);
6728                 XGINew_SetReg1(pVBInfo->P3c4,
6729                                 0x2B,
6730                                 pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1);
6731                 XGINew_SetReg1(pVBInfo->P3c4,
6732                                 0x2C,
6733                                 pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2);
6734                 value += 0x10;
6735         }
6736
6737         if (!(modeflag & Charx8Dot)) {
6738                 XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
6739                 XGINew_SetReg3(pVBInfo->P3c0, 0x13); /* set index */
6740                 XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data, panning = 0, shift left 1 dot*/
6741
6742                 XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */
6743                 XGINew_SetReg3(pVBInfo->P3c0, 0x20);
6744
6745                 XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
6746         }
6747
6748 }
6749
6750 /* no shadow case */
6751 static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex,
6752                 struct vb_device_info *pVBInfo)
6753 {
6754         unsigned char temp, Miscdata;
6755         unsigned short xres, yres, modeflag, resindex, lvdstableindex;
6756         unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
6757         unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
6758         unsigned short value;
6759
6760         lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
6761         temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
6762                                         & (LCDPolarity << 8)) >> 8);
6763         temp &= LCDPolarity;
6764         Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc);
6765
6766         XGINew_SetReg3(pVBInfo->P3c2, (Miscdata & 0x3F) | temp);
6767
6768         temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
6769                                         & LCDPolarity);
6770         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */
6771         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */
6772
6773         XGI_SetXG27FPBits(pVBInfo);
6774         resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
6775         if (ModeNo <= 0x13) {
6776                 xres = pVBInfo->StResInfo[resindex].HTotal;
6777                 yres = pVBInfo->StResInfo[resindex].VTotal;
6778                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
6779         } else {
6780                 xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
6781                 yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
6782                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
6783         }
6784
6785         if (!(modeflag & Charx8Dot))
6786                 xres = xres * 8 / 9;
6787
6788         LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
6789
6790         LVDSHBS = xres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE
6791                         - xres) / 2;
6792         if ((ModeNo <= 0x13) && (modeflag & HalfDCLK))
6793                 LVDSHBS -= xres / 4;
6794
6795         if (LVDSHBS > LVDSHT)
6796                 LVDSHBS -= LVDSHT;
6797
6798         LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP;
6799         if (LVDSHRS > LVDSHT)
6800                 LVDSHRS -= LVDSHT;
6801
6802         LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC;
6803         if (LVDSHRE > LVDSHT)
6804                 LVDSHRE -= LVDSHT;
6805
6806         LVDSHBE = LVDSHBS + LVDSHT
6807                         - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE;
6808
6809         LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
6810
6811         LVDSVBS = yres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE
6812                         - yres) / 2;
6813         if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
6814                 LVDSVBS += yres / 2;
6815
6816         if (LVDSVBS > LVDSVT)
6817                 LVDSVBS -= LVDSVT;
6818
6819         LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP;
6820         if (LVDSVRS > LVDSVT)
6821                 LVDSVRS -= LVDSVT;
6822
6823         LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC;
6824         if (LVDSVRE > LVDSVT)
6825                 LVDSVRE -= LVDSVT;
6826
6827         LVDSVBE = LVDSVBS + LVDSVT
6828                         - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE;
6829
6830         temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
6831         XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
6832
6833         if (!(modeflag & Charx8Dot))
6834                 XGINew_SetRegOR(pVBInfo->P3c4, 0x1, 0x1);
6835
6836         /* HT SR0B[1:0] CR00 */
6837         value = (LVDSHT >> 3) - 5;
6838         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
6839         XGINew_SetReg1(pVBInfo->P3d4, 0x0, (value & 0xFF));
6840
6841         /* HBS SR0B[5:4] CR02 */
6842         value = (LVDSHBS >> 3) - 1;
6843         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
6844         XGINew_SetReg1(pVBInfo->P3d4, 0x2, (value & 0xFF));
6845
6846         /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
6847         value = (LVDSHBE >> 3) - 1;
6848         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
6849         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
6850         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
6851
6852         /* HRS SR0B[7:6] CR04 */
6853         value = (LVDSHRS >> 3) + 2;
6854         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
6855         XGINew_SetReg1(pVBInfo->P3d4, 0x4, (value & 0xFF));
6856
6857         /* Panel HRS SR2F[1:0] SR2E[7:0]  */
6858         value--;
6859         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
6860         XGINew_SetReg1(pVBInfo->P3c4, 0x2E, (value & 0xFF));
6861
6862         /* HRE SR0C[2] CR05[4:0] */
6863         value = (LVDSHRE >> 3) + 2;
6864         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
6865         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
6866
6867         /* Panel HRE SR2F[7:2]  */
6868         value--;
6869         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
6870
6871         /* VT SR0A[0] CR07[5][0] CR06 */
6872         value = LVDSVT - 2;
6873         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
6874         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
6875         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
6876         XGINew_SetReg1(pVBInfo->P3d4, 0x06, (value & 0xFF));
6877
6878         /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
6879         value = LVDSVBS - 1;
6880         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
6881         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
6882         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
6883         XGINew_SetReg1(pVBInfo->P3d4, 0x15, (value & 0xFF));
6884
6885         /* VBE SR0A[4] CR16 */
6886         value = LVDSVBE - 1;
6887         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
6888         XGINew_SetReg1(pVBInfo->P3d4, 0x16, (value & 0xFF));
6889
6890         /* VRS SR0A[3] CR7[7][2] CR10 */
6891         value = LVDSVRS - 1;
6892         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
6893         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
6894         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
6895         XGINew_SetReg1(pVBInfo->P3d4, 0x10, (value & 0xFF));
6896
6897         /* Panel VRS SR35[2:0] SR34[7:0] */
6898         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, (value & 0x700) >> 8);
6899         XGINew_SetReg1(pVBInfo->P3c4, 0x34, value & 0xFF);
6900
6901         /* VRE SR0A[5] CR11[3:0] */
6902         value = LVDSVRE - 1;
6903         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
6904         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
6905
6906         /* Panel VRE SR3F[7:2] */
6907         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, (value << 2) & 0xFC);
6908
6909         for (temp = 0, value = 0; temp < 3; temp++) {
6910
6911                 XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, value);
6912                 XGINew_SetReg1(pVBInfo->P3c4,
6913                                 0x2B,
6914                                 pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1);
6915                 XGINew_SetReg1(pVBInfo->P3c4,
6916                                 0x2C,
6917                                 pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2);
6918                 value += 0x10;
6919         }
6920
6921         if (!(modeflag & Charx8Dot)) {
6922                 XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
6923                 XGINew_SetReg3(pVBInfo->P3c0, 0x13); /* set index */
6924                 XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data, panning = 0, shift left 1 dot*/
6925
6926                 XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */
6927                 XGINew_SetReg3(pVBInfo->P3c0, 0x20);
6928
6929                 XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
6930         }
6931
6932 }
6933
6934 /* --------------------------------------------------------------------- */
6935 /* Function : XGI_IsLCDON */
6936 /* Input : */
6937 /* Output : 0 : Skip PSC Control */
6938 /* 1: Disable PSC */
6939 /* Description : */
6940 /* --------------------------------------------------------------------- */
6941 static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
6942 {
6943         unsigned short tempax;
6944
6945         tempax = pVBInfo->VBInfo;
6946         if (tempax & SetCRT2ToDualEdge)
6947                 return 0;
6948         else if (tempax & (DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode))
6949                 return 1;
6950
6951         return 0;
6952 }
6953
6954 static void XGI_EnablePWD(struct vb_device_info *pVBInfo)
6955 {
6956         unsigned short index, temp;
6957
6958         index = XGI_GetLCDCapPtr(pVBInfo);
6959         temp = pVBInfo->LCDCapList[index].PWD_2B;
6960         XGINew_SetReg1(pVBInfo->Part4Port, 0x2B, temp);
6961         XGINew_SetReg1(pVBInfo->Part4Port, 0x2C,
6962                         pVBInfo->LCDCapList[index].PWD_2C);
6963         XGINew_SetReg1(pVBInfo->Part4Port, 0x2D,
6964                         pVBInfo->LCDCapList[index].PWD_2D);
6965         XGINew_SetReg1(pVBInfo->Part4Port, 0x2E,
6966                         pVBInfo->LCDCapList[index].PWD_2E);
6967         XGINew_SetReg1(pVBInfo->Part4Port, 0x2F,
6968                         pVBInfo->LCDCapList[index].PWD_2F);
6969         XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x80); /* enable PWD */
6970 }
6971
6972 static void XGI_DisablePWD(struct vb_device_info *pVBInfo)
6973 {
6974         XGINew_SetRegAND(pVBInfo->Part4Port, 0x27, 0x7F); /* disable PWD */
6975 }
6976
6977 /* --------------------------------------------------------------------- */
6978 /* Function : XGI_DisableChISLCD */
6979 /* Input : */
6980 /* Output : 0 -> Not LCD Mode */
6981 /* Description : */
6982 /* --------------------------------------------------------------------- */
6983 static unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo)
6984 {
6985         unsigned short tempbx, tempah;
6986
6987         tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
6988         tempah = ~((unsigned short) XGINew_GetReg1(pVBInfo->Part1Port, 0x2E));
6989
6990         if (tempbx & (EnableChA | DisableChA)) {
6991                 if (!(tempah & 0x08)) /* Chk LCDA Mode */
6992                         return 0;
6993         }
6994
6995         if (!(tempbx & (EnableChB | DisableChB)))
6996                 return 0;
6997
6998         if (tempah & 0x01) /* Chk LCDB Mode */
6999                 return 1;
7000
7001         return 0;
7002 }
7003
7004 /* --------------------------------------------------------------------- */
7005 /* Function : XGI_EnableChISLCD */
7006 /* Input : */
7007 /* Output : 0 -> Not LCD mode */
7008 /* Description : */
7009 /* --------------------------------------------------------------------- */
7010 static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo)
7011 {
7012         unsigned short tempbx, tempah;
7013
7014         tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
7015         tempah = ~((unsigned short) XGINew_GetReg1(pVBInfo->Part1Port, 0x2E));
7016
7017         if (tempbx & (EnableChA | DisableChA)) {
7018                 if (!(tempah & 0x08)) /* Chk LCDA Mode */
7019                         return 0;
7020         }
7021
7022         if (!(tempbx & (EnableChB | DisableChB)))
7023                 return 0;
7024
7025         if (tempah & 0x01) /* Chk LCDB Mode */
7026                 return 1;
7027
7028         return 0;
7029 }
7030
7031 void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension,
7032                 struct vb_device_info *pVBInfo)
7033 {
7034         unsigned short tempax, tempbx, tempah = 0, tempbl = 0;
7035
7036         if (pVBInfo->SetFlag == Win9xDOSMode)
7037                 return;
7038
7039         if (HwDeviceExtension->jChipType < XG40) {
7040                 if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
7041                                 || (XGI_DisableChISLCD(pVBInfo))) {
7042                         if (!XGI_IsLCDON(pVBInfo)) {
7043                                 if (pVBInfo->LCDInfo & SetPWDEnable)
7044                                         XGI_EnablePWD(pVBInfo);
7045                                 else {
7046                                         pVBInfo->LCDInfo &= ~SetPWDEnable;
7047                                         XGI_DisablePWD(pVBInfo);
7048                                         if (pVBInfo->VBType & (VB_XGI301LV
7049                                                         | VB_XGI302LV
7050                                                         | VB_XGI301C)) {
7051                                                 tempbx = 0xFE; /* not 01h */
7052                                                 tempax = 0;
7053                                         } else {
7054                                                 tempbx = 0xF7; /* not 08h */
7055                                                 tempax = 0x08;
7056                                         }
7057                                         XGI_SetPanelPower(tempax, tempbx,
7058                                                         pVBInfo);
7059                                         XGI_SetPanelDelay(3, pVBInfo);
7060                                 }
7061                         } /* end if (!XGI_IsLCDON(pVBInfo)) */
7062                 }
7063         }
7064
7065         /*
7066         if (CH7017) {
7067                 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2toLCDA)) || (XGI_DisableChISLCD(pVBInfo))) {
7068                         if (!XGI_IsLCDON(pVBInfo)) {
7069                                 if (DISCHARGE) {
7070                                         tempbx = XGINew_GetCH7005(0x61);
7071                                         if (tempbx < 0x01) // first time we power up
7072                                                 XGINew_SetCH7005(0x0066); // and disable power sequence
7073                                         else
7074                                                 XGINew_SetCH7005(0x5f66); // leave VDD on - disable power
7075                                 }
7076                         }
7077                 }
7078         }
7079         */
7080
7081         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
7082                         | VB_XGI302LV | VB_XGI301C)) {
7083                 tempah = 0x3F;
7084                 if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) {
7085                         if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
7086                                 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
7087                                         tempah = 0x7F; /* Disable Channel A */
7088                                         if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
7089                                                 tempah = 0xBF; /* Disable Channel B */
7090
7091                                         if (pVBInfo->SetFlag & DisableChB)
7092                                                 tempah &= 0xBF; /* force to disable Cahnnel */
7093
7094                                         if (pVBInfo->SetFlag & DisableChA)
7095                                                 tempah &= 0x7F; /* Force to disable Channel B */
7096                                 }
7097                         }
7098                 }
7099
7100                 XGINew_SetRegAND(pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */
7101
7102                 if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
7103                         if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
7104                                         || (XGI_DisableChISLCD(pVBInfo))
7105                                         || (XGI_IsLCDON(pVBInfo)))
7106                                 XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */
7107                 }
7108
7109                 if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
7110                                 & (DisableCRT2Display | SetCRT2ToLCDA
7111                                                 | SetSimuScanMode))) {
7112                         if (pVBInfo->SetFlag & GatingCRT)
7113                                 XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
7114                         XGI_DisplayOff(HwDeviceExtension, pVBInfo);
7115                 }
7116
7117                 if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
7118                         if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
7119                                         & SetCRT2ToLCDA))
7120                                 XGINew_SetRegAND(pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */
7121                 }
7122
7123                 XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */
7124
7125                 if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
7126                         XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xdf);
7127
7128                 if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
7129                                 & (DisableCRT2Display | SetSimuScanMode))
7130                                 || ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
7131                                                 && (pVBInfo->VBInfo
7132                                                                 & (SetCRT2ToRAMDAC
7133                                                                                 | SetCRT2ToLCD
7134                                                                                 | SetCRT2ToTV))))
7135                         XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
7136
7137                 if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
7138                                 & (DisableCRT2Display | SetSimuScanMode))
7139                                 || (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
7140                                 || (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
7141                                                 | SetCRT2ToLCD | SetCRT2ToTV))) {
7142                         tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */
7143                         XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */
7144                         XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */
7145                         XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */
7146                 }
7147         } else { /* {301} */
7148                 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
7149                         XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
7150                         XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */
7151                         XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */
7152                 }
7153
7154                 if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA
7155                                 | SetSimuScanMode))
7156                         XGI_DisplayOff(HwDeviceExtension, pVBInfo);
7157         }
7158
7159         if (HwDeviceExtension->jChipType < XG40) {
7160                 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
7161                                 || (XGI_DisableChISLCD(pVBInfo))
7162                                 || (XGI_IsLCDON(pVBInfo))) {
7163                         if (pVBInfo->LCDInfo & SetPWDEnable) {
7164                                 if (pVBInfo->LCDInfo & SetPWDEnable)
7165                                         XGI_BacklightByDrv(pVBInfo);
7166                                 else {
7167                                         XGI_SetPanelDelay(4, pVBInfo);
7168                                         if (pVBInfo->VBType & VB_XGI301LV) {
7169                                                 tempbl = 0xFD;
7170                                                 tempah = 0x00;
7171                                         } else {
7172                                                 tempbl = 0xFB;
7173                                                 tempah = 0x04;
7174                                         }
7175                                 }
7176                         }
7177                         XGI_SetPanelPower(tempah, tempbl, pVBInfo);
7178                 }
7179         }
7180 }
7181
7182 /* --------------------------------------------------------------------- */
7183 /* Function : XGI_GetTVPtrIndex */
7184 /* Input : */
7185 /* Output : */
7186 /* Description : bx 0 : ExtNTSC */
7187 /* 1 : StNTSC */
7188 /* 2 : ExtPAL */
7189 /* 3 : StPAL */
7190 /* 4 : ExtHiTV */
7191 /* 5 : StHiTV */
7192 /* 6 : Ext525i */
7193 /* 7 : St525i */
7194 /* 8 : Ext525p */
7195 /* 9 : St525p */
7196 /* A : Ext750p */
7197 /* B : St750p */
7198 /* --------------------------------------------------------------------- */
7199 static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
7200 {
7201         unsigned short tempbx = 0;
7202
7203         if (pVBInfo->TVInfo & SetPALTV)
7204                 tempbx = 2;
7205         if (pVBInfo->TVInfo & SetYPbPrMode1080i)
7206                 tempbx = 4;
7207         if (pVBInfo->TVInfo & SetYPbPrMode525i)
7208                 tempbx = 6;
7209         if (pVBInfo->TVInfo & SetYPbPrMode525p)
7210                 tempbx = 8;
7211         if (pVBInfo->TVInfo & SetYPbPrMode750p)
7212                 tempbx = 10;
7213         if (pVBInfo->TVInfo & TVSimuMode)
7214                 tempbx++;
7215
7216         return tempbx;
7217 }
7218
7219 /* --------------------------------------------------------------------- */
7220 /* Function : XGI_GetTVPtrIndex2 */
7221 /* Input : */
7222 /* Output : bx 0 : NTSC */
7223 /* 1 : PAL */
7224 /* 2 : PALM */
7225 /* 3 : PALN */
7226 /* 4 : NTSC1024x768 */
7227 /* 5 : PAL-M 1024x768 */
7228 /* 6-7: reserved */
7229 /* cl 0 : YFilter1 */
7230 /* 1 : YFilter2 */
7231 /* ch 0 : 301A */
7232 /* 1 : 301B/302B/301LV/302LV */
7233 /* Description : */
7234 /* --------------------------------------------------------------------- */
7235 static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
7236                 unsigned char *tempch, struct vb_device_info *pVBInfo)
7237 {
7238         *tempbx = 0;
7239         *tempcl = 0;
7240         *tempch = 0;
7241
7242         if (pVBInfo->TVInfo & SetPALTV)
7243                 *tempbx = 1;
7244
7245         if (pVBInfo->TVInfo & SetPALMTV)
7246                 *tempbx = 2;
7247
7248         if (pVBInfo->TVInfo & SetPALNTV)
7249                 *tempbx = 3;
7250
7251         if (pVBInfo->TVInfo & NTSC1024x768) {
7252                 *tempbx = 4;
7253                 if (pVBInfo->TVInfo & SetPALMTV)
7254                         *tempbx = 5;
7255         }
7256
7257         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
7258                         | VB_XGI302LV | VB_XGI301C)) {
7259                 if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
7260                                 & TVSimuMode)) {
7261                         *tempbx += 8;
7262                         *tempcl += 1;
7263                 }
7264         }
7265
7266         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
7267                         | VB_XGI302LV | VB_XGI301C))
7268                 (*tempch)++;
7269 }
7270
7271 static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
7272 {
7273         unsigned short index;
7274
7275         unsigned char tempah, tempbl, tempbh;
7276
7277         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
7278                         | VB_XGI302LV | VB_XGI301C)) {
7279                 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA
7280                                 | SetCRT2ToTV | SetCRT2ToRAMDAC)) {
7281                         tempbl = 0;
7282                         tempbh = 0;
7283
7284                         index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */
7285                         tempbl = pVBInfo->XGI_TVDelayList[index];
7286
7287                         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
7288                                         | VB_XGI301LV | VB_XGI302LV
7289                                         | VB_XGI301C))
7290                                 tempbl = pVBInfo->XGI_TVDelayList2[index];
7291
7292                         if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
7293                                 tempbl = tempbl >> 4;
7294                         /*
7295                         if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
7296                                 tempbl = CRT2Delay1;    // Get CRT2 Delay
7297                         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
7298                                 tempbl = CRT2Delay2;
7299                         */
7300                         if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
7301                                 index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */
7302                                 tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation;
7303
7304                                 if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
7305                                         tempbl = tempbh;
7306                         }
7307
7308                         tempbl &= 0x0F;
7309                         tempbh &= 0xF0;
7310                         tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x2D);
7311
7312                         if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
7313                                         | SetCRT2ToTV)) { /* Channel B */
7314                                 tempah &= 0xF0;
7315                                 tempah |= tempbl;
7316                         }
7317
7318                         if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */
7319                                 tempah &= 0x0F;
7320                                 tempah |= tempbh;
7321                         }
7322                         XGINew_SetReg1(pVBInfo->Part1Port, 0x2D, tempah);
7323                 }
7324         } else if (pVBInfo->IF_DEF_LVDS == 1) {
7325                 tempbl = 0;
7326                 tempbh = 0;
7327                 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
7328                         tempah
7329                                         = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(
7330                                                         pVBInfo)].LCD_DelayCompensation; /* / Get LCD Delay */
7331                         tempah &= 0x0f;
7332                         tempah = tempah << 4;
7333                         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2D, 0x0f,
7334                                         tempah);
7335                 }
7336         }
7337 }
7338
7339 static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo)
7340 {
7341         unsigned short temp;
7342
7343         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
7344
7345         if (temp & LCDRGB18Bit) {
7346                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
7347                                 (unsigned short) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */
7348                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
7349         } else {
7350                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
7351                                 (unsigned short) (0x30 | (tempcx & 0x00C0)));
7352                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
7353         }
7354
7355         /*
7356         if (tempcx & EnableLCD24bpp) {  // 24bits
7357                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x30 | (tempcx&0x00C0)));
7358                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
7359         } else {
7360                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x20 | (tempcx&0x00C0))); // Enable Dither
7361                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
7362         }
7363         */
7364 }
7365
7366 /* --------------------------------------------------------------------- */
7367 /* Function : XGI_SetLCDCap_B */
7368 /* Input : cx -> LCD Capability */
7369 /* Output : */
7370 /* Description : */
7371 /* --------------------------------------------------------------------- */
7372 static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo)
7373 {
7374         if (tempcx & EnableLCD24bpp) /* 24bits */
7375                 XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
7376                                 (unsigned short) (((tempcx & 0x00ff) >> 6)
7377                                                 | 0x0c));
7378         else
7379                 XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
7380                                 (unsigned short) (((tempcx & 0x00ff) >> 6)
7381                                                 | 0x18)); /* Enable Dither */
7382 }
7383
7384 static void SetSpectrum(struct vb_device_info *pVBInfo)
7385 {
7386         unsigned short index;
7387
7388         index = XGI_GetLCDCapPtr(pVBInfo);
7389
7390         XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */
7391         XGI_LongWait(pVBInfo);
7392         XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
7393         XGI_LongWait(pVBInfo);
7394
7395         XGINew_SetReg1(pVBInfo->Part4Port, 0x31,
7396                         pVBInfo->LCDCapList[index].Spectrum_31);
7397         XGINew_SetReg1(pVBInfo->Part4Port, 0x32,
7398                         pVBInfo->LCDCapList[index].Spectrum_32);
7399         XGINew_SetReg1(pVBInfo->Part4Port, 0x33,
7400                         pVBInfo->LCDCapList[index].Spectrum_33);
7401         XGINew_SetReg1(pVBInfo->Part4Port, 0x34,
7402                         pVBInfo->LCDCapList[index].Spectrum_34);
7403         XGI_LongWait(pVBInfo);
7404         XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
7405 }
7406
7407 static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
7408 {
7409         unsigned short tempcx;
7410
7411         tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
7412
7413         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
7414                         | VB_XGI302LV | VB_XGI301C)) {
7415                 if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */
7416                         /* Set 301LV Capability */
7417                         XGINew_SetReg1(pVBInfo->Part4Port, 0x24,
7418                                         (unsigned char) (tempcx & 0x1F));
7419                 }
7420                 /* VB Driving */
7421                 XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D,
7422                                 ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
7423                                 (unsigned short) ((tempcx & (EnableVBCLKDRVLOW
7424                                                 | EnablePLLSPLOW)) >> 8));
7425         }
7426
7427         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
7428                         | VB_XGI302LV | VB_XGI301C)) {
7429                 if (pVBInfo->VBInfo & SetCRT2ToLCD)
7430                         XGI_SetLCDCap_B(tempcx, pVBInfo);
7431                 else if (pVBInfo->VBInfo & SetCRT2ToLCDA)
7432                         XGI_SetLCDCap_A(tempcx, pVBInfo);
7433
7434                 if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
7435                         if (tempcx & EnableSpectrum)
7436                                 SetSpectrum(pVBInfo);
7437                 }
7438         } else {
7439                 /* LVDS,CH7017 */
7440                 XGI_SetLCDCap_A(tempcx, pVBInfo);
7441         }
7442 }
7443
7444 /* --------------------------------------------------------------------- */
7445 /* Function : XGI_SetAntiFlicker */
7446 /* Input : */
7447 /* Output : */
7448 /* Description : Set TV Customized Param. */
7449 /* --------------------------------------------------------------------- */
7450 static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex,
7451                 struct vb_device_info *pVBInfo)
7452 {
7453         unsigned short tempbx, index;
7454
7455         unsigned char tempah;
7456
7457         if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
7458                 return;
7459
7460         tempbx = XGI_GetTVPtrIndex(pVBInfo);
7461         tempbx &= 0xFE;
7462
7463         if (ModeNo <= 0x13)
7464                 index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
7465         else
7466                 index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
7467
7468         tempbx += index;
7469         tempah = TVAntiFlickList[tempbx];
7470         tempah = tempah << 4;
7471
7472         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
7473 }
7474
7475 static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex,
7476                 struct vb_device_info *pVBInfo)
7477 {
7478         unsigned short tempbx, index;
7479
7480         unsigned char tempah;
7481
7482         tempbx = XGI_GetTVPtrIndex(pVBInfo);
7483         tempbx &= 0xFE;
7484
7485         if (ModeNo <= 0x13)
7486                 index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
7487         else
7488                 index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
7489
7490         tempbx += index;
7491         tempah = TVEdgeList[tempbx];
7492         tempah = tempah << 5;
7493
7494         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
7495 }
7496
7497 static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
7498 {
7499         unsigned short tempbx;
7500
7501         unsigned char tempcl, tempch;
7502
7503         unsigned long tempData;
7504
7505         XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
7506         tempData = TVPhaseList[tempbx];
7507
7508         XGINew_SetReg1(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData
7509                         & 0x000000FF));
7510         XGINew_SetReg1(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData
7511                         & 0x0000FF00) >> 8));
7512         XGINew_SetReg1(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData
7513                         & 0x00FF0000) >> 16));
7514         XGINew_SetReg1(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData
7515                         & 0xFF000000) >> 24));
7516 }
7517
7518 static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
7519                 struct vb_device_info *pVBInfo)
7520 {
7521         unsigned short tempbx, index;
7522
7523         unsigned char tempcl, tempch, tempal, *filterPtr;
7524
7525         XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
7526
7527         switch (tempbx) {
7528         case 0x00:
7529         case 0x04:
7530                 filterPtr = NTSCYFilter1;
7531                 break;
7532
7533         case 0x01:
7534                 filterPtr = PALYFilter1;
7535                 break;
7536
7537         case 0x02:
7538         case 0x05:
7539         case 0x0D:
7540                 filterPtr = PALMYFilter1;
7541                 break;
7542
7543         case 0x03:
7544                 filterPtr = PALNYFilter1;
7545                 break;
7546
7547         case 0x08:
7548         case 0x0C:
7549                 filterPtr = NTSCYFilter2;
7550                 break;
7551
7552         case 0x0A:
7553                 filterPtr = PALMYFilter2;
7554                 break;
7555
7556         case 0x0B:
7557                 filterPtr = PALNYFilter2;
7558                 break;
7559
7560         case 0x09:
7561                 filterPtr = PALYFilter2;
7562                 break;
7563
7564         default:
7565                 return;
7566         }
7567
7568         if (ModeNo <= 0x13)
7569                 tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
7570         else
7571                 tempal
7572                                 = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
7573
7574         if (tempcl == 0)
7575                 index = tempal * 4;
7576         else
7577                 index = tempal * 7;
7578
7579         if ((tempcl == 0) && (tempch == 1)) {
7580                 XGINew_SetReg1(pVBInfo->Part2Port, 0x35, 0);
7581                 XGINew_SetReg1(pVBInfo->Part2Port, 0x36, 0);
7582                 XGINew_SetReg1(pVBInfo->Part2Port, 0x37, 0);
7583                 XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
7584         } else {
7585                 XGINew_SetReg1(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
7586                 XGINew_SetReg1(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
7587                 XGINew_SetReg1(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
7588                 XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
7589         }
7590
7591         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
7592                         | VB_XGI302LV | VB_XGI301C)) {
7593                 XGINew_SetReg1(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
7594                 XGINew_SetReg1(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
7595                 XGINew_SetReg1(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
7596         }
7597 }
7598
7599 /* --------------------------------------------------------------------- */
7600 /* Function : XGI_OEM310Setting */
7601 /* Input : */
7602 /* Output : */
7603 /* Description : Customized Param. for 301 */
7604 /* --------------------------------------------------------------------- */
7605 static void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex,
7606                 struct vb_device_info *pVBInfo)
7607 {
7608         if (pVBInfo->SetFlag & Win9xDOSMode)
7609                 return;
7610
7611         /* GetPart1IO(); */
7612         XGI_SetDelayComp(pVBInfo);
7613
7614         if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
7615                 XGI_SetLCDCap(pVBInfo);
7616
7617         if (pVBInfo->VBInfo & SetCRT2ToTV) {
7618                 /* GetPart2IO() */
7619                 XGI_SetPhaseIncr(pVBInfo);
7620                 XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
7621                 XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
7622
7623                 if (pVBInfo->VBType & VB_XGI301)
7624                         XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
7625         }
7626 }
7627
7628 /* --------------------------------------------------------------------- */
7629 /* Function : XGI_SetCRT2ModeRegs */
7630 /* Input : */
7631 /* Output : */
7632 /* Description : Origin code for crt2group */
7633 /* --------------------------------------------------------------------- */
7634 void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
7635                 struct xgi_hw_device_info *HwDeviceExtension,
7636                 struct vb_device_info *pVBInfo)
7637 {
7638         unsigned short tempbl;
7639         short tempcl;
7640
7641         unsigned char tempah;
7642
7643         /* XGINew_SetReg1(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */
7644         tempah = 0;
7645         if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
7646                 tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00);
7647                 tempah &= ~0x10; /* BTRAMDAC */
7648                 tempah |= 0x40; /* BTRAM */
7649
7650                 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
7651                                 | SetCRT2ToLCD)) {
7652                         tempah = 0x40; /* BTDRAM */
7653                         if (ModeNo > 0x13) {
7654                                 tempcl = pVBInfo->ModeType;
7655                                 tempcl -= ModeVGA;
7656                                 if (tempcl >= 0) {
7657                                         tempah = (0x008 >> tempcl); /* BT Color */
7658                                         if (tempah == 0)
7659                                                 tempah = 1;
7660                                         tempah |= 0x040;
7661                                 }
7662                         }
7663                         if (pVBInfo->VBInfo & SetInSlaveMode)
7664                                 tempah ^= 0x50; /* BTDAC */
7665                 }
7666         }
7667
7668         /* 0210 shampoo
7669         if (pVBInfo->VBInfo & DisableCRT2Display) {
7670                 tempah = 0;
7671         }
7672
7673         XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah);
7674         if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
7675                 tempcl = pVBInfo->ModeType;
7676                 if (ModeNo > 0x13) {
7677                         tempcl -= ModeVGA;
7678                         if ((tempcl > 0) || (tempcl == 0)) {
7679                                 tempah=(0x008>>tempcl) ;
7680                                 if (tempah == 0)
7681                                         tempah = 1;
7682                                 tempah |= 0x040;
7683                         }
7684                 } else {
7685                         tempah = 0x040;
7686                 }
7687
7688                 if (pVBInfo->VBInfo & SetInSlaveMode) {
7689                         tempah = (tempah ^ 0x050);
7690                 }
7691         }
7692         */
7693
7694         XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah);
7695         tempah = 0x08;
7696         tempbl = 0xf0;
7697
7698         if (pVBInfo->VBInfo & DisableCRT2Display) {
7699                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
7700         } else {
7701                 tempah = 0x00;
7702                 tempbl = 0xff;
7703
7704                 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
7705                                 | SetCRT2ToLCD | SetCRT2ToLCDA)) {
7706                         if ((pVBInfo->VBInfo & SetCRT2ToLCDA)
7707                                         && (!(pVBInfo->VBInfo & SetSimuScanMode))) {
7708                                 tempbl &= 0xf7;
7709                                 tempah |= 0x01;
7710                                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e,
7711                                                 tempbl, tempah);
7712                         } else {
7713                                 if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
7714                                         tempbl &= 0xf7;
7715                                         tempah |= 0x01;
7716                                 }
7717
7718                                 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
7719                                                 | SetCRT2ToTV | SetCRT2ToLCD)) {
7720                                         tempbl &= 0xf8;
7721                                         tempah = 0x01;
7722
7723                                         if (!(pVBInfo->VBInfo & SetInSlaveMode))
7724                                                 tempah |= 0x02;
7725
7726                                         if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
7727                                                 tempah = tempah ^ 0x05;
7728                                                 if (!(pVBInfo->VBInfo
7729                                                                 & SetCRT2ToLCD))
7730                                                         tempah = tempah ^ 0x01;
7731                                         }
7732
7733                                         if (!(pVBInfo->VBInfo
7734                                                         & SetCRT2ToDualEdge))
7735                                                 tempah |= 0x08;
7736                                         XGINew_SetRegANDOR(pVBInfo->Part1Port,
7737                                                         0x2e, tempbl, tempah);
7738                                 } else {
7739                                         XGINew_SetRegANDOR(pVBInfo->Part1Port,
7740                                                         0x2e, tempbl, tempah);
7741                                 }
7742                         }
7743                 } else {
7744                         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl,
7745                                         tempah);
7746                 }
7747         }
7748
7749         if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
7750                         | SetCRT2ToLCDA)) {
7751                 tempah &= (~0x08);
7752                 if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
7753                                 & SetInSlaveMode))) {
7754                         tempah |= 0x010;
7755                 }
7756                 tempah |= 0x080;
7757
7758                 if (pVBInfo->VBInfo & SetCRT2ToTV) {
7759                         /* if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { */
7760                         tempah |= 0x020;
7761                         if (ModeNo > 0x13) {
7762                                 if (pVBInfo->VBInfo & DriverMode)
7763                                         tempah = tempah ^ 0x20;
7764                         }
7765                         /* } */
7766                 }
7767
7768                 XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
7769                 tempah = 0;
7770
7771                 if (pVBInfo->LCDInfo & SetLCDDualLink)
7772                         tempah |= 0x40;
7773
7774                 if (pVBInfo->VBInfo & SetCRT2ToTV) {
7775                         /* if ((!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) && (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))) { */
7776                         if (pVBInfo->TVInfo & RPLLDIV2XO)
7777                                 tempah |= 0x40;
7778                         /* } */
7779                 }
7780
7781                 if ((pVBInfo->LCDResInfo == Panel1280x1024)
7782                                 || (pVBInfo->LCDResInfo == Panel1280x1024x75))
7783                         tempah |= 0x80;
7784
7785                 if (pVBInfo->LCDResInfo == Panel1280x960)
7786                         tempah |= 0x80;
7787
7788                 XGINew_SetReg1(pVBInfo->Part4Port, 0x0C, tempah);
7789         }
7790
7791         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
7792                         | VB_XGI302LV | VB_XGI301C)) {
7793                 tempah = 0;
7794                 tempbl = 0xfb;
7795
7796                 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
7797                         tempbl = 0xff;
7798                         if (pVBInfo->VBInfo & SetCRT2ToLCDA)
7799                                 tempah |= 0x04; /* shampoo 0129 */
7800                 }
7801
7802                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x13, tempbl, tempah);
7803                 tempah = 0x00;
7804                 tempbl = 0xcf;
7805                 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
7806                         if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
7807                                 tempah |= 0x30;
7808                 }
7809
7810                 XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
7811                 tempah = 0;
7812                 tempbl = 0x3f;
7813
7814                 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
7815                         if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
7816                                 tempah |= 0xc0;
7817                 }
7818                 XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, tempbl, tempah);
7819         }
7820
7821         tempah = 0;
7822         tempbl = 0x7f;
7823         if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) {
7824                 tempbl = 0xff;
7825                 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
7826                         tempah |= 0x80;
7827         }
7828
7829         XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x23, tempbl, tempah);
7830
7831         if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
7832                 if (pVBInfo->LCDInfo & SetLCDDualLink) {
7833                         XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x20);
7834                         XGINew_SetRegOR(pVBInfo->Part4Port, 0x34, 0x10);
7835                 }
7836         }
7837 }
7838
7839 static void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension,
7840                 struct vb_device_info *pVBInfo)
7841 {
7842         unsigned short tempbx;
7843
7844         tempbx = 0;
7845
7846         if (pVBInfo->VBInfo & SetCRT2ToLCDA)
7847                 tempbx = 0x08A0;
7848
7849 }
7850
7851 void XGI_OpenCRTC(struct xgi_hw_device_info *HwDeviceExtension,
7852                 struct vb_device_info *pVBInfo)
7853 {
7854         unsigned short tempbx;
7855         tempbx = 0;
7856 }
7857
7858 void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
7859                 struct vb_device_info *pVBInfo)
7860 {
7861
7862         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
7863
7864 }
7865
7866 void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
7867                 struct vb_device_info *pVBInfo)
7868 {
7869
7870         XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
7871
7872 }
7873
7874 unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo)
7875 {
7876         unsigned short flag;
7877
7878         if (pVBInfo->IF_DEF_LVDS == 1) {
7879                 return 1;
7880         } else {
7881                 flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00);
7882                 if ((flag == 1) || (flag == 2))
7883                         return 1; /* 301b */
7884                 else
7885                         return 0;
7886         }
7887 }
7888
7889 void XGI_LongWait(struct vb_device_info *pVBInfo)
7890 {
7891         unsigned short i;
7892
7893         i = XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
7894
7895         if (!(i & 0xC0)) {
7896                 for (i = 0; i < 0xFFFF; i++) {
7897                         if (!(XGINew_GetReg2(pVBInfo->P3da) & 0x08))
7898                                 break;
7899                 }
7900
7901                 for (i = 0; i < 0xFFFF; i++) {
7902                         if ((XGINew_GetReg2(pVBInfo->P3da) & 0x08))
7903                                 break;
7904                 }
7905         }
7906 }
7907
7908 static void XGI_VBLongWait(struct vb_device_info *pVBInfo)
7909 {
7910         unsigned short tempal, temp, i, j;
7911         return;
7912         if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
7913                 temp = 0;
7914                 for (i = 0; i < 3; i++) {
7915                         for (j = 0; j < 100; j++) {
7916                                 tempal = XGINew_GetReg2(pVBInfo->P3da);
7917                                 if (temp & 0x01) { /* VBWaitMode2 */
7918                                         if ((tempal & 0x08))
7919                                                 continue;
7920
7921                                         if (!(tempal & 0x08))
7922                                                 break;
7923
7924                                 } else { /* VBWaitMode1 */
7925                                         if (!(tempal & 0x08))
7926                                                 continue;
7927
7928                                         if ((tempal & 0x08))
7929                                                 break;
7930                                 }
7931                         }
7932                         temp = temp ^ 0x01;
7933                 }
7934         } else {
7935                 XGI_LongWait(pVBInfo);
7936         }
7937         return;
7938 }
7939
7940 unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
7941                 unsigned short ModeNo, unsigned short ModeIdIndex,
7942                 struct vb_device_info *pVBInfo)
7943 {
7944         short LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 },
7945                         LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01,
7946                                         0x01, 0x01 };
7947
7948         unsigned short RefreshRateTableIndex, i, modeflag, index, temp;
7949
7950         if (ModeNo <= 0x13)
7951                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
7952         else
7953                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7954
7955         if (pVBInfo->IF_DEF_CH7005 == 1) {
7956                 if (pVBInfo->VBInfo & SetCRT2ToTV) {
7957                         if (modeflag & HalfDCLK)
7958                                 return 0;
7959                 }
7960         }
7961
7962         if (ModeNo < 0x14)
7963                 return 0xFFFF;
7964
7965         index = XGINew_GetReg1(pVBInfo->P3d4, 0x33);
7966         index = index >> pVBInfo->SelectCRT2Rate;
7967         index &= 0x0F;
7968
7969         if (pVBInfo->LCDInfo & LCDNonExpanding)
7970                 index = 0;
7971
7972         if (index > 0)
7973                 index--;
7974
7975         if (pVBInfo->SetFlag & ProgrammingCRT2) {
7976                 if (pVBInfo->IF_DEF_CH7005 == 1) {
7977                         if (pVBInfo->VBInfo & SetCRT2ToTV)
7978                                 index = 0;
7979                 }
7980
7981                 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
7982                         if (pVBInfo->IF_DEF_LVDS == 0) {
7983                                 if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
7984                                                 | VB_XGI301LV | VB_XGI302LV
7985                                                 | VB_XGI301C))
7986                                         temp
7987                                                         = LCDARefreshIndex[pVBInfo->LCDResInfo
7988                                                                         & 0x0F]; /* 301b */
7989                                 else
7990                                         temp
7991                                                         = LCDRefreshIndex[pVBInfo->LCDResInfo
7992                                                                         & 0x0F];
7993
7994                                 if (index > temp)
7995                                         index = temp;
7996                         } else {
7997                                 index = 0;
7998                         }
7999                 }
8000         }
8001
8002         RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
8003         ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
8004         if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
8005                 /*
8006                 if (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & XG2xNotSupport) {
8007                         index++;
8008                 }
8009                 */
8010                 if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800)
8011                                 && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
8012                                                 == 600)) {
8013                         index++;
8014                 }
8015                 /* Alan 10/19/2007; do the similiar adjustment like XGISearchCRT1Rate() */
8016                 if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024)
8017                                 && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
8018                                                 == 768)) {
8019                         index++;
8020                 }
8021                 if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280)
8022                                 && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
8023                                                 == 1024)) {
8024                         index++;
8025                 }
8026         }
8027
8028         i = 0;
8029         do {
8030                 if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID
8031                                 != ModeNo)
8032                         break;
8033                 temp
8034                                 = pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
8035                 temp &= ModeInfoFlag;
8036                 if (temp < pVBInfo->ModeType)
8037                         break;
8038                 i++;
8039                 index--;
8040
8041         } while (index != 0xFFFF);
8042         if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
8043                 if (pVBInfo->VBInfo & SetInSlaveMode) {
8044                         temp
8045                                         = pVBInfo->RefIndex[RefreshRateTableIndex
8046                                                         + i - 1].Ext_InfoFlag;
8047                         if (temp & InterlaceMode)
8048                                 i++;
8049                 }
8050         }
8051         i--;
8052         if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
8053                 temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex,
8054                                 RefreshRateTableIndex, &i, pVBInfo);
8055         }
8056         return RefreshRateTableIndex + i; /* return (0x01 | (temp1<<1)); */
8057 }
8058
8059 static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
8060                 struct xgi_hw_device_info *HwDeviceExtension,
8061                 struct vb_device_info *pVBInfo)
8062 {
8063         unsigned short RefreshRateTableIndex;
8064         /* unsigned short temp ; */
8065
8066         /* pVBInfo->SelectCRT2Rate = 0; */
8067
8068         pVBInfo->SetFlag |= ProgrammingCRT2;
8069         RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
8070                         ModeIdIndex, pVBInfo);
8071         XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
8072         XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
8073         XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
8074                         HwDeviceExtension, pVBInfo);
8075         XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
8076         XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
8077 }
8078
8079 unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
8080                 struct xgi_hw_device_info *HwDeviceExtension,
8081                 struct vb_device_info *pVBInfo)
8082 {
8083         unsigned short tempbx, ModeIdIndex, RefreshRateTableIndex;
8084
8085         tempbx = pVBInfo->VBInfo;
8086         pVBInfo->SetFlag |= ProgrammingCRT2;
8087         XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
8088         pVBInfo->SelectCRT2Rate = 4;
8089         RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
8090                         ModeIdIndex, pVBInfo);
8091         XGI_SaveCRT2Info(ModeNo, pVBInfo);
8092         XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
8093         XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
8094         XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
8095                         RefreshRateTableIndex, pVBInfo);
8096         XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
8097                         RefreshRateTableIndex, pVBInfo);
8098         XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
8099                         RefreshRateTableIndex, pVBInfo);
8100         XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
8101                         HwDeviceExtension, pVBInfo);
8102         XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
8103                         RefreshRateTableIndex, pVBInfo);
8104         XGI_SetTap4Regs(pVBInfo);
8105         XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
8106         XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
8107                         HwDeviceExtension, pVBInfo);
8108         XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
8109         XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
8110         XGI_AutoThreshold(pVBInfo);
8111         return 1;
8112 }
8113
8114 void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
8115 {
8116         unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
8117                         0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
8118                         0x05, 0x00 };
8119
8120         unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
8121
8122         unsigned char CR17, CR63, SR31;
8123         unsigned short temp;
8124         unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
8125
8126         int i;
8127         XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
8128
8129         /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
8130         XGINew_SetReg1(pVBInfo->P3d4, 0x57, 0x4A);
8131         XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1(
8132                         pVBInfo->P3d4, 0x53) | 0x02));
8133
8134         SR31 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x31);
8135         CR63 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x63);
8136         SR01 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x01);
8137
8138         XGINew_SetReg1(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF));
8139         XGINew_SetReg1(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF));
8140
8141         CR17 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x17);
8142         XGINew_SetReg1(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80));
8143
8144         SR1F = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
8145         XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04));
8146
8147         SR07 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x07);
8148         XGINew_SetReg1(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB));
8149         SR06 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x06);
8150         XGINew_SetReg1(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3));
8151
8152         XGINew_SetReg1(pVBInfo->P3d4, 0x11, 0x00);
8153
8154         for (i = 0; i < 8; i++)
8155                 XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]);
8156
8157         for (i = 8; i < 11; i++)
8158                 XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 8),
8159                                 CRTCData[i]);
8160
8161         for (i = 11; i < 13; i++)
8162                 XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 4),
8163                                 CRTCData[i]);
8164
8165         for (i = 13; i < 16; i++)
8166                 XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i - 3),
8167                                 CRTCData[i]);
8168
8169         XGINew_SetReg1(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16]
8170                         & 0xE0));
8171
8172         XGINew_SetReg1(pVBInfo->P3c4, 0x31, 0x00);
8173         XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B);
8174         XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE1);
8175
8176         XGINew_SetReg3(pVBInfo->P3c8, 0x00);
8177
8178         for (i = 0; i < 256; i++) {
8179                 XGINew_SetReg3((pVBInfo->P3c8 + 1),
8180                                 (unsigned char) DAC_TEST_PARMS[0]);
8181                 XGINew_SetReg3((pVBInfo->P3c8 + 1),
8182                                 (unsigned char) DAC_TEST_PARMS[1]);
8183                 XGINew_SetReg3((pVBInfo->P3c8 + 1),
8184                                 (unsigned char) DAC_TEST_PARMS[2]);
8185         }
8186
8187         XGI_VBLongWait(pVBInfo);
8188         XGI_VBLongWait(pVBInfo);
8189         XGI_VBLongWait(pVBInfo);
8190
8191         mdelay(1);
8192
8193         XGI_WaitDisply(pVBInfo);
8194         temp = XGINew_GetReg2(pVBInfo->P3c2);
8195
8196         if (temp & 0x10)
8197                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
8198         else
8199                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
8200
8201         /* alan, avoid display something, set BLACK DAC if not restore DAC */
8202         XGINew_SetReg3(pVBInfo->P3c8, 0x00);
8203
8204         for (i = 0; i < 256; i++) {
8205                 XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
8206                 XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
8207                 XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
8208         }
8209
8210         XGINew_SetReg1(pVBInfo->P3c4, 0x01, SR01);
8211         XGINew_SetReg1(pVBInfo->P3d4, 0x63, CR63);
8212         XGINew_SetReg1(pVBInfo->P3c4, 0x31, SR31);
8213
8214         /* [2004/05/11] Vicent */
8215         XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1(
8216                         pVBInfo->P3d4, 0x53) & 0xFD));
8217         XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
8218 }
8219
8220 void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension,
8221                 struct vb_device_info *pVBInfo)
8222 {
8223         unsigned short tempbl, tempah;
8224
8225         if (pVBInfo->SetFlag == Win9xDOSMode) {
8226                 if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
8227                                 | VB_XGI302LV | VB_XGI301C)) {
8228                         XGI_DisplayOn(HwDeviceExtension, pVBInfo);
8229                         return;
8230                 } else
8231                         /* LVDS or CH7017 */
8232                         return;
8233         }
8234
8235         if (HwDeviceExtension->jChipType < XG40) {
8236                 if (!XGI_DisableChISLCD(pVBInfo)) {
8237                         if ((XGI_EnableChISLCD(pVBInfo)) || (pVBInfo->VBInfo
8238                                         & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
8239                                 if (pVBInfo->LCDInfo & SetPWDEnable) {
8240                                         XGI_EnablePWD(pVBInfo);
8241                                 } else {
8242                                         pVBInfo->LCDInfo &= (~SetPWDEnable);
8243                                         if (pVBInfo->VBType & (VB_XGI301LV
8244                                                         | VB_XGI302LV
8245                                                         | VB_XGI301C)) {
8246                                                 tempbl = 0xFD;
8247                                                 tempah = 0x02;
8248                                         } else {
8249                                                 tempbl = 0xFB;
8250                                                 tempah = 0x00;
8251                                         }
8252
8253                                         XGI_SetPanelPower(tempah, tempbl,
8254                                                         pVBInfo);
8255                                         XGI_SetPanelDelay(1, pVBInfo);
8256                                 }
8257                         }
8258                 }
8259         } /* Not 340 */
8260
8261         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
8262                         | VB_XGI302LV | VB_XGI301C)) {
8263                 if (!(pVBInfo->SetFlag & DisableChA)) {
8264                         if (pVBInfo->SetFlag & EnableChA) {
8265                                 XGINew_SetReg1(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
8266                         } else {
8267                                 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */
8268                                         XGINew_SetReg1(pVBInfo->Part1Port,
8269                                                         0x1E, 0x20); /* Power on */
8270                                 }
8271                         }
8272                 }
8273
8274                 if (!(pVBInfo->SetFlag & DisableChB)) {
8275                         if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo
8276                                         & (SetCRT2ToLCD | SetCRT2ToTV
8277                                                         | SetCRT2ToRAMDAC))) {
8278                                 tempah = (unsigned char) XGINew_GetReg1(
8279                                                 pVBInfo->P3c4, 0x32);
8280                                 tempah &= 0xDF;
8281                                 if (pVBInfo->VBInfo & SetInSlaveMode) {
8282                                         if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
8283                                                 tempah |= 0x20;
8284                                 }
8285                                 XGINew_SetReg1(pVBInfo->P3c4, 0x32, tempah);
8286                                 XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x20);
8287
8288                                 tempah = (unsigned char) XGINew_GetReg1(
8289                                                 pVBInfo->Part1Port, 0x2E);
8290
8291                                 if (!(tempah & 0x80))
8292                                         XGINew_SetRegOR(pVBInfo->Part1Port,
8293                                                         0x2E, 0x80); /* BVBDOENABLE = 1 */
8294
8295                                 XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */
8296                         }
8297                 }
8298
8299                 if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
8300                                 || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
8301                         XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x00, ~0xE0,
8302                                         0x20); /* shampoo 0129 */
8303                         if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
8304                                 if (!XGI_DisableChISLCD(pVBInfo)) {
8305                                         if (XGI_EnableChISLCD(pVBInfo)
8306                                                         || (pVBInfo->VBInfo
8307                                                                         & (SetCRT2ToLCD
8308                                                                                         | SetCRT2ToLCDA)))
8309                                                 XGINew_SetRegAND(
8310                                                                 pVBInfo->Part4Port,
8311                                                                 0x2A, 0x7F); /* LVDS PLL power on */
8312                                 }
8313                                 XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */
8314                         }
8315                 }
8316
8317                 tempah = 0x00;
8318
8319                 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
8320                         tempah = 0xc0;
8321
8322                         if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
8323                                 if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
8324                                         if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
8325                                                 tempah = tempah & 0x40;
8326                                                 if (pVBInfo->VBInfo
8327                                                                 & SetCRT2ToLCDA)
8328                                                         tempah = tempah ^ 0xC0;
8329
8330                                                 if (pVBInfo->SetFlag
8331                                                                 & DisableChB)
8332                                                         tempah &= 0xBF;
8333
8334                                                 if (pVBInfo->SetFlag
8335                                                                 & DisableChA)
8336                                                         tempah &= 0x7F;
8337
8338                                                 if (pVBInfo->SetFlag
8339                                                                 & EnableChB)
8340                                                         tempah |= 0x40;
8341
8342                                                 if (pVBInfo->SetFlag
8343                                                                 & EnableChA)
8344                                                         tempah |= 0x80;
8345                                         }
8346                                 }
8347                         }
8348                 }
8349
8350                 XGINew_SetRegOR(pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */
8351
8352                 if (pVBInfo->SetFlag & Win9xDOSMode) {
8353                         XGI_DisplayOn(HwDeviceExtension, pVBInfo);
8354                         return;
8355                 }
8356
8357                 if (!(pVBInfo->SetFlag & DisableChA)) {
8358                         XGI_VBLongWait(pVBInfo);
8359                         if (!(pVBInfo->SetFlag & GatingCRT)) {
8360                                 XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo);
8361                                 XGI_DisplayOn(HwDeviceExtension, pVBInfo);
8362                                 XGI_VBLongWait(pVBInfo);
8363                         }
8364                 }
8365         } /* 301 */
8366         else { /* LVDS */
8367                 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
8368                                 | SetCRT2ToLCDA))
8369                         XGINew_SetRegOR(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */
8370
8371                 tempah = (unsigned char) XGINew_GetReg1(pVBInfo->Part1Port,
8372                                 0x2E);
8373                 if (!(tempah & 0x80))
8374                         XGINew_SetRegOR(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
8375
8376                 XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F);
8377                 XGI_DisplayOn(HwDeviceExtension, pVBInfo);
8378         } /* End of VB */
8379
8380         if (HwDeviceExtension->jChipType < XG40) {
8381                 if (!XGI_EnableChISLCD(pVBInfo)) {
8382                         if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8383                                 if (XGI_BacklightByDrv(pVBInfo))
8384                                         return;
8385                         } else
8386                                 return;
8387                 }
8388
8389                 if (pVBInfo->LCDInfo & SetPWDEnable) {
8390                         XGI_FirePWDEnable(pVBInfo);
8391                         return;
8392                 }
8393
8394                 XGI_SetPanelDelay(2, pVBInfo);
8395
8396                 if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
8397                         tempah = 0x01;
8398                         tempbl = 0xFE; /* turn on backlght */
8399                 } else {
8400                         tempbl = 0xF7;
8401                         tempah = 0x00;
8402                 }
8403                 XGI_SetPanelPower(tempah, tempbl, pVBInfo);
8404         }
8405 }
8406
8407 static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension,
8408                 unsigned short ModeNo, unsigned short ModeIdIndex,
8409                 struct vb_device_info *pVBInfo)
8410 {
8411         unsigned short StandTableIndex, RefreshRateTableIndex, b3CC, temp;
8412
8413         unsigned short XGINew_P3cc = pVBInfo->P3cc;
8414
8415         /* XGINew_CRT1Mode = ModeNo; // SaveModeID */
8416         StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
8417         /* XGI_SetBIOSData(ModeNo, ModeIdIndex); */
8418         /* XGI_ClearBankRegs(ModeNo, ModeIdIndex); */
8419         XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
8420         XGI_SetMiscRegs(StandTableIndex, pVBInfo);
8421         XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo);
8422         XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
8423         XGI_SetGRCRegs(StandTableIndex, pVBInfo);
8424         XGI_ClearExt1Regs(pVBInfo);
8425
8426         /* if (pVBInfo->IF_DEF_ExpLink) */
8427         if (HwDeviceExtension->jChipType == XG27) {
8428                 if (pVBInfo->IF_DEF_LVDS == 0)
8429                         XGI_SetDefaultVCLK(pVBInfo);
8430         }
8431
8432         temp = ~ProgrammingCRT2;
8433         pVBInfo->SetFlag &= temp;
8434         pVBInfo->SelectCRT2Rate = 0;
8435
8436         if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
8437                         | VB_XGI302LV | VB_XGI301C)) {
8438                 if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA
8439                                 | SetInSlaveMode)) {
8440                         pVBInfo->SetFlag |= ProgrammingCRT2;
8441                 }
8442         }
8443
8444         RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
8445                         ModeIdIndex, pVBInfo);
8446         if (RefreshRateTableIndex != 0xFFFF) {
8447                 XGI_SetSync(RefreshRateTableIndex, pVBInfo);
8448                 XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex,
8449                                 pVBInfo, HwDeviceExtension);
8450                 XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
8451                                 RefreshRateTableIndex, pVBInfo);
8452                 XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
8453                                 HwDeviceExtension, pVBInfo);
8454                 XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
8455                                 RefreshRateTableIndex, pVBInfo);
8456         }
8457
8458         if ((HwDeviceExtension->jChipType >= XG20)
8459                         && (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */
8460                 if ((ModeNo == 0x00) | (ModeNo == 0x01)) {
8461                         XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x4E);
8462                         XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE9);
8463                         b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc);
8464                         XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C));
8465                 } else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo
8466                                 == 0x0D)) {
8467                         XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B);
8468                         XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE3);
8469                         b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc);
8470                         XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C));
8471                 }
8472         }
8473
8474         if (HwDeviceExtension->jChipType >= XG21) {
8475                 temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
8476                 if (temp & 0xA0) {
8477
8478                         /* XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */
8479                         /* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* P. DWN */
8480                         /* XG21 CRT1 Timing */
8481                         if (HwDeviceExtension->jChipType == XG27)
8482                                 XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
8483                                                 RefreshRateTableIndex, pVBInfo);
8484                         else
8485                                 XGI_SetXG21CRTC(ModeNo, ModeIdIndex,
8486                                                 RefreshRateTableIndex, pVBInfo);
8487
8488                         XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
8489                                         RefreshRateTableIndex);
8490
8491                         if (HwDeviceExtension->jChipType == XG27)
8492                                 XGI_SetXG27LCD(pVBInfo, RefreshRateTableIndex,
8493                                                 ModeNo);
8494                         else
8495                                 XGI_SetXG21LCD(pVBInfo, RefreshRateTableIndex,
8496                                                 ModeNo);
8497
8498                         if (pVBInfo->IF_DEF_LVDS == 1) {
8499                                 if (HwDeviceExtension->jChipType == XG27)
8500                                         XGI_SetXG27LVDSPara(ModeNo,
8501                                                         ModeIdIndex, pVBInfo);
8502                                 else
8503                                         XGI_SetXG21LVDSPara(ModeNo,
8504                                                         ModeIdIndex, pVBInfo);
8505                         }
8506                         /* XGINew_SetRegOR(pVBInfo->P3d4, 0x48, 0x20); *//* P. ON */
8507                 }
8508         }
8509
8510         pVBInfo->SetFlag &= (~ProgrammingCRT2);
8511         XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
8512         XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
8513                         RefreshRateTableIndex, pVBInfo);
8514
8515         /* XGI_LoadCharacter(); //dif ifdef TVFont */
8516
8517         XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
8518         /* XGI_ClearBuffer(HwDeviceExtension, ModeNo, pVBInfo); */
8519 }
8520
8521 unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
8522                         unsigned short ModeNo)
8523 {
8524         unsigned short ModeIdIndex;
8525         /* unsigned char *pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; */
8526         struct vb_device_info VBINF;
8527         struct vb_device_info *pVBInfo = &VBINF;
8528         pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
8529         pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
8530         pVBInfo->IF_DEF_LVDS = 0;
8531         pVBInfo->IF_DEF_CH7005 = 0;
8532         pVBInfo->IF_DEF_LCDA = 1;
8533         pVBInfo->IF_DEF_CH7017 = 0;
8534         pVBInfo->IF_DEF_CH7007 = 0; /* [Billy] 2007/05/14 */
8535         pVBInfo->IF_DEF_VideoCapture = 0;
8536         pVBInfo->IF_DEF_ScaleLCD = 0;
8537         pVBInfo->IF_DEF_OEMUtil = 0;
8538         pVBInfo->IF_DEF_PWD = 0;
8539
8540         if (HwDeviceExtension->jChipType >= XG20) { /* kuku 2004/06/25 */
8541                 pVBInfo->IF_DEF_YPbPr = 0;
8542                 pVBInfo->IF_DEF_HiVision = 0;
8543                 pVBInfo->IF_DEF_CRT2Monitor = 0;
8544                 pVBInfo->VBType = 0; /*set VBType default 0*/
8545         } else if (HwDeviceExtension->jChipType >= XG40) {
8546                 pVBInfo->IF_DEF_YPbPr = 1;
8547                 pVBInfo->IF_DEF_HiVision = 1;
8548                 pVBInfo->IF_DEF_CRT2Monitor = 1;
8549         } else {
8550                 pVBInfo->IF_DEF_YPbPr = 1;
8551                 pVBInfo->IF_DEF_HiVision = 1;
8552                 pVBInfo->IF_DEF_CRT2Monitor = 0;
8553         }
8554
8555         pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
8556         pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
8557         pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
8558         pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
8559         pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
8560         pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C;
8561         pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
8562         pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
8563         pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
8564         pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
8565         pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
8566         pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
8567         pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
8568         pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
8569         pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
8570         pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
8571         pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
8572         pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
8573
8574         if (HwDeviceExtension->jChipType == XG21) { /* for x86 Linux, XG21 LVDS */
8575                 if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
8576                         pVBInfo->IF_DEF_LVDS = 1;
8577         }
8578         if (HwDeviceExtension->jChipType == XG27) {
8579                 if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
8580                         if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20)
8581                                 pVBInfo->IF_DEF_LVDS = 1;
8582                 }
8583         }
8584
8585         if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
8586                 XGI_GetVBType(pVBInfo);
8587
8588         InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
8589         if (ModeNo & 0x80) {
8590                 ModeNo = ModeNo & 0x7F;
8591                 /* XGINew_flag_clearbuffer = 0; */
8592         }
8593         /* else {
8594                 XGINew_flag_clearbuffer = 1;
8595         }
8596         */
8597         XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
8598
8599         if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */
8600                 XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
8601
8602         XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
8603
8604         XGI_GetVGAType(HwDeviceExtension, pVBInfo);
8605
8606         if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
8607                 XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
8608                 XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
8609                 XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
8610                 XGI_DisableBridge(HwDeviceExtension, pVBInfo);
8611                 /* XGI_OpenCRTC(HwDeviceExtension, pVBInfo); */
8612
8613                 if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
8614                         XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
8615                                         ModeIdIndex, pVBInfo);
8616
8617                         if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
8618                                 XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
8619                                                 HwDeviceExtension, pVBInfo);
8620                         }
8621                 } else {
8622                         if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
8623                                 XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
8624                                                 ModeIdIndex, pVBInfo);
8625                                 if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
8626                                         XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
8627                                                         HwDeviceExtension,
8628                                                         pVBInfo);
8629                                 }
8630                         }
8631                 }
8632
8633                 if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
8634                         switch (HwDeviceExtension->ujVBChipID) {
8635                         case VB_CHIP_301:
8636                                 XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
8637                                                 pVBInfo); /*add for CRT2 */
8638                                 break;
8639
8640                         case VB_CHIP_302:
8641                                 XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
8642                                                 pVBInfo); /*add for CRT2 */
8643                                 break;
8644
8645                         default:
8646                                 break;
8647                         }
8648                 }
8649
8650                 XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
8651                 XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/
8652                 XGI_CloseCRTC(HwDeviceExtension, pVBInfo);
8653                 XGI_EnableBridge(HwDeviceExtension, pVBInfo);
8654         } /* !XG20 */
8655         else {
8656                 if (pVBInfo->IF_DEF_LVDS == 1)
8657                         if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo))
8658                                 return 0;
8659
8660                 if (ModeNo <= 0x13) {
8661                         pVBInfo->ModeType
8662                                         = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
8663                                                         & ModeInfoFlag;
8664                 } else {
8665                         pVBInfo->ModeType
8666                                         = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag
8667                                                         & ModeInfoFlag;
8668                 }
8669
8670                 pVBInfo->SetFlag = 0;
8671                 if (pVBInfo->IF_DEF_CH7007 != 1)
8672                         pVBInfo->VBInfo = DisableCRT2Display;
8673
8674                 XGI_DisplayOff(HwDeviceExtension, pVBInfo);
8675
8676                 XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex,
8677                                 pVBInfo);
8678
8679                 XGI_DisplayOn(HwDeviceExtension, pVBInfo);
8680                 /*
8681                 if (HwDeviceExtension->jChipType == XG21)
8682                         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80);
8683                 */
8684         }
8685
8686         /*
8687         if (ModeNo <= 0x13) {
8688                 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
8689         } else {
8690                 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8691         }
8692         pVBInfo->ModeType = modeflag&ModeInfoFlag;
8693         pVBInfo->SetFlag = 0x00;
8694         pVBInfo->VBInfo = DisableCRT2Display;
8695         temp = XGINew_CheckMemorySize(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
8696
8697         if (temp == 0)
8698                 return (0);
8699
8700         XGI_DisplayOff(HwDeviceExtension, pVBInfo) ;
8701         XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
8702         XGI_DisplayOn(HwDeviceExtension, pVBInfo);
8703         */
8704
8705         XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
8706
8707         if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
8708                 XGI_LockCRT2(HwDeviceExtension, pVBInfo);
8709         }
8710
8711         return 1;
8712 }