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