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