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