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