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