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