staging/xgifb: Remove duplicated code in loops.
[linux-2.6-block.git] / drivers / staging / xgifb / vb_setmode.c
CommitLineData
d80aaa01 1#include <linux/delay.h>
d7636e0b 2#include "XGIfb.h"
d7636e0b 3
d7636e0b 4#include "vb_def.h"
56810a92 5#include "vb_init.h"
d7636e0b 6#include "vb_util.h"
7#include "vb_table.h"
e054102b 8#include "vb_setmode.h"
d7636e0b 9
10#define IndexMask 0xff
95072592 11#define TVCLKBASE_315_25 (TVCLKBASE_315 + 25)
d7636e0b 12
624554da 13static const unsigned short XGINew_VGA_DAC[] = {
82d6eb5b
BP
14 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
15 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
16 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
17 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
18 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
19 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
20 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
21 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
22 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
23 0x0B, 0x0C, 0x0D, 0x0F, 0x10};
d7636e0b 24
80adad85 25void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
d7636e0b 26{
a7e46d8b 27 pVBInfo->MCLKData = XGI340New_MCLKData;
21df8fc8 28
21df8fc8
PS
29 pVBInfo->LCDResInfo = 0;
30 pVBInfo->LCDTypeInfo = 0;
31 pVBInfo->LCDInfo = 0;
32 pVBInfo->VBInfo = 0;
33 pVBInfo->TVInfo = 0;
34
35 pVBInfo->SR15 = XGI340_SR13;
36 pVBInfo->CR40 = XGI340_cr41;
6d12dae4 37
21df8fc8 38 /* 310 customization related */
6896b94e 39 if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
21df8fc8
PS
40 pVBInfo->LCDCapList = XGI_LCDDLCapList;
41 else
42 pVBInfo->LCDCapList = XGI_LCDCapList;
d7636e0b 43
21df8fc8 44 if (ChipType >= XG20)
6d12dae4 45 pVBInfo->XGINew_CR97 = 0x10;
d7636e0b 46
21df8fc8 47 if (ChipType == XG27) {
6490311f 48 unsigned char temp;
a7e46d8b 49 pVBInfo->MCLKData = XGI27New_MCLKData;
21df8fc8 50 pVBInfo->CR40 = XGI27_cr41;
6d12dae4 51 pVBInfo->XGINew_CR97 = 0xc1;
6490311f 52 pVBInfo->SR15 = XG27_SR13;
21df8fc8 53
6490311f
DES
54 /*Z11m DDR*/
55 temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
56 /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
57 if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
6d12dae4 58 pVBInfo->XGINew_CR97 = 0x80;
21df8fc8
PS
59 }
60
61}
d7636e0b 62
1d7f656d 63static void XGI_SetSeqRegs(unsigned short ModeNo,
1d7f656d
KT
64 unsigned short ModeIdIndex,
65 struct vb_device_info *pVBInfo)
cc1e2398 66{
76a5899b 67 unsigned char SRdata, i;
cc1e2398 68
8104e329 69 xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
d7636e0b 70
76a5899b
PH
71 for (i = 0; i < 4; i++) {
72 /* Get SR1,2,3,4 from file */
73 /* SR1 is with screen off 0x20 */
74 SRdata = XGI330_StandTable.SR[i];
75 xgifb_reg_set(pVBInfo->P3c4, i+1, SRdata); /* Set SR 1 2 3 4 */
21df8fc8 76 }
cc1e2398
AK
77}
78
cc1e2398 79static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
1d7f656d 80 struct vb_device_info *pVBInfo)
cc1e2398
AK
81{
82 unsigned char CRTCdata;
83 unsigned short i;
21df8fc8 84
9388ad9c 85 CRTCdata = xgifb_reg_get(pVBInfo->P3d4, 0x11);
cc1e2398 86 CRTCdata &= 0x7f;
8104e329 87 xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
21df8fc8 88
cc1e2398 89 for (i = 0; i <= 0x18; i++) {
1d7f656d 90 /* Get CRTC from file */
3625c9a7 91 CRTCdata = XGI330_StandTable.CRTC[i];
8104e329 92 xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
cc1e2398 93 }
cc1e2398 94}
21df8fc8 95
1d7f656d 96static void XGI_SetATTRegs(unsigned short ModeNo,
1d7f656d
KT
97 unsigned short ModeIdIndex,
98 struct vb_device_info *pVBInfo)
cc1e2398
AK
99{
100 unsigned char ARdata;
101 unsigned short i, modeflag;
21df8fc8 102
b397992e 103 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
cc1e2398
AK
104
105 for (i = 0; i <= 0x13; i++) {
3625c9a7 106 ARdata = XGI330_StandTable.ATTR[i];
661a6384
MG
107
108 if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */
109 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
110 ARdata = 0;
d3ae5762 111 } else if ((pVBInfo->VBInfo &
661a6384 112 (SetCRT2ToTV | SetCRT2ToLCD)) &&
d3ae5762 113 (pVBInfo->VBInfo & SetInSlaveMode)) {
cc1e2398 114 ARdata = 0;
21df8fc8
PS
115 }
116 }
117
d8ad0a6d 118 inb(pVBInfo->P3da); /* reset 3da */
efdf4ee7
AK
119 outb(i, pVBInfo->P3c0); /* set index */
120 outb(ARdata, pVBInfo->P3c0); /* set data */
cc1e2398 121 }
21df8fc8 122
d8ad0a6d 123 inb(pVBInfo->P3da); /* reset 3da */
efdf4ee7
AK
124 outb(0x14, pVBInfo->P3c0); /* set index */
125 outb(0x00, pVBInfo->P3c0); /* set data */
d8ad0a6d 126 inb(pVBInfo->P3da); /* Enable Attribute */
efdf4ee7 127 outb(0x20, pVBInfo->P3c0);
cc1e2398 128}
21df8fc8 129
a157961c 130static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo)
cc1e2398
AK
131{
132 unsigned char GRdata;
133 unsigned short i;
21df8fc8 134
cc1e2398 135 for (i = 0; i <= 0x08; i++) {
1d7f656d 136 /* Get GR from file */
3625c9a7 137 GRdata = XGI330_StandTable.GRC[i];
8104e329 138 xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
cc1e2398 139 }
21df8fc8 140
cc1e2398 141 if (pVBInfo->ModeType > ModeVGA) {
9388ad9c 142 GRdata = xgifb_reg_get(pVBInfo->P3ce, 0x05);
cc1e2398 143 GRdata &= 0xBF; /* 256 color disable */
8104e329 144 xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata);
21df8fc8 145 }
cc1e2398 146}
d7636e0b 147
cc1e2398
AK
148static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
149{
150 unsigned short i;
d7636e0b 151
cc1e2398 152 for (i = 0x0A; i <= 0x0E; i++)
8104e329 153 xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
cc1e2398 154}
d7636e0b 155
cc1e2398
AK
156static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
157{
d7636e0b 158
ec9e5d3e 159 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
acfe093e
AK
160 xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[0].SR2B);
161 xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[0].SR2C);
21df8fc8 162
ec9e5d3e 163 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
acfe093e
AK
164 xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[1].SR2B);
165 xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[1].SR2C);
21df8fc8 166
dc50556b 167 xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30);
cc1e2398 168 return 0;
d7636e0b 169}
170
cc1e2398
AK
171static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
172 unsigned short ModeIdIndex,
173 unsigned short RefreshRateTableIndex, unsigned short *i,
21df8fc8
PS
174 struct vb_device_info *pVBInfo)
175{
cc1e2398 176 unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
21df8fc8 177
b397992e
AK
178 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
179 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
a39325d2 180 tempbx = XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
cc1e2398 181 tempax = 0;
21df8fc8 182
cc1e2398
AK
183 if (pVBInfo->IF_DEF_LVDS == 0) {
184 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
185 tempax |= SupportRAMDAC2;
21df8fc8 186
cc1e2398
AK
187 if (pVBInfo->VBType & VB_XGI301C)
188 tempax |= SupportCRT2in301C;
21df8fc8 189 }
21df8fc8 190
1d7f656d 191 /* 301b */
a3d675c8 192 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
cc1e2398 193 tempax |= SupportLCD;
21df8fc8 194
3b175621
MG
195 if (pVBInfo->LCDResInfo != Panel_1280x1024 &&
196 pVBInfo->LCDResInfo != Panel_1280x960 &&
197 (pVBInfo->LCDInfo & LCDNonExpanding) &&
198 resinfo >= 9)
199 return 0;
21df8fc8 200 }
21df8fc8 201
599801f9 202 if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */
31fb40fd
AK
203 tempax |= SupportHiVision;
204 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
205 ((resinfo == 4) ||
206 (resinfo == 3 &&
207 (pVBInfo->SetFlag & TVSimuMode)) ||
208 (resinfo > 7)))
3b175621 209 return 0;
d3ae5762 210 } else if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO |
1d7f656d
KT
211 SetCRT2ToSVIDEO |
212 SetCRT2ToSCART |
599801f9
PH
213 SetCRT2ToYPbPr525750 |
214 SetCRT2ToHiVision)) {
d3ae5762
AK
215 tempax |= SupportTV;
216
217 if (pVBInfo->VBType & (VB_SIS301B |
218 VB_SIS302B |
219 VB_SIS301LV |
220 VB_SIS302LV |
221 VB_XGI301C))
222 tempax |= SupportTV1024;
223
224 if (!(pVBInfo->VBInfo & TVSetPAL) &&
225 (modeflag & NoSupportSimuTV) &&
226 (pVBInfo->VBInfo & SetInSlaveMode) &&
227 (!(pVBInfo->VBInfo & SetNotSimuMode)))
228 return 0;
cc1e2398 229 }
d3ae5762
AK
230 } else if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* for LVDS */
231 tempax |= SupportLCD;
d7636e0b 232
d3ae5762
AK
233 if (resinfo > 0x08)
234 return 0; /* 1024x768 */
d7636e0b 235
d3ae5762
AK
236 if (pVBInfo->LCDResInfo < Panel_1024x768) {
237 if (resinfo > 0x07)
238 return 0; /* 800x600 */
d7636e0b 239
d3ae5762
AK
240 if (resinfo == 0x04)
241 return 0; /* 512x384 */
cc1e2398
AK
242 }
243 }
21df8fc8 244
a39325d2 245 for (; XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
1d7f656d 246 tempbx; (*i)--) {
a39325d2 247 infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].
1d7f656d 248 Ext_InfoFlag;
cc1e2398
AK
249 if (infoflag & tempax)
250 return 1;
21df8fc8 251
cc1e2398
AK
252 if ((*i) == 0)
253 break;
21df8fc8 254 }
d7636e0b 255
cc1e2398 256 for ((*i) = 0;; (*i)++) {
a39325d2 257 infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].
1d7f656d 258 Ext_InfoFlag;
a39325d2 259 if (XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID
cc1e2398
AK
260 != tempbx) {
261 return 0;
262 }
d7636e0b 263
cc1e2398
AK
264 if (infoflag & tempax)
265 return 1;
21df8fc8 266 }
cc1e2398 267 return 1;
d7636e0b 268}
269
cc1e2398 270static void XGI_SetSync(unsigned short RefreshRateTableIndex,
21df8fc8 271 struct vb_device_info *pVBInfo)
d7636e0b 272{
cc1e2398 273 unsigned short sync, temp;
d7636e0b 274
1d7f656d 275 /* di+0x00 */
a39325d2 276 sync = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
cc1e2398
AK
277 sync &= 0xC0;
278 temp = 0x2F;
279 temp |= sync;
efdf4ee7 280 outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */
d7636e0b 281}
282
cc1e2398
AK
283static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
284 struct xgi_hw_device_info *HwDeviceExtension)
d7636e0b 285{
cc1e2398
AK
286 unsigned char data, data1, pushax;
287 unsigned short i, j;
d7636e0b 288
1d7f656d 289 /* unlock cr0-7 */
9388ad9c 290 data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
cc1e2398 291 data &= 0x7F;
8104e329 292 xgifb_reg_set(pVBInfo->P3d4, 0x11, data);
cc1e2398 293
6154e7f4 294 data = pVBInfo->TimingH.data[0];
8104e329 295 xgifb_reg_set(pVBInfo->P3d4, 0, data);
cc1e2398
AK
296
297 for (i = 0x01; i <= 0x04; i++) {
6154e7f4 298 data = pVBInfo->TimingH.data[i];
8104e329 299 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data);
21df8fc8 300 }
d7636e0b 301
cc1e2398 302 for (i = 0x05; i <= 0x06; i++) {
6154e7f4 303 data = pVBInfo->TimingH.data[i];
8104e329 304 xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data);
cc1e2398 305 }
d7636e0b 306
9388ad9c 307 j = xgifb_reg_get(pVBInfo->P3c4, 0x0e);
cc1e2398 308 j &= 0x1F;
6154e7f4 309 data = pVBInfo->TimingH.data[7];
cc1e2398
AK
310 data &= 0xE0;
311 data |= j;
8104e329 312 xgifb_reg_set(pVBInfo->P3c4, 0x0e, data);
21df8fc8 313
cc1e2398 314 if (HwDeviceExtension->jChipType >= XG20) {
9388ad9c 315 data = xgifb_reg_get(pVBInfo->P3d4, 0x04);
cc1e2398 316 data = data - 1;
8104e329 317 xgifb_reg_set(pVBInfo->P3d4, 0x04, data);
9388ad9c 318 data = xgifb_reg_get(pVBInfo->P3d4, 0x05);
cc1e2398
AK
319 data1 = data;
320 data1 &= 0xE0;
321 data &= 0x1F;
322 if (data == 0) {
323 pushax = data;
9388ad9c 324 data = xgifb_reg_get(pVBInfo->P3c4, 0x0c);
cc1e2398 325 data &= 0xFB;
8104e329 326 xgifb_reg_set(pVBInfo->P3c4, 0x0c, data);
cc1e2398 327 data = pushax;
21df8fc8 328 }
cc1e2398
AK
329 data = data - 1;
330 data |= data1;
8104e329 331 xgifb_reg_set(pVBInfo->P3d4, 0x05, data);
9388ad9c 332 data = xgifb_reg_get(pVBInfo->P3c4, 0x0e);
cc1e2398
AK
333 data = data >> 5;
334 data = data + 3;
335 if (data > 7)
336 data = data - 7;
337 data = data << 5;
ec9e5d3e 338 xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data);
21df8fc8 339 }
21df8fc8
PS
340}
341
1d7f656d
KT
342static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
343 unsigned short ModeNo,
344 struct vb_device_info *pVBInfo)
d7636e0b 345{
cc1e2398
AK
346 unsigned char data;
347 unsigned short i, j;
d7636e0b 348
cc1e2398 349 for (i = 0x00; i <= 0x01; i++) {
6154e7f4 350 data = pVBInfo->TimingV.data[i];
8104e329 351 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data);
21df8fc8 352 }
d7636e0b 353
cc1e2398 354 for (i = 0x02; i <= 0x03; i++) {
6154e7f4 355 data = pVBInfo->TimingV.data[i];
8104e329 356 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
21df8fc8 357 }
d7636e0b 358
cc1e2398 359 for (i = 0x04; i <= 0x05; i++) {
6154e7f4 360 data = pVBInfo->TimingV.data[i];
8104e329 361 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
cc1e2398 362 }
d7636e0b 363
9388ad9c 364 j = xgifb_reg_get(pVBInfo->P3c4, 0x0a);
cc1e2398 365 j &= 0xC0;
6154e7f4 366 data = pVBInfo->TimingV.data[6];
cc1e2398
AK
367 data &= 0x3F;
368 data |= j;
8104e329 369 xgifb_reg_set(pVBInfo->P3c4, 0x0a, data);
d7636e0b 370
6154e7f4 371 data = pVBInfo->TimingV.data[6];
cc1e2398
AK
372 data &= 0x80;
373 data = data >> 2;
d7636e0b 374
b397992e 375 i = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
cc1e2398
AK
376 i &= DoubleScanMode;
377 if (i)
378 data |= 0x80;
d7636e0b 379
9388ad9c 380 j = xgifb_reg_get(pVBInfo->P3d4, 0x09);
cc1e2398
AK
381 j &= 0x5F;
382 data |= j;
8104e329 383 xgifb_reg_set(pVBInfo->P3d4, 0x09, data);
d7636e0b 384}
385
cc1e2398
AK
386static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
387 unsigned short RefreshRateTableIndex,
388 struct vb_device_info *pVBInfo,
389 struct xgi_hw_device_info *HwDeviceExtension)
21df8fc8 390{
cc1e2398
AK
391 unsigned char index, data;
392 unsigned short i;
21df8fc8 393
1d7f656d 394 /* Get index */
a39325d2 395 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
cc1e2398 396 index = index & IndexMask;
21df8fc8 397
9388ad9c 398 data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
cc1e2398 399 data &= 0x7F;
8104e329 400 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
21df8fc8 401
cc1e2398 402 for (i = 0; i < 8; i++)
6154e7f4 403 pVBInfo->TimingH.data[i]
7853bced 404 = XGI_CRT1Table[index].CR[i];
21df8fc8 405
cc1e2398 406 for (i = 0; i < 7; i++)
6154e7f4 407 pVBInfo->TimingV.data[i]
7853bced 408 = XGI_CRT1Table[index].CR[i + 8];
21df8fc8 409
cc1e2398 410 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
21df8fc8 411
cc1e2398 412 XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
21df8fc8 413
cc1e2398 414 if (pVBInfo->ModeType > 0x03)
8104e329 415 xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F);
21df8fc8
PS
416}
417
cc1e2398
AK
418/* --------------------------------------------------------------------- */
419/* Function : XGI_SetXG21CRTC */
420/* Input : Stand or enhance CRTC table */
421/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
422/* Description : Set LCD timing */
423/* --------------------------------------------------------------------- */
424static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
425 unsigned short RefreshRateTableIndex,
21df8fc8 426 struct vb_device_info *pVBInfo)
d7636e0b 427{
34c13ee2 428 unsigned char index, Tempax, Tempbx, Tempcx, Tempdx;
cc1e2398 429 unsigned short Temp1, Temp2, Temp3;
21df8fc8 430
a39325d2 431 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
34c13ee2 432 /* Tempax: CR4 HRS */
7853bced 433 Tempax = XGI_CRT1Table[index].CR[3];
34c13ee2
AK
434 Tempcx = Tempax; /* Tempcx: HRS */
435 /* SR2E[7:0]->HRS */
436 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
437
7853bced 438 Tempdx = XGI_CRT1Table[index].CR[5]; /* SRB */
34c13ee2
AK
439 Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
440 Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
441 Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
442 Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
443
7853bced 444 Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
34c13ee2
AK
445 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
446
7853bced 447 Tempbx = XGI_CRT1Table[index].CR[6]; /* SRC */
34c13ee2
AK
448 Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
449 Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
450 Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
451
452 Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
453 Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
454
455 Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
456 if (Tempax < Tempcx) /* HRE < HRS */
457 Temp2 |= 0x40; /* Temp2 + 0x40 */
458
459 Temp2 &= 0xFF;
460 Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
461 Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
462 Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
463 Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
464 /* SR2F D[7:2]->HRE, D[1:0]->HRS */
465 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
466 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
467
468 /* CR10 VRS */
7853bced 469 Tempax = XGI_CRT1Table[index].CR[10];
34c13ee2
AK
470 Tempbx = Tempax; /* Tempbx: VRS */
471 Tempax &= 0x01; /* Tempax[0]: VRS[0] */
472 xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
473 /* CR7[2][7] VRE */
7853bced 474 Tempax = XGI_CRT1Table[index].CR[9];
34c13ee2
AK
475 Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
476 Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
477 Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
478 Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
479 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
480
481 Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
482 Temp1 <<= 1; /* Temp1[8]: VRS[8] */
483 Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
484 Tempax &= 0x80;
485 Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
486 Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
487 /* Tempax: SRA */
7853bced 488 Tempax = XGI_CRT1Table[index].CR[14];
34c13ee2
AK
489 Tempax &= 0x08; /* Tempax[3]: VRS[3] */
490 Temp2 = Tempax;
491 Temp2 <<= 7; /* Temp2[10]: VRS[10] */
492 Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
493
494 /* Tempax: CR11 VRE */
7853bced 495 Tempax = XGI_CRT1Table[index].CR[11];
34c13ee2
AK
496 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
497 /* Tempbx: SRA */
7853bced 498 Tempbx = XGI_CRT1Table[index].CR[14];
34c13ee2
AK
499 Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
500 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
501 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
502 Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
503 Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
504
505 Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
506 if (Tempax < Temp3) /* VRE < VRS */
507 Temp2 |= 0x20; /* VRE + 0x20 */
508
509 Temp2 &= 0xFF;
510 Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
511 Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
512 Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
513 Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
514 Tempbx = (unsigned char) Temp1;
515 Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
516 Tempax &= 0x7F;
517 /* SR3F D[7:2]->VRE D[1:0]->VRS */
518 xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
d7636e0b 519}
520
1d7f656d
KT
521static void XGI_SetXG27CRTC(unsigned short ModeNo,
522 unsigned short ModeIdIndex,
523 unsigned short RefreshRateTableIndex,
524 struct vb_device_info *pVBInfo)
21df8fc8 525{
34c13ee2
AK
526 unsigned short index, Tempax, Tempbx, Tempcx;
527
a39325d2 528 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
34c13ee2 529 /* Tempax: CR4 HRS */
7853bced 530 Tempax = XGI_CRT1Table[index].CR[3];
34c13ee2
AK
531 Tempbx = Tempax; /* Tempbx: HRS[7:0] */
532 /* SR2E[7:0]->HRS */
533 xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
534
535 /* SR0B */
7853bced 536 Tempax = XGI_CRT1Table[index].CR[5];
34c13ee2
AK
537 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
538 Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
539
7853bced 540 Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
34c13ee2
AK
541 Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
542 Tempcx = Tempax; /* Tempcx: HRE[4:0] */
543
7853bced 544 Tempax = XGI_CRT1Table[index].CR[6]; /* SRC */
34c13ee2
AK
545 Tempax &= 0x04; /* Tempax[2]: HRE[5] */
546 Tempax <<= 3; /* Tempax[5]: HRE[5] */
547 Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
548
549 Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
550 Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
551
552 /* Tempax: CR4 HRS */
7853bced 553 Tempax = XGI_CRT1Table[index].CR[3];
34c13ee2
AK
554 Tempax &= 0x3F; /* Tempax: HRS[5:0] */
555 if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
556 Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
557
7853bced 558 Tempax = XGI_CRT1Table[index].CR[5]; /* SR0B */
34c13ee2
AK
559 Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
560 Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
561 Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
562 /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
563 xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
564 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
565
566 /* CR10 VRS */
7853bced 567 Tempax = XGI_CRT1Table[index].CR[10];
34c13ee2
AK
568 /* SR34[7:0]->VRS[7:0] */
569 xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax);
570
571 Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
572 /* CR7[7][2] VRS[9][8] */
7853bced 573 Tempax = XGI_CRT1Table[index].CR[9];
34c13ee2
AK
574 Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
575 Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
576 Tempax >>= 2; /* Tempax[0]: VRS[8] */
577 /* SR35[0]: VRS[8] */
578 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
579 Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
580 Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
581 /* Tempax: SR0A */
7853bced 582 Tempax = XGI_CRT1Table[index].CR[14];
34c13ee2
AK
583 Tempax &= 0x08; /* SR0A[3] VRS[10] */
584 Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
585
586 /* Tempax: CR11 VRE */
7853bced 587 Tempax = XGI_CRT1Table[index].CR[11];
34c13ee2
AK
588 Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
589 /* Tempbx: SR0A */
7853bced 590 Tempbx = XGI_CRT1Table[index].CR[14];
34c13ee2
AK
591 Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
592 Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
593 Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
594 Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
595 Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
596 Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
597
598 if (Tempbx <= Tempcx) /* VRE <= VRS */
599 Tempbx |= 0x20; /* VRE + 0x20 */
600
601 /* Tempax: Tempax[7:0]; VRE[5:0]00 */
602 Tempax = (Tempbx << 2) & 0xFF;
603 /* SR3F[7:2]:VRE[5:0] */
604 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
605 Tempax = Tempcx >> 8;
606 /* SR35[2:0]:VRS[10:8] */
607 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax);
cc1e2398 608}
d7636e0b 609
a2d08cf3
AK
610static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
611{
612 unsigned char temp;
613
614 /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
615 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
616 temp = (temp & 3) << 6;
617 /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
618 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80);
619 /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
620 xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
621
622}
623
105d8d0d
AK
624static void xgifb_set_lcd(int chip_id,
625 struct vb_device_info *pVBInfo,
626 unsigned short RefreshRateTableIndex,
627 unsigned short ModeNo)
21df8fc8 628{
e2e544c9 629 unsigned short temp;
21df8fc8 630
8104e329
AK
631 xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00);
632 xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00);
633 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00);
634 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00);
21df8fc8 635
105d8d0d 636 if (chip_id == XG27) {
e2e544c9
PH
637 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
638 if ((temp & 0x03) == 0) { /* dual 12 */
105d8d0d
AK
639 xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13);
640 xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13);
641 }
21df8fc8
PS
642 }
643
105d8d0d
AK
644 if (chip_id == XG27) {
645 XGI_SetXG27FPBits(pVBInfo);
646 } else {
e2e544c9
PH
647 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
648 if (temp & 0x01) {
105d8d0d
AK
649 /* 18 bits FP */
650 xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40);
651 xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40);
652 }
653 }
21df8fc8 654
b9bf6e4e 655 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
21df8fc8 656
dc50556b
AK
657 xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
658 xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
21df8fc8 659
e2e544c9
PH
660 temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
661 if (temp & 0x4000)
34c13ee2
AK
662 /* Hsync polarity */
663 xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
e2e544c9 664 if (temp & 0x8000)
34c13ee2
AK
665 /* Vsync polarity */
666 xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
21df8fc8 667}
d7636e0b 668
669/* --------------------------------------------------------------------- */
cc1e2398
AK
670/* Function : XGI_UpdateXG21CRTC */
671/* Input : */
672/* Output : CRT1 CRTC */
673/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
d7636e0b 674/* --------------------------------------------------------------------- */
1d7f656d
KT
675static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
676 struct vb_device_info *pVBInfo,
677 unsigned short RefreshRateTableIndex)
cc1e2398 678{
34c13ee2 679 int index = -1;
cc1e2398 680
dc50556b 681 xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
34c13ee2 682 if (ModeNo == 0x2E &&
a39325d2 683 (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
34c13ee2
AK
684 RES640x480x60))
685 index = 12;
a39325d2 686 else if (ModeNo == 0x2E && (XGI330_RefIndex[RefreshRateTableIndex].
1d7f656d 687 Ext_CRT1CRTC == RES640x480x72))
34c13ee2
AK
688 index = 13;
689 else if (ModeNo == 0x2F)
690 index = 14;
691 else if (ModeNo == 0x50)
692 index = 15;
693 else if (ModeNo == 0x59)
694 index = 16;
cc1e2398
AK
695
696 if (index != -1) {
8104e329 697 xgifb_reg_set(pVBInfo->P3d4, 0x02,
7c5c07a6 698 XGI_UpdateCRT1Table[index].CR02);
8104e329 699 xgifb_reg_set(pVBInfo->P3d4, 0x03,
7c5c07a6 700 XGI_UpdateCRT1Table[index].CR03);
8104e329 701 xgifb_reg_set(pVBInfo->P3d4, 0x15,
7c5c07a6 702 XGI_UpdateCRT1Table[index].CR15);
8104e329 703 xgifb_reg_set(pVBInfo->P3d4, 0x16,
7c5c07a6 704 XGI_UpdateCRT1Table[index].CR16);
cc1e2398
AK
705 }
706}
707
708static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
709 unsigned short ModeNo, unsigned short ModeIdIndex,
21df8fc8
PS
710 unsigned short RefreshRateTableIndex,
711 struct vb_device_info *pVBInfo)
712{
cc1e2398
AK
713 unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
714
715 unsigned char data;
716
b397992e 717 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
21df8fc8 718
b397992e 719 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
e8e6c754
AK
720 tempax = XGI330_ModeResInfo[resindex].HTotal;
721 tempbx = XGI330_ModeResInfo[resindex].VTotal;
21df8fc8 722
cc1e2398
AK
723 if (modeflag & HalfDCLK)
724 tempax = tempax >> 1;
21df8fc8 725
34c13ee2
AK
726 if (modeflag & HalfDCLK)
727 tempax = tempax << 1;
21df8fc8 728
a39325d2 729 temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
21df8fc8 730
34c13ee2
AK
731 if (temp & InterlaceMode)
732 tempbx = tempbx >> 1;
21df8fc8 733
34c13ee2
AK
734 if (modeflag & DoubleScanMode)
735 tempbx = tempbx << 1;
21df8fc8 736
cc1e2398 737 tempcx = 8;
21df8fc8 738
cc1e2398
AK
739 tempax /= tempcx;
740 tempax -= 1;
741 tempbx -= 1;
742 tempcx = tempax;
9388ad9c
PH
743 temp = xgifb_reg_get(pVBInfo->P3d4, 0x11);
744 data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
cc1e2398 745 data &= 0x7F;
8104e329
AK
746 xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
747 xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
ec9e5d3e 748 xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c,
cc1e2398 749 (unsigned short) ((tempcx & 0x0ff00) >> 10));
8104e329 750 xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
cc1e2398
AK
751 tempax = 0;
752 tempbx = tempbx >> 8;
21df8fc8 753
cc1e2398
AK
754 if (tempbx & 0x01)
755 tempax |= 0x02;
21df8fc8 756
cc1e2398
AK
757 if (tempbx & 0x02)
758 tempax |= 0x40;
21df8fc8 759
ec9e5d3e 760 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax);
9388ad9c 761 data = xgifb_reg_get(pVBInfo->P3d4, 0x07);
cc1e2398
AK
762 data &= 0xFF;
763 tempax = 0;
21df8fc8 764
cc1e2398
AK
765 if (tempbx & 0x04)
766 tempax |= 0x02;
21df8fc8 767
ec9e5d3e 768 xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
8104e329 769 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp);
cc1e2398 770}
21df8fc8 771
1d7f656d
KT
772static void XGI_SetCRT1Offset(unsigned short ModeNo,
773 unsigned short ModeIdIndex,
774 unsigned short RefreshRateTableIndex,
775 struct xgi_hw_device_info *HwDeviceExtension,
776 struct vb_device_info *pVBInfo)
d7636e0b 777{
cc1e2398 778 unsigned short temp, ah, al, temp2, i, DisplayUnit;
21df8fc8 779
cc1e2398 780 /* GetOffset */
b397992e 781 temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
cc1e2398 782 temp = temp >> 8;
224114c7 783 temp = XGI330_ScreenOffset[temp];
21df8fc8 784
a39325d2 785 temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
cc1e2398 786 temp2 &= InterlaceMode;
21df8fc8 787
cc1e2398
AK
788 if (temp2)
789 temp = temp << 1;
21df8fc8 790
cc1e2398 791 temp2 = pVBInfo->ModeType - ModeEGA;
21df8fc8 792
cc1e2398
AK
793 switch (temp2) {
794 case 0:
795 temp2 = 1;
796 break;
797 case 1:
798 temp2 = 2;
799 break;
800 case 2:
801 temp2 = 4;
802 break;
803 case 3:
804 temp2 = 4;
805 break;
806 case 4:
807 temp2 = 6;
808 break;
809 case 5:
810 temp2 = 8;
811 break;
812 default:
813 break;
814 }
21df8fc8 815
cc1e2398
AK
816 if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
817 temp = temp * temp2 + temp2 / 2;
818 else
819 temp *= temp2;
21df8fc8 820
cc1e2398
AK
821 /* SetOffset */
822 DisplayUnit = temp;
823 temp2 = temp;
824 temp = temp >> 8; /* ah */
825 temp &= 0x0F;
58839b01 826 i = xgifb_reg_get(pVBInfo->P3c4, 0x0E);
cc1e2398
AK
827 i &= 0xF0;
828 i |= temp;
8104e329 829 xgifb_reg_set(pVBInfo->P3c4, 0x0E, i);
21df8fc8 830
cc1e2398
AK
831 temp = (unsigned char) temp2;
832 temp &= 0xFF; /* al */
8104e329 833 xgifb_reg_set(pVBInfo->P3d4, 0x13, temp);
21df8fc8 834
cc1e2398 835 /* SetDisplayUnit */
a39325d2 836 temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
cc1e2398
AK
837 temp2 &= InterlaceMode;
838 if (temp2)
839 DisplayUnit >>= 1;
21df8fc8 840
cc1e2398
AK
841 DisplayUnit = DisplayUnit << 5;
842 ah = (DisplayUnit & 0xff00) >> 8;
843 al = DisplayUnit & 0x00ff;
844 if (al == 0)
845 ah += 1;
846 else
847 ah += 2;
21df8fc8 848
cc1e2398
AK
849 if (HwDeviceExtension->jChipType >= XG20)
850 if ((ModeNo == 0x4A) | (ModeNo == 0x49))
851 ah -= 1;
21df8fc8 852
8104e329 853 xgifb_reg_set(pVBInfo->P3c4, 0x10, ah);
d7636e0b 854}
855
cc1e2398
AK
856static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
857 unsigned short ModeIdIndex,
858 unsigned short RefreshRateTableIndex,
859 struct xgi_hw_device_info *HwDeviceExtension,
860 struct vb_device_info *pVBInfo)
d7636e0b 861{
ef9a6b99 862 unsigned short VCLKIndex, modeflag;
21df8fc8 863
34c13ee2 864 /* si+Ext_ResInfo */
b397992e 865 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
21df8fc8 866
7ac54d03
AK
867 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /*301b*/
868 if (pVBInfo->LCDResInfo != Panel_1024x768)
869 /* LCDXlat2VCLK */
870 VCLKIndex = VCLK108_2_315 + 5;
871 else
872 VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */
873 } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
874 if (pVBInfo->SetFlag & RPLLDIV2XO)
875 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2;
876 else
877 VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK;
878
879 if (pVBInfo->SetFlag & TVSimuMode) {
880 if (modeflag & Charx8Dot) {
881 VCLKIndex = TVCLKBASE_315_25 + HiTVSimuVCLK;
882 } else {
883 VCLKIndex = TVCLKBASE_315_25 + HiTVTextVCLK;
798b4da5 884 }
7ac54d03 885 }
798b4da5 886
7ac54d03
AK
887 /* 301lv */
888 if (pVBInfo->VBType & VB_SIS301LV) {
3bcc2460 889 if (pVBInfo->SetFlag & RPLLDIV2XO)
7ac54d03 890 VCLKIndex = YPbPr525iVCLK_2;
3bcc2460 891 else
7ac54d03 892 VCLKIndex = YPbPr525iVCLK;
cc1e2398 893 }
7ac54d03
AK
894 } else if (pVBInfo->VBInfo & SetCRT2ToTV) {
895 if (pVBInfo->SetFlag & RPLLDIV2XO)
896 VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2;
897 else
898 VCLKIndex = TVCLKBASE_315_25 + TVVCLK;
899 } else { /* for CRT2 */
900 /* di+Ext_CRTVCLK */
901 VCLKIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
902 VCLKIndex &= IndexMask;
21df8fc8 903 }
d7636e0b 904
cc1e2398 905 return VCLKIndex;
21df8fc8 906}
d7636e0b 907
1d7f656d
KT
908static void XGI_SetCRT1VCLK(unsigned short ModeNo,
909 unsigned short ModeIdIndex,
910 struct xgi_hw_device_info *HwDeviceExtension,
911 unsigned short RefreshRateTableIndex,
912 struct vb_device_info *pVBInfo)
d7636e0b 913{
108afbf8 914 unsigned char index, data;
21df8fc8
PS
915 unsigned short vclkindex;
916
917 if (pVBInfo->IF_DEF_LVDS == 1) {
a39325d2 918 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
58839b01 919 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
8104e329 920 xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
acfe093e
AK
921 xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B);
922 xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C);
8104e329 923 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
6896b94e
PH
924 } else if ((pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
925 | VB_SIS302LV | VB_XGI301C)) && (pVBInfo->VBInfo
a3d675c8 926 & XGI_SetCRT2ToLCDA)) {
21df8fc8
PS
927 vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex,
928 RefreshRateTableIndex, HwDeviceExtension,
929 pVBInfo);
58839b01 930 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
8104e329 931 xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
acfe093e 932 data = XGI_VBVCLKData[vclkindex].Part4_A;
8104e329 933 xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
acfe093e 934 data = XGI_VBVCLKData[vclkindex].Part4_B;
8104e329
AK
935 xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
936 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
21df8fc8 937 } else {
a39325d2 938 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
58839b01 939 data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
8104e329 940 xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
acfe093e
AK
941 xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B);
942 xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C);
8104e329 943 xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
21df8fc8 944 }
d7636e0b 945
21df8fc8 946 if (HwDeviceExtension->jChipType >= XG20) {
b397992e 947 if (XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag &
1d7f656d 948 HalfDCLK) {
58839b01 949 data = xgifb_reg_get(pVBInfo->P3c4, 0x2B);
8104e329 950 xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
58839b01 951 data = xgifb_reg_get(pVBInfo->P3c4, 0x2C);
21df8fc8
PS
952 index = data;
953 index &= 0xE0;
954 data &= 0x1F;
955 data = data << 1;
956 data += 1;
957 data |= index;
8104e329 958 xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
21df8fc8
PS
959 }
960 }
961}
d7636e0b 962
e85f2036
AK
963static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
964{
965 unsigned char temp;
966
967 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
968 temp = (temp & 1) << 6;
969 /* SR06[6] 18bit Dither */
970 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp);
971 /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
972 xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
973
974}
975
063b9c4b 976static void XGI_SetCRT1FIFO(unsigned short ModeNo,
21df8fc8
PS
977 struct xgi_hw_device_info *HwDeviceExtension,
978 struct vb_device_info *pVBInfo)
979{
980 unsigned short data;
981
58839b01 982 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
21df8fc8 983 data &= 0xfe;
8104e329 984 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
21df8fc8 985
34c13ee2
AK
986 xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34);
987 data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
988 data &= 0xC0;
989 xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30);
990 data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
991 data |= 0x01;
992 xgifb_reg_set(pVBInfo->P3c4, 0x3D, data);
d7636e0b 993
21df8fc8
PS
994 if (HwDeviceExtension->jChipType == XG21)
995 XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
996}
d7636e0b 997
cc1e2398
AK
998static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
999 unsigned short ModeNo, unsigned short RefreshRateTableIndex,
21df8fc8
PS
1000 struct vb_device_info *pVBInfo)
1001{
cc1e2398
AK
1002 unsigned short data, data2 = 0;
1003 short VCLK;
d7636e0b 1004
cc1e2398 1005 unsigned char index;
d7636e0b 1006
a39325d2 1007 index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
34c13ee2 1008 index &= IndexMask;
acfe093e 1009 VCLK = XGI_VCLKData[index].CLOCK;
d7636e0b 1010
58839b01 1011 data = xgifb_reg_get(pVBInfo->P3c4, 0x32);
cc1e2398
AK
1012 data &= 0xf3;
1013 if (VCLK >= 200)
1014 data |= 0x0c; /* VCLK > 200 */
d7636e0b 1015
cc1e2398
AK
1016 if (HwDeviceExtension->jChipType >= XG20)
1017 data &= ~0x04; /* 2 pixel mode */
d7636e0b 1018
8104e329 1019 xgifb_reg_set(pVBInfo->P3c4, 0x32, data);
cc1e2398
AK
1020
1021 if (HwDeviceExtension->jChipType < XG20) {
58839b01 1022 data = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
cc1e2398
AK
1023 data &= 0xE7;
1024 if (VCLK < 200)
1025 data |= 0x10;
8104e329 1026 xgifb_reg_set(pVBInfo->P3c4, 0x1F, data);
cc1e2398
AK
1027 }
1028
cc1e2398
AK
1029 data2 = 0x00;
1030
ec9e5d3e 1031 xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2);
cc1e2398 1032 if (HwDeviceExtension->jChipType >= XG27)
ec9e5d3e 1033 xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
cc1e2398
AK
1034
1035}
1036
1037static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
1038 unsigned short ModeNo, unsigned short ModeIdIndex,
1039 unsigned short RefreshRateTableIndex,
1040 struct vb_device_info *pVBInfo)
1041{
1042 unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
1043 xres;
1044
b397992e 1045 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
a39325d2 1046 infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
cc1e2398 1047
58839b01 1048 if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01)
ec9e5d3e 1049 xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
cc1e2398 1050
34c13ee2 1051 data = infoflag;
cc1e2398 1052 data2 = 0;
969f7f3b
AK
1053 data2 |= 0x02;
1054 data3 = pVBInfo->ModeType - ModeVGA;
1055 data3 = data3 << 2;
1056 data2 |= data3;
21df8fc8 1057 data &= InterlaceMode;
d7636e0b 1058
21df8fc8
PS
1059 if (data)
1060 data2 |= 0x20;
d7636e0b 1061
ec9e5d3e 1062 xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2);
b397992e 1063 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
e8e6c754 1064 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
21df8fc8
PS
1065
1066 data = 0x0000;
1067 if (infoflag & InterlaceMode) {
1068 if (xres == 1024)
1069 data = 0x0035;
1070 else if (xres == 1280)
1071 data = 0x0048;
1072 }
d7636e0b 1073
5d1c2a9b
PH
1074 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data);
1075 xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, 0);
d7636e0b 1076
21df8fc8 1077 if (modeflag & HalfDCLK)
ec9e5d3e 1078 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08);
21df8fc8
PS
1079
1080 data2 = 0;
1081
1082 if (modeflag & LineCompareOff)
1083 data2 |= 0x08;
1084
ec9e5d3e 1085 xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2);
21df8fc8 1086 data = 0x60;
969f7f3b
AK
1087 data = data ^ 0x60;
1088 data = data ^ 0xA0;
ec9e5d3e 1089 xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data);
21df8fc8
PS
1090
1091 XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
1092 pVBInfo);
1093
58839b01 1094 data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
21df8fc8
PS
1095
1096 if (HwDeviceExtension->jChipType == XG27) {
1097 if (data & 0x40)
1098 data = 0x2c;
1099 else
1100 data = 0x6c;
8104e329 1101 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
b9bf6e4e 1102 xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10);
21df8fc8
PS
1103 } else if (HwDeviceExtension->jChipType >= XG20) {
1104 if (data & 0x40)
1105 data = 0x33;
1106 else
1107 data = 0x73;
8104e329
AK
1108 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1109 xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02);
21df8fc8
PS
1110 } else {
1111 if (data & 0x40)
1112 data = 0x2c;
1113 else
1114 data = 0x6c;
8104e329 1115 xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
21df8fc8 1116 }
d7636e0b 1117
d7636e0b 1118}
1119
1d7f656d
KT
1120static void XGI_WriteDAC(unsigned short dl,
1121 unsigned short ah,
1122 unsigned short al,
1123 unsigned short dh,
1124 struct vb_device_info *pVBInfo)
cc1e2398
AK
1125{
1126 unsigned short temp, bh, bl;
1127
1128 bh = ah;
1129 bl = al;
1130
1131 if (dl != 0) {
1132 temp = bh;
1133 bh = dh;
1134 dh = temp;
1135 if (dl == 1) {
1136 temp = bl;
1137 bl = dh;
1138 dh = temp;
1139 } else {
1140 temp = bl;
1141 bl = bh;
1142 bh = temp;
1143 }
1144 }
efdf4ee7
AK
1145 outb((unsigned short) dh, pVBInfo->P3c9);
1146 outb((unsigned short) bh, pVBInfo->P3c9);
1147 outb((unsigned short) bl, pVBInfo->P3c9);
cc1e2398
AK
1148}
1149
063b9c4b 1150static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex,
21df8fc8
PS
1151 struct vb_device_info *pVBInfo)
1152{
1bb52cc9
AK
1153 unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh;
1154 const unsigned short *table = XGINew_VGA_DAC;
d7636e0b 1155
efdf4ee7
AK
1156 outb(0xFF, pVBInfo->P3c6);
1157 outb(0x00, pVBInfo->P3c8);
d7636e0b 1158
1bb52cc9 1159 for (i = 0; i < 16; i++) {
21df8fc8 1160 data = table[i];
d7636e0b 1161
21df8fc8
PS
1162 for (k = 0; k < 3; k++) {
1163 data2 = 0;
d7636e0b 1164
21df8fc8
PS
1165 if (data & 0x01)
1166 data2 = 0x2A;
d7636e0b 1167
21df8fc8
PS
1168 if (data & 0x02)
1169 data2 += 0x15;
d7636e0b 1170
efdf4ee7 1171 outb(data2, pVBInfo->P3c9);
21df8fc8
PS
1172 data = data >> 2;
1173 }
1174 }
d7636e0b 1175
1bb52cc9
AK
1176 for (i = 16; i < 32; i++) {
1177 data = table[i];
21df8fc8 1178
1bb52cc9
AK
1179 for (k = 0; k < 3; k++)
1180 outb(data, pVBInfo->P3c9);
1181 }
21df8fc8 1182
1bb52cc9 1183 si = 32;
21df8fc8 1184
1bb52cc9
AK
1185 for (m = 0; m < 9; m++) {
1186 di = si;
1187 bx = si + 0x04;
1188 dl = 0;
21df8fc8 1189
1bb52cc9
AK
1190 for (n = 0; n < 3; n++) {
1191 for (o = 0; o < 5; o++) {
1192 dh = table[si];
1193 ah = table[di];
1194 al = table[bx];
1195 si++;
1196 XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1197 }
21df8fc8 1198
1bb52cc9 1199 si -= 2;
21df8fc8 1200
1bb52cc9
AK
1201 for (o = 0; o < 3; o++) {
1202 dh = table[bx];
1203 ah = table[di];
1204 al = table[si];
1205 si--;
1206 XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
21df8fc8
PS
1207 }
1208
1bb52cc9 1209 dl++;
21df8fc8 1210 }
1bb52cc9
AK
1211
1212 si += 5;
21df8fc8
PS
1213 }
1214}
d7636e0b 1215
1d7f656d
KT
1216static void XGI_GetLVDSResInfo(unsigned short ModeNo,
1217 unsigned short ModeIdIndex,
1218 struct vb_device_info *pVBInfo)
21df8fc8
PS
1219{
1220 unsigned short resindex, xres, yres, modeflag;
d7636e0b 1221
34c13ee2 1222 /* si+Ext_ResInfo */
b397992e 1223 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
d7636e0b 1224
34c13ee2 1225 /* si+Ext_ResInfo */
b397992e 1226 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
d7636e0b 1227
e8e6c754
AK
1228 xres = XGI330_ModeResInfo[resindex].HTotal;
1229 yres = XGI330_ModeResInfo[resindex].VTotal;
d7636e0b 1230
34c13ee2
AK
1231 if (modeflag & HalfDCLK)
1232 xres = xres << 1;
1233
1234 if (modeflag & DoubleScanMode)
1235 yres = yres << 1;
d7636e0b 1236
21df8fc8
PS
1237 if (xres == 720)
1238 xres = 640;
d7636e0b 1239
21df8fc8
PS
1240 pVBInfo->VGAHDE = xres;
1241 pVBInfo->HDE = xres;
1242 pVBInfo->VGAVDE = yres;
1243 pVBInfo->VDE = yres;
1244}
d7636e0b 1245
bdc9eb14 1246static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table,
9d1c6299 1247 unsigned short ModeNo,
cc1e2398 1248 unsigned short ModeIdIndex,
21df8fc8
PS
1249 unsigned short RefreshRateTableIndex,
1250 struct vb_device_info *pVBInfo)
1251{
6c27b370 1252 unsigned short i, tempdx, tempbx, modeflag;
d7636e0b 1253
9d1c6299 1254 tempbx = 0;
cc1e2398 1255
b397992e 1256 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
21df8fc8 1257
cc1e2398 1258 i = 0;
21df8fc8 1259
9d1c6299 1260 while (table[i].PANELID != 0xff) {
cc1e2398
AK
1261 tempdx = pVBInfo->LCDResInfo;
1262 if (tempbx & 0x0080) { /* OEMUtil */
1263 tempbx &= (~0x0080);
1264 tempdx = pVBInfo->LCDTypeInfo;
21df8fc8
PS
1265 }
1266
cc1e2398
AK
1267 if (pVBInfo->LCDInfo & EnableScalingLCD)
1268 tempdx &= (~PanelResInfo);
21df8fc8 1269
9d1c6299
AK
1270 if (table[i].PANELID == tempdx) {
1271 tempbx = table[i].MASK;
cc1e2398 1272 tempdx = pVBInfo->LCDInfo;
21df8fc8 1273
cc1e2398
AK
1274 if (modeflag & HalfDCLK)
1275 tempdx |= SetLCDLowResolution;
21df8fc8 1276
cc1e2398 1277 tempbx &= tempdx;
9d1c6299 1278 if (tempbx == table[i].CAP)
cc1e2398 1279 break;
21df8fc8 1280 }
cc1e2398
AK
1281 i++;
1282 }
21df8fc8 1283
9d1c6299 1284 return table[i].DATAPTR;
d7636e0b 1285}
1286
24572545 1287static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo,
cc1e2398
AK
1288 unsigned short ModeIdIndex,
1289 unsigned short RefreshRateTableIndex,
21df8fc8
PS
1290 struct vb_device_info *pVBInfo)
1291{
56d276ca 1292 unsigned short i, tempdx, tempal, modeflag;
21df8fc8 1293
b397992e 1294 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
a39325d2 1295 tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
cc1e2398 1296 tempal = tempal & 0x3f;
cc1e2398 1297 tempdx = pVBInfo->TVInfo;
21df8fc8 1298
cc1e2398
AK
1299 if (pVBInfo->VBInfo & SetInSlaveMode)
1300 tempdx = tempdx | SetTVLockMode;
21df8fc8 1301
cc1e2398
AK
1302 if (modeflag & HalfDCLK)
1303 tempdx = tempdx | SetTVLowResolution;
21df8fc8 1304
cc1e2398 1305 i = 0;
21df8fc8 1306
6265ee4c
AK
1307 while (XGI_TVDataTable[i].MASK != 0xffff) {
1308 if ((tempdx & XGI_TVDataTable[i].MASK) ==
1309 XGI_TVDataTable[i].CAP)
cc1e2398
AK
1310 break;
1311 i++;
1312 }
21df8fc8 1313
18ba866b 1314 return &XGI_TVDataTable[i].DATAPTR[tempal];
21df8fc8 1315}
d7636e0b 1316
cc1e2398
AK
1317static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
1318 unsigned short RefreshRateTableIndex,
21df8fc8
PS
1319 struct vb_device_info *pVBInfo)
1320{
6008f877
AK
1321 struct SiS_LVDSData const *LCDPtr;
1322
1323 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
1324 return;
1325
1326 LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeNo, ModeIdIndex,
1327 RefreshRateTableIndex, pVBInfo);
1328 pVBInfo->VGAHT = LCDPtr->VGAHT;
1329 pVBInfo->VGAVT = LCDPtr->VGAVT;
1330 pVBInfo->HT = LCDPtr->LCDHT;
1331 pVBInfo->VT = LCDPtr->LCDVT;
1332
1333 if (pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))
1334 return;
1335
1336 if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
1337 (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
1338 pVBInfo->HDE = 1024;
1339 pVBInfo->VDE = 768;
1340 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
1341 (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
1342 pVBInfo->HDE = 1280;
1343 pVBInfo->VDE = 1024;
1344 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
1345 pVBInfo->HDE = 1400;
1346 pVBInfo->VDE = 1050;
1347 } else {
1348 pVBInfo->HDE = 1600;
1349 pVBInfo->VDE = 1200;
21df8fc8 1350 }
21df8fc8
PS
1351}
1352
cc1e2398
AK
1353static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
1354 unsigned short RefreshRateTableIndex,
21df8fc8
PS
1355 struct xgi_hw_device_info *HwDeviceExtension,
1356 struct vb_device_info *pVBInfo)
1357{
9d1c6299 1358 unsigned short i;
bdc9eb14
AK
1359 struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL;
1360 struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL;
21df8fc8 1361
a3d675c8 1362 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
9d1c6299 1363 LCDPtr = XGI_GetLcdPtr(xgifb_epllcd_crt1_h, ModeNo, ModeIdIndex,
a7e46d8b 1364 RefreshRateTableIndex, pVBInfo);
21df8fc8 1365
aef6bc74 1366 for (i = 0; i < 8; i++)
6154e7f4 1367 pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i];
aef6bc74 1368 }
21df8fc8 1369
aef6bc74 1370 XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
21df8fc8 1371
a3d675c8 1372 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
9d1c6299
AK
1373 LCDPtr1 = XGI_GetLcdPtr(xgifb_epllcd_crt1_v, ModeNo,
1374 ModeIdIndex, RefreshRateTableIndex,
1375 pVBInfo);
aef6bc74 1376 for (i = 0; i < 7; i++)
6154e7f4 1377 pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i];
cc1e2398 1378 }
aef6bc74
AK
1379
1380 XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
cc1e2398 1381}
21df8fc8 1382
cc1e2398
AK
1383static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
1384{
1385 unsigned char tempal, tempah, tempbl, i;
1386
58839b01 1387 tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36);
cc1e2398
AK
1388 tempal = tempah & 0x0F;
1389 tempah = tempah & 0xF0;
1390 i = 0;
1391 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
21df8fc8 1392
cc1e2398
AK
1393 while (tempbl != 0xFF) {
1394 if (tempbl & 0x80) { /* OEMUtil */
1395 tempal = tempah;
1396 tempbl = tempbl & ~(0x80);
21df8fc8
PS
1397 }
1398
cc1e2398
AK
1399 if (tempal == tempbl)
1400 break;
21df8fc8 1401
cc1e2398 1402 i++;
21df8fc8 1403
cc1e2398 1404 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
21df8fc8
PS
1405 }
1406
cc1e2398 1407 return i;
21df8fc8
PS
1408}
1409
cc1e2398 1410static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
21df8fc8 1411{
cc1e2398 1412 unsigned short tempah, tempal, tempbl, i;
21df8fc8 1413
cc1e2398
AK
1414 tempal = pVBInfo->LCDResInfo;
1415 tempah = pVBInfo->LCDTypeInfo;
21df8fc8 1416
cc1e2398
AK
1417 i = 0;
1418 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
21df8fc8 1419
cc1e2398
AK
1420 while (tempbl != 0xFF) {
1421 if ((tempbl & 0x80) && (tempbl != 0x80)) {
1422 tempal = tempah;
1423 tempbl &= ~0x80;
21df8fc8
PS
1424 }
1425
cc1e2398
AK
1426 if (tempal == tempbl)
1427 break;
21df8fc8 1428
cc1e2398
AK
1429 i++;
1430 tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1431 }
21df8fc8 1432
cc1e2398 1433 if (tempbl == 0xFF) {
255aabd2 1434 pVBInfo->LCDResInfo = Panel_1024x768;
cc1e2398
AK
1435 pVBInfo->LCDTypeInfo = 0;
1436 i = 0;
1437 }
21df8fc8 1438
cc1e2398
AK
1439 return i;
1440}
21df8fc8 1441
1d7f656d
KT
1442static void XGI_GetLCDSync(unsigned short *HSyncWidth,
1443 unsigned short *VSyncWidth,
1444 struct vb_device_info *pVBInfo)
cc1e2398
AK
1445{
1446 unsigned short Index;
21df8fc8 1447
cc1e2398
AK
1448 Index = XGI_GetLCDCapPtr(pVBInfo);
1449 *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
1450 *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
21df8fc8 1451
cc1e2398
AK
1452 return;
1453}
21df8fc8 1454
cc1e2398
AK
1455static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
1456 unsigned short RefreshRateTableIndex,
1457 struct vb_device_info *pVBInfo)
1458{
1459 unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
1460 unsigned long temp, temp1, temp2, temp3, push3;
bdc9eb14 1461 struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL;
21df8fc8 1462
b397992e 1463 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
826215d9
PH
1464 LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeNo, ModeIdIndex,
1465 RefreshRateTableIndex, pVBInfo);
21df8fc8 1466
09cb8e50
AK
1467 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
1468 push1 = tempbx;
1469 push2 = tempax;
1470
1471 /* GetLCDResInfo */
255aabd2
PH
1472 if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
1473 (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
09cb8e50
AK
1474 tempax = 1024;
1475 tempbx = 768;
255aabd2
PH
1476 } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
1477 (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
09cb8e50
AK
1478 tempax = 1280;
1479 tempbx = 1024;
255aabd2 1480 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
09cb8e50
AK
1481 tempax = 1400;
1482 tempbx = 1050;
1483 } else {
1484 tempax = 1600;
1485 tempbx = 1200;
1486 }
21df8fc8 1487
09cb8e50
AK
1488 if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
1489 pVBInfo->HDE = tempax;
1490 pVBInfo->VDE = tempbx;
1491 pVBInfo->VGAHDE = tempax;
1492 pVBInfo->VGAVDE = tempbx;
1493 }
cc1e2398 1494
09cb8e50 1495 tempax = pVBInfo->HT;
21df8fc8 1496
826215d9 1497 tempbx = LCDPtr1->LCDHDES;
21df8fc8 1498
09cb8e50
AK
1499 tempcx = pVBInfo->HDE;
1500 tempbx = tempbx & 0x0fff;
1501 tempcx += tempbx;
21df8fc8 1502
09cb8e50
AK
1503 if (tempcx >= tempax)
1504 tempcx -= tempax;
21df8fc8 1505
09cb8e50 1506 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
21df8fc8 1507
09cb8e50
AK
1508 tempcx = tempcx >> 3;
1509 tempbx = tempbx >> 3;
21df8fc8 1510
09cb8e50
AK
1511 xgifb_reg_set(pVBInfo->Part1Port, 0x16,
1512 (unsigned short) (tempbx & 0xff));
1513 xgifb_reg_set(pVBInfo->Part1Port, 0x17,
1514 (unsigned short) (tempcx & 0xff));
cc1e2398 1515
09cb8e50 1516 tempax = pVBInfo->HT;
cc1e2398 1517
826215d9 1518 tempbx = LCDPtr1->LCDHRS;
cc1e2398 1519
09cb8e50 1520 tempcx = push2;
21df8fc8 1521
09cb8e50
AK
1522 if (pVBInfo->LCDInfo & EnableScalingLCD)
1523 tempcx = LCDPtr1->LCDHSync;
21df8fc8 1524
09cb8e50 1525 tempcx += tempbx;
21df8fc8 1526
09cb8e50
AK
1527 if (tempcx >= tempax)
1528 tempcx -= tempax;
21df8fc8 1529
09cb8e50
AK
1530 tempax = tempbx & 0x07;
1531 tempax = tempax >> 5;
1532 tempcx = tempcx >> 3;
1533 tempbx = tempbx >> 3;
21df8fc8 1534
09cb8e50
AK
1535 tempcx &= 0x1f;
1536 tempax |= tempcx;
21df8fc8 1537
09cb8e50
AK
1538 xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax);
1539 xgifb_reg_set(pVBInfo->Part1Port, 0x14,
1540 (unsigned short) (tempbx & 0xff));
21df8fc8 1541
09cb8e50 1542 tempax = pVBInfo->VT;
826215d9 1543 tempbx = LCDPtr1->LCDVDES;
09cb8e50 1544 tempcx = pVBInfo->VDE;
21df8fc8 1545
09cb8e50
AK
1546 tempbx = tempbx & 0x0fff;
1547 tempcx += tempbx;
1548 if (tempcx >= tempax)
1549 tempcx -= tempax;
21df8fc8 1550
09cb8e50
AK
1551 xgifb_reg_set(pVBInfo->Part1Port, 0x1b,
1552 (unsigned short) (tempbx & 0xff));
1553 xgifb_reg_set(pVBInfo->Part1Port, 0x1c,
1554 (unsigned short) (tempcx & 0xff));
21df8fc8 1555
09cb8e50
AK
1556 tempbx = (tempbx >> 8) & 0x07;
1557 tempcx = (tempcx >> 8) & 0x07;
21df8fc8 1558
09cb8e50
AK
1559 xgifb_reg_set(pVBInfo->Part1Port, 0x1d,
1560 (unsigned short) ((tempcx << 3)
1561 | tempbx));
21df8fc8 1562
09cb8e50 1563 tempax = pVBInfo->VT;
826215d9 1564 tempbx = LCDPtr1->LCDVRS;
21df8fc8 1565
09cb8e50 1566 tempcx = push1;
21df8fc8 1567
09cb8e50
AK
1568 if (pVBInfo->LCDInfo & EnableScalingLCD)
1569 tempcx = LCDPtr1->LCDVSync;
21df8fc8 1570
09cb8e50
AK
1571 tempcx += tempbx;
1572 if (tempcx >= tempax)
1573 tempcx -= tempax;
21df8fc8 1574
09cb8e50
AK
1575 xgifb_reg_set(pVBInfo->Part1Port, 0x18,
1576 (unsigned short) (tempbx & 0xff));
1577 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f,
1578 (unsigned short) (tempcx & 0x0f));
21df8fc8 1579
09cb8e50 1580 tempax = ((tempbx >> 8) & 0x07) << 3;
21df8fc8 1581
09cb8e50
AK
1582 tempbx = pVBInfo->VGAVDE;
1583 if (tempbx != pVBInfo->VDE)
1584 tempax |= 0x40;
21df8fc8 1585
a3d675c8 1586 if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA)
09cb8e50 1587 tempax |= 0x40;
21df8fc8 1588
09cb8e50
AK
1589 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07,
1590 tempax);
21df8fc8 1591
09cb8e50
AK
1592 tempcx = pVBInfo->VGAVT;
1593 tempbx = pVBInfo->VDE;
1594 tempax = pVBInfo->VGAVDE;
1595 tempcx -= tempax;
21df8fc8 1596
09cb8e50
AK
1597 temp = tempax; /* 0430 ylshieh */
1598 temp1 = (temp << 18) / tempbx;
21df8fc8 1599
09cb8e50 1600 tempdx = (unsigned short) ((temp << 18) % tempbx);
21df8fc8 1601
09cb8e50
AK
1602 if (tempdx != 0)
1603 temp1 += 1;
21df8fc8 1604
09cb8e50
AK
1605 temp2 = temp1;
1606 push3 = temp2;
cc1e2398 1607
09cb8e50
AK
1608 xgifb_reg_set(pVBInfo->Part1Port, 0x37,
1609 (unsigned short) (temp2 & 0xff));
1610 xgifb_reg_set(pVBInfo->Part1Port, 0x36,
1611 (unsigned short) ((temp2 >> 8) & 0xff));
cc1e2398 1612
09cb8e50
AK
1613 tempbx = (unsigned short) (temp2 >> 16);
1614 tempax = tempbx & 0x03;
21df8fc8 1615
09cb8e50
AK
1616 tempbx = pVBInfo->VGAVDE;
1617 if (tempbx == pVBInfo->VDE)
1618 tempax |= 0x04;
1619
1620 xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax);
1621
1622 if (pVBInfo->VBType & VB_XGI301C) {
1623 temp2 = push3;
1624 xgifb_reg_set(pVBInfo->Part4Port,
1625 0x3c,
1626 (unsigned short) (temp2 & 0xff));
1627 xgifb_reg_set(pVBInfo->Part4Port,
1628 0x3b,
1629 (unsigned short) ((temp2 >> 8) &
1630 0xff));
a35cd0ba 1631 tempbx = (unsigned short) (temp2 >> 16);
09cb8e50
AK
1632 xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a,
1633 ~0xc0,
1634 (unsigned short) ((tempbx &
1635 0xff) << 6));
1636
1637 tempcx = pVBInfo->VGAVDE;
1638 if (tempcx == pVBInfo->VDE)
1639 xgifb_reg_and_or(pVBInfo->Part4Port,
1640 0x30, ~0x0c, 0x00);
1641 else
1642 xgifb_reg_and_or(pVBInfo->Part4Port,
1643 0x30, ~0x0c, 0x08);
1644 }
21df8fc8 1645
09cb8e50
AK
1646 tempcx = pVBInfo->VGAHDE;
1647 tempbx = pVBInfo->HDE;
21df8fc8 1648
09cb8e50 1649 temp1 = tempcx << 16;
d7636e0b 1650
09cb8e50 1651 tempax = (unsigned short) (temp1 / tempbx);
21df8fc8 1652
09cb8e50
AK
1653 if ((tempbx & 0xffff) == (tempcx & 0xffff))
1654 tempax = 65535;
21df8fc8 1655
09cb8e50
AK
1656 temp3 = tempax;
1657 temp1 = pVBInfo->VGAHDE << 16;
d7636e0b 1658
09cb8e50
AK
1659 temp1 /= temp3;
1660 temp3 = temp3 << 16;
1661 temp1 -= 1;
21df8fc8 1662
09cb8e50 1663 temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
d7636e0b 1664
09cb8e50
AK
1665 tempax = (unsigned short) (temp3 & 0xff);
1666 xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax);
d7636e0b 1667
09cb8e50
AK
1668 temp1 = pVBInfo->VGAVDE << 18;
1669 temp1 = temp1 / push3;
1670 tempbx = (unsigned short) (temp1 & 0xffff);
21df8fc8 1671
255aabd2 1672 if (pVBInfo->LCDResInfo == Panel_1024x768)
09cb8e50 1673 tempbx -= 1;
21df8fc8 1674
09cb8e50
AK
1675 tempax = ((tempbx >> 8) & 0xff) << 3;
1676 tempax |= (unsigned short) ((temp3 >> 8) & 0x07);
1677 xgifb_reg_set(pVBInfo->Part1Port, 0x20,
1678 (unsigned short) (tempax & 0xff));
1679 xgifb_reg_set(pVBInfo->Part1Port, 0x21,
1680 (unsigned short) (tempbx & 0xff));
21df8fc8 1681
09cb8e50 1682 temp3 = temp3 >> 16;
a35cd0ba 1683
09cb8e50
AK
1684 if (modeflag & HalfDCLK)
1685 temp3 = temp3 >> 1;
a35cd0ba 1686
09cb8e50
AK
1687 xgifb_reg_set(pVBInfo->Part1Port, 0x22,
1688 (unsigned short) ((temp3 >> 8) & 0xff));
1689 xgifb_reg_set(pVBInfo->Part1Port, 0x23,
1690 (unsigned short) (temp3 & 0xff));
21df8fc8 1691}
d7636e0b 1692
cc1e2398
AK
1693/* --------------------------------------------------------------------- */
1694/* Function : XGI_GETLCDVCLKPtr */
1695/* Input : */
1696/* Output : al -> VCLK Index */
1697/* Description : */
1698/* --------------------------------------------------------------------- */
1699static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
21df8fc8
PS
1700 struct vb_device_info *pVBInfo)
1701{
cc1e2398 1702 unsigned short index;
d7636e0b 1703
a3d675c8 1704 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
cc1e2398 1705 index = XGI_GetLCDCapPtr1(pVBInfo);
d7636e0b 1706
cc1e2398
AK
1707 if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
1708 *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
1709 *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
1710 } else { /* LCDA */
1711 *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
1712 *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
21df8fc8 1713 }
21df8fc8 1714 }
cc1e2398 1715 return;
d7636e0b 1716}
1717
cc1e2398
AK
1718static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
1719 unsigned short ModeNo, unsigned short ModeIdIndex,
1720 struct vb_device_info *pVBInfo)
d7636e0b 1721{
d7636e0b 1722
cc1e2398 1723 unsigned short index, modeflag;
cc1e2398 1724 unsigned char tempal;
d7636e0b 1725
34c13ee2 1726 /* si+Ext_ResInfo */
b397992e 1727 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
d7636e0b 1728
1d7f656d
KT
1729 if ((pVBInfo->SetFlag & ProgrammingCRT2) &&
1730 (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
cc1e2398
AK
1731 index = XGI_GetLCDCapPtr(pVBInfo);
1732 tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
d7636e0b 1733
a3d675c8 1734 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
cc1e2398 1735 return tempal;
d7636e0b 1736
cc1e2398 1737 /* {TV} */
1d7f656d 1738 if (pVBInfo->VBType &
6896b94e
PH
1739 (VB_SIS301B |
1740 VB_SIS302B |
1741 VB_SIS301LV |
1742 VB_SIS302LV |
1d7f656d 1743 VB_XGI301C)) {
599801f9 1744 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
ccc8cb25 1745 tempal = TVCLKBASE_315 + HiTVVCLKDIV2;
cc1e2398 1746 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
ccc8cb25 1747 tempal = TVCLKBASE_315 + HiTVVCLK;
cc1e2398 1748 if (pVBInfo->TVInfo & TVSimuMode) {
ccc8cb25 1749 tempal = TVCLKBASE_315 + HiTVSimuVCLK;
cc1e2398 1750 if (!(modeflag & Charx8Dot))
3bcc2460
MG
1751 tempal = TVCLKBASE_315 +
1752 HiTVTextVCLK;
d7636e0b 1753
cc1e2398
AK
1754 }
1755 return tempal;
1756 }
d7636e0b 1757
599801f9 1758 if (pVBInfo->TVInfo & TVSetYPbPr750p) {
a3d675c8 1759 tempal = XGI_YPbPr750pVCLK;
cc1e2398
AK
1760 return tempal;
1761 }
d7636e0b 1762
599801f9 1763 if (pVBInfo->TVInfo & TVSetYPbPr525p) {
cc1e2398
AK
1764 tempal = YPbPr525pVCLK;
1765 return tempal;
1766 }
d7636e0b 1767
cc1e2398 1768 tempal = NTSC1024VCLK;
d7636e0b 1769
cc1e2398 1770 if (!(pVBInfo->TVInfo & NTSC1024x768)) {
ccc8cb25 1771 tempal = TVCLKBASE_315 + TVVCLKDIV2;
cc1e2398 1772 if (!(pVBInfo->TVInfo & RPLLDIV2XO))
ccc8cb25 1773 tempal = TVCLKBASE_315 + TVVCLK;
cc1e2398 1774 }
d7636e0b 1775
cc1e2398
AK
1776 if (pVBInfo->VBInfo & SetCRT2ToTV)
1777 return tempal;
1778 }
cc1e2398 1779 } /* {End of VB} */
d7636e0b 1780
516354e0 1781 inb((pVBInfo->P3ca + 0x02));
a39325d2 1782 tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
cc1e2398 1783 return tempal;
d7636e0b 1784}
1785
cc1e2398
AK
1786static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
1787 unsigned char *di_1, struct vb_device_info *pVBInfo)
d7636e0b 1788{
6896b94e
PH
1789 if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B
1790 | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
3bcc2460
MG
1791 if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
1792 (pVBInfo->SetFlag & ProgrammingCRT2)) {
e8cb03d4 1793 *di_0 = XGI_VBVCLKData[tempal].Part4_A;
a7e46d8b 1794 *di_1 = XGI_VBVCLKData[tempal].Part4_B;
cc1e2398
AK
1795 }
1796 } else {
1797 *di_0 = XGI_VCLKData[tempal].SR2B;
1798 *di_1 = XGI_VCLKData[tempal].SR2C;
1799 }
d7636e0b 1800}
d7636e0b 1801
cc1e2398
AK
1802static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex,
1803 unsigned short RefreshRateTableIndex,
21df8fc8
PS
1804 struct vb_device_info *pVBInfo)
1805{
cc1e2398
AK
1806 unsigned char di_0, di_1, tempal;
1807 int i;
21df8fc8 1808
cc1e2398
AK
1809 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
1810 pVBInfo);
1811 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
1812 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
1813
1814 for (i = 0; i < 4; i++) {
ec9e5d3e 1815 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30,
cc1e2398 1816 (unsigned short) (0x10 * i));
a3d675c8 1817 if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
cc1e2398 1818 && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
8104e329
AK
1819 xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0);
1820 xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1);
cc1e2398 1821 } else {
8104e329
AK
1822 xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0);
1823 xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1);
cc1e2398
AK
1824 }
1825 }
d7636e0b 1826}
1827
cc1e2398
AK
1828static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
1829 struct vb_device_info *pVBInfo)
d7636e0b 1830{
cc1e2398 1831 unsigned short tempcl, tempch, temp, tempbl, tempax;
d7636e0b 1832
6896b94e
PH
1833 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
1834 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398
AK
1835 tempcl = 0;
1836 tempch = 0;
58839b01 1837 temp = xgifb_reg_get(pVBInfo->P3c4, 0x01);
21df8fc8 1838
cc1e2398 1839 if (!(temp & 0x20)) {
58839b01 1840 temp = xgifb_reg_get(pVBInfo->P3d4, 0x17);
cc1e2398 1841 if (temp & 0x80) {
58839b01 1842 temp = xgifb_reg_get(pVBInfo->P3d4, 0x53);
cc1e2398
AK
1843 if (!(temp & 0x40))
1844 tempcl |= ActiveCRT1;
1845 }
1846 }
21df8fc8 1847
58839b01 1848 temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e);
cc1e2398 1849 temp &= 0x0f;
21df8fc8 1850
cc1e2398 1851 if (!(temp == 0x08)) {
949eb0ae 1852 /* Check ChannelA */
1d7f656d 1853 tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13);
cc1e2398
AK
1854 if (tempax & 0x04)
1855 tempcl = tempcl | ActiveLCD;
21df8fc8 1856
cc1e2398 1857 temp &= 0x05;
d7636e0b 1858
cc1e2398
AK
1859 if (!(tempcl & ActiveLCD))
1860 if (temp == 0x01)
1861 tempcl |= ActiveCRT2;
1862
1863 if (temp == 0x04)
1864 tempcl |= ActiveLCD;
1865
1866 if (temp == 0x05) {
58839b01 1867 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00);
cc1e2398
AK
1868
1869 if (!(temp & 0x08))
1870 tempch |= ActiveAVideo;
1871
1872 if (!(temp & 0x04))
1873 tempch |= ActiveSVideo;
1874
1875 if (temp & 0x02)
1876 tempch |= ActiveSCART;
1877
599801f9 1878 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
cc1e2398
AK
1879 if (temp & 0x01)
1880 tempch |= ActiveHiTV;
21df8fc8 1881 }
21df8fc8 1882
599801f9 1883 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
58839b01 1884 temp = xgifb_reg_get(
cc1e2398
AK
1885 pVBInfo->Part2Port,
1886 0x4d);
21df8fc8 1887
cc1e2398
AK
1888 if (temp & 0x10)
1889 tempch |= ActiveYPbPr;
21df8fc8 1890 }
cc1e2398
AK
1891
1892 if (tempch != 0)
1893 tempcl |= ActiveTV;
21df8fc8 1894 }
cc1e2398 1895 }
21df8fc8 1896
58839b01 1897 temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
cc1e2398
AK
1898 if (tempcl & ActiveLCD) {
1899 if ((pVBInfo->SetFlag & ReserveTVOption)) {
1900 if (temp & ActiveTV)
1901 tempcl |= ActiveTV;
21df8fc8
PS
1902 }
1903 }
cc1e2398 1904 temp = tempcl;
a3d675c8 1905 tempbl = ~XGI_ModeSwitchStatus;
ec9e5d3e 1906 xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp);
21df8fc8 1907
cc1e2398 1908 if (!(pVBInfo->SetFlag & ReserveTVOption))
8104e329 1909 xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch);
cc1e2398
AK
1910 } else {
1911 return;
21df8fc8 1912 }
cc1e2398 1913}
d7636e0b 1914
cc1e2398 1915void XGI_GetVBType(struct vb_device_info *pVBInfo)
d7636e0b 1916{
cc1e2398 1917 unsigned short flag, tempbx, tempah;
d7636e0b 1918
7eec23a7
MG
1919 if (pVBInfo->IF_DEF_LVDS != 0)
1920 return;
cc1e2398 1921
7eec23a7
MG
1922 tempbx = VB_SIS302B;
1923 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
1924 if (flag == 0x02)
1925 goto finish;
1926
1927 tempbx = VB_SIS301;
1928 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01);
1929 if (flag < 0xB0)
1930 goto finish;
1931
1932 tempbx = VB_SIS301B;
1933 if (flag < 0xC0)
1934 goto bigger_than_0xB0;
1935
1936 tempbx = VB_XGI301C;
1937 if (flag < 0xD0)
1938 goto bigger_than_0xB0;
1939
1940 tempbx = VB_SIS301LV;
1941 if (flag < 0xE0)
1942 goto bigger_than_0xB0;
1943
1944 tempbx = VB_SIS302LV;
1945 tempah = xgifb_reg_get(pVBInfo->Part4Port, 0x39);
1946 if (tempah != 0xFF)
1947 tempbx = VB_XGI301C;
1948
1949bigger_than_0xB0:
1950 if (tempbx & (VB_SIS301B | VB_SIS302B)) {
1951 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x23);
1952 if (!(flag & 0x02))
1953 tempbx = tempbx | VB_NoLCD;
cc1e2398 1954 }
7eec23a7
MG
1955
1956finish:
1957 pVBInfo->VBType = tempbx;
d7636e0b 1958}
1959
fac2cc92 1960static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
cc1e2398 1961 struct xgi_hw_device_info *HwDeviceExtension,
21df8fc8
PS
1962 struct vb_device_info *pVBInfo)
1963{
cc1e2398 1964 unsigned short tempax, push, tempbx, temp, modeflag;
d7636e0b 1965
b397992e 1966 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
cc1e2398 1967 pVBInfo->SetFlag = 0;
6896b94e 1968 pVBInfo->ModeType = modeflag & ModeTypeMask;
cc1e2398
AK
1969 tempbx = 0;
1970
f9317351
MG
1971 if (!(pVBInfo->VBType & 0xFFFF))
1972 return;
1973
1974 /* Check Display Device */
1975 temp = xgifb_reg_get(pVBInfo->P3d4, 0x30);
1976 tempbx = tempbx | temp;
1977 temp = xgifb_reg_get(pVBInfo->P3d4, 0x31);
1978 push = temp;
1979 push = push << 8;
1980 tempax = temp << 8;
1981 tempbx = tempbx | tempax;
1982 temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA
1983 | SetInSlaveMode | DisableCRT2Display);
1984 temp = 0xFFFF ^ temp;
1985 tempbx &= temp;
1986
1987 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
1988
1b149edf
AK
1989 if (pVBInfo->VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV |
1990 VB_XGI301C)) {
1991 if (temp & EnableDualEdge) {
1992 tempbx |= SetCRT2ToDualEdge;
1993 if (temp & SetToLCDA)
1994 tempbx |= XGI_SetCRT2ToLCDA;
cc1e2398 1995 }
f9317351 1996 }
21df8fc8 1997
f9317351 1998 if (pVBInfo->IF_DEF_YPbPr == 1) {
1b149edf 1999 if (pVBInfo->VBType & (VB_SIS301LV|VB_SIS302LV|VB_XGI301C)) {
f9317351
MG
2000 if (temp & SetYPbPr) {
2001 if (pVBInfo->IF_DEF_HiVision == 1) {
1b149edf
AK
2002 /* shampoo add for new scratch */
2003 temp = xgifb_reg_get(pVBInfo->P3d4,
2004 0x35);
f9317351
MG
2005 temp &= YPbPrMode;
2006 tempbx |= SetCRT2ToHiVision;
2007
2008 if (temp != YPbPrMode1080i) {
1b149edf
AK
2009 tempbx &= (~SetCRT2ToHiVision);
2010 tempbx |= SetCRT2ToYPbPr525750;
cc1e2398 2011 }
cc1e2398
AK
2012 }
2013 }
2014 }
f9317351 2015 }
21df8fc8 2016
f9317351 2017 tempax = push; /* restore CR31 */
21df8fc8 2018
1b149edf
AK
2019 if (pVBInfo->IF_DEF_YPbPr == 1) {
2020 if (pVBInfo->IF_DEF_HiVision == 1)
2021 temp = 0x09FC;
2022 else
2023 temp = 0x097C;
2024 } else if (pVBInfo->IF_DEF_HiVision == 1) {
2025 temp = 0x01FC;
2026 } else {
2027 temp = 0x017C;
f9317351 2028 }
21df8fc8 2029
f9317351
MG
2030 if (!(tempbx & temp)) {
2031 tempax |= DisableCRT2Display;
2032 tempbx = 0;
2033 }
21df8fc8 2034
31fb40fd
AK
2035 if (!(pVBInfo->VBType & VB_NoLCD)) {
2036 if (tempbx & XGI_SetCRT2ToLCDA) {
2037 if (tempbx & SetSimuScanMode)
1b149edf 2038 tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC |
31fb40fd
AK
2039 SwitchCRT2));
2040 else
1b149edf
AK
2041 tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC |
2042 SetCRT2ToTV | SwitchCRT2));
cc1e2398 2043 }
f9317351 2044 }
21df8fc8 2045
f9317351
MG
2046 /* shampoo add */
2047 /* for driver abnormal */
2048 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
2049 if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
2050 if (tempbx & SetCRT2ToRAMDAC) {
1b149edf
AK
2051 tempbx &= (0xFF00 | SetCRT2ToRAMDAC |
2052 SwitchCRT2 | SetSimuScanMode);
599801f9 2053 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
cc1e2398 2054 }
f9317351 2055 } else {
1b149edf 2056 tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD |
f9317351 2057 SetCRT2ToTV));
cc1e2398 2058 }
f9317351 2059 }
21df8fc8 2060
f9317351
MG
2061 if (!(pVBInfo->VBType & VB_NoLCD)) {
2062 if (tempbx & SetCRT2ToLCD) {
1b149edf 2063 tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchCRT2 |
1d7f656d 2064 SetSimuScanMode);
599801f9 2065 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
cc1e2398 2066 }
f9317351 2067 }
21df8fc8 2068
f9317351 2069 if (tempbx & SetCRT2ToSCART) {
1b149edf 2070 tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchCRT2 |
f9317351
MG
2071 SetSimuScanMode);
2072 tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2073 }
21df8fc8 2074
f9317351
MG
2075 if (pVBInfo->IF_DEF_YPbPr == 1) {
2076 if (tempbx & SetCRT2ToYPbPr525750)
1b149edf 2077 tempbx &= (0xFF00 | SwitchCRT2 | SetSimuScanMode);
f9317351 2078 }
21df8fc8 2079
f9317351
MG
2080 if (pVBInfo->IF_DEF_HiVision == 1) {
2081 if (tempbx & SetCRT2ToHiVision)
1b149edf 2082 tempbx &= (0xFF00 | SetCRT2ToHiVision | SwitchCRT2 |
f9317351
MG
2083 SetSimuScanMode);
2084 }
21df8fc8 2085
f9317351
MG
2086 if (tempax & DisableCRT2Display) { /* Set Display Device Info */
2087 if (!(tempbx & (SwitchCRT2 | SetSimuScanMode)))
2088 tempbx = DisableCRT2Display;
2089 }
21df8fc8 2090
f9317351 2091 if (!(tempbx & DisableCRT2Display)) {
1b149edf 2092 if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) {
31fb40fd 2093 if (!(tempbx & XGI_SetCRT2ToLCDA))
1b149edf 2094 tempbx |= (SetInSlaveMode | SetSimuScanMode);
21df8fc8 2095 }
f9317351
MG
2096
2097 /* LCD+TV can't support in slave mode
2098 * (Force LCDA+TV->LCDB) */
1b149edf
AK
2099 if ((tempbx & SetInSlaveMode) && (tempbx & XGI_SetCRT2ToLCDA)) {
2100 tempbx ^= (SetCRT2ToLCD | XGI_SetCRT2ToLCDA |
f9317351
MG
2101 SetCRT2ToDualEdge);
2102 pVBInfo->SetFlag |= ReserveTVOption;
2103 }
21df8fc8 2104 }
cc1e2398
AK
2105
2106 pVBInfo->VBInfo = tempbx;
21df8fc8
PS
2107}
2108
fac2cc92 2109static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
21df8fc8 2110 struct vb_device_info *pVBInfo)
d7636e0b 2111{
5fc699f6 2112 unsigned short tempbx = 0, resinfo = 0, modeflag, index1;
d7636e0b 2113
cc1e2398 2114 if (pVBInfo->VBInfo & SetCRT2ToTV) {
b397992e
AK
2115 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2116 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
d7636e0b 2117
5fc699f6
PH
2118 tempbx = xgifb_reg_get(pVBInfo->P3d4, 0x35);
2119 if (tempbx & TVSetPAL) {
2120 tempbx &= (SetCHTVOverScan |
2121 TVSetPALM |
2122 TVSetPALN |
2123 TVSetPAL);
2124 if (tempbx & TVSetPALM)
2125 /* set to NTSC if PAL-M */
2126 tempbx &= ~TVSetPAL;
2127 } else
2128 tempbx &= (SetCHTVOverScan |
2129 TVSetNTSCJ |
2130 TVSetPAL);
d7636e0b 2131
a8b35290
AK
2132 if (pVBInfo->VBInfo & SetCRT2ToSCART)
2133 tempbx |= TVSetPAL;
d7636e0b 2134
cc1e2398 2135 if (pVBInfo->IF_DEF_YPbPr == 1) {
599801f9 2136 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
58839b01 2137 index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35);
cc1e2398 2138 index1 &= YPbPrMode;
d7636e0b 2139
cc1e2398 2140 if (index1 == YPbPrMode525i)
599801f9 2141 tempbx |= TVSetYPbPr525i;
21df8fc8 2142
cc1e2398 2143 if (index1 == YPbPrMode525p)
599801f9 2144 tempbx = tempbx | TVSetYPbPr525p;
cc1e2398 2145 if (index1 == YPbPrMode750p)
599801f9 2146 tempbx = tempbx | TVSetYPbPr750p;
cc1e2398
AK
2147 }
2148 }
21df8fc8 2149
cc1e2398 2150 if (pVBInfo->IF_DEF_HiVision == 1) {
599801f9
PH
2151 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
2152 tempbx = tempbx | TVSetHiVision | TVSetPAL;
cc1e2398 2153 }
21df8fc8 2154
a8b35290
AK
2155 if ((pVBInfo->VBInfo & SetInSlaveMode) &&
2156 (!(pVBInfo->VBInfo & SetNotSimuMode)))
2157 tempbx |= TVSimuMode;
2158
2159 if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8))
2160 /* NTSC 1024x768, */
2161 tempbx |= NTSC1024x768;
2162
2163 tempbx |= RPLLDIV2XO;
2164
2165 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2166 if (pVBInfo->VBInfo & SetInSlaveMode)
2167 tempbx &= (~RPLLDIV2XO);
2168 } else if (tempbx & (TVSetYPbPr525p | TVSetYPbPr750p)) {
2169 tempbx &= (~RPLLDIV2XO);
2170 } else if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B |
2171 VB_SIS301LV | VB_SIS302LV |
2172 VB_XGI301C))) {
2173 if (tempbx & TVSimuMode)
2174 tempbx &= (~RPLLDIV2XO);
cc1e2398
AK
2175 }
2176 }
2177 pVBInfo->TVInfo = tempbx;
2178}
21df8fc8 2179
fac2cc92
AK
2180static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
2181 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
cc1e2398 2182{
ef9a6b99 2183 unsigned short temp, tempax, tempbx, resinfo = 0, LCDIdIndex;
21df8fc8 2184
cc1e2398
AK
2185 pVBInfo->LCDResInfo = 0;
2186 pVBInfo->LCDTypeInfo = 0;
2187 pVBInfo->LCDInfo = 0;
21df8fc8 2188
34c13ee2 2189 /* si+Ext_ResInfo // */
b397992e 2190 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
58839b01 2191 temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
cc1e2398 2192 tempbx = temp & 0x0F;
21df8fc8 2193
cc1e2398 2194 if (tempbx == 0)
255aabd2 2195 tempbx = Panel_1024x768; /* default */
cc1e2398 2196
949eb0ae 2197 /* LCD75 */
255aabd2 2198 if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) {
cc1e2398 2199 if (pVBInfo->VBInfo & DriverMode) {
58839b01 2200 tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33);
a3d675c8 2201 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
cc1e2398 2202 tempax &= 0x0F;
21df8fc8 2203 else
cc1e2398 2204 tempax = tempax >> 4;
21df8fc8 2205
cc1e2398
AK
2206 if ((resinfo == 6) || (resinfo == 9)) {
2207 if (tempax >= 3)
2208 tempbx |= PanelRef75Hz;
2209 } else if ((resinfo == 7) || (resinfo == 8)) {
2210 if (tempax >= 4)
2211 tempbx |= PanelRef75Hz;
21df8fc8 2212 }
cc1e2398
AK
2213 }
2214 }
21df8fc8 2215
cc1e2398 2216 pVBInfo->LCDResInfo = tempbx;
21df8fc8 2217
cc1e2398 2218 /* End of LCD75 */
21df8fc8 2219
a3d675c8 2220 if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
cc1e2398 2221 return 0;
21df8fc8 2222
cc1e2398 2223 tempbx = 0;
21df8fc8 2224
58839b01 2225 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
d7636e0b 2226
cc1e2398 2227 temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
d7636e0b 2228
cc1e2398 2229 tempbx |= temp;
d7636e0b 2230
cc1e2398 2231 LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
d7636e0b 2232
cc1e2398 2233 tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
d7636e0b 2234
718e715d
AK
2235 if (((pVBInfo->VBType & VB_SIS302LV) ||
2236 (pVBInfo->VBType & VB_XGI301C)) && (tempax & XGI_LCDDualLink))
2237 tempbx |= SetLCDDualLink;
2238
2239 if ((pVBInfo->LCDResInfo == Panel_1400x1050) &&
2240 (pVBInfo->VBInfo & SetCRT2ToLCD) && (resinfo == 9) &&
2241 (!(tempbx & EnableScalingLCD)))
2242 /*
2243 * set to center in 1280x1024 LCDB
2244 * for Panel_1400x1050
2245 */
2246 tempbx |= SetLCDtoNonExpanding;
21df8fc8 2247
cc1e2398
AK
2248 if (pVBInfo->VBInfo & SetInSlaveMode) {
2249 if (pVBInfo->VBInfo & SetNotSimuMode)
a3d675c8 2250 tempbx |= XGI_LCDVESATiming;
cc1e2398 2251 } else {
a3d675c8 2252 tempbx |= XGI_LCDVESATiming;
cc1e2398 2253 }
21df8fc8 2254
cc1e2398 2255 pVBInfo->LCDInfo = tempbx;
d7636e0b 2256
cc1e2398 2257 return 1;
21df8fc8 2258}
d7636e0b 2259
cc1e2398
AK
2260unsigned char XGI_SearchModeID(unsigned short ModeNo,
2261 unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo)
d7636e0b 2262{
34c13ee2 2263 for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
b397992e 2264 if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
34c13ee2 2265 break;
b397992e 2266 if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
34c13ee2 2267 return 0;
21df8fc8 2268 }
d7636e0b 2269
cc1e2398 2270 return 1;
21df8fc8 2271}
d7636e0b 2272
cc1e2398
AK
2273static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
2274{
2275 unsigned char ujRet = 0;
2276 unsigned char i = 0;
21df8fc8 2277
cc1e2398
AK
2278 for (i = 0; i < 8; i++) {
2279 ujRet = ujRet << 1;
cc1e2398 2280 ujRet |= (ujDate >> i) & 1;
21df8fc8 2281 }
d7636e0b 2282
cc1e2398
AK
2283 return ujRet;
2284}
21df8fc8 2285
cc1e2398
AK
2286/*----------------------------------------------------------------------------*/
2287/* output */
2288/* bl[5] : LVDS signal */
2289/* bl[1] : LVDS backlight */
2290/* bl[0] : LVDS VDD */
2291/*----------------------------------------------------------------------------*/
2292static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
2293{
2294 unsigned char CR4A, temp;
21df8fc8 2295
58839b01 2296 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
dc50556b 2297 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
21df8fc8 2298
58839b01 2299 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
21df8fc8 2300
cc1e2398
AK
2301 temp = XG21GPIODataTransfer(temp);
2302 temp &= 0x23;
8104e329 2303 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
cc1e2398
AK
2304 return temp;
2305}
2306
2307/*----------------------------------------------------------------------------*/
2308/* output */
2309/* bl[5] : LVDS signal */
2310/* bl[1] : LVDS backlight */
2311/* bl[0] : LVDS VDD */
2312/*----------------------------------------------------------------------------*/
2313static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
2314{
2315 unsigned char CR4A, CRB4, temp;
21df8fc8 2316
58839b01 2317 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
dc50556b 2318 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
21df8fc8 2319
58839b01 2320 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
21df8fc8 2321
cc1e2398
AK
2322 temp &= 0x0C;
2323 temp >>= 2;
8104e329 2324 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
58839b01 2325 CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4);
cc1e2398
AK
2326 temp |= ((CRB4 & 0x04) << 3);
2327 return temp;
2328}
21df8fc8 2329
0ebf538b
AK
2330/*----------------------------------------------------------------------------*/
2331/* input */
2332/* bl[5] : 1;LVDS signal on */
2333/* bl[1] : 1;LVDS backlight on */
2334/* bl[0] : 1:LVDS VDD on */
2335/* bh: 100000b : clear bit 5, to set bit5 */
2336/* 000010b : clear bit 1, to set bit1 */
2337/* 000001b : clear bit 0, to set bit0 */
2338/*----------------------------------------------------------------------------*/
2339static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
2340 struct vb_device_info *pVBInfo)
2341{
2342 unsigned char CR4A, temp;
2343
2344 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2345 tempbh &= 0x23;
2346 tempbl &= 0x23;
2347 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
2348
2349 if (tempbh & 0x20) {
2350 temp = (tempbl >> 4) & 0x02;
2351
2352 /* CR B4[1] */
2353 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
2354
2355 }
2356
2357 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2358
2359 temp = XG21GPIODataTransfer(temp);
2360 temp &= ~tempbh;
2361 temp |= tempbl;
2362 xgifb_reg_set(pVBInfo->P3d4, 0x48, temp);
2363}
2364
776115a0
AK
2365static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
2366 struct vb_device_info *pVBInfo)
2367{
2368 unsigned char CR4A, temp;
2369 unsigned short tempbh0, tempbl0;
2370
2371 tempbh0 = tempbh;
2372 tempbl0 = tempbl;
2373 tempbh0 &= 0x20;
2374 tempbl0 &= 0x20;
2375 tempbh0 >>= 3;
2376 tempbl0 >>= 3;
2377
2378 if (tempbh & 0x20) {
2379 temp = (tempbl >> 4) & 0x02;
2380
2381 /* CR B4[1] */
2382 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
2383
2384 }
2385 xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
2386
2387 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2388 tempbh &= 0x03;
2389 tempbl &= 0x03;
2390 tempbh <<= 2;
2391 tempbl <<= 2; /* GPIOC,GPIOD */
2392 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
2393 xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
2394}
2395
fab04b97
AK
2396static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
2397 struct xgi_hw_device_info *pXGIHWDE,
cc1e2398
AK
2398 struct vb_device_info *pVBInfo)
2399{
2400
ec9e5d3e 2401 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
cc1e2398
AK
2402 if (pXGIHWDE->jChipType == XG21) {
2403 if (pVBInfo->IF_DEF_LVDS == 1) {
2404 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
1d7f656d
KT
2405 /* LVDS VDD on */
2406 XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo);
886230c1 2407 mdelay(xgifb_info->lvds_data.PSC_S2);
cc1e2398
AK
2408 }
2409 if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
1d7f656d
KT
2410 /* LVDS signal on */
2411 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
886230c1 2412 mdelay(xgifb_info->lvds_data.PSC_S3);
1d7f656d
KT
2413 /* LVDS backlight on */
2414 XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo);
cc1e2398 2415 } else {
1d7f656d
KT
2416 /* DVO/DVI signal on */
2417 XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
cc1e2398 2418 }
21df8fc8 2419
21df8fc8
PS
2420 }
2421
cc1e2398
AK
2422 if (pXGIHWDE->jChipType == XG27) {
2423 if (pVBInfo->IF_DEF_LVDS == 1) {
2424 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
1d7f656d
KT
2425 /* LVDS VDD on */
2426 XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo);
886230c1 2427 mdelay(xgifb_info->lvds_data.PSC_S2);
cc1e2398
AK
2428 }
2429 if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
1d7f656d
KT
2430 /* LVDS signal on */
2431 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
886230c1 2432 mdelay(xgifb_info->lvds_data.PSC_S3);
1d7f656d
KT
2433 /* LVDS backlight on */
2434 XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo);
cc1e2398 2435 } else {
1d7f656d
KT
2436 /* DVO/DVI signal on */
2437 XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
cc1e2398 2438 }
21df8fc8 2439
cc1e2398 2440 }
d7636e0b 2441}
2442
fab04b97
AK
2443void XGI_DisplayOff(struct xgifb_video_info *xgifb_info,
2444 struct xgi_hw_device_info *pXGIHWDE,
21df8fc8
PS
2445 struct vb_device_info *pVBInfo)
2446{
d7636e0b 2447
cc1e2398
AK
2448 if (pXGIHWDE->jChipType == XG21) {
2449 if (pVBInfo->IF_DEF_LVDS == 1) {
1d7f656d
KT
2450 /* LVDS backlight off */
2451 XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo);
886230c1 2452 mdelay(xgifb_info->lvds_data.PSC_S3);
cc1e2398 2453 } else {
1d7f656d
KT
2454 /* DVO/DVI signal off */
2455 XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo);
cc1e2398 2456 }
21df8fc8
PS
2457 }
2458
cc1e2398
AK
2459 if (pXGIHWDE->jChipType == XG27) {
2460 if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
1d7f656d
KT
2461 /* LVDS backlight off */
2462 XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo);
886230c1 2463 mdelay(xgifb_info->lvds_data.PSC_S3);
cc1e2398 2464 }
21df8fc8 2465
cc1e2398 2466 if (pVBInfo->IF_DEF_LVDS == 0)
1d7f656d
KT
2467 /* DVO/DVI signal off */
2468 XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo);
cc1e2398 2469 }
21df8fc8 2470
ec9e5d3e 2471 xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
cc1e2398 2472}
21df8fc8 2473
cc1e2398
AK
2474static void XGI_WaitDisply(struct vb_device_info *pVBInfo)
2475{
d8ad0a6d 2476 while ((inb(pVBInfo->P3da) & 0x01))
cc1e2398 2477 break;
21df8fc8 2478
d8ad0a6d 2479 while (!(inb(pVBInfo->P3da) & 0x01))
cc1e2398
AK
2480 break;
2481}
21df8fc8 2482
cc1e2398
AK
2483static void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
2484{
09cb8e50 2485 xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40);
cc1e2398 2486}
21df8fc8 2487
1d7f656d
KT
2488static void XGI_SaveCRT2Info(unsigned short ModeNo,
2489 struct vb_device_info *pVBInfo)
cc1e2398
AK
2490{
2491 unsigned short temp1, temp2;
21df8fc8 2492
1d7f656d
KT
2493 /* reserve CR34 for CRT1 Mode No */
2494 xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo);
cc1e2398
AK
2495 temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
2496 temp2 = ~(SetInSlaveMode >> 8);
ec9e5d3e 2497 xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1);
cc1e2398 2498}
21df8fc8 2499
1d7f656d
KT
2500static void XGI_GetCRT2ResInfo(unsigned short ModeNo,
2501 unsigned short ModeIdIndex,
2502 struct vb_device_info *pVBInfo)
cc1e2398
AK
2503{
2504 unsigned short xres, yres, modeflag, resindex;
21df8fc8 2505
b397992e 2506 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
e8e6c754
AK
2507 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
2508 yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
34c13ee2 2509 /* si+St_ModeFlag */
b397992e 2510 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
21df8fc8 2511
34c13ee2
AK
2512 if (modeflag & HalfDCLK)
2513 xres *= 2;
21df8fc8 2514
34c13ee2
AK
2515 if (modeflag & DoubleScanMode)
2516 yres *= 2;
21df8fc8 2517
3339db8a
MG
2518 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
2519 goto exit;
2520
22006839
AK
2521 if (pVBInfo->LCDResInfo == Panel_1600x1200) {
2522 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2523 if (yres == 1024)
2524 yres = 1056;
3339db8a 2525 }
22006839 2526 }
21df8fc8 2527
22006839
AK
2528 if (pVBInfo->LCDResInfo == Panel_1280x1024) {
2529 if (yres == 400)
2530 yres = 405;
2531 else if (yres == 350)
2532 yres = 360;
cc1e2398 2533
22006839
AK
2534 if (pVBInfo->LCDInfo & XGI_LCDVESATiming) {
2535 if (yres == 360)
2536 yres = 375;
3339db8a 2537 }
22006839 2538 }
21df8fc8 2539
22006839
AK
2540 if (pVBInfo->LCDResInfo == Panel_1024x768) {
2541 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2542 if (!(pVBInfo->LCDInfo & LCDNonExpanding)) {
2543 if (yres == 350)
2544 yres = 357;
2545 else if (yres == 400)
2546 yres = 420;
2547 else if (yres == 480)
2548 yres = 525;
21df8fc8
PS
2549 }
2550 }
2551 }
2552
3339db8a
MG
2553 if (xres == 720)
2554 xres = 640;
2555
2556exit:
cc1e2398
AK
2557 pVBInfo->VGAHDE = xres;
2558 pVBInfo->HDE = xres;
2559 pVBInfo->VGAVDE = yres;
2560 pVBInfo->VDE = yres;
2561}
21df8fc8 2562
cc1e2398
AK
2563static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
2564{
21df8fc8 2565
a3d675c8 2566 if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) &&
cc1e2398
AK
2567 (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
2568 return 1;
21df8fc8 2569
cc1e2398
AK
2570 return 0;
2571}
2572
1d7f656d
KT
2573static void XGI_GetRAMDAC2DATA(unsigned short ModeNo,
2574 unsigned short ModeIdIndex,
2575 unsigned short RefreshRateTableIndex,
2576 struct vb_device_info *pVBInfo)
cc1e2398
AK
2577{
2578 unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
34c13ee2 2579 CRT1Index;
cc1e2398
AK
2580
2581 pVBInfo->RVBHCMAX = 1;
2582 pVBInfo->RVBHCFACT = 1;
b397992e 2583 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
a39325d2 2584 CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
34c13ee2 2585 CRT1Index &= IndexMask;
7853bced
AK
2586 temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[0];
2587 temp2 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[5];
34c13ee2 2588 tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
7853bced 2589 tempbx = (unsigned short) XGI_CRT1Table[CRT1Index].CR[8];
34c13ee2 2590 tempcx = (unsigned short)
7853bced 2591 XGI_CRT1Table[CRT1Index].CR[14] << 8;
34c13ee2
AK
2592 tempcx &= 0x0100;
2593 tempcx = tempcx << 2;
2594 tempbx |= tempcx;
7853bced 2595 temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[9];
cc1e2398
AK
2596
2597 if (temp1 & 0x01)
2598 tempbx |= 0x0100;
2599
2600 if (temp1 & 0x20)
2601 tempbx |= 0x0200;
2602 tempax += 5;
2603
2604 if (modeflag & Charx8Dot)
2605 tempax *= 8;
2606 else
2607 tempax *= 9;
2608
2609 pVBInfo->VGAHT = tempax;
2610 pVBInfo->HT = tempax;
2611 tempbx++;
2612 pVBInfo->VGAVT = tempbx;
2613 pVBInfo->VT = tempbx;
2614}
2615
2616static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
2617 unsigned short RefreshRateTableIndex,
2618 struct vb_device_info *pVBInfo)
2619{
9d1c6299 2620 unsigned short tempax = 0, tempbx = 0, modeflag, resinfo;
cc1e2398 2621
bdc9eb14 2622 struct SiS_LCDData const *LCDPtr = NULL;
cc1e2398 2623
34c13ee2 2624 /* si+Ext_ResInfo */
b397992e
AK
2625 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2626 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
cc1e2398
AK
2627 pVBInfo->NewFlickerMode = 0;
2628 pVBInfo->RVBHRS = 50;
2629
2630 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
2631 XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
2632 pVBInfo);
2633 return;
2634 }
2635
a3d675c8 2636 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
9d1c6299 2637 LCDPtr = XGI_GetLcdPtr(XGI_LCDDataTable, ModeNo, ModeIdIndex,
a7e46d8b 2638 RefreshRateTableIndex, pVBInfo);
cc1e2398
AK
2639
2640 pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
2641 pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
2642 pVBInfo->VGAHT = LCDPtr->VGAHT;
2643 pVBInfo->VGAVT = LCDPtr->VGAVT;
2644 pVBInfo->HT = LCDPtr->LCDHT;
2645 pVBInfo->VT = LCDPtr->LCDVT;
21df8fc8 2646
255aabd2 2647 if (pVBInfo->LCDResInfo == Panel_1024x768) {
cc1e2398
AK
2648 tempax = 1024;
2649 tempbx = 768;
2650
a3d675c8 2651 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
cc1e2398
AK
2652 if (pVBInfo->VGAVDE == 357)
2653 tempbx = 527;
2654 else if (pVBInfo->VGAVDE == 420)
2655 tempbx = 620;
2656 else if (pVBInfo->VGAVDE == 525)
2657 tempbx = 775;
2658 else if (pVBInfo->VGAVDE == 600)
2659 tempbx = 775;
cc1e2398
AK
2660 else
2661 tempbx = 768;
2662 } else
2663 tempbx = 768;
255aabd2 2664 } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) {
cc1e2398
AK
2665 tempax = 1024;
2666 tempbx = 768;
255aabd2 2667 } else if (pVBInfo->LCDResInfo == Panel_1280x1024) {
cc1e2398
AK
2668 tempax = 1280;
2669 if (pVBInfo->VGAVDE == 360)
2670 tempbx = 768;
2671 else if (pVBInfo->VGAVDE == 375)
2672 tempbx = 800;
2673 else if (pVBInfo->VGAVDE == 405)
2674 tempbx = 864;
2675 else
2676 tempbx = 1024;
255aabd2 2677 } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) {
cc1e2398
AK
2678 tempax = 1280;
2679 tempbx = 1024;
255aabd2 2680 } else if (pVBInfo->LCDResInfo == Panel_1280x960) {
cc1e2398
AK
2681 tempax = 1280;
2682 if (pVBInfo->VGAVDE == 350)
2683 tempbx = 700;
2684 else if (pVBInfo->VGAVDE == 400)
2685 tempbx = 800;
2686 else if (pVBInfo->VGAVDE == 1024)
2687 tempbx = 960;
2688 else
2689 tempbx = 960;
255aabd2 2690 } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
cc1e2398
AK
2691 tempax = 1400;
2692 tempbx = 1050;
2693
2694 if (pVBInfo->VGAVDE == 1024) {
2695 tempax = 1280;
2696 tempbx = 1024;
2697 }
255aabd2 2698 } else if (pVBInfo->LCDResInfo == Panel_1600x1200) {
cc1e2398
AK
2699 tempax = 1600;
2700 tempbx = 1200; /* alan 10/14/2003 */
a3d675c8 2701 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
cc1e2398
AK
2702 if (pVBInfo->VGAVDE == 350)
2703 tempbx = 875;
2704 else if (pVBInfo->VGAVDE == 400)
2705 tempbx = 1000;
21df8fc8
PS
2706 }
2707 }
21df8fc8 2708
cc1e2398
AK
2709 if (pVBInfo->LCDInfo & LCDNonExpanding) {
2710 tempax = pVBInfo->VGAHDE;
2711 tempbx = pVBInfo->VGAVDE;
2712 }
21df8fc8 2713
cc1e2398
AK
2714 pVBInfo->HDE = tempax;
2715 pVBInfo->VDE = tempbx;
2716 return;
2717 }
21df8fc8 2718
cc1e2398 2719 if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
24572545
AK
2720 struct SiS_TVData const *TVPtr;
2721
2722 TVPtr = XGI_GetTVPtr(ModeNo, ModeIdIndex, RefreshRateTableIndex,
2723 pVBInfo);
21df8fc8 2724
cc1e2398
AK
2725 pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
2726 pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
2727 pVBInfo->VGAHT = TVPtr->VGAHT;
2728 pVBInfo->VGAVT = TVPtr->VGAVT;
2729 pVBInfo->HDE = TVPtr->TVHDE;
2730 pVBInfo->VDE = TVPtr->TVVDE;
2731 pVBInfo->RVBHRS = TVPtr->RVBHRS;
2732 pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
21df8fc8 2733
599801f9 2734 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
cc1e2398
AK
2735 if (resinfo == 0x08)
2736 pVBInfo->NewFlickerMode = 0x40;
2737 else if (resinfo == 0x09)
2738 pVBInfo->NewFlickerMode = 0x40;
2739 else if (resinfo == 0x12)
2740 pVBInfo->NewFlickerMode = 0x40;
21df8fc8 2741
cc1e2398
AK
2742 if (pVBInfo->VGAVDE == 350)
2743 pVBInfo->TVInfo |= TVSimuMode;
21df8fc8 2744
cc1e2398
AK
2745 tempax = ExtHiTVHT;
2746 tempbx = ExtHiTVVT;
21df8fc8 2747
cc1e2398 2748 if (pVBInfo->VBInfo & SetInSlaveMode) {
21df8fc8 2749 if (pVBInfo->TVInfo & TVSimuMode) {
cc1e2398
AK
2750 tempax = StHiTVHT;
2751 tempbx = StHiTVVT;
2752
2753 if (!(modeflag & Charx8Dot)) {
2754 tempax = StHiTextTVHT;
2755 tempbx = StHiTextTVVT;
21df8fc8
PS
2756 }
2757 }
2758 }
599801f9
PH
2759 } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
2760 if (pVBInfo->TVInfo & TVSetYPbPr750p) {
cc1e2398
AK
2761 tempax = YPbPrTV750pHT; /* Ext750pTVHT */
2762 tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
2763 }
2764
599801f9 2765 if (pVBInfo->TVInfo & TVSetYPbPr525p) {
cc1e2398
AK
2766 tempax = YPbPrTV525pHT; /* Ext525pTVHT */
2767 tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
599801f9 2768 } else if (pVBInfo->TVInfo & TVSetYPbPr525i) {
cc1e2398
AK
2769 tempax = YPbPrTV525iHT; /* Ext525iTVHT */
2770 tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
2771 if (pVBInfo->TVInfo & NTSC1024x768)
2772 tempax = NTSC1024x768HT;
2773 }
21df8fc8 2774 } else {
cc1e2398
AK
2775 tempax = PALHT;
2776 tempbx = PALVT;
599801f9 2777 if (!(pVBInfo->TVInfo & TVSetPAL)) {
cc1e2398
AK
2778 tempax = NTSCHT;
2779 tempbx = NTSCVT;
2780 if (pVBInfo->TVInfo & NTSC1024x768)
2781 tempax = NTSC1024x768HT;
21df8fc8
PS
2782 }
2783 }
21df8fc8 2784
cc1e2398
AK
2785 pVBInfo->HT = tempax;
2786 pVBInfo->VT = tempbx;
2787 return;
21df8fc8 2788 }
21df8fc8
PS
2789}
2790
cc1e2398 2791static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
21df8fc8 2792 unsigned short RefreshRateTableIndex,
21df8fc8 2793 struct vb_device_info *pVBInfo)
d7636e0b 2794{
cc1e2398 2795 unsigned char di_0, di_1, tempal;
21df8fc8 2796
cc1e2398
AK
2797 tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
2798 pVBInfo);
2799 XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
2800 XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
21df8fc8 2801
6896b94e 2802 if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */
cc1e2398 2803 /* 301 */
8104e329
AK
2804 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10);
2805 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
2806 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
cc1e2398 2807 } else { /* 301b/302b/301lv/302lv */
8104e329
AK
2808 xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
2809 xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
21df8fc8
PS
2810 }
2811
8104e329 2812 xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12);
21df8fc8 2813
cc1e2398 2814 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
b9bf6e4e 2815 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28);
cc1e2398 2816 else
b9bf6e4e 2817 xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08);
cc1e2398 2818}
21df8fc8 2819
cc1e2398
AK
2820static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
2821 unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
2822{
2823 unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
2824 short index;
2825 unsigned short modeflag;
21df8fc8 2826
b397992e 2827 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6896b94e 2828 index = (modeflag & ModeTypeMask) - ModeEGA;
21df8fc8 2829
cc1e2398
AK
2830 if (index < 0)
2831 index = 0;
21df8fc8 2832
cc1e2398
AK
2833 return ColorDepth[index];
2834}
21df8fc8 2835
1d7f656d
KT
2836static unsigned short XGI_GetOffset(unsigned short ModeNo,
2837 unsigned short ModeIdIndex,
cc1e2398
AK
2838 unsigned short RefreshRateTableIndex,
2839 struct xgi_hw_device_info *HwDeviceExtension,
2840 struct vb_device_info *pVBInfo)
2841{
2842 unsigned short temp, colordepth, modeinfo, index, infoflag,
2843 ColorDepth[] = { 0x01, 0x02, 0x04 };
21df8fc8 2844
b397992e 2845 modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
a39325d2 2846 infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
21df8fc8 2847
cc1e2398 2848 index = (modeinfo >> 8) & 0xFF;
21df8fc8 2849
224114c7 2850 temp = XGI330_ScreenOffset[index];
21df8fc8 2851
cc1e2398
AK
2852 if (infoflag & InterlaceMode)
2853 temp = temp << 1;
21df8fc8 2854
cc1e2398 2855 colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
21df8fc8 2856
cc1e2398
AK
2857 if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
2858 temp = ModeNo - 0x7C;
2859 colordepth = ColorDepth[temp];
2860 temp = 0x6B;
2861 if (infoflag & InterlaceMode)
2862 temp = temp << 1;
21df8fc8 2863 }
053004b3 2864 return temp * colordepth;
cc1e2398 2865}
21df8fc8 2866
cc1e2398
AK
2867static void XGI_SetCRT2Offset(unsigned short ModeNo,
2868 unsigned short ModeIdIndex,
2869 unsigned short RefreshRateTableIndex,
2870 struct xgi_hw_device_info *HwDeviceExtension,
2871 struct vb_device_info *pVBInfo)
2872{
2873 unsigned short offset;
2874 unsigned char temp;
21df8fc8 2875
cc1e2398
AK
2876 if (pVBInfo->VBInfo & SetInSlaveMode)
2877 return;
21df8fc8 2878
cc1e2398
AK
2879 offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
2880 HwDeviceExtension, pVBInfo);
2881 temp = (unsigned char) (offset & 0xFF);
8104e329 2882 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
cc1e2398 2883 temp = (unsigned char) ((offset & 0xFF00) >> 8);
8104e329 2884 xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp);
cc1e2398 2885 temp = (unsigned char) (((offset >> 3) & 0xFF) + 1);
8104e329 2886 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
cc1e2398 2887}
21df8fc8 2888
cc1e2398
AK
2889static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
2890{
1d7f656d
KT
2891 /* threshold high ,disable auto threshold */
2892 xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B);
2893 /* threshold low default 04h */
2894 xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04);
cc1e2398 2895}
21df8fc8 2896
cc1e2398
AK
2897static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
2898 struct xgi_hw_device_info *HwDeviceExtension,
2899 unsigned short RefreshRateTableIndex,
2900 struct vb_device_info *pVBInfo)
2901{
ef9a6b99 2902 u8 tempcx;
21df8fc8 2903
cc1e2398
AK
2904 XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
2905 HwDeviceExtension, pVBInfo);
2906 XGI_SetCRT2FIFO(pVBInfo);
21df8fc8 2907
cc1e2398 2908 for (tempcx = 4; tempcx < 7; tempcx++)
8104e329 2909 xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0);
21df8fc8 2910
8104e329
AK
2911 xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00);
2912 xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
cc1e2398 2913}
21df8fc8 2914
cc1e2398
AK
2915static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
2916 struct xgi_hw_device_info *HwDeviceExtension,
2917 unsigned short RefreshRateTableIndex,
2918 struct vb_device_info *pVBInfo)
2919{
2920 unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
ef9a6b99 2921 pushbx = 0, CRT1Index, modeflag;
cc1e2398 2922
a39325d2 2923 CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
34c13ee2 2924 CRT1Index &= IndexMask;
b397992e 2925 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
21df8fc8 2926
cc1e2398
AK
2927 /* bainy change table name */
2928 if (modeflag & HalfDCLK) {
1d7f656d
KT
2929 /* BTVGA2HT 0x08,0x09 */
2930 temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF;
8104e329 2931 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
cc1e2398 2932 temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
ec9e5d3e 2933 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
1d7f656d
KT
2934 /* BTVGA2HDEE 0x0A,0x0C */
2935 temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF;
8104e329 2936 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
cc1e2398
AK
2937 tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
2938 pushbx = pVBInfo->VGAHDE / 2 + 16;
21df8fc8 2939 tempcx = tempcx >> 1;
cc1e2398
AK
2940 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
2941 tempcx += tempbx;
21df8fc8 2942
cc1e2398 2943 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
7853bced
AK
2944 tempbx = XGI_CRT1Table[CRT1Index].CR[4];
2945 tempbx |= ((XGI_CRT1Table[CRT1Index].CR[14] &
1d7f656d 2946 0xC0) << 2);
cc1e2398 2947 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
7853bced 2948 tempcx = XGI_CRT1Table[CRT1Index].CR[5];
cc1e2398 2949 tempcx &= 0x1F;
7853bced 2950 temp = XGI_CRT1Table[CRT1Index].CR[15];
cc1e2398
AK
2951 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
2952 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
2953 }
21df8fc8 2954
cc1e2398
AK
2955 tempbx += 4;
2956 tempcx += 4;
21df8fc8 2957
cc1e2398
AK
2958 if (tempcx > (pVBInfo->VGAHT / 2))
2959 tempcx = pVBInfo->VGAHT / 2;
21df8fc8 2960
cc1e2398 2961 temp = tempbx & 0x00FF;
21df8fc8 2962
8104e329 2963 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
cc1e2398
AK
2964 } else {
2965 temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
8104e329 2966 xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
cc1e2398 2967 temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
ec9e5d3e 2968 xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
1d7f656d
KT
2969 /* BTVGA2HDEE 0x0A,0x0C */
2970 temp = (pVBInfo->VGAHDE + 16) & 0x0FF;
8104e329 2971 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
cc1e2398
AK
2972 tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
2973 pushbx = pVBInfo->VGAHDE + 16;
2974 tempcx = tempcx >> 1;
2975 tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
2976 tempcx += tempbx;
21df8fc8 2977
cc1e2398 2978 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
7853bced
AK
2979 tempbx = XGI_CRT1Table[CRT1Index].CR[3];
2980 tempbx |= ((XGI_CRT1Table[CRT1Index].CR[5] &
1d7f656d 2981 0xC0) << 2);
cc1e2398 2982 tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
7853bced 2983 tempcx = XGI_CRT1Table[CRT1Index].CR[4];
cc1e2398 2984 tempcx &= 0x1F;
7853bced 2985 temp = XGI_CRT1Table[CRT1Index].CR[6];
cc1e2398
AK
2986 temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
2987 tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
2988 tempbx += 16;
2989 tempcx += 16;
2990 }
21df8fc8 2991
cc1e2398
AK
2992 if (tempcx > pVBInfo->VGAHT)
2993 tempcx = pVBInfo->VGAHT;
21df8fc8 2994
cc1e2398 2995 temp = tempbx & 0x00FF;
8104e329 2996 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
cc1e2398 2997 }
21df8fc8 2998
cc1e2398
AK
2999 tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
3000 tempbx = pushbx;
3001 tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
3002 tempax |= (tempbx & 0xFF00);
3003 temp = (tempax & 0xFF00) >> 8;
8104e329 3004 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
21df8fc8 3005 temp = tempcx & 0x00FF;
8104e329 3006 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
cc1e2398 3007 tempcx = (pVBInfo->VGAVT - 1);
21df8fc8 3008 temp = tempcx & 0x00FF;
21df8fc8 3009
8104e329 3010 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
cc1e2398
AK
3011 tempbx = pVBInfo->VGAVDE - 1;
3012 temp = tempbx & 0x00FF;
8104e329 3013 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp);
cc1e2398
AK
3014 temp = ((tempbx & 0xFF00) << 3) >> 8;
3015 temp |= ((tempcx & 0xFF00) >> 8);
8104e329 3016 xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp);
21df8fc8 3017
cc1e2398
AK
3018 tempax = pVBInfo->VGAVDE;
3019 tempbx = pVBInfo->VGAVDE;
3020 tempcx = pVBInfo->VGAVT;
1d7f656d
KT
3021 /* BTVGA2VRS 0x10,0x11 */
3022 tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1;
3023 /* BTVGA2VRE 0x11 */
3024 tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1;
21df8fc8 3025
cc1e2398 3026 if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
7853bced
AK
3027 tempbx = XGI_CRT1Table[CRT1Index].CR[10];
3028 temp = XGI_CRT1Table[CRT1Index].CR[9];
21df8fc8 3029
cc1e2398
AK
3030 if (temp & 0x04)
3031 tempbx |= 0x0100;
21df8fc8 3032
cc1e2398
AK
3033 if (temp & 0x080)
3034 tempbx |= 0x0200;
21df8fc8 3035
7853bced 3036 temp = XGI_CRT1Table[CRT1Index].CR[14];
21df8fc8 3037
cc1e2398
AK
3038 if (temp & 0x08)
3039 tempbx |= 0x0400;
21df8fc8 3040
7853bced 3041 temp = XGI_CRT1Table[CRT1Index].CR[11];
cc1e2398 3042 tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
21df8fc8
PS
3043 }
3044
cc1e2398 3045 temp = tempbx & 0x00FF;
8104e329 3046 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
cc1e2398
AK
3047 temp = ((tempbx & 0xFF00) >> 8) << 4;
3048 temp = ((tempcx & 0x000F) | (temp));
8104e329 3049 xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp);
cc1e2398 3050 tempax = 0;
21df8fc8 3051
cc1e2398
AK
3052 if (modeflag & DoubleScanMode)
3053 tempax |= 0x80;
21df8fc8 3054
cc1e2398
AK
3055 if (modeflag & HalfDCLK)
3056 tempax |= 0x40;
21df8fc8 3057
ec9e5d3e 3058 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
cc1e2398 3059}
21df8fc8 3060
cc1e2398
AK
3061static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
3062{
3063 unsigned long tempax, tempbx;
21df8fc8 3064
cc1e2398
AK
3065 tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
3066 & 0xFFFF;
3067 tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
3068 tempax = (tempax * pVBInfo->HT) / tempbx;
21df8fc8 3069
cc1e2398
AK
3070 return (unsigned short) tempax;
3071}
21df8fc8 3072
cc1e2398
AK
3073static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
3074 struct xgi_hw_device_info *HwDeviceExtension,
3075 unsigned short RefreshRateTableIndex,
3076 struct vb_device_info *pVBInfo)
3077{
3078 unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
ef9a6b99 3079 modeflag;
21df8fc8 3080
34c13ee2 3081 /* si+Ext_ResInfo */
b397992e
AK
3082 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3083 resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
21df8fc8 3084
cc1e2398
AK
3085 if (!(pVBInfo->VBInfo & SetInSlaveMode))
3086 return;
21df8fc8 3087
cc1e2398 3088 temp = 0xFF; /* set MAX HT */
8104e329 3089 xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
cc1e2398 3090 tempcx = 0x08;
21df8fc8 3091
6896b94e 3092 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
cc1e2398 3093 modeflag |= Charx8Dot;
21df8fc8 3094
cc1e2398 3095 tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
21df8fc8 3096
cc1e2398
AK
3097 if (modeflag & HalfDCLK)
3098 tempax = tempax >> 1;
21df8fc8 3099
cc1e2398
AK
3100 tempax = (tempax / tempcx) - 1;
3101 tempbx |= ((tempax & 0x00FF) << 8);
3102 temp = tempax & 0x00FF;
8104e329 3103 xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp);
21df8fc8 3104
cc1e2398 3105 temp = (tempbx & 0xFF00) >> 8;
21df8fc8 3106
cc1e2398 3107 if (pVBInfo->VBInfo & SetCRT2ToTV) {
6896b94e
PH
3108 if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3109 | VB_SIS302LV | VB_XGI301C)))
cc1e2398 3110 temp += 2;
21df8fc8 3111
31fb40fd
AK
3112 if ((pVBInfo->VBInfo & SetCRT2ToHiVision) &&
3113 !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7))
cc1e2398 3114 temp -= 2;
21df8fc8
PS
3115 }
3116
1d7f656d
KT
3117 /* 0x05 Horizontal Display Start */
3118 xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp);
3119 /* 0x06 Horizontal Blank end */
3120 xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03);
21df8fc8 3121
cc1e2398
AK
3122 if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
3123 if (pVBInfo->VBInfo & SetCRT2ToTV)
3124 tempax = pVBInfo->VGAHT;
3125 else
3126 tempax = XGI_GetVGAHT2(pVBInfo);
3127 }
21df8fc8 3128
cc1e2398
AK
3129 if (tempax >= pVBInfo->VGAHT)
3130 tempax = pVBInfo->VGAHT;
21df8fc8 3131
cc1e2398
AK
3132 if (modeflag & HalfDCLK)
3133 tempax = tempax >> 1;
3134
3135 tempax = (tempax / tempcx) - 5;
3136 tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
599801f9 3137 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
cc1e2398
AK
3138 temp = (tempbx & 0x00FF) - 1;
3139 if (!(modeflag & HalfDCLK)) {
3140 temp -= 6;
3141 if (pVBInfo->TVInfo & TVSimuMode) {
3142 temp -= 4;
34c13ee2 3143 temp -= 10;
cc1e2398
AK
3144 }
3145 }
21df8fc8 3146 } else {
cc1e2398
AK
3147 tempbx = (tempbx & 0xFF00) >> 8;
3148 tempcx = (tempcx + tempbx) >> 1;
3149 temp = (tempcx & 0x00FF) + 2;
21df8fc8 3150
cc1e2398
AK
3151 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3152 temp -= 1;
3153 if (!(modeflag & HalfDCLK)) {
3154 if ((modeflag & Charx8Dot)) {
3155 temp += 4;
3156 if (pVBInfo->VGAHDE >= 800)
3157 temp -= 6;
3158 }
3159 }
6596fc06
AK
3160 } else if (!(modeflag & HalfDCLK)) {
3161 temp -= 4;
255aabd2 3162 if (pVBInfo->LCDResInfo != Panel_1280x960 &&
6596fc06
AK
3163 pVBInfo->VGAHDE >= 800) {
3164 temp -= 7;
6596fc06 3165 if (pVBInfo->VGAHDE >= 1280 &&
255aabd2 3166 pVBInfo->LCDResInfo != Panel_1280x960 &&
6596fc06
AK
3167 (pVBInfo->LCDInfo & LCDNonExpanding))
3168 temp += 28;
cc1e2398
AK
3169 }
3170 }
3171 }
21df8fc8 3172
1d7f656d
KT
3173 /* 0x07 Horizontal Retrace Start */
3174 xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
3175 /* 0x08 Horizontal Retrace End */
3176 xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0);
21df8fc8 3177
cc1e2398
AK
3178 if (pVBInfo->VBInfo & SetCRT2ToTV) {
3179 if (pVBInfo->TVInfo & TVSimuMode) {
34c13ee2 3180 if (ModeNo == 0x50) {
cc1e2398 3181 if (pVBInfo->TVInfo & SetNTSCTV) {
8104e329 3182 xgifb_reg_set(pVBInfo->Part1Port,
cc1e2398 3183 0x07, 0x30);
8104e329 3184 xgifb_reg_set(pVBInfo->Part1Port,
cc1e2398
AK
3185 0x08, 0x03);
3186 } else {
8104e329 3187 xgifb_reg_set(pVBInfo->Part1Port,
cc1e2398 3188 0x07, 0x2f);
8104e329 3189 xgifb_reg_set(pVBInfo->Part1Port,
cc1e2398
AK
3190 0x08, 0x02);
3191 }
21df8fc8 3192 }
21df8fc8
PS
3193 }
3194 }
3195
8104e329 3196 xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
ec9e5d3e 3197 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
8104e329 3198 xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
21df8fc8 3199
cc1e2398
AK
3200 tempbx = pVBInfo->VGAVT;
3201 push1 = tempbx;
3202 tempcx = 0x121;
3203 tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
21df8fc8 3204
cc1e2398
AK
3205 if (tempbx == 357)
3206 tempbx = 350;
3207 if (tempbx == 360)
3208 tempbx = 350;
3209 if (tempbx == 375)
3210 tempbx = 350;
3211 if (tempbx == 405)
3212 tempbx = 400;
3213 if (tempbx == 525)
3214 tempbx = 480;
21df8fc8 3215
cc1e2398 3216 push2 = tempbx;
21df8fc8 3217
cc1e2398 3218 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
255aabd2 3219 if (pVBInfo->LCDResInfo == Panel_1024x768) {
a3d675c8 3220 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
cc1e2398
AK
3221 if (tempbx == 350)
3222 tempbx += 5;
3223 if (tempbx == 480)
3224 tempbx += 5;
3225 }
3226 }
3227 }
3228 tempbx--;
3229 temp = tempbx & 0x00FF;
3230 tempbx--;
3231 temp = tempbx & 0x00FF;
1d7f656d
KT
3232 /* 0x10 vertical Blank Start */
3233 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
cc1e2398
AK
3234 tempbx = push2;
3235 tempbx--;
3236 temp = tempbx & 0x00FF;
8104e329 3237 xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
d7636e0b 3238
cc1e2398
AK
3239 if (tempbx & 0x0100)
3240 tempcx |= 0x0002;
21df8fc8 3241
cc1e2398 3242 tempax = 0x000B;
21df8fc8 3243
cc1e2398
AK
3244 if (modeflag & DoubleScanMode)
3245 tempax |= 0x08000;
21df8fc8 3246
cc1e2398
AK
3247 if (tempbx & 0x0200)
3248 tempcx |= 0x0040;
21df8fc8 3249
cc1e2398 3250 temp = (tempax & 0xFF00) >> 8;
8104e329 3251 xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
21df8fc8 3252
cc1e2398
AK
3253 if (tempbx & 0x0400)
3254 tempcx |= 0x0600;
21df8fc8 3255
1d7f656d
KT
3256 /* 0x11 Vertival Blank End */
3257 xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00);
21df8fc8 3258
cc1e2398
AK
3259 tempax = push1;
3260 tempax -= tempbx; /* 0x0C Vertical Retrace Start */
3261 tempax = tempax >> 2;
3262 push1 = tempax; /* push ax */
3263
3264 if (resinfo != 0x09) {
3265 tempax = tempax << 1;
3266 tempbx += tempax;
3267 }
3268
599801f9 3269 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
470c5338
MG
3270 if ((pVBInfo->VBType & VB_SIS301LV) &&
3271 !(pVBInfo->TVInfo & TVSetHiVision)) {
3272 if ((pVBInfo->TVInfo & TVSimuMode) &&
3273 (pVBInfo->TVInfo & TVSetPAL)) {
3274 if (!(pVBInfo->VBType & VB_SIS301LV) ||
3275 !(pVBInfo->TVInfo &
3276 (TVSetYPbPr525p |
3277 TVSetYPbPr750p |
3278 TVSetHiVision)))
3279 tempbx += 40;
cc1e2398
AK
3280 }
3281 } else {
3282 tempbx -= 10;
3283 }
d3ae5762
AK
3284 } else if (pVBInfo->TVInfo & TVSimuMode) {
3285 if (pVBInfo->TVInfo & TVSetPAL) {
3286 if (pVBInfo->VBType & VB_SIS301LV) {
3287 if (!(pVBInfo->TVInfo &
3288 (TVSetYPbPr525p |
3289 TVSetYPbPr750p |
3290 TVSetHiVision)))
cc1e2398 3291 tempbx += 40;
d3ae5762
AK
3292 } else {
3293 tempbx += 40;
21df8fc8
PS
3294 }
3295 }
3296 }
cc1e2398
AK
3297 tempax = push1;
3298 tempax = tempax >> 2;
3299 tempax++;
3300 tempax += tempbx;
3301 push1 = tempax; /* push ax */
21df8fc8 3302
599801f9 3303 if ((pVBInfo->TVInfo & TVSetPAL)) {
cc1e2398
AK
3304 if (tempbx <= 513) {
3305 if (tempax >= 513)
3306 tempbx = 513;
3307 }
3308 }
3309
3310 temp = tempbx & 0x00FF;
8104e329 3311 xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
21df8fc8
PS
3312 tempbx--;
3313 temp = tempbx & 0x00FF;
8104e329 3314 xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
21df8fc8 3315
cc1e2398
AK
3316 if (tempbx & 0x0100)
3317 tempcx |= 0x0008;
21df8fc8 3318
cc1e2398 3319 if (tempbx & 0x0200)
ec9e5d3e 3320 xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
21df8fc8 3321
cc1e2398 3322 tempbx++;
21df8fc8 3323
cc1e2398
AK
3324 if (tempbx & 0x0100)
3325 tempcx |= 0x0004;
21df8fc8 3326
cc1e2398
AK
3327 if (tempbx & 0x0200)
3328 tempcx |= 0x0080;
21df8fc8 3329
cc1e2398
AK
3330 if (tempbx & 0x0400)
3331 tempcx |= 0x0C00;
21df8fc8 3332
cc1e2398
AK
3333 tempbx = push1; /* pop ax */
3334 temp = tempbx & 0x00FF;
3335 temp &= 0x0F;
1d7f656d
KT
3336 /* 0x0D vertical Retrace End */
3337 xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
21df8fc8 3338
cc1e2398
AK
3339 if (tempbx & 0x0010)
3340 tempcx |= 0x2000;
21df8fc8 3341
cc1e2398 3342 temp = tempcx & 0x00FF;
8104e329 3343 xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
cc1e2398 3344 temp = (tempcx & 0x0FF00) >> 8;
8104e329 3345 xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
cc1e2398
AK
3346 tempax = modeflag;
3347 temp = (tempax & 0xFF00) >> 8;
21df8fc8 3348
cc1e2398 3349 temp = (temp >> 1) & 0x09;
21df8fc8 3350
6896b94e 3351 if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
cc1e2398 3352 temp |= 0x01;
21df8fc8 3353
8104e329
AK
3354 xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
3355 xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
3356 xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
21df8fc8 3357
cc1e2398
AK
3358 if (pVBInfo->LCDInfo & LCDRGB18Bit)
3359 temp = 0x80;
3360 else
3361 temp = 0x00;
21df8fc8 3362
8104e329 3363 xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
21df8fc8 3364
cc1e2398
AK
3365 return;
3366}
21df8fc8 3367
cc1e2398
AK
3368static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
3369 unsigned short RefreshRateTableIndex,
3370 struct xgi_hw_device_info *HwDeviceExtension,
3371 struct vb_device_info *pVBInfo)
3372{
3373 unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
ef9a6b99 3374 modeflag;
d21222d1 3375 unsigned char const *TimingPoint;
21df8fc8 3376
cc1e2398
AK
3377 unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
3378
34c13ee2 3379 /* si+Ext_ResInfo */
b397992e 3380 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
21df8fc8 3381
cc1e2398
AK
3382 tempax = 0;
3383
3384 if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
3385 tempax |= 0x0800;
21df8fc8 3386
cc1e2398
AK
3387 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3388 tempax |= 0x0400;
21df8fc8 3389
cc1e2398
AK
3390 if (pVBInfo->VBInfo & SetCRT2ToSCART)
3391 tempax |= 0x0200;
21df8fc8 3392
599801f9 3393 if (!(pVBInfo->TVInfo & TVSetPAL))
cc1e2398 3394 tempax |= 0x1000;
21df8fc8 3395
599801f9 3396 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
cc1e2398 3397 tempax |= 0x0100;
21df8fc8 3398
599801f9 3399 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
cc1e2398 3400 tempax &= 0xfe00;
21df8fc8 3401
cc1e2398 3402 tempax = (tempax & 0xff00) >> 8;
21df8fc8 3403
8104e329 3404 xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax);
073b61e8 3405 TimingPoint = XGI330_NTSCTiming;
d7636e0b 3406
599801f9 3407 if (pVBInfo->TVInfo & TVSetPAL)
073b61e8 3408 TimingPoint = XGI330_PALTiming;
d7636e0b 3409
599801f9 3410 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
073b61e8 3411 TimingPoint = XGI330_HiTVExtTiming;
d7636e0b 3412
cc1e2398 3413 if (pVBInfo->VBInfo & SetInSlaveMode)
073b61e8 3414 TimingPoint = XGI330_HiTVSt2Timing;
d7636e0b 3415
cc1e2398 3416 if (pVBInfo->SetFlag & TVSimuMode)
073b61e8 3417 TimingPoint = XGI330_HiTVSt1Timing;
21df8fc8 3418
cc1e2398 3419 if (!(modeflag & Charx8Dot))
073b61e8 3420 TimingPoint = XGI330_HiTVTextTiming;
cc1e2398 3421 }
21df8fc8 3422
599801f9
PH
3423 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
3424 if (pVBInfo->TVInfo & TVSetYPbPr525i)
073b61e8 3425 TimingPoint = XGI330_YPbPr525iTiming;
cc1e2398 3426
599801f9 3427 if (pVBInfo->TVInfo & TVSetYPbPr525p)
073b61e8 3428 TimingPoint = XGI330_YPbPr525pTiming;
cc1e2398 3429
599801f9 3430 if (pVBInfo->TVInfo & TVSetYPbPr750p)
073b61e8 3431 TimingPoint = XGI330_YPbPr750pTiming;
21df8fc8 3432 }
d7636e0b 3433
cc1e2398 3434 for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
8104e329 3435 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
cc1e2398
AK
3436
3437 for (i = 0x39; i <= 0x45; i++, j++)
1d7f656d
KT
3438 /* di->temp2[j] */
3439 xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
cc1e2398
AK
3440
3441 if (pVBInfo->VBInfo & SetCRT2ToTV)
ec9e5d3e 3442 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
cc1e2398
AK
3443
3444 temp = pVBInfo->NewFlickerMode;
3445 temp &= 0x80;
ec9e5d3e 3446 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
cc1e2398 3447
599801f9 3448 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
cc1e2398 3449 tempax = 950;
21df8fc8 3450
599801f9 3451 if (pVBInfo->TVInfo & TVSetPAL)
cc1e2398
AK
3452 tempax = 520;
3453 else
3454 tempax = 440;
3455
3456 if (pVBInfo->VDE <= tempax) {
3457 tempax -= pVBInfo->VDE;
3458 tempax = tempax >> 2;
3459 tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
3460 push1 = tempax;
3461 temp = (tempax & 0xFF00) >> 8;
3462 temp += (unsigned short) TimingPoint[0];
3463
6896b94e
PH
3464 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3465 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398
AK
3466 if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
3467 | SetCRT2ToSVIDEO | SetCRT2ToSCART
599801f9 3468 | SetCRT2ToYPbPr525750)) {
cc1e2398
AK
3469 tempcx = pVBInfo->VGAHDE;
3470 if (tempcx >= 1024) {
3471 temp = 0x17; /* NTSC */
599801f9 3472 if (pVBInfo->TVInfo & TVSetPAL)
cc1e2398
AK
3473 temp = 0x19; /* PAL */
3474 }
3475 }
3476 }
3477
8104e329 3478 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
cc1e2398
AK
3479 tempax = push1;
3480 temp = (tempax & 0xFF00) >> 8;
3481 temp += TimingPoint[1];
3482
6896b94e
PH
3483 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3484 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398
AK
3485 if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
3486 | SetCRT2ToSVIDEO | SetCRT2ToSCART
599801f9 3487 | SetCRT2ToYPbPr525750))) {
cc1e2398
AK
3488 tempcx = pVBInfo->VGAHDE;
3489 if (tempcx >= 1024) {
3490 temp = 0x1D; /* NTSC */
599801f9 3491 if (pVBInfo->TVInfo & TVSetPAL)
cc1e2398
AK
3492 temp = 0x52; /* PAL */
3493 }
3494 }
3495 }
8104e329 3496 xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp);
21df8fc8 3497 }
d7636e0b 3498
cc1e2398
AK
3499 /* 301b */
3500 tempcx = pVBInfo->HT;
d7636e0b 3501
cc1e2398
AK
3502 if (XGI_IsLCDDualLink(pVBInfo))
3503 tempcx = tempcx >> 1;
21df8fc8 3504
cc1e2398
AK
3505 tempcx -= 2;
3506 temp = tempcx & 0x00FF;
8104e329 3507 xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp);
21df8fc8 3508
cc1e2398 3509 temp = (tempcx & 0xFF00) >> 8;
ec9e5d3e 3510 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
21df8fc8 3511
cc1e2398
AK
3512 tempcx = pVBInfo->HT >> 1;
3513 push1 = tempcx; /* push cx */
3514 tempcx += 7;
21df8fc8 3515
599801f9 3516 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
cc1e2398
AK
3517 tempcx -= 4;
3518
3519 temp = tempcx & 0x00FF;
3520 temp = temp << 4;
ec9e5d3e 3521 xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp);
cc1e2398
AK
3522
3523 tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
3524 tempbx += tempcx;
3525 push2 = tempbx;
3526 temp = tempbx & 0x00FF;
8104e329 3527 xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp);
cc1e2398
AK
3528 temp = (tempbx & 0xFF00) >> 8;
3529 temp = temp << 4;
ec9e5d3e 3530 xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp);
cc1e2398
AK
3531
3532 tempbx = push2;
3533 tempbx = tempbx + 8;
599801f9 3534 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
cc1e2398
AK
3535 tempbx = tempbx - 4;
3536 tempcx = tempbx;
21df8fc8
PS
3537 }
3538
cc1e2398 3539 temp = (tempbx & 0x00FF) << 4;
ec9e5d3e 3540 xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp);
d7636e0b 3541
cc1e2398
AK
3542 j += 2;
3543 tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
3544 temp = tempcx & 0x00FF;
8104e329 3545 xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp);
cc1e2398 3546 temp = ((tempcx & 0xFF00) >> 8) << 4;
ec9e5d3e 3547 xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp);
21df8fc8 3548
cc1e2398 3549 tempcx += 8;
599801f9 3550 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
cc1e2398 3551 tempcx -= 4;
21df8fc8 3552
cc1e2398
AK
3553 temp = tempcx & 0xFF;
3554 temp = temp << 4;
ec9e5d3e 3555 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
cc1e2398
AK
3556
3557 tempcx = push1; /* pop cx */
3558 j += 2;
3559 temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
3560 tempcx -= temp;
3561 temp = tempcx & 0x00FF;
3562 temp = temp << 4;
ec9e5d3e 3563 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
cc1e2398
AK
3564
3565 tempcx -= 11;
3566
3567 if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
3568 tempax = XGI_GetVGAHT2(pVBInfo);
3569 tempcx = tempax - 1;
21df8fc8 3570 }
cc1e2398 3571 temp = tempcx & 0x00FF;
8104e329 3572 xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp);
d7636e0b 3573
cc1e2398 3574 tempbx = pVBInfo->VDE;
21df8fc8 3575
cc1e2398
AK
3576 if (pVBInfo->VGAVDE == 360)
3577 tempbx = 746;
3578 if (pVBInfo->VGAVDE == 375)
3579 tempbx = 746;
3580 if (pVBInfo->VGAVDE == 405)
3581 tempbx = 853;
3582
3583 if (pVBInfo->VBInfo & SetCRT2ToTV) {
1d7f656d 3584 if (pVBInfo->VBType &
6896b94e 3585 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
1d7f656d 3586 if (!(pVBInfo->TVInfo &
599801f9 3587 (TVSetYPbPr525p | TVSetYPbPr750p)))
cc1e2398
AK
3588 tempbx = tempbx >> 1;
3589 } else
3590 tempbx = tempbx >> 1;
21df8fc8
PS
3591 }
3592
cc1e2398
AK
3593 tempbx -= 2;
3594 temp = tempbx & 0x00FF;
21df8fc8 3595
599801f9 3596 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
6896b94e 3597 if (pVBInfo->VBType & VB_SIS301LV) {
599801f9 3598 if (pVBInfo->TVInfo & TVSetHiVision) {
cc1e2398
AK
3599 if (pVBInfo->VBInfo & SetInSlaveMode) {
3600 if (ModeNo == 0x2f)
3601 temp += 1;
3602 }
3603 }
d3ae5762
AK
3604 } else if (pVBInfo->VBInfo & SetInSlaveMode) {
3605 if (ModeNo == 0x2f)
3606 temp += 1;
21df8fc8 3607 }
cc1e2398 3608 }
21df8fc8 3609
8104e329 3610 xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp);
21df8fc8 3611
cc1e2398
AK
3612 temp = (tempcx & 0xFF00) >> 8;
3613 temp |= ((tempbx & 0xFF00) >> 8) << 6;
21df8fc8 3614
599801f9 3615 if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) {
6896b94e 3616 if (pVBInfo->VBType & VB_SIS301LV) {
599801f9 3617 if (pVBInfo->TVInfo & TVSetHiVision) {
cc1e2398 3618 temp |= 0x10;
21df8fc8 3619
cc1e2398
AK
3620 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3621 temp |= 0x20;
3622 }
3623 } else {
3624 temp |= 0x10;
3625 if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3626 temp |= 0x20;
21df8fc8
PS
3627 }
3628 }
21df8fc8 3629
8104e329 3630 xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp);
21df8fc8 3631
6896b94e
PH
3632 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3633 | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */
cc1e2398
AK
3634 tempbx = pVBInfo->VDE;
3635 tempcx = tempbx - 2;
21df8fc8 3636
cc1e2398 3637 if (pVBInfo->VBInfo & SetCRT2ToTV) {
599801f9
PH
3638 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p
3639 | TVSetYPbPr750p)))
cc1e2398
AK
3640 tempbx = tempbx >> 1;
3641 }
21df8fc8 3642
6896b94e 3643 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
cc1e2398
AK
3644 temp = 0;
3645 if (tempcx & 0x0400)
3646 temp |= 0x20;
21df8fc8 3647
cc1e2398
AK
3648 if (tempbx & 0x0400)
3649 temp |= 0x40;
21df8fc8 3650
8104e329 3651 xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp);
cc1e2398 3652 }
21df8fc8 3653
cc1e2398 3654 temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
8104e329 3655 xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp);
cc1e2398 3656 temp = (tempbx - 3) & 0x00FF;
8104e329 3657 xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp);
cc1e2398 3658 }
21df8fc8 3659
cc1e2398 3660 tempbx = tempbx & 0x00FF;
21df8fc8 3661
cc1e2398
AK
3662 if (!(modeflag & HalfDCLK)) {
3663 tempcx = pVBInfo->VGAHDE;
3664 if (tempcx >= pVBInfo->HDE) {
3665 tempbx |= 0x2000;
3666 tempax &= 0x00FF;
3667 }
3668 }
21df8fc8 3669
cc1e2398 3670 tempcx = 0x0101;
21df8fc8 3671
cc1e2398
AK
3672 if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/
3673 if (pVBInfo->VGAHDE >= 1024) {
3674 tempcx = 0x1920;
3675 if (pVBInfo->VGAHDE >= 1280) {
3676 tempcx = 0x1420;
3677 tempbx = tempbx & 0xDFFF;
3678 }
21df8fc8
PS
3679 }
3680 }
3681
cc1e2398
AK
3682 if (!(tempbx & 0x2000)) {
3683 if (modeflag & HalfDCLK)
3684 tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
21df8fc8 3685
cc1e2398
AK
3686 push1 = tempbx;
3687 tempeax = pVBInfo->VGAHDE;
3688 tempebx = (tempcx & 0xFF00) >> 8;
3689 longtemp = tempeax * tempebx;
3690 tempecx = tempcx & 0x00FF;
3691 longtemp = longtemp / tempecx;
21df8fc8 3692
cc1e2398
AK
3693 /* 301b */
3694 tempecx = 8 * 1024;
21df8fc8 3695
6896b94e
PH
3696 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3697 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398
AK
3698 tempecx = tempecx * 8;
3699 }
21df8fc8 3700
cc1e2398
AK
3701 longtemp = longtemp * tempecx;
3702 tempecx = pVBInfo->HDE;
3703 temp2 = longtemp % tempecx;
3704 tempeax = longtemp / tempecx;
3705 if (temp2 != 0)
3706 tempeax += 1;
21df8fc8 3707
cc1e2398 3708 tempax = (unsigned short) tempeax;
21df8fc8 3709
cc1e2398 3710 /* 301b */
6896b94e
PH
3711 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3712 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398
AK
3713 tempcx = ((tempax & 0xFF00) >> 5) >> 8;
3714 }
3715 /* end 301b */
21df8fc8 3716
cc1e2398
AK
3717 tempbx = push1;
3718 tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00)
3719 | (tempbx & 0x00FF));
3720 tempax = (unsigned short) (((tempeax & 0x000000FF) << 8)
3721 | (tempax & 0x00FF));
3722 temp = (tempax & 0xFF00) >> 8;
3723 } else {
3724 temp = (tempax & 0x00FF) >> 8;
3725 }
21df8fc8 3726
8104e329 3727 xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp);
cc1e2398 3728 temp = (tempbx & 0xFF00) >> 8;
ec9e5d3e 3729 xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
cc1e2398 3730 temp = tempcx & 0x00FF;
21df8fc8 3731
cc1e2398
AK
3732 if (tempbx & 0x2000)
3733 temp = 0;
21df8fc8 3734
cc1e2398
AK
3735 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
3736 temp |= 0x18;
21df8fc8 3737
ec9e5d3e 3738 xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
599801f9 3739 if (pVBInfo->TVInfo & TVSetPAL) {
cc1e2398
AK
3740 tempbx = 0x0382;
3741 tempcx = 0x007e;
3742 } else {
3743 tempbx = 0x0369;
3744 tempcx = 0x0061;
3745 }
21df8fc8 3746
cc1e2398 3747 temp = tempbx & 0x00FF;
8104e329 3748 xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp);
cc1e2398 3749 temp = tempcx & 0x00FF;
8104e329 3750 xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp);
21df8fc8 3751
cc1e2398
AK
3752 temp = ((tempcx & 0xFF00) >> 8) & 0x03;
3753 temp = temp << 2;
3754 temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
21df8fc8 3755
599801f9 3756 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
cc1e2398 3757 temp |= 0x10;
21df8fc8 3758
599801f9 3759 if (pVBInfo->TVInfo & TVSetYPbPr525p)
cc1e2398 3760 temp |= 0x20;
21df8fc8 3761
599801f9 3762 if (pVBInfo->TVInfo & TVSetYPbPr750p)
cc1e2398
AK
3763 temp |= 0x60;
3764 }
21df8fc8 3765
8104e329 3766 xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp);
58839b01 3767 temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */
8104e329 3768 xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
cc1e2398 3769
599801f9 3770 if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) {
cc1e2398
AK
3771 if (pVBInfo->TVInfo & NTSC1024x768) {
3772 TimingPoint = XGI_NTSC1024AdjTime;
3773 for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
8104e329 3774 xgifb_reg_set(pVBInfo->Part2Port, i,
cc1e2398 3775 TimingPoint[j]);
21df8fc8 3776 }
8104e329 3777 xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72);
21df8fc8 3778 }
cc1e2398 3779 }
21df8fc8 3780
949eb0ae 3781 /* Modify for 301C PALM Support */
cc1e2398 3782 if (pVBInfo->VBType & VB_XGI301C) {
599801f9 3783 if (pVBInfo->TVInfo & TVSetPALM)
ec9e5d3e 3784 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08,
cc1e2398 3785 0x08); /* PALM Mode */
21df8fc8 3786 }
21df8fc8 3787
599801f9 3788 if (pVBInfo->TVInfo & TVSetPALM) {
9388ad9c 3789 tempax = xgifb_reg_get(pVBInfo->Part2Port, 0x01);
cc1e2398 3790 tempax--;
dc50556b 3791 xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax);
d7636e0b 3792
dc50556b 3793 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF);
cc1e2398 3794 }
21df8fc8 3795
599801f9 3796 if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
cc1e2398 3797 if (!(pVBInfo->VBInfo & SetInSlaveMode))
8104e329 3798 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00);
21df8fc8 3799 }
cc1e2398
AK
3800
3801 if (pVBInfo->VBInfo & SetCRT2ToTV)
3802 return;
21df8fc8 3803}
d7636e0b 3804
cc1e2398
AK
3805static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
3806 struct xgi_hw_device_info *HwDeviceExtension,
21df8fc8
PS
3807 unsigned short RefreshRateTableIndex,
3808 struct vb_device_info *pVBInfo)
3809{
ef9a6b99
PH
3810 unsigned short pushbx, tempax, tempbx, tempcx, temp, tempah,
3811 tempbh, tempch;
d7636e0b 3812
bdc9eb14 3813 struct XGI_LCDDesStruct const *LCDBDesPtr = NULL;
d7636e0b 3814
34c13ee2 3815 /* si+Ext_ResInfo */
cc1e2398
AK
3816 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
3817 return;
21df8fc8 3818
cc1e2398 3819 tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
21df8fc8 3820
cc1e2398
AK
3821 if (XGI_IsLCDDualLink(pVBInfo))
3822 tempbx = tempbx >> 1;
21df8fc8 3823
cc1e2398
AK
3824 tempbx -= 1;
3825 temp = tempbx & 0x00FF;
8104e329 3826 xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp);
cc1e2398
AK
3827 temp = (tempbx & 0xFF00) >> 8;
3828 temp = temp << 4;
ec9e5d3e 3829 xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
cc1e2398 3830 temp = 0x01;
21df8fc8 3831
8104e329 3832 xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp);
cc1e2398 3833 tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
cc1e2398
AK
3834 tempbx--;
3835 temp = tempbx & 0x00FF;
8104e329 3836 xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp);
cc1e2398 3837 temp = ((tempbx & 0xFF00) >> 8) & 0x07;
ec9e5d3e 3838 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
21df8fc8 3839
cc1e2398 3840 tempcx = pVBInfo->VT - 1;
cc1e2398 3841 temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
8104e329 3842 xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp);
cc1e2398
AK
3843 temp = (tempcx & 0xFF00) >> 8;
3844 temp = temp << 5;
8104e329 3845 xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp);
ec9e5d3e
AK
3846 xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
3847 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
3848 xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
3849 xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
d7636e0b 3850
558f758b 3851 /* Customized LCDB Does not add */
9d1c6299
AK
3852 if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
3853 LCDBDesPtr = XGI_GetLcdPtr(xgifb_lcddldes, ModeNo, ModeIdIndex,
3854 RefreshRateTableIndex, pVBInfo);
3855 else
3856 LCDBDesPtr = XGI_GetLcdPtr(XGI_LCDDesDataTable, ModeNo,
3857 ModeIdIndex, RefreshRateTableIndex,
3858 pVBInfo);
3859
cc1e2398
AK
3860 tempah = pVBInfo->LCDResInfo;
3861 tempah &= PanelResInfo;
d7636e0b 3862
255aabd2 3863 if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) {
cc1e2398
AK
3864 tempbx = 1024;
3865 tempcx = 768;
255aabd2
PH
3866 } else if ((tempah == Panel_1280x1024) ||
3867 (tempah == Panel_1280x1024x75)) {
cc1e2398
AK
3868 tempbx = 1280;
3869 tempcx = 1024;
255aabd2 3870 } else if (tempah == Panel_1400x1050) {
cc1e2398
AK
3871 tempbx = 1400;
3872 tempcx = 1050;
3873 } else {
3874 tempbx = 1600;
3875 tempcx = 1200;
3876 }
d7636e0b 3877
cc1e2398
AK
3878 if (pVBInfo->LCDInfo & EnableScalingLCD) {
3879 tempbx = pVBInfo->HDE;
3880 tempcx = pVBInfo->VDE;
3881 }
d7636e0b 3882
cc1e2398
AK
3883 pushbx = tempbx;
3884 tempax = pVBInfo->VT;
3885 pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
3886 pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
3887 pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
3888 pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
3889 tempbx = pVBInfo->LCDVDES;
3890 tempcx += tempbx;
d7636e0b 3891
cc1e2398
AK
3892 if (tempcx >= tempax)
3893 tempcx -= tempax; /* lcdvdes */
d7636e0b 3894
cc1e2398 3895 temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
8104e329 3896 xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp);
cc1e2398 3897 temp = tempcx & 0x00FF;
8104e329 3898 xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp);
cc1e2398
AK
3899 tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
3900 tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
3901 tempah = tempch;
3902 tempah = tempah << 3;
3903 tempah |= tempbh;
8104e329 3904 xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah);
d7636e0b 3905
cc1e2398
AK
3906 /* getlcdsync() */
3907 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
3908 tempcx = tempbx;
3909 tempax = pVBInfo->VT;
3910 tempbx = pVBInfo->LCDVRS;
d7636e0b 3911
cc1e2398
AK
3912 tempcx += tempbx;
3913 if (tempcx >= tempax)
3914 tempcx -= tempax;
d7636e0b 3915
cc1e2398 3916 temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
8104e329 3917 xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp);
cc1e2398
AK
3918 temp = (tempbx & 0xFF00) >> 8;
3919 temp = temp << 4;
3920 temp |= (tempcx & 0x000F);
8104e329 3921 xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
cc1e2398
AK
3922 tempcx = pushbx;
3923 tempax = pVBInfo->HT;
3924 tempbx = pVBInfo->LCDHDES;
3925 tempbx &= 0x0FFF;
3926
3927 if (XGI_IsLCDDualLink(pVBInfo)) {
3928 tempax = tempax >> 1;
3929 tempbx = tempbx >> 1;
3930 tempcx = tempcx >> 1;
3931 }
3932
6896b94e 3933 if (pVBInfo->VBType & VB_SIS302LV)
cc1e2398
AK
3934 tempbx += 1;
3935
3936 if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
3937 tempbx += 1;
3938
3939 tempcx += tempbx;
3940
3941 if (tempcx >= tempax)
3942 tempcx -= tempax;
3943
3944 temp = tempbx & 0x00FF;
8104e329 3945 xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
cc1e2398 3946 temp = ((tempbx & 0xFF00) >> 8) << 4;
8104e329 3947 xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp);
cc1e2398 3948 temp = tempcx & 0x00FF;
8104e329 3949 xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
cc1e2398 3950 temp = (tempcx & 0xFF00) >> 8;
8104e329 3951 xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp);
cc1e2398 3952
cc1e2398
AK
3953 XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
3954 tempcx = tempax;
3955 tempax = pVBInfo->HT;
3956 tempbx = pVBInfo->LCDHRS;
cc1e2398
AK
3957 if (XGI_IsLCDDualLink(pVBInfo)) {
3958 tempax = tempax >> 1;
3959 tempbx = tempbx >> 1;
3960 tempcx = tempcx >> 1;
3961 }
3962
6896b94e 3963 if (pVBInfo->VBType & VB_SIS302LV)
cc1e2398
AK
3964 tempbx += 1;
3965
3966 tempcx += tempbx;
3967
3968 if (tempcx >= tempax)
3969 tempcx -= tempax;
3970
3971 temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
8104e329 3972 xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp);
cc1e2398
AK
3973
3974 temp = (tempbx & 0xFF00) >> 8;
3975 temp = temp << 4;
ec9e5d3e 3976 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
cc1e2398 3977 temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
8104e329 3978 xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp);
cc1e2398 3979
a3d675c8 3980 if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
cc1e2398 3981 if (pVBInfo->VGAVDE == 525) {
6896b94e
PH
3982 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
3983 | VB_SIS301LV | VB_SIS302LV
cc1e2398
AK
3984 | VB_XGI301C)) {
3985 temp = 0xC6;
3986 } else
3987 temp = 0xC4;
3988
8104e329
AK
3989 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
3990 xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3);
21df8fc8 3991 }
cc1e2398
AK
3992
3993 if (pVBInfo->VGAVDE == 420) {
6896b94e
PH
3994 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
3995 | VB_SIS301LV | VB_SIS302LV
cc1e2398
AK
3996 | VB_XGI301C)) {
3997 temp = 0x4F;
3998 } else
3999 temp = 0x4E;
8104e329 4000 xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
21df8fc8 4001 }
cc1e2398
AK
4002 }
4003}
4004
4005/* --------------------------------------------------------------------- */
4006/* Function : XGI_GetTap4Ptr */
4007/* Input : */
4008/* Output : di -> Tap4 Reg. Setting Pointer */
4009/* Description : */
4010/* --------------------------------------------------------------------- */
1cccd9e4
AK
4011static struct XGI301C_Tap4TimingStruct const
4012*XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo)
cc1e2398
AK
4013{
4014 unsigned short tempax, tempbx, i;
1cccd9e4 4015 struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
cc1e2398
AK
4016
4017 if (tempcx == 0) {
4018 tempax = pVBInfo->VGAHDE;
4019 tempbx = pVBInfo->HDE;
4020 } else {
4021 tempax = pVBInfo->VGAVDE;
4022 tempbx = pVBInfo->VDE;
4023 }
4024
11fbdcde
AK
4025 if (tempax <= tempbx)
4026 return &xgifb_tap4_timing[0];
cc1e2398 4027 else
11fbdcde 4028 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */
cc1e2398 4029
599801f9 4030 if (pVBInfo->TVInfo & TVSetPAL)
cc1e2398
AK
4031 Tap4TimingPtr = PALTap4Timing;
4032
599801f9
PH
4033 if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
4034 if ((pVBInfo->TVInfo & TVSetYPbPr525i) ||
4035 (pVBInfo->TVInfo & TVSetYPbPr525p))
11fbdcde 4036 Tap4TimingPtr = xgifb_ntsc_525_tap4_timing;
599801f9 4037 if (pVBInfo->TVInfo & TVSetYPbPr750p)
cc1e2398
AK
4038 Tap4TimingPtr = YPbPr750pTap4Timing;
4039 }
4040
599801f9 4041 if (pVBInfo->VBInfo & SetCRT2ToHiVision)
11fbdcde 4042 Tap4TimingPtr = xgifb_tap4_timing;
cc1e2398
AK
4043
4044 i = 0;
4045 while (Tap4TimingPtr[i].DE != 0xFFFF) {
4046 if (Tap4TimingPtr[i].DE == tempax)
21df8fc8 4047 break;
cc1e2398
AK
4048 i++;
4049 }
4050 return &Tap4TimingPtr[i];
4051}
4052
4053static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
4054{
4055 unsigned short i, j;
1cccd9e4 4056 struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
cc1e2398
AK
4057
4058 if (!(pVBInfo->VBType & VB_XGI301C))
4059 return;
4060
cc1e2398
AK
4061 Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
4062 for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
8104e329 4063 xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
cc1e2398 4064
1d7f656d 4065 if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
599801f9 4066 (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) {
1d7f656d
KT
4067 /* Set Vertical Scaling */
4068 Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo);
cc1e2398 4069 for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
1d7f656d
KT
4070 xgifb_reg_set(pVBInfo->Part2Port,
4071 i,
4072 Tap4TimingPtr->Reg[j]);
cc1e2398
AK
4073 }
4074
1d7f656d 4075 if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
599801f9 4076 (!(pVBInfo->VBInfo & SetCRT2ToHiVision)))
1d7f656d
KT
4077 /* Enable V.Scaling */
4078 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04);
cc1e2398 4079 else
1d7f656d
KT
4080 /* Enable H.Scaling */
4081 xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10);
cc1e2398
AK
4082}
4083
4084static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
4085 struct vb_device_info *pVBInfo)
4086{
4087 unsigned short i;
d21222d1 4088 unsigned char const *tempdi;
cc1e2398
AK
4089 unsigned short modeflag;
4090
34c13ee2 4091 /* si+Ext_ResInfo */
b397992e 4092 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
cc1e2398 4093
8104e329 4094 xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00);
599801f9 4095 if (pVBInfo->TVInfo & TVSetPAL) {
8104e329
AK
4096 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
4097 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
cc1e2398 4098 } else {
8104e329
AK
4099 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5);
4100 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7);
cc1e2398
AK
4101 }
4102
4103 if (!(pVBInfo->VBInfo & SetCRT2ToTV))
4104 return;
4105
599801f9 4106 if (pVBInfo->TVInfo & TVSetPALM) {
8104e329
AK
4107 xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
4108 xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
4109 xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8);
cc1e2398
AK
4110 }
4111
599801f9
PH
4112 if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo
4113 & SetCRT2ToYPbPr525750)) {
4114 if (pVBInfo->TVInfo & TVSetYPbPr525i)
cc1e2398
AK
4115 return;
4116
073b61e8 4117 tempdi = XGI330_HiTVGroup3Data;
cc1e2398 4118 if (pVBInfo->SetFlag & TVSimuMode) {
073b61e8 4119 tempdi = XGI330_HiTVGroup3Simu;
cc1e2398 4120 if (!(modeflag & Charx8Dot))
073b61e8 4121 tempdi = XGI330_HiTVGroup3Text;
21df8fc8 4122 }
cc1e2398 4123
599801f9 4124 if (pVBInfo->TVInfo & TVSetYPbPr525p)
073b61e8 4125 tempdi = XGI330_Ren525pGroup3;
cc1e2398 4126
599801f9 4127 if (pVBInfo->TVInfo & TVSetYPbPr750p)
073b61e8 4128 tempdi = XGI330_Ren750pGroup3;
cc1e2398
AK
4129
4130 for (i = 0; i <= 0x3E; i++)
8104e329 4131 xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]);
cc1e2398
AK
4132
4133 if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
599801f9 4134 if (pVBInfo->TVInfo & TVSetYPbPr525p)
8104e329 4135 xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f);
21df8fc8
PS
4136 }
4137 }
cc1e2398
AK
4138 return;
4139} /* {end of XGI_SetGroup3} */
d7636e0b 4140
cc1e2398 4141static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
21df8fc8 4142 unsigned short RefreshRateTableIndex,
cc1e2398 4143 struct xgi_hw_device_info *HwDeviceExtension,
21df8fc8
PS
4144 struct vb_device_info *pVBInfo)
4145{
cc1e2398 4146 unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
d7636e0b 4147
cc1e2398
AK
4148 unsigned long tempebx, tempeax, templong;
4149
34c13ee2 4150 /* si+Ext_ResInfo */
b397992e 4151 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
cc1e2398 4152 temp = pVBInfo->RVBHCFACT;
8104e329 4153 xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp);
cc1e2398
AK
4154
4155 tempbx = pVBInfo->RVBHCMAX;
4156 temp = tempbx & 0x00FF;
8104e329 4157 xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp);
cc1e2398
AK
4158 temp2 = ((tempbx & 0xFF00) >> 8) << 7;
4159 tempcx = pVBInfo->VGAHT - 1;
4160 temp = tempcx & 0x00FF;
8104e329 4161 xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp);
cc1e2398
AK
4162
4163 temp = ((tempcx & 0xFF00) >> 8) << 3;
4164 temp2 |= temp;
4165
4166 tempcx = pVBInfo->VGAVT - 1;
4167 if (!(pVBInfo->VBInfo & SetCRT2ToTV))
4168 tempcx -= 5;
4169
4170 temp = tempcx & 0x00FF;
8104e329 4171 xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp);
cc1e2398 4172 temp = temp2 | ((tempcx & 0xFF00) >> 8);
8104e329 4173 xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp);
b9bf6e4e 4174 xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08);
cc1e2398
AK
4175 tempcx = pVBInfo->VBInfo;
4176 tempbx = pVBInfo->VGAHDE;
4177
4178 if (modeflag & HalfDCLK)
4179 tempbx = tempbx >> 1;
4180
4181 if (XGI_IsLCDDualLink(pVBInfo))
4182 tempbx = tempbx >> 1;
4183
599801f9 4184 if (tempcx & SetCRT2ToHiVision) {
cc1e2398
AK
4185 temp = 0;
4186 if (tempbx <= 1024)
4187 temp = 0xA0;
4188 if (tempbx == 1280)
4189 temp = 0xC0;
4190 } else if (tempcx & SetCRT2ToTV) {
4191 temp = 0xA0;
4192 if (tempbx <= 800)
4193 temp = 0x80;
4194 } else {
4195 temp = 0x80;
4196 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4197 temp = 0;
4198 if (tempbx > 800)
4199 temp = 0x60;
4200 }
4201 }
4202
599801f9 4203 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) {
cc1e2398
AK
4204 temp = 0x00;
4205 if (pVBInfo->VGAHDE == 1280)
4206 temp = 0x40;
4207 if (pVBInfo->VGAHDE == 1024)
4208 temp = 0x20;
4209 }
ec9e5d3e 4210 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
cc1e2398
AK
4211
4212 tempebx = pVBInfo->VDE;
4213
599801f9 4214 if (tempcx & SetCRT2ToHiVision) {
cc1e2398
AK
4215 if (!(temp & 0xE000))
4216 tempbx = tempbx >> 1;
4217 }
4218
4219 tempcx = pVBInfo->RVBHRS;
4220 temp = tempcx & 0x00FF;
8104e329 4221 xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp);
cc1e2398
AK
4222
4223 tempeax = pVBInfo->VGAVDE;
4224 tempcx |= 0x04000;
4225
4226 if (tempeax <= tempebx) {
4227 tempcx = (tempcx & (~0x4000));
4228 tempeax = pVBInfo->VGAVDE;
4229 } else {
4230 tempeax -= tempebx;
4231 }
4232
4233 templong = (tempeax * 256 * 1024) % tempebx;
4234 tempeax = (tempeax * 256 * 1024) / tempebx;
4235 tempebx = tempeax;
4236
4237 if (templong != 0)
4238 tempebx++;
4239
4240 temp = (unsigned short) (tempebx & 0x000000FF);
8104e329 4241 xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp);
cc1e2398
AK
4242
4243 temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8);
8104e329 4244 xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp);
cc1e2398
AK
4245 tempbx = (unsigned short) (tempebx >> 16);
4246 temp = tempbx & 0x00FF;
4247 temp = temp << 4;
4248 temp |= ((tempcx & 0xFF00) >> 8);
8104e329 4249 xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp);
cc1e2398
AK
4250
4251 /* 301b */
6896b94e
PH
4252 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4253 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398 4254 temp = 0x0028;
8104e329 4255 xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp);
cc1e2398
AK
4256 tempax = pVBInfo->VGAHDE;
4257 if (modeflag & HalfDCLK)
4258 tempax = tempax >> 1;
d7636e0b 4259
cc1e2398
AK
4260 if (XGI_IsLCDDualLink(pVBInfo))
4261 tempax = tempax >> 1;
d7636e0b 4262
cc1e2398
AK
4263 if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4264 if (tempax > 800)
4265 tempax -= 800;
d3ae5762
AK
4266 } else if (pVBInfo->VGAHDE > 800) {
4267 if (pVBInfo->VGAHDE == 1024)
4268 tempax = (tempax * 25 / 32) - 1;
4269 else
4270 tempax = (tempax * 20 / 32) - 1;
cc1e2398
AK
4271 }
4272 tempax -= 1;
21df8fc8 4273
cc1e2398
AK
4274 temp = (tempax & 0xFF00) >> 8;
4275 temp = ((temp & 0x0003) << 4);
8104e329 4276 xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp);
cc1e2398 4277 temp = (tempax & 0x00FF);
8104e329 4278 xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp);
21df8fc8 4279
599801f9 4280 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) {
cc1e2398 4281 if (pVBInfo->VGAHDE > 800)
b9bf6e4e 4282 xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08);
d7636e0b 4283
cc1e2398
AK
4284 }
4285 temp = 0x0036;
d7636e0b 4286
cc1e2398
AK
4287 if (pVBInfo->VBInfo & SetCRT2ToTV) {
4288 if (!(pVBInfo->TVInfo & (NTSC1024x768
599801f9
PH
4289 | TVSetYPbPr525p | TVSetYPbPr750p
4290 | TVSetHiVision))) {
cc1e2398
AK
4291 temp |= 0x0001;
4292 if ((pVBInfo->VBInfo & SetInSlaveMode)
4293 && (!(pVBInfo->TVInfo
4294 & TVSimuMode)))
4295 temp &= (~0x0001);
4296 }
4297 }
d7636e0b 4298
ec9e5d3e 4299 xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
cc1e2398
AK
4300 tempbx = pVBInfo->HT;
4301 if (XGI_IsLCDDualLink(pVBInfo))
4302 tempbx = tempbx >> 1;
4303 tempbx = (tempbx >> 1) - 2;
4304 temp = ((tempbx & 0x0700) >> 8) << 3;
ec9e5d3e 4305 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
cc1e2398 4306 temp = tempbx & 0x00FF;
8104e329 4307 xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp);
cc1e2398
AK
4308 }
4309 /* end 301b */
d7636e0b 4310
8951dadc 4311 XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
cc1e2398 4312}
d7636e0b 4313
cc1e2398
AK
4314static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
4315{
ec9e5d3e 4316 xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
cc1e2398 4317}
d7636e0b 4318
cc1e2398
AK
4319static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex,
4320 struct vb_device_info *pVBInfo)
4321{
cc1e2398
AK
4322 if (pVBInfo->ModeType == ModeVGA) {
4323 if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
6896b94e 4324 | DisableCRT2Display))) {
cc1e2398 4325 XGINew_EnableCRT2(pVBInfo);
21df8fc8 4326 }
21df8fc8 4327 }
cc1e2398 4328 return;
d7636e0b 4329}
4330
063b9c4b 4331static void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
21df8fc8 4332 struct vb_device_info *pVBInfo)
d7636e0b 4333{
ec9e5d3e 4334 xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x40);
d7636e0b 4335}
4336
063b9c4b 4337static void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
21df8fc8 4338 struct vb_device_info *pVBInfo)
d7636e0b 4339{
4340
ec9e5d3e 4341 xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00);
d7636e0b 4342}
4343
fab04b97
AK
4344static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info,
4345 unsigned short ModeNo, unsigned short ModeIdIndex,
4346 struct vb_device_info *pVBInfo)
21df8fc8 4347{
fab04b97 4348 unsigned short xres, yres, colordepth, modeflag, resindex;
21df8fc8 4349
b397992e 4350 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
e8e6c754
AK
4351 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
4352 yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
34c13ee2 4353 /* si+St_ModeFlag */
b397992e 4354 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
21df8fc8
PS
4355
4356 if (!(modeflag & Charx8Dot)) {
4357 xres /= 9;
4358 xres *= 8;
4359 }
4360
34c13ee2
AK
4361 if ((ModeNo > 0x13) && (modeflag & HalfDCLK))
4362 xres *= 2;
21df8fc8 4363
34c13ee2
AK
4364 if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
4365 yres *= 2;
21df8fc8 4366
fab04b97 4367 if (xres > xgifb_info->lvds_data.LVDSHDE)
21df8fc8
PS
4368 return 0;
4369
fab04b97 4370 if (yres > xgifb_info->lvds_data.LVDSVDE)
21df8fc8
PS
4371 return 0;
4372
34c13ee2
AK
4373 if (xres != xgifb_info->lvds_data.LVDSHDE ||
4374 yres != xgifb_info->lvds_data.LVDSVDE) {
4375 colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
4376 if (colordepth > 2)
4377 return 0;
21df8fc8
PS
4378 }
4379 return 1;
d7636e0b 4380}
4381
fab04b97
AK
4382static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
4383 int chip_id,
64db29f5
AK
4384 unsigned short ModeNo,
4385 unsigned short ModeIdIndex,
4386 struct vb_device_info *pVBInfo)
21df8fc8
PS
4387{
4388 unsigned char temp, Miscdata;
fab04b97 4389 unsigned short xres, yres, modeflag, resindex;
21df8fc8
PS
4390 unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
4391 unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
4392 unsigned short value;
4393
fab04b97 4394 temp = (unsigned char) ((xgifb_info->lvds_data.LVDS_Capability &
1d7f656d 4395 (LCDPolarity << 8)) >> 8);
21df8fc8 4396 temp &= LCDPolarity;
9388ad9c 4397 Miscdata = inb(pVBInfo->P3cc);
21df8fc8 4398
efdf4ee7 4399 outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2);
21df8fc8 4400
fab04b97 4401 temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity;
1d7f656d
KT
4402 /* SR35[7] FP VSync polarity */
4403 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80);
4404 /* SR30[5] FP HSync polarity */
4405 xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1);
21df8fc8 4406
64db29f5
AK
4407 if (chip_id == XG27)
4408 XGI_SetXG27FPBits(pVBInfo);
4409 else
4410 XGI_SetXG21FPBits(pVBInfo);
4411
b397992e 4412 resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
e8e6c754
AK
4413 xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
4414 yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
34c13ee2 4415 /* si+St_ModeFlag */
b397992e 4416 modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
21df8fc8
PS
4417
4418 if (!(modeflag & Charx8Dot))
4419 xres = xres * 8 / 9;
4420
fab04b97 4421 LVDSHT = xgifb_info->lvds_data.LVDSHT;
d7636e0b 4422
fab04b97 4423 LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2;
21df8fc8
PS
4424
4425 if (LVDSHBS > LVDSHT)
4426 LVDSHBS -= LVDSHT;
4427
fab04b97 4428 LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP;
21df8fc8
PS
4429 if (LVDSHRS > LVDSHT)
4430 LVDSHRS -= LVDSHT;
4431
fab04b97 4432 LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC;
21df8fc8
PS
4433 if (LVDSHRE > LVDSHT)
4434 LVDSHRE -= LVDSHT;
4435
fab04b97 4436 LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE;
21df8fc8 4437
fab04b97 4438 LVDSVT = xgifb_info->lvds_data.LVDSVT;
d7636e0b 4439
fab04b97 4440 LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2;
34c13ee2 4441 if (modeflag & DoubleScanMode)
21df8fc8
PS
4442 LVDSVBS += yres / 2;
4443
4444 if (LVDSVBS > LVDSVT)
4445 LVDSVBS -= LVDSVT;
4446
fab04b97 4447 LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP;
21df8fc8
PS
4448 if (LVDSVRS > LVDSVT)
4449 LVDSVRS -= LVDSVT;
4450
fab04b97 4451 LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC;
21df8fc8
PS
4452 if (LVDSVRE > LVDSVT)
4453 LVDSVRE -= LVDSVT;
4454
fab04b97 4455 LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE;
21df8fc8 4456
9388ad9c 4457 temp = xgifb_reg_get(pVBInfo->P3d4, 0x11);
8104e329 4458 xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
21df8fc8
PS
4459
4460 if (!(modeflag & Charx8Dot))
b9bf6e4e 4461 xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1);
21df8fc8
PS
4462
4463 /* HT SR0B[1:0] CR00 */
4464 value = (LVDSHT >> 3) - 5;
ec9e5d3e 4465 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
8104e329 4466 xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF));
21df8fc8
PS
4467
4468 /* HBS SR0B[5:4] CR02 */
4469 value = (LVDSHBS >> 3) - 1;
ec9e5d3e 4470 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
8104e329 4471 xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF));
21df8fc8
PS
4472
4473 /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
4474 value = (LVDSHBE >> 3) - 1;
ec9e5d3e
AK
4475 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
4476 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
4477 xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
21df8fc8
PS
4478
4479 /* HRS SR0B[7:6] CR04 */
4480 value = (LVDSHRS >> 3) + 2;
ec9e5d3e 4481 xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
8104e329 4482 xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF));
21df8fc8
PS
4483
4484 /* Panel HRS SR2F[1:0] SR2E[7:0] */
4485 value--;
ec9e5d3e 4486 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
8104e329 4487 xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF));
21df8fc8
PS
4488
4489 /* HRE SR0C[2] CR05[4:0] */
4490 value = (LVDSHRE >> 3) + 2;
ec9e5d3e
AK
4491 xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
4492 xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
21df8fc8
PS
4493
4494 /* Panel HRE SR2F[7:2] */
4495 value--;
ec9e5d3e 4496 xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
21df8fc8
PS
4497
4498 /* VT SR0A[0] CR07[5][0] CR06 */
4499 value = LVDSVT - 2;
ec9e5d3e
AK
4500 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
4501 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
4502 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
8104e329 4503 xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF));
21df8fc8
PS
4504
4505 /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
4506 value = LVDSVBS - 1;
ec9e5d3e
AK
4507 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
4508 xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
4509 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
8104e329 4510 xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF));
21df8fc8
PS
4511
4512 /* VBE SR0A[4] CR16 */
4513 value = LVDSVBE - 1;
ec9e5d3e 4514 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
8104e329 4515 xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF));
21df8fc8
PS
4516
4517 /* VRS SR0A[3] CR7[7][2] CR10 */
4518 value = LVDSVRS - 1;
ec9e5d3e
AK
4519 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
4520 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
4521 xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
8104e329 4522 xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF));
21df8fc8 4523
64db29f5
AK
4524 if (chip_id == XG27) {
4525 /* Panel VRS SR35[2:0] SR34[7:0] */
4526 xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07,
4527 (value & 0x700) >> 8);
4528 xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF);
4529 } else {
4530 /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
4531 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03,
4532 (value & 0x600) >> 9);
4533 xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF);
4534 xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01);
4535 }
21df8fc8
PS
4536
4537 /* VRE SR0A[5] CR11[3:0] */
4538 value = LVDSVRE - 1;
ec9e5d3e
AK
4539 xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
4540 xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
21df8fc8
PS
4541
4542 /* Panel VRE SR3F[7:2] */
64db29f5
AK
4543 if (chip_id == XG27)
4544 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
4545 (value << 2) & 0xFC);
4546 else
4547 /* SR3F[7] has to be 0, h/w bug */
4548 xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
4549 (value << 2) & 0x7C);
21df8fc8
PS
4550
4551 for (temp = 0, value = 0; temp < 3; temp++) {
4552
ec9e5d3e 4553 xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
8104e329 4554 xgifb_reg_set(pVBInfo->P3c4,
fab04b97 4555 0x2B, xgifb_info->lvds_data.VCLKData1);
8104e329 4556 xgifb_reg_set(pVBInfo->P3c4,
fab04b97 4557 0x2C, xgifb_info->lvds_data.VCLKData2);
21df8fc8
PS
4558 value += 0x10;
4559 }
d7636e0b 4560
21df8fc8 4561 if (!(modeflag & Charx8Dot)) {
d8ad0a6d 4562 inb(pVBInfo->P3da); /* reset 3da */
efdf4ee7 4563 outb(0x13, pVBInfo->P3c0); /* set index */
1d7f656d
KT
4564 /* set data, panning = 0, shift left 1 dot*/
4565 outb(0x00, pVBInfo->P3c0);
d7636e0b 4566
d8ad0a6d 4567 inb(pVBInfo->P3da); /* Enable Attribute */
efdf4ee7 4568 outb(0x20, pVBInfo->P3c0);
d7636e0b 4569
d8ad0a6d 4570 inb(pVBInfo->P3da); /* reset 3da */
21df8fc8 4571 }
d7636e0b 4572
4573}
4574
4575/* --------------------------------------------------------------------- */
4576/* Function : XGI_IsLCDON */
4577/* Input : */
dda08c59
BP
4578/* Output : 0 : Skip PSC Control */
4579/* 1: Disable PSC */
d7636e0b 4580/* Description : */
4581/* --------------------------------------------------------------------- */
063b9c4b 4582static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
d7636e0b 4583{
21df8fc8 4584 unsigned short tempax;
d7636e0b 4585
21df8fc8
PS
4586 tempax = pVBInfo->VBInfo;
4587 if (tempax & SetCRT2ToDualEdge)
4588 return 0;
6896b94e 4589 else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode))
21df8fc8 4590 return 1;
d7636e0b 4591
21df8fc8 4592 return 0;
d7636e0b 4593}
4594
d7636e0b 4595/* --------------------------------------------------------------------- */
4596/* Function : XGI_EnableChISLCD */
4597/* Input : */
4598/* Output : 0 -> Not LCD mode */
06cc47b9 4599/* Description : if bool enable = true -> enable, else disable */
d7636e0b 4600/* --------------------------------------------------------------------- */
06cc47b9
PH
4601static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo,
4602 bool enable)
d7636e0b 4603{
21df8fc8 4604 unsigned short tempbx, tempah;
d7636e0b 4605
06cc47b9
PH
4606 if (enable)
4607 tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
4608 else
4609 tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
4610
58839b01 4611 tempah = ~((unsigned short) xgifb_reg_get(pVBInfo->Part1Port, 0x2E));
d7636e0b 4612
21df8fc8
PS
4613 if (tempbx & (EnableChA | DisableChA)) {
4614 if (!(tempah & 0x08)) /* Chk LCDA Mode */
4615 return 0;
4616 }
d7636e0b 4617
21df8fc8 4618 if (!(tempbx & (EnableChB | DisableChB)))
dda08c59 4619 return 0;
d7636e0b 4620
21df8fc8
PS
4621 if (tempah & 0x01) /* Chk LCDB Mode */
4622 return 1;
d7636e0b 4623
cc1e2398
AK
4624 return 0;
4625}
4626
fab04b97
AK
4627static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
4628 struct xgi_hw_device_info *HwDeviceExtension,
cc1e2398
AK
4629 struct vb_device_info *pVBInfo)
4630{
fd0ad470 4631 unsigned short tempah = 0;
cc1e2398 4632
6896b94e
PH
4633 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4634 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398 4635 tempah = 0x3F;
1d7f656d
KT
4636 if (!(pVBInfo->VBInfo &
4637 (DisableCRT2Display | SetSimuScanMode))) {
a3d675c8 4638 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
cc1e2398
AK
4639 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
4640 tempah = 0x7F; /* Disable Channel A */
3bcc2460
MG
4641 if (!(pVBInfo->VBInfo &
4642 XGI_SetCRT2ToLCDA))
1d7f656d
KT
4643 /* Disable Channel B */
4644 tempah = 0xBF;
cc1e2398
AK
4645
4646 if (pVBInfo->SetFlag & DisableChB)
1d7f656d
KT
4647 /* force to disable Cahnnel */
4648 tempah &= 0xBF;
cc1e2398
AK
4649
4650 if (pVBInfo->SetFlag & DisableChA)
1d7f656d
KT
4651 /* Force to disable Channel B */
4652 tempah &= 0x7F;
cc1e2398
AK
4653 }
4654 }
4655 }
4656
1d7f656d
KT
4657 /* disable part4_1f */
4658 xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah);
cc1e2398 4659
6896b94e 4660 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
3bcc2460 4661 if (((pVBInfo->VBInfo &
06cc47b9
PH
4662 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) ||
4663 (XGI_EnableChISLCD(pVBInfo, false)) ||
4664 (XGI_IsLCDON(pVBInfo)))
1d7f656d
KT
4665 /* LVDS Driver power down */
4666 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80);
cc1e2398
AK
4667 }
4668
4669 if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
a3d675c8 4670 & (DisableCRT2Display | XGI_SetCRT2ToLCDA
cc1e2398
AK
4671 | SetSimuScanMode))) {
4672 if (pVBInfo->SetFlag & GatingCRT)
4673 XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
fab04b97 4674 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
cc1e2398
AK
4675 }
4676
a3d675c8 4677 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
cc1e2398 4678 if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
a3d675c8 4679 & XGI_SetCRT2ToLCDA))
1d7f656d
KT
4680 /* Power down */
4681 xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf);
cc1e2398
AK
4682 }
4683
1d7f656d
KT
4684 /* disable TV as primary VGA swap */
4685 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf);
cc1e2398
AK
4686
4687 if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
dc50556b 4688 xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf);
cc1e2398 4689
1d7f656d
KT
4690 if ((pVBInfo->SetFlag & DisableChB) ||
4691 (pVBInfo->VBInfo &
4692 (DisableCRT2Display | SetSimuScanMode)) ||
a3d675c8 4693 ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
1d7f656d
KT
4694 (pVBInfo->VBInfo &
4695 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
1d7f656d
KT
4696 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
4697
4698 if ((pVBInfo->SetFlag & DisableChB) ||
4699 (pVBInfo->VBInfo &
4700 (DisableCRT2Display | SetSimuScanMode)) ||
a3d675c8 4701 (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) ||
1d7f656d
KT
4702 (pVBInfo->VBInfo &
4703 (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
4704 /* save Part1 index 0 */
4705 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
4706 /* BTDAC = 1, avoid VB reset */
4707 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10);
4708 /* disable CRT2 */
4709 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
4710 /* restore Part1 index 0 */
4711 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
cc1e2398
AK
4712 }
4713 } else { /* {301} */
4714 if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
1d7f656d
KT
4715 xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
4716 /* Disable CRT2 */
4717 xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
4718 /* Disable TV asPrimary VGA swap */
4719 xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF);
cc1e2398
AK
4720 }
4721
a3d675c8 4722 if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA
cc1e2398 4723 | SetSimuScanMode))
fab04b97 4724 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
cc1e2398 4725 }
cc1e2398
AK
4726}
4727
4728/* --------------------------------------------------------------------- */
4729/* Function : XGI_GetTVPtrIndex */
4730/* Input : */
4731/* Output : */
4732/* Description : bx 0 : ExtNTSC */
4733/* 1 : StNTSC */
4734/* 2 : ExtPAL */
4735/* 3 : StPAL */
4736/* 4 : ExtHiTV */
4737/* 5 : StHiTV */
4738/* 6 : Ext525i */
4739/* 7 : St525i */
4740/* 8 : Ext525p */
4741/* 9 : St525p */
4742/* A : Ext750p */
4743/* B : St750p */
4744/* --------------------------------------------------------------------- */
4745static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
4746{
4747 unsigned short tempbx = 0;
4748
599801f9 4749 if (pVBInfo->TVInfo & TVSetPAL)
cc1e2398 4750 tempbx = 2;
599801f9 4751 if (pVBInfo->TVInfo & TVSetHiVision)
cc1e2398 4752 tempbx = 4;
599801f9 4753 if (pVBInfo->TVInfo & TVSetYPbPr525i)
cc1e2398 4754 tempbx = 6;
599801f9 4755 if (pVBInfo->TVInfo & TVSetYPbPr525p)
cc1e2398 4756 tempbx = 8;
599801f9 4757 if (pVBInfo->TVInfo & TVSetYPbPr750p)
cc1e2398
AK
4758 tempbx = 10;
4759 if (pVBInfo->TVInfo & TVSimuMode)
4760 tempbx++;
4761
4762 return tempbx;
4763}
4764
4765/* --------------------------------------------------------------------- */
4766/* Function : XGI_GetTVPtrIndex2 */
4767/* Input : */
4768/* Output : bx 0 : NTSC */
4769/* 1 : PAL */
4770/* 2 : PALM */
4771/* 3 : PALN */
4772/* 4 : NTSC1024x768 */
4773/* 5 : PAL-M 1024x768 */
4774/* 6-7: reserved */
4775/* cl 0 : YFilter1 */
4776/* 1 : YFilter2 */
4777/* ch 0 : 301A */
4778/* 1 : 301B/302B/301LV/302LV */
4779/* Description : */
4780/* --------------------------------------------------------------------- */
4781static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
4782 unsigned char *tempch, struct vb_device_info *pVBInfo)
4783{
4784 *tempbx = 0;
4785 *tempcl = 0;
4786 *tempch = 0;
4787
599801f9 4788 if (pVBInfo->TVInfo & TVSetPAL)
cc1e2398
AK
4789 *tempbx = 1;
4790
599801f9 4791 if (pVBInfo->TVInfo & TVSetPALM)
cc1e2398
AK
4792 *tempbx = 2;
4793
599801f9 4794 if (pVBInfo->TVInfo & TVSetPALN)
cc1e2398
AK
4795 *tempbx = 3;
4796
4797 if (pVBInfo->TVInfo & NTSC1024x768) {
4798 *tempbx = 4;
599801f9 4799 if (pVBInfo->TVInfo & TVSetPALM)
cc1e2398
AK
4800 *tempbx = 5;
4801 }
4802
6896b94e
PH
4803 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4804 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398
AK
4805 if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
4806 & TVSimuMode)) {
4807 *tempbx += 8;
4808 *tempcl += 1;
4809 }
4810 }
4811
6896b94e
PH
4812 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4813 | VB_SIS302LV | VB_XGI301C))
cc1e2398 4814 (*tempch)++;
d7636e0b 4815}
4816
cc1e2398 4817static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
d7636e0b 4818{
cc1e2398 4819 unsigned char tempah, tempbl, tempbh;
d7636e0b 4820
6896b94e
PH
4821 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4822 | VB_SIS302LV | VB_XGI301C)) {
a3d675c8 4823 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA
cc1e2398 4824 | SetCRT2ToTV | SetCRT2ToRAMDAC)) {
cc1e2398 4825 tempbh = 0;
03f76fc6 4826 tempbl = XGI301TVDelay;
d7636e0b 4827
cc1e2398
AK
4828 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
4829 tempbl = tempbl >> 4;
3bcc2460
MG
4830 if (pVBInfo->VBInfo &
4831 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
03f76fc6 4832 tempbh = XGI301LCDDelay;
d7636e0b 4833
a3d675c8 4834 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
cc1e2398
AK
4835 tempbl = tempbh;
4836 }
d7636e0b 4837
cc1e2398
AK
4838 tempbl &= 0x0F;
4839 tempbh &= 0xF0;
58839b01 4840 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D);
d7636e0b 4841
cc1e2398
AK
4842 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
4843 | SetCRT2ToTV)) { /* Channel B */
4844 tempah &= 0xF0;
4845 tempah |= tempbl;
4846 }
d7636e0b 4847
3bcc2460
MG
4848 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
4849 /* Channel A */
cc1e2398
AK
4850 tempah &= 0x0F;
4851 tempah |= tempbh;
4852 }
8104e329 4853 xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah);
cc1e2398 4854 }
cc1e2398
AK
4855 }
4856}
d7636e0b 4857
1d7f656d
KT
4858static void XGI_SetLCDCap_A(unsigned short tempcx,
4859 struct vb_device_info *pVBInfo)
cc1e2398
AK
4860{
4861 unsigned short temp;
d7636e0b 4862
58839b01 4863 temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
cc1e2398
AK
4864
4865 if (temp & LCDRGB18Bit) {
ec9e5d3e 4866 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
1d7f656d
KT
4867 /* Enable Dither */
4868 (unsigned short) (0x20 | (tempcx & 0x00C0)));
ec9e5d3e 4869 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
cc1e2398 4870 } else {
ec9e5d3e 4871 xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
cc1e2398 4872 (unsigned short) (0x30 | (tempcx & 0x00C0)));
ec9e5d3e 4873 xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
21df8fc8 4874 }
cc1e2398 4875}
d7636e0b 4876
cc1e2398
AK
4877/* --------------------------------------------------------------------- */
4878/* Function : XGI_SetLCDCap_B */
4879/* Input : cx -> LCD Capability */
4880/* Output : */
4881/* Description : */
4882/* --------------------------------------------------------------------- */
1d7f656d
KT
4883static void XGI_SetLCDCap_B(unsigned short tempcx,
4884 struct vb_device_info *pVBInfo)
cc1e2398
AK
4885{
4886 if (tempcx & EnableLCD24bpp) /* 24bits */
ec9e5d3e 4887 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
cc1e2398
AK
4888 (unsigned short) (((tempcx & 0x00ff) >> 6)
4889 | 0x0c));
4890 else
ec9e5d3e 4891 xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
cc1e2398
AK
4892 (unsigned short) (((tempcx & 0x00ff) >> 6)
4893 | 0x18)); /* Enable Dither */
d7636e0b 4894}
4895
7f04ec30
AK
4896static void XGI_LongWait(struct vb_device_info *pVBInfo)
4897{
4898 unsigned short i;
4899
4900 i = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
4901
4902 if (!(i & 0xC0)) {
4903 for (i = 0; i < 0xFFFF; i++) {
4904 if (!(inb(pVBInfo->P3da) & 0x08))
4905 break;
4906 }
4907
4908 for (i = 0; i < 0xFFFF; i++) {
4909 if ((inb(pVBInfo->P3da) & 0x08))
4910 break;
4911 }
4912 }
4913}
4914
cc1e2398 4915static void SetSpectrum(struct vb_device_info *pVBInfo)
d7636e0b 4916{
cc1e2398 4917 unsigned short index;
d7636e0b 4918
cc1e2398 4919 index = XGI_GetLCDCapPtr(pVBInfo);
d7636e0b 4920
1d7f656d
KT
4921 /* disable down spectrum D[4] */
4922 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F);
cc1e2398 4923 XGI_LongWait(pVBInfo);
b9bf6e4e 4924 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
cc1e2398
AK
4925 XGI_LongWait(pVBInfo);
4926
8104e329 4927 xgifb_reg_set(pVBInfo->Part4Port, 0x31,
cc1e2398 4928 pVBInfo->LCDCapList[index].Spectrum_31);
8104e329 4929 xgifb_reg_set(pVBInfo->Part4Port, 0x32,
cc1e2398 4930 pVBInfo->LCDCapList[index].Spectrum_32);
8104e329 4931 xgifb_reg_set(pVBInfo->Part4Port, 0x33,
cc1e2398 4932 pVBInfo->LCDCapList[index].Spectrum_33);
8104e329 4933 xgifb_reg_set(pVBInfo->Part4Port, 0x34,
cc1e2398
AK
4934 pVBInfo->LCDCapList[index].Spectrum_34);
4935 XGI_LongWait(pVBInfo);
b9bf6e4e 4936 xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
d7636e0b 4937}
4938
cc1e2398 4939static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
21df8fc8 4940{
cc1e2398 4941 unsigned short tempcx;
21df8fc8 4942
cc1e2398 4943 tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
21df8fc8 4944
f951dd05
PH
4945 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV |
4946 VB_SIS302LV | VB_XGI301C)) {
1d7f656d 4947 if (pVBInfo->VBType &
6896b94e 4948 (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
cc1e2398 4949 /* Set 301LV Capability */
8104e329 4950 xgifb_reg_set(pVBInfo->Part4Port, 0x24,
cc1e2398 4951 (unsigned char) (tempcx & 0x1F));
21df8fc8 4952 }
cc1e2398 4953 /* VB Driving */
ec9e5d3e 4954 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D,
cc1e2398
AK
4955 ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
4956 (unsigned short) ((tempcx & (EnableVBCLKDRVLOW
4957 | EnablePLLSPLOW)) >> 8));
21df8fc8 4958
cc1e2398
AK
4959 if (pVBInfo->VBInfo & SetCRT2ToLCD)
4960 XGI_SetLCDCap_B(tempcx, pVBInfo);
a3d675c8 4961 else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
cc1e2398 4962 XGI_SetLCDCap_A(tempcx, pVBInfo);
21df8fc8 4963
6896b94e 4964 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
cc1e2398
AK
4965 if (tempcx & EnableSpectrum)
4966 SetSpectrum(pVBInfo);
4967 }
4968 } else {
4969 /* LVDS,CH7017 */
4970 XGI_SetLCDCap_A(tempcx, pVBInfo);
4971 }
4972}
21df8fc8 4973
cc1e2398
AK
4974/* --------------------------------------------------------------------- */
4975/* Function : XGI_SetAntiFlicker */
4976/* Input : */
4977/* Output : */
4978/* Description : Set TV Customized Param. */
4979/* --------------------------------------------------------------------- */
1d7f656d
KT
4980static void XGI_SetAntiFlicker(unsigned short ModeNo,
4981 unsigned short ModeIdIndex,
4982 struct vb_device_info *pVBInfo)
cc1e2398 4983{
36ae035b 4984 unsigned short tempbx;
21df8fc8 4985
cc1e2398 4986 unsigned char tempah;
21df8fc8 4987
599801f9 4988 if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
cc1e2398 4989 return;
21df8fc8 4990
cc1e2398
AK
4991 tempbx = XGI_GetTVPtrIndex(pVBInfo);
4992 tempbx &= 0xFE;
cc1e2398
AK
4993 tempah = TVAntiFlickList[tempbx];
4994 tempah = tempah << 4;
21df8fc8 4995
ec9e5d3e 4996 xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
cc1e2398 4997}
21df8fc8 4998
1d7f656d
KT
4999static void XGI_SetEdgeEnhance(unsigned short ModeNo,
5000 unsigned short ModeIdIndex,
5001 struct vb_device_info *pVBInfo)
cc1e2398 5002{
354f49fa 5003 unsigned short tempbx;
21df8fc8 5004
cc1e2398 5005 unsigned char tempah;
21df8fc8 5006
cc1e2398
AK
5007 tempbx = XGI_GetTVPtrIndex(pVBInfo);
5008 tempbx &= 0xFE;
cc1e2398
AK
5009 tempah = TVEdgeList[tempbx];
5010 tempah = tempah << 5;
21df8fc8 5011
ec9e5d3e 5012 xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
d7636e0b 5013}
5014
cc1e2398 5015static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
21df8fc8 5016{
cc1e2398 5017 unsigned short tempbx;
21df8fc8 5018
cc1e2398 5019 unsigned char tempcl, tempch;
21df8fc8 5020
cc1e2398 5021 unsigned long tempData;
d7636e0b 5022
cc1e2398
AK
5023 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
5024 tempData = TVPhaseList[tempbx];
21df8fc8 5025
8104e329 5026 xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData
cc1e2398 5027 & 0x000000FF));
8104e329 5028 xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData
cc1e2398 5029 & 0x0000FF00) >> 8));
8104e329 5030 xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData
cc1e2398 5031 & 0x00FF0000) >> 16));
8104e329 5032 xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData
cc1e2398
AK
5033 & 0xFF000000) >> 24));
5034}
21df8fc8 5035
cc1e2398
AK
5036static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
5037 struct vb_device_info *pVBInfo)
5038{
5039 unsigned short tempbx, index;
a68292fc
AK
5040 unsigned char const *filterPtr;
5041 unsigned char tempcl, tempch, tempal;
21df8fc8 5042
cc1e2398 5043 XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
21df8fc8 5044
cc1e2398
AK
5045 switch (tempbx) {
5046 case 0x00:
5047 case 0x04:
5048 filterPtr = NTSCYFilter1;
5049 break;
21df8fc8 5050
cc1e2398
AK
5051 case 0x01:
5052 filterPtr = PALYFilter1;
5053 break;
21df8fc8 5054
cc1e2398
AK
5055 case 0x02:
5056 case 0x05:
5057 case 0x0D:
cc1e2398 5058 case 0x03:
2555e945 5059 filterPtr = xgifb_palmn_yfilter1;
cc1e2398 5060 break;
21df8fc8 5061
cc1e2398
AK
5062 case 0x08:
5063 case 0x0C:
cc1e2398 5064 case 0x0A:
cc1e2398 5065 case 0x0B:
cc1e2398 5066 case 0x09:
80f86f8f 5067 filterPtr = xgifb_yfilter2;
cc1e2398 5068 break;
21df8fc8 5069
cc1e2398
AK
5070 default:
5071 return;
21df8fc8 5072 }
d7636e0b 5073
b397992e 5074 tempal = XGI330_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
cc1e2398
AK
5075 if (tempcl == 0)
5076 index = tempal * 4;
5077 else
5078 index = tempal * 7;
d7636e0b 5079
cc1e2398 5080 if ((tempcl == 0) && (tempch == 1)) {
8104e329
AK
5081 xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0);
5082 xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0);
5083 xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0);
5084 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
cc1e2398 5085 } else {
8104e329
AK
5086 xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
5087 xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
5088 xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
5089 xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
cc1e2398 5090 }
d7636e0b 5091
6896b94e
PH
5092 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5093 | VB_SIS302LV | VB_XGI301C)) {
8104e329
AK
5094 xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
5095 xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
5096 xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
cc1e2398 5097 }
d7636e0b 5098}
5099
d7636e0b 5100/* --------------------------------------------------------------------- */
5101/* Function : XGI_OEM310Setting */
5102/* Input : */
5103/* Output : */
5104/* Description : Customized Param. for 301 */
5105/* --------------------------------------------------------------------- */
1d7f656d
KT
5106static void XGI_OEM310Setting(unsigned short ModeNo,
5107 unsigned short ModeIdIndex,
5108 struct vb_device_info *pVBInfo)
d7636e0b 5109{
21df8fc8 5110 XGI_SetDelayComp(pVBInfo);
d7636e0b 5111
a3d675c8 5112 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
21df8fc8 5113 XGI_SetLCDCap(pVBInfo);
d7636e0b 5114
21df8fc8 5115 if (pVBInfo->VBInfo & SetCRT2ToTV) {
21df8fc8
PS
5116 XGI_SetPhaseIncr(pVBInfo);
5117 XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
5118 XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
d7636e0b 5119
6896b94e 5120 if (pVBInfo->VBType & VB_SIS301)
21df8fc8
PS
5121 XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
5122 }
d7636e0b 5123}
5124
cc1e2398
AK
5125/* --------------------------------------------------------------------- */
5126/* Function : XGI_SetCRT2ModeRegs */
5127/* Input : */
5128/* Output : */
5129/* Description : Origin code for crt2group */
5130/* --------------------------------------------------------------------- */
fac2cc92 5131static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
cc1e2398
AK
5132 struct xgi_hw_device_info *HwDeviceExtension,
5133 struct vb_device_info *pVBInfo)
d7636e0b 5134{
cc1e2398
AK
5135 unsigned short tempbl;
5136 short tempcl;
21df8fc8 5137
cc1e2398 5138 unsigned char tempah;
21df8fc8 5139
cc1e2398
AK
5140 tempah = 0;
5141 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
58839b01 5142 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
cc1e2398
AK
5143 tempah &= ~0x10; /* BTRAMDAC */
5144 tempah |= 0x40; /* BTRAM */
21df8fc8 5145
cc1e2398
AK
5146 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
5147 | SetCRT2ToLCD)) {
5148 tempah = 0x40; /* BTDRAM */
34c13ee2
AK
5149 tempcl = pVBInfo->ModeType;
5150 tempcl -= ModeVGA;
5151 if (tempcl >= 0) {
5152 /* BT Color */
5153 tempah = (0x008 >> tempcl);
5154 if (tempah == 0)
5155 tempah = 1;
5156 tempah |= 0x040;
cc1e2398
AK
5157 }
5158 if (pVBInfo->VBInfo & SetInSlaveMode)
5159 tempah ^= 0x50; /* BTDAC */
5160 }
5161 }
21df8fc8 5162
8104e329 5163 xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
cc1e2398
AK
5164 tempah = 0x08;
5165 tempbl = 0xf0;
5166
e123e466
MG
5167 if (pVBInfo->VBInfo & DisableCRT2Display)
5168 goto reg_and_or;
cc1e2398 5169
e123e466
MG
5170 tempah = 0x00;
5171 tempbl = 0xff;
cc1e2398 5172
e123e466
MG
5173 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV |
5174 SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
5175 goto reg_and_or;
21df8fc8 5176
e123e466
MG
5177 if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
5178 (!(pVBInfo->VBInfo & SetSimuScanMode))) {
5179 tempbl &= 0xf7;
5180 tempah |= 0x01;
5181 goto reg_and_or;
21df8fc8 5182 }
d7636e0b 5183
e123e466
MG
5184 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5185 tempbl &= 0xf7;
5186 tempah |= 0x01;
5187 }
5188
5189 if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)))
5190 goto reg_and_or;
5191
5192 tempbl &= 0xf8;
5193 tempah = 0x01;
5194
5195 if (!(pVBInfo->VBInfo & SetInSlaveMode))
5196 tempah |= 0x02;
5197
5198 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
5199 tempah = tempah ^ 0x05;
5200 if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
5201 tempah = tempah ^ 0x01;
5202 }
5203
5204 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
5205 tempah |= 0x08;
5206
5207reg_and_or:
5208 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
5209
cc1e2398 5210 if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
a3d675c8 5211 | XGI_SetCRT2ToLCDA)) {
cc1e2398
AK
5212 tempah &= (~0x08);
5213 if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
5214 & SetInSlaveMode))) {
5215 tempah |= 0x010;
5216 }
5217 tempah |= 0x080;
21df8fc8 5218
cc1e2398 5219 if (pVBInfo->VBInfo & SetCRT2ToTV) {
cc1e2398 5220 tempah |= 0x020;
34c13ee2
AK
5221 if (pVBInfo->VBInfo & DriverMode)
5222 tempah = tempah ^ 0x20;
cc1e2398 5223 }
21df8fc8 5224
ec9e5d3e 5225 xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
cc1e2398
AK
5226 tempah = 0;
5227
5228 if (pVBInfo->LCDInfo & SetLCDDualLink)
5229 tempah |= 0x40;
5230
5231 if (pVBInfo->VBInfo & SetCRT2ToTV) {
cc1e2398
AK
5232 if (pVBInfo->TVInfo & RPLLDIV2XO)
5233 tempah |= 0x40;
21df8fc8 5234 }
cc1e2398 5235
255aabd2
PH
5236 if ((pVBInfo->LCDResInfo == Panel_1280x1024)
5237 || (pVBInfo->LCDResInfo == Panel_1280x1024x75))
cc1e2398
AK
5238 tempah |= 0x80;
5239
255aabd2 5240 if (pVBInfo->LCDResInfo == Panel_1280x960)
cc1e2398
AK
5241 tempah |= 0x80;
5242
8104e329 5243 xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah);
d7636e0b 5244 }
d7636e0b 5245
6896b94e
PH
5246 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5247 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398
AK
5248 tempah = 0;
5249 tempbl = 0xfb;
21df8fc8 5250
cc1e2398
AK
5251 if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
5252 tempbl = 0xff;
a3d675c8 5253 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
cc1e2398 5254 tempah |= 0x04; /* shampoo 0129 */
21df8fc8 5255 }
d7636e0b 5256
ec9e5d3e 5257 xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah);
cc1e2398
AK
5258 tempah = 0x00;
5259 tempbl = 0xcf;
5260 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5261 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5262 tempah |= 0x30;
5263 }
d7636e0b 5264
ec9e5d3e 5265 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
cc1e2398
AK
5266 tempah = 0;
5267 tempbl = 0x3f;
d7636e0b 5268
cc1e2398
AK
5269 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5270 if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5271 tempah |= 0xc0;
5272 }
ec9e5d3e 5273 xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah);
21df8fc8 5274 }
d7636e0b 5275
cc1e2398
AK
5276 tempah = 0;
5277 tempbl = 0x7f;
a3d675c8 5278 if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) {
cc1e2398
AK
5279 tempbl = 0xff;
5280 if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
5281 tempah |= 0x80;
21df8fc8 5282 }
d7636e0b 5283
ec9e5d3e 5284 xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah);
d7636e0b 5285
6896b94e 5286 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
cc1e2398 5287 if (pVBInfo->LCDInfo & SetLCDDualLink) {
b9bf6e4e
AK
5288 xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20);
5289 xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10);
cc1e2398
AK
5290 }
5291 }
d7636e0b 5292}
5293
d7636e0b 5294
cc1e2398
AK
5295void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
5296 struct vb_device_info *pVBInfo)
d7636e0b 5297{
d7636e0b 5298
ec9e5d3e 5299 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
cc1e2398 5300
d7636e0b 5301}
5302
cc1e2398 5303void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
21df8fc8
PS
5304 struct vb_device_info *pVBInfo)
5305{
21df8fc8 5306
ec9e5d3e 5307 xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
21df8fc8 5308
cc1e2398 5309}
21df8fc8 5310
cc1e2398
AK
5311unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo)
5312{
5313 unsigned short flag;
21df8fc8 5314
cc1e2398
AK
5315 if (pVBInfo->IF_DEF_LVDS == 1) {
5316 return 1;
5317 } else {
58839b01 5318 flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
cc1e2398
AK
5319 if ((flag == 1) || (flag == 2))
5320 return 1; /* 301b */
5321 else
5322 return 0;
5323 }
5324}
21df8fc8 5325
cc1e2398
AK
5326unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
5327 unsigned short ModeNo, unsigned short ModeIdIndex,
5328 struct vb_device_info *pVBInfo)
5329{
f2c22605
PH
5330 const u8 LCDARefreshIndex[] = {
5331 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00 };
21df8fc8 5332
ef9a6b99 5333 unsigned short RefreshRateTableIndex, i, index, temp;
d7636e0b 5334
58839b01 5335 index = xgifb_reg_get(pVBInfo->P3d4, 0x33);
cc1e2398
AK
5336 index = index >> pVBInfo->SelectCRT2Rate;
5337 index &= 0x0F;
d7636e0b 5338
cc1e2398
AK
5339 if (pVBInfo->LCDInfo & LCDNonExpanding)
5340 index = 0;
d7636e0b 5341
cc1e2398
AK
5342 if (index > 0)
5343 index--;
d7636e0b 5344
cc1e2398 5345 if (pVBInfo->SetFlag & ProgrammingCRT2) {
a3d675c8 5346 if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
cc1e2398 5347 if (pVBInfo->IF_DEF_LVDS == 0) {
f2c22605
PH
5348 temp = LCDARefreshIndex[
5349 pVBInfo->LCDResInfo & 0x07];
cc1e2398
AK
5350
5351 if (index > temp)
5352 index = temp;
5353 } else {
5354 index = 0;
5355 }
5356 }
21df8fc8 5357 }
d7636e0b 5358
b397992e 5359 RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex;
a39325d2 5360 ModeNo = XGI330_RefIndex[RefreshRateTableIndex].ModeID;
cc1e2398 5361 if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
a39325d2
AK
5362 if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 800) &&
5363 (XGI330_RefIndex[RefreshRateTableIndex].YRes == 600)) {
cc1e2398
AK
5364 index++;
5365 }
949eb0ae 5366 /* do the similar adjustment like XGISearchCRT1Rate() */
a39325d2
AK
5367 if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1024) &&
5368 (XGI330_RefIndex[RefreshRateTableIndex].YRes == 768)) {
cc1e2398
AK
5369 index++;
5370 }
a39325d2
AK
5371 if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
5372 (XGI330_RefIndex[RefreshRateTableIndex].YRes == 1024)) {
cc1e2398
AK
5373 index++;
5374 }
5375 }
5376
5377 i = 0;
5378 do {
a39325d2 5379 if (XGI330_RefIndex[RefreshRateTableIndex + i].
1d7f656d 5380 ModeID != ModeNo)
cc1e2398 5381 break;
a39325d2 5382 temp = XGI330_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
6896b94e 5383 temp &= ModeTypeMask;
cc1e2398
AK
5384 if (temp < pVBInfo->ModeType)
5385 break;
5386 i++;
5387 index--;
5388
5389 } while (index != 0xFFFF);
5390 if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
5391 if (pVBInfo->VBInfo & SetInSlaveMode) {
a39325d2 5392 temp = XGI330_RefIndex[RefreshRateTableIndex + i - 1].
1d7f656d 5393 Ext_InfoFlag;
cc1e2398
AK
5394 if (temp & InterlaceMode)
5395 i++;
21df8fc8
PS
5396 }
5397 }
cc1e2398
AK
5398 i--;
5399 if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
5400 temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex,
5401 RefreshRateTableIndex, &i, pVBInfo);
5402 }
9a0b295e 5403 return RefreshRateTableIndex + i;
cc1e2398 5404}
d7636e0b 5405
cc1e2398
AK
5406static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
5407 struct xgi_hw_device_info *HwDeviceExtension,
5408 struct vb_device_info *pVBInfo)
5409{
5410 unsigned short RefreshRateTableIndex;
cc1e2398
AK
5411
5412 pVBInfo->SetFlag |= ProgrammingCRT2;
5413 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
5414 ModeIdIndex, pVBInfo);
5415 XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
5416 XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5417 XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5418 HwDeviceExtension, pVBInfo);
5419 XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5420 XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
d7636e0b 5421}
5422
fac2cc92 5423static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
21df8fc8
PS
5424 struct xgi_hw_device_info *HwDeviceExtension,
5425 struct vb_device_info *pVBInfo)
5426{
a9e29e6d 5427 unsigned short ModeIdIndex, RefreshRateTableIndex;
21df8fc8 5428
cc1e2398
AK
5429 pVBInfo->SetFlag |= ProgrammingCRT2;
5430 XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
5431 pVBInfo->SelectCRT2Rate = 4;
5432 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
5433 ModeIdIndex, pVBInfo);
5434 XGI_SaveCRT2Info(ModeNo, pVBInfo);
5435 XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
5436 XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5437 XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
5438 RefreshRateTableIndex, pVBInfo);
5439 XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
5440 RefreshRateTableIndex, pVBInfo);
5441 XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
5442 RefreshRateTableIndex, pVBInfo);
5443 XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5444 HwDeviceExtension, pVBInfo);
5445 XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
5446 RefreshRateTableIndex, pVBInfo);
5447 XGI_SetTap4Regs(pVBInfo);
5448 XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
5449 XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5450 HwDeviceExtension, pVBInfo);
5451 XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5452 XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
5453 XGI_AutoThreshold(pVBInfo);
5454 return 1;
5455}
21df8fc8 5456
cc1e2398
AK
5457void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
5458{
5459 unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
5460 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
5461 0x05, 0x00 };
21df8fc8 5462
cc1e2398 5463 unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
d7636e0b 5464
cc1e2398
AK
5465 unsigned char CR17, CR63, SR31;
5466 unsigned short temp;
d7636e0b 5467
cc1e2398 5468 int i;
8104e329 5469 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
21df8fc8 5470
949eb0ae 5471 /* to fix XG42 single LCD sense to CRT+LCD */
8104e329 5472 xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A);
9388ad9c 5473 xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get(
cc1e2398 5474 pVBInfo->P3d4, 0x53) | 0x02));
21df8fc8 5475
9388ad9c
PH
5476 SR31 = xgifb_reg_get(pVBInfo->P3c4, 0x31);
5477 CR63 = xgifb_reg_get(pVBInfo->P3d4, 0x63);
5478 SR01 = xgifb_reg_get(pVBInfo->P3c4, 0x01);
21df8fc8 5479
8104e329
AK
5480 xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF));
5481 xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF));
21df8fc8 5482
9388ad9c 5483 CR17 = xgifb_reg_get(pVBInfo->P3d4, 0x17);
8104e329 5484 xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80));
21df8fc8 5485
9388ad9c 5486 SR1F = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
8104e329 5487 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04));
21df8fc8 5488
9388ad9c 5489 SR07 = xgifb_reg_get(pVBInfo->P3c4, 0x07);
8104e329 5490 xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB));
9388ad9c 5491 SR06 = xgifb_reg_get(pVBInfo->P3c4, 0x06);
8104e329 5492 xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3));
21df8fc8 5493
8104e329 5494 xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00);
21df8fc8 5495
cc1e2398 5496 for (i = 0; i < 8; i++)
8104e329 5497 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]);
d7636e0b 5498
cc1e2398 5499 for (i = 8; i < 11; i++)
8104e329 5500 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 8),
cc1e2398 5501 CRTCData[i]);
21df8fc8 5502
cc1e2398 5503 for (i = 11; i < 13; i++)
8104e329 5504 xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 4),
cc1e2398 5505 CRTCData[i]);
21df8fc8 5506
cc1e2398 5507 for (i = 13; i < 16; i++)
8104e329 5508 xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i - 3),
cc1e2398 5509 CRTCData[i]);
21df8fc8 5510
8104e329 5511 xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16]
cc1e2398 5512 & 0xE0));
21df8fc8 5513
8104e329
AK
5514 xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00);
5515 xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B);
5516 xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1);
21df8fc8 5517
efdf4ee7 5518 outb(0x00, pVBInfo->P3c8);
cc1e2398 5519
771f3eed
PH
5520 for (i = 0; i < 256 * 3; i++) {
5521 outb(0x0F, (pVBInfo->P3c8 + 1)); /* DAC_TEST_PARMS */
cc1e2398
AK
5522 }
5523
cc1e2398
AK
5524 mdelay(1);
5525
5526 XGI_WaitDisply(pVBInfo);
d8ad0a6d 5527 temp = inb(pVBInfo->P3c2);
cc1e2398
AK
5528
5529 if (temp & 0x10)
ec9e5d3e 5530 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
cc1e2398 5531 else
ec9e5d3e 5532 xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
21df8fc8 5533
949eb0ae 5534 /* avoid display something, set BLACK DAC if not restore DAC */
efdf4ee7 5535 outb(0x00, pVBInfo->P3c8);
21df8fc8 5536
771f3eed 5537 for (i = 0; i < 256 * 3; i++) {
efdf4ee7 5538 outb(0, (pVBInfo->P3c8 + 1));
21df8fc8 5539 }
d7636e0b 5540
8104e329
AK
5541 xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01);
5542 xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63);
5543 xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31);
21df8fc8 5544
9388ad9c 5545 xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get(
cc1e2398 5546 pVBInfo->P3d4, 0x53) & 0xFD));
8104e329 5547 xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
cc1e2398 5548}
21df8fc8 5549
fab04b97
AK
5550static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
5551 struct xgi_hw_device_info *HwDeviceExtension,
cc1e2398
AK
5552 struct vb_device_info *pVBInfo)
5553{
fd0ad470 5554 unsigned short tempah;
21df8fc8 5555
6896b94e
PH
5556 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5557 | VB_SIS302LV | VB_XGI301C)) {
cc1e2398 5558 if (!(pVBInfo->SetFlag & DisableChA)) {
66b43eb2
PH
5559 if ((pVBInfo->SetFlag & EnableChA) ||
5560 (pVBInfo->VBInfo & SetCRT2ToDualEdge)) {
1d7f656d
KT
5561 /* Power on */
5562 xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20);
cc1e2398 5563 }
21df8fc8 5564 }
d7636e0b 5565
cc1e2398
AK
5566 if (!(pVBInfo->SetFlag & DisableChB)) {
5567 if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo
5568 & (SetCRT2ToLCD | SetCRT2ToTV
5569 | SetCRT2ToRAMDAC))) {
9388ad9c 5570 tempah = xgifb_reg_get(pVBInfo->P3c4, 0x32);
cc1e2398
AK
5571 tempah &= 0xDF;
5572 if (pVBInfo->VBInfo & SetInSlaveMode) {
1d7f656d
KT
5573 if (!(pVBInfo->VBInfo &
5574 SetCRT2ToRAMDAC))
cc1e2398
AK
5575 tempah |= 0x20;
5576 }
8104e329 5577 xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah);
b9bf6e4e 5578 xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20);
d7636e0b 5579
9388ad9c
PH
5580 tempah = xgifb_reg_get(pVBInfo->Part1Port,
5581 0x2E);
d7636e0b 5582
cc1e2398 5583 if (!(tempah & 0x80))
b9bf6e4e 5584 xgifb_reg_or(pVBInfo->Part1Port,
1d7f656d 5585 0x2E, 0x80);
1d7f656d 5586 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
cc1e2398
AK
5587 }
5588 }
d7636e0b 5589
cc1e2398
AK
5590 if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
5591 || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
ec9e5d3e 5592 xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0,
cc1e2398 5593 0x20); /* shampoo 0129 */
6896b94e 5594 if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
06cc47b9
PH
5595 if (!XGI_EnableChISLCD(pVBInfo, false)) {
5596 if (XGI_EnableChISLCD(pVBInfo, true) ||
1d7f656d 5597 (pVBInfo->VBInfo &
a3d675c8 5598 (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
1d7f656d 5599 /* LVDS PLL power on */
dc50556b 5600 xgifb_reg_and(
1d7f656d
KT
5601 pVBInfo->Part4Port,
5602 0x2A,
5603 0x7F);
cc1e2398 5604 }
1d7f656d
KT
5605 /* LVDS Driver power on */
5606 xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F);
cc1e2398
AK
5607 }
5608 }
d7636e0b 5609
cc1e2398 5610 tempah = 0x00;
d7636e0b 5611
cc1e2398
AK
5612 if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5613 tempah = 0xc0;
d7636e0b 5614
b1bf998c
MG
5615 if (!(pVBInfo->VBInfo & SetSimuScanMode) &&
5616 (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
5617 (pVBInfo->VBInfo & SetCRT2ToDualEdge)) {
5618 tempah = tempah & 0x40;
5619 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
5620 tempah = tempah ^ 0xC0;
5621
5622 if (pVBInfo->SetFlag & DisableChB)
5623 tempah &= 0xBF;
5624
5625 if (pVBInfo->SetFlag & DisableChA)
5626 tempah &= 0x7F;
5627
5628 if (pVBInfo->SetFlag & EnableChB)
5629 tempah |= 0x40;
5630
5631 if (pVBInfo->SetFlag & EnableChA)
5632 tempah |= 0x80;
cc1e2398
AK
5633 }
5634 }
d7636e0b 5635
1d7f656d
KT
5636 /* EnablePart4_1F */
5637 xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah);
d7636e0b 5638
cc1e2398 5639 if (!(pVBInfo->SetFlag & DisableChA)) {
cc1e2398 5640 if (!(pVBInfo->SetFlag & GatingCRT)) {
1d7f656d
KT
5641 XGI_DisableGatingCRT(HwDeviceExtension,
5642 pVBInfo);
fab04b97
AK
5643 XGI_DisplayOn(xgifb_info, HwDeviceExtension,
5644 pVBInfo);
cc1e2398
AK
5645 }
5646 }
5647 } /* 301 */
5648 else { /* LVDS */
5649 if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
a3d675c8 5650 | XGI_SetCRT2ToLCDA))
1d7f656d
KT
5651 /* enable CRT2 */
5652 xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20);
d7636e0b 5653
9388ad9c 5654 tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E);
cc1e2398 5655 if (!(tempah & 0x80))
1d7f656d 5656 xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
d7636e0b 5657
dc50556b 5658 xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
fab04b97 5659 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
cc1e2398 5660 } /* End of VB */
d7636e0b 5661}
5662
fab04b97
AK
5663static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
5664 struct xgi_hw_device_info *HwDeviceExtension,
cc1e2398 5665 unsigned short ModeNo, unsigned short ModeIdIndex,
21df8fc8 5666 struct vb_device_info *pVBInfo)
d7636e0b 5667{
a157961c 5668 unsigned short RefreshRateTableIndex, temp;
d7636e0b 5669
a157961c 5670 XGI_SetSeqRegs(ModeNo, ModeIdIndex, pVBInfo);
3625c9a7 5671 outb(XGI330_StandTable.MISC, pVBInfo->P3c2);
a157961c
AK
5672 XGI_SetCRTCRegs(HwDeviceExtension, pVBInfo);
5673 XGI_SetATTRegs(ModeNo, ModeIdIndex, pVBInfo);
5674 XGI_SetGRCRegs(pVBInfo);
cc1e2398 5675 XGI_ClearExt1Regs(pVBInfo);
d7636e0b 5676
cc1e2398
AK
5677 if (HwDeviceExtension->jChipType == XG27) {
5678 if (pVBInfo->IF_DEF_LVDS == 0)
5679 XGI_SetDefaultVCLK(pVBInfo);
21df8fc8 5680 }
d7636e0b 5681
cc1e2398
AK
5682 temp = ~ProgrammingCRT2;
5683 pVBInfo->SetFlag &= temp;
5684 pVBInfo->SelectCRT2Rate = 0;
d7636e0b 5685
6896b94e
PH
5686 if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5687 | VB_SIS302LV | VB_XGI301C)) {
a3d675c8 5688 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA
cc1e2398
AK
5689 | SetInSlaveMode)) {
5690 pVBInfo->SetFlag |= ProgrammingCRT2;
21df8fc8 5691 }
cc1e2398 5692 }
d7636e0b 5693
cc1e2398
AK
5694 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
5695 ModeIdIndex, pVBInfo);
5696 if (RefreshRateTableIndex != 0xFFFF) {
5697 XGI_SetSync(RefreshRateTableIndex, pVBInfo);
5698 XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5699 pVBInfo, HwDeviceExtension);
5700 XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
5701 RefreshRateTableIndex, pVBInfo);
5702 XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5703 HwDeviceExtension, pVBInfo);
5704 XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
5705 RefreshRateTableIndex, pVBInfo);
5706 }
5707
cc1e2398 5708 if (HwDeviceExtension->jChipType >= XG21) {
58839b01 5709 temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
cc1e2398 5710 if (temp & 0xA0) {
21df8fc8 5711
cc1e2398
AK
5712 if (HwDeviceExtension->jChipType == XG27)
5713 XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
5714 RefreshRateTableIndex, pVBInfo);
5715 else
5716 XGI_SetXG21CRTC(ModeNo, ModeIdIndex,
5717 RefreshRateTableIndex, pVBInfo);
21df8fc8 5718
cc1e2398
AK
5719 XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
5720 RefreshRateTableIndex);
21df8fc8 5721
105d8d0d
AK
5722 xgifb_set_lcd(HwDeviceExtension->jChipType,
5723 pVBInfo, RefreshRateTableIndex, ModeNo);
cc1e2398 5724
64db29f5 5725 if (pVBInfo->IF_DEF_LVDS == 1)
fab04b97
AK
5726 xgifb_set_lvds(xgifb_info,
5727 HwDeviceExtension->jChipType,
64db29f5 5728 ModeNo, ModeIdIndex, pVBInfo);
21df8fc8 5729 }
21df8fc8 5730 }
d7636e0b 5731
cc1e2398
AK
5732 pVBInfo->SetFlag &= (~ProgrammingCRT2);
5733 XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
5734 XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
5735 RefreshRateTableIndex, pVBInfo);
cc1e2398 5736 XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
d7636e0b 5737}
5738
fab04b97
AK
5739unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
5740 struct xgi_hw_device_info *HwDeviceExtension,
cc1e2398 5741 unsigned short ModeNo)
21df8fc8 5742{
cc1e2398 5743 unsigned short ModeIdIndex;
cc1e2398
AK
5744 struct vb_device_info VBINF;
5745 struct vb_device_info *pVBInfo = &VBINF;
cc1e2398 5746 pVBInfo->IF_DEF_LVDS = 0;
cc1e2398 5747
949eb0ae 5748 if (HwDeviceExtension->jChipType >= XG20) {
cc1e2398
AK
5749 pVBInfo->IF_DEF_YPbPr = 0;
5750 pVBInfo->IF_DEF_HiVision = 0;
5751 pVBInfo->IF_DEF_CRT2Monitor = 0;
5752 pVBInfo->VBType = 0; /*set VBType default 0*/
cc1e2398
AK
5753 } else {
5754 pVBInfo->IF_DEF_YPbPr = 1;
5755 pVBInfo->IF_DEF_HiVision = 1;
06587335 5756 pVBInfo->IF_DEF_CRT2Monitor = 1;
cc1e2398
AK
5757 }
5758
56810a92 5759 XGIRegInit(pVBInfo, xgifb_info->vga_base);
21df8fc8 5760
1d7f656d
KT
5761 /* for x86 Linux, XG21 LVDS */
5762 if (HwDeviceExtension->jChipType == XG21) {
58839b01 5763 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
cc1e2398
AK
5764 pVBInfo->IF_DEF_LVDS = 1;
5765 }
5766 if (HwDeviceExtension->jChipType == XG27) {
58839b01
AK
5767 if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
5768 if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20)
cc1e2398
AK
5769 pVBInfo->IF_DEF_LVDS = 1;
5770 }
5771 }
21df8fc8 5772
949eb0ae 5773 if (HwDeviceExtension->jChipType < XG20)
cc1e2398 5774 XGI_GetVBType(pVBInfo);
21df8fc8 5775
cc1e2398 5776 InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
ef497f46 5777 if (ModeNo & 0x80)
cc1e2398 5778 ModeNo = ModeNo & 0x7F;
8104e329 5779 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
21df8fc8 5780
949eb0ae 5781 if (HwDeviceExtension->jChipType < XG20)
cc1e2398 5782 XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
21df8fc8 5783
cc1e2398 5784 XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
21df8fc8 5785
949eb0ae 5786 if (HwDeviceExtension->jChipType < XG20) {
cc1e2398
AK
5787 XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
5788 XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
5789 XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
fab04b97 5790 XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
21df8fc8 5791
e44adfdb
PH
5792 if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA) ||
5793 (!(pVBInfo->VBInfo & SwitchCRT2))) {
fab04b97 5794 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
cc1e2398 5795 ModeIdIndex, pVBInfo);
21df8fc8 5796
a3d675c8 5797 if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
cc1e2398
AK
5798 XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
5799 HwDeviceExtension, pVBInfo);
5800 }
cc1e2398 5801 }
21df8fc8 5802
6896b94e 5803 if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) {
cc1e2398 5804 switch (HwDeviceExtension->ujVBChipID) {
e44adfdb 5805 case VB_CHIP_301: /* fall through */
cc1e2398
AK
5806 case VB_CHIP_302:
5807 XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
5808 pVBInfo); /*add for CRT2 */
5809 break;
21df8fc8 5810
cc1e2398
AK
5811 default:
5812 break;
5813 }
5814 }
21df8fc8 5815
cc1e2398
AK
5816 XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
5817 XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/
fab04b97 5818 XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
cc1e2398
AK
5819 } /* !XG20 */
5820 else {
5821 if (pVBInfo->IF_DEF_LVDS == 1)
fab04b97 5822 if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo,
1d7f656d
KT
5823 ModeIdIndex,
5824 pVBInfo))
cc1e2398 5825 return 0;
21df8fc8 5826
b397992e 5827 pVBInfo->ModeType = XGI330_EModeIDTable[ModeIdIndex].
6896b94e 5828 Ext_ModeFlag & ModeTypeMask;
21df8fc8 5829
cc1e2398 5830 pVBInfo->SetFlag = 0;
83f76a9d 5831 pVBInfo->VBInfo = DisableCRT2Display;
21df8fc8 5832
fab04b97 5833 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
21df8fc8 5834
fab04b97
AK
5835 XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
5836 ModeIdIndex, pVBInfo);
21df8fc8 5837
fab04b97 5838 XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
cc1e2398 5839 }
21df8fc8 5840
cc1e2398 5841 XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
21df8fc8 5842
3bcc2460 5843 if (HwDeviceExtension->jChipType < XG20)
cc1e2398 5844 XGI_LockCRT2(HwDeviceExtension, pVBInfo);
21df8fc8 5845
cc1e2398 5846 return 1;
d7636e0b 5847}