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