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