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