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