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