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