1 /*
2  * XG20, XG21, XG40, XG42 frame buffer device
3  * for Linux kernels  2.5.x, 2.6.x
4  * Base on TW's sis fbdev code.
5  */
6 
7 /* #include <linux/config.h> */
8 #include <linux/version.h>
9 #include <linux/module.h>
10 #include <linux/moduleparam.h>
11 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/mm.h>
16 #include <linux/tty.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
19 #include <linux/fb.h>
20 #include <linux/console.h>
21 #include <linux/selection.h>
22 #include <linux/ioport.h>
23 #include <linux/init.h>
24 #include <linux/pci.h>
25 #include <linux/vmalloc.h>
26 #include <linux/vt_kern.h>
27 #include <linux/capability.h>
28 #include <linux/fs.h>
29 #include <linux/types.h>
30 #include <linux/proc_fs.h>
31 
32 #ifndef XGIFB_PAN
33 #define XGIFB_PAN
34 #endif
35 
36 #include <asm/io.h>
37 #ifdef CONFIG_MTRR
38 #include <asm/mtrr.h>
39 #endif
40 
41 #include "XGIfb.h"
42 #include "vgatypes.h"
43 #include "XGI_main.h"
44 #include "vb_util.h"
45 
46 #define Index_CR_GPIO_Reg1 0x48
47 #define Index_CR_GPIO_Reg2 0x49
48 #define Index_CR_GPIO_Reg3 0x4a
49 
50 #define GPIOG_EN    (1<<6)
51 #define GPIOG_WRITE (1<<6)
52 #define GPIOG_READ  (1<<1)
53 int XGIfb_GetXG21DefaultLVDSModeIdx(void);
54 
55 #define XGIFB_ROM_SIZE	65536
56 
57 /* -------------------- Macro definitions ---------------------------- */
58 
59 #undef XGIFBDEBUG
60 
61 #ifdef XGIFBDEBUG
62 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
63 #else
64 #define DPRINTK(fmt, args...)
65 #endif
66 
67 #ifdef XGIFBDEBUG
dumpVGAReg(void)68 static void dumpVGAReg(void)
69 {
70 	u8 i, reg;
71 
72 	outXGIIDXREG(XGISR, 0x05, 0x86);
73 	/*
74 	outXGIIDXREG(XGISR, 0x08, 0x4f);
75 	outXGIIDXREG(XGISR, 0x0f, 0x20);
76 	outXGIIDXREG(XGISR, 0x11, 0x4f);
77 	outXGIIDXREG(XGISR, 0x13, 0x45);
78 	outXGIIDXREG(XGISR, 0x14, 0x51);
79 	outXGIIDXREG(XGISR, 0x1e, 0x41);
80 	outXGIIDXREG(XGISR, 0x1f, 0x0);
81 	outXGIIDXREG(XGISR, 0x20, 0xa1);
82 	outXGIIDXREG(XGISR, 0x22, 0xfb);
83 	outXGIIDXREG(XGISR, 0x26, 0x22);
84 	outXGIIDXREG(XGISR, 0x3e, 0x07);
85 	*/
86 
87 	/* outXGIIDXREG(XGICR, 0x19, 0x00); */
88 	/* outXGIIDXREG(XGICR, 0x1a, 0x3C); */
89 	/* outXGIIDXREG(XGICR, 0x22, 0xff); */
90 	/* outXGIIDXREG(XGICR, 0x3D, 0x10); */
91 
92 	/* outXGIIDXREG(XGICR, 0x4a, 0xf3); */
93 
94 	/* outXGIIDXREG(XGICR, 0x57, 0x0); */
95 	/* outXGIIDXREG(XGICR, 0x7a, 0x2c); */
96 
97 	/* outXGIIDXREG(XGICR, 0x82, 0xcc); */
98 	/* outXGIIDXREG(XGICR, 0x8c, 0x0); */
99 	/*
100 	outXGIIDXREG(XGICR, 0x99, 0x1);
101 	outXGIIDXREG(XGICR, 0x41, 0x40);
102 	*/
103 
104 	for (i = 0; i < 0x4f; i++) {
105 		inXGIIDXREG(XGISR, i, reg);
106 		printk("\no 3c4 %x", i);
107 		printk("\ni 3c5 => %x", reg);
108 	}
109 
110 	for (i = 0; i < 0xF0; i++) {
111 		inXGIIDXREG(XGICR, i, reg);
112 		printk("\no 3d4 %x", i);
113 		printk("\ni 3d5 => %x", reg);
114 	}
115 	/*
116 	outXGIIDXREG(XGIPART1,0x2F,1);
117 	for (i=1; i < 0x50; i++) {
118 		inXGIIDXREG(XGIPART1, i, reg);
119 		printk("\no d004 %x", i);
120 		printk("\ni d005 => %x", reg);
121 	}
122 
123 	for (i=0; i < 0x50; i++) {
124 		 inXGIIDXREG(XGIPART2, i, reg);
125 		 printk("\no d010 %x", i);
126 		 printk("\ni d011 => %x", reg);
127 	}
128 	for (i=0; i < 0x50; i++) {
129 		inXGIIDXREG(XGIPART3, i, reg);
130 		printk("\no d012 %x",i);
131 		printk("\ni d013 => %x",reg);
132 	}
133 	for (i=0; i < 0x50; i++) {
134 		inXGIIDXREG(XGIPART4, i, reg);
135 		printk("\no d014 %x",i);
136 		printk("\ni d015 => %x",reg);
137 	}
138 	*/
139 }
140 #else
dumpVGAReg(void)141 static inline void dumpVGAReg(void)
142 {
143 }
144 #endif
145 
146 /* data for XGI components */
147 struct video_info xgi_video_info;
148 
149 #if 1
150 #define DEBUGPRN(x)
151 #else
152 #define DEBUGPRN(x) printk(KERN_INFO x "\n");
153 #endif
154 
155 /* --------------- Hardware Access Routines -------------------------- */
156 
XGIfb_mode_rate_to_dclock(struct vb_device_info * XGI_Pr,struct xgi_hw_device_info * HwDeviceExtension,unsigned char modeno,unsigned char rateindex)157 static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
158 		struct xgi_hw_device_info *HwDeviceExtension,
159 		unsigned char modeno, unsigned char rateindex)
160 {
161 	unsigned short ModeNo = modeno;
162 	unsigned short ModeIdIndex = 0, ClockIndex = 0;
163 	unsigned short RefreshRateTableIndex = 0;
164 
165 	/* unsigned long  temp = 0; */
166 	int Clock;
167 	XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
168 	InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
169 
170 	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
171 			ModeIdIndex, XGI_Pr);
172 
173 	/*
174 	temp = XGI_SearchModeID(ModeNo , &ModeIdIndex,  XGI_Pr) ;
175 	if (!temp) {
176 		printk(KERN_ERR "Could not find mode %x\n", ModeNo);
177 		return 65000;
178 	}
179 
180 	RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
181 	RefreshRateTableIndex += (rateindex - 1);
182 
183 	*/
184 	ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
185 
186 	Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
187 
188 	return Clock;
189 }
190 
XGIfb_mode_rate_to_ddata(struct vb_device_info * XGI_Pr,struct xgi_hw_device_info * HwDeviceExtension,unsigned char modeno,unsigned char rateindex,u32 * left_margin,u32 * right_margin,u32 * upper_margin,u32 * lower_margin,u32 * hsync_len,u32 * vsync_len,u32 * sync,u32 * vmode)191 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
192 		struct xgi_hw_device_info *HwDeviceExtension,
193 		unsigned char modeno, unsigned char rateindex,
194 		u32 *left_margin, u32 *right_margin, u32 *upper_margin,
195 		u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
196 		u32 *vmode)
197 {
198 	unsigned short ModeNo = modeno;
199 	unsigned short ModeIdIndex = 0, index = 0;
200 	unsigned short RefreshRateTableIndex = 0;
201 
202 	unsigned short VRE, VBE, VRS, VBS, VDE, VT;
203 	unsigned short HRE, HBE, HRS, HBS, HDE, HT;
204 	unsigned char sr_data, cr_data, cr_data2;
205 	unsigned long cr_data3;
206 	int A, B, C, D, E, F, temp, j;
207 	XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
208 	InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
209 	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
210 			ModeIdIndex, XGI_Pr);
211 	/*
212 	temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
213 	if (!temp)
214 		return 0;
215 
216 	RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
217 	RefreshRateTableIndex += (rateindex - 1);
218 	*/
219 	index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
220 
221 	sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
222 
223 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
224 
225 	/* Horizontal total */
226 	HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
227 	A = HT + 5;
228 
229 	/*
230 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
231 
232 	Horizontal display enable end
233 	HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
234 	*/
235 	HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
236 	E = HDE + 1;
237 
238 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
239 
240 	/* Horizontal retrace (=sync) start */
241 	HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
242 	F = HRS - E - 3;
243 
244 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
245 
246 	/* Horizontal blank start */
247 	HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
248 
249 	sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
250 
251 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
252 
253 	cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
254 
255 	/* Horizontal blank end */
256 	HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
257 			| ((unsigned short) (sr_data & 0x03) << 6);
258 
259 	/* Horizontal retrace (=sync) end */
260 	HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
261 
262 	temp = HBE - ((E - 1) & 255);
263 	B = (temp > 0) ? temp : (temp + 256);
264 
265 	temp = HRE - ((E + F + 3) & 63);
266 	C = (temp > 0) ? temp : (temp + 64);
267 
268 	D = B - F - C;
269 
270 	*left_margin = D * 8;
271 	*right_margin = F * 8;
272 	*hsync_len = C * 8;
273 
274 	sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
275 
276 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
277 
278 	cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
279 
280 	/* Vertical total */
281 	VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
282 			| ((unsigned short) (cr_data2 & 0x20) << 4)
283 			| ((unsigned short) (sr_data & 0x01) << 10);
284 	A = VT + 2;
285 
286 	/* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
287 
288 	/* Vertical display enable end */
289 	/*
290 	VDE = (cr_data & 0xff) |
291 		((unsigned short) (cr_data2 & 0x02) << 7) |
292 		((unsigned short) (cr_data2 & 0x40) << 3) |
293 		((unsigned short) (sr_data & 0x02) << 9);
294 	*/
295 	VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
296 	E = VDE + 1;
297 
298 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
299 
300 	/* Vertical retrace (=sync) start */
301 	VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
302 			| ((unsigned short) (cr_data2 & 0x80) << 2)
303 			| ((unsigned short) (sr_data & 0x08) << 7);
304 	F = VRS + 1 - E;
305 
306 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
307 
308 	cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
309 
310 	/* Vertical blank start */
311 	VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
312 			| ((unsigned short) (cr_data3 & 0x20) << 4)
313 			| ((unsigned short) (sr_data & 0x04) << 8);
314 
315 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
316 
317 	/* Vertical blank end */
318 	VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
319 	temp = VBE - ((E - 1) & 511);
320 	B = (temp > 0) ? temp : (temp + 512);
321 
322 	cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
323 
324 	/* Vertical retrace (=sync) end */
325 	VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
326 	temp = VRE - ((E + F - 1) & 31);
327 	C = (temp > 0) ? temp : (temp + 32);
328 
329 	D = B - F - C;
330 
331 	*upper_margin = D;
332 	*lower_margin = F;
333 	*vsync_len = C;
334 
335 	if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
336 		*sync &= ~FB_SYNC_VERT_HIGH_ACT;
337 	else
338 		*sync |= FB_SYNC_VERT_HIGH_ACT;
339 
340 	if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
341 		*sync &= ~FB_SYNC_HOR_HIGH_ACT;
342 	else
343 		*sync |= FB_SYNC_HOR_HIGH_ACT;
344 
345 	*vmode = FB_VMODE_NONINTERLACED;
346 	if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
347 		*vmode = FB_VMODE_INTERLACED;
348 	else {
349 		j = 0;
350 		while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
351 			if (XGI_Pr->EModeIDTable[j].Ext_ModeID
352 					== XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
353 				if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
354 						& DoubleScanMode) {
355 					*vmode = FB_VMODE_DOUBLE;
356 				}
357 				break;
358 			}
359 			j++;
360 		}
361 	}
362 
363 	return 1;
364 }
365 
XGIRegInit(struct vb_device_info * XGI_Pr,unsigned long BaseAddr)366 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
367 {
368 	XGI_Pr->RelIO = BaseAddr;
369 	XGI_Pr->P3c4 = BaseAddr + 0x14;
370 	XGI_Pr->P3d4 = BaseAddr + 0x24;
371 	XGI_Pr->P3c0 = BaseAddr + 0x10;
372 	XGI_Pr->P3ce = BaseAddr + 0x1e;
373 	XGI_Pr->P3c2 = BaseAddr + 0x12;
374 	XGI_Pr->P3ca = BaseAddr + 0x1a;
375 	XGI_Pr->P3c6 = BaseAddr + 0x16;
376 	XGI_Pr->P3c7 = BaseAddr + 0x17;
377 	XGI_Pr->P3c8 = BaseAddr + 0x18;
378 	XGI_Pr->P3c9 = BaseAddr + 0x19;
379 	XGI_Pr->P3da = BaseAddr + 0x2A;
380 	XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
381 	XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
382 	XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
383 	XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
384 	XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
385 
386 }
387 
XGIfb_set_reg4(u16 port,unsigned long data)388 void XGIfb_set_reg4(u16 port, unsigned long data)
389 {
390 	outl((u32)(data & 0xffffffff), port);
391 }
392 
XGIfb_get_reg3(u16 port)393 u32 XGIfb_get_reg3(u16 port)
394 {
395 	u32 data;
396 
397 	data = inl(port);
398 	return data;
399 }
400 
401 /* ------------ Interface for init & mode switching code ------------- */
402 
XGIfb_query_VGA_config_space(struct xgi_hw_device_info * pXGIhw_ext,unsigned long offset,unsigned long set,unsigned long * value)403 unsigned char XGIfb_query_VGA_config_space(
404 		struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
405 		unsigned long set, unsigned long *value)
406 {
407 	static struct pci_dev *pdev = NULL;
408 	static unsigned char init = 0, valid_pdev = 0;
409 
410 	if (!set)
411 		DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
412 	else
413 		DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
414 
415 	if (!init) {
416 		init = 1;
417 		pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
418 				pdev);
419 		if (pdev) {
420 			valid_pdev = 1;
421 			pci_dev_put(pdev);
422 		}
423 	}
424 
425 	if (!valid_pdev) {
426 		printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
427 				xgi_video_info.chip_id);
428 		return 0;
429 	}
430 
431 	if (set == 0)
432 		pci_read_config_dword(pdev, offset, (u32 *) value);
433 	else
434 		pci_write_config_dword(pdev, offset, (u32)(*value));
435 
436 	return 1;
437 }
438 
439 /*
440 unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
441 	unsigned long offset, unsigned long set, unsigned long *value)
442 {
443 	static struct pci_dev *pdev = NULL;
444 	static unsigned char init = 0, valid_pdev = 0;
445 	u16 nbridge_id = 0;
446 
447 	if (!init) {
448 		init = 1;
449 		switch (xgi_video_info.chip) {
450 		case XGI_540:
451 			nbridge_id = PCI_DEVICE_ID_XG_540;
452 			break;
453 		case XGI_630:
454 			nbridge_id = PCI_DEVICE_ID_XG_630;
455 			break;
456 		case XGI_730:
457 			nbridge_id = PCI_DEVICE_ID_XG_730;
458 			break;
459 		case XGI_550:
460 			nbridge_id = PCI_DEVICE_ID_XG_550;
461 			break;
462 		case XGI_650:
463 			nbridge_id = PCI_DEVICE_ID_XG_650;
464 			break;
465 		case XGI_740:
466 			nbridge_id = PCI_DEVICE_ID_XG_740;
467 			break;
468 		default:
469 			nbridge_id = 0;
470 			break;
471 		}
472 
473 		pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
474 		if (pdev) {
475 			valid_pdev = 1;
476 			pci_dev_put(pdev);
477 		}
478 	}
479 
480 	if (!valid_pdev) {
481 		printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
482 			nbridge_id);
483 		return 0;
484 	}
485 
486 	if (set == 0)
487 		pci_read_config_dword(pdev, offset, (u32 *)value);
488 	else
489 		pci_write_config_dword(pdev, offset, (u32)(*value));
490 
491 	return 1;
492 }
493 */
494 /* ------------------ Internal helper routines ----------------- */
495 
XGIfb_search_mode(const char * name)496 static void XGIfb_search_mode(const char *name)
497 {
498 	int i = 0, j = 0, l;
499 
500 	if (name == NULL) {
501 		printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
502 		xgifb_mode_idx = DEFAULT_MODE;
503 		if ((xgi_video_info.chip == XG21)
504 				&& ((xgi_video_info.disp_state & DISPTYPE_DISP2)
505 						== DISPTYPE_LCD)) {
506 			xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
507 		}
508 		return;
509 	}
510 
511 	if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
512 		printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
513 		xgifb_mode_idx = DEFAULT_MODE;
514 		if ((xgi_video_info.chip == XG21)
515 				&& ((xgi_video_info.disp_state & DISPTYPE_DISP2)
516 						== DISPTYPE_LCD)) {
517 			xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
518 		}
519 		return;
520 	}
521 
522 	while (XGIbios_mode[i].mode_no != 0) {
523 		l = min(strlen(name), strlen(XGIbios_mode[i].name));
524 		if (!strncmp(name, XGIbios_mode[i].name, l)) {
525 			xgifb_mode_idx = i;
526 			j = 1;
527 			break;
528 		}
529 		i++;
530 	}
531 	if (!j)
532 		printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
533 }
534 
XGIfb_search_vesamode(unsigned int vesamode)535 static void XGIfb_search_vesamode(unsigned int vesamode)
536 {
537 	int i = 0, j = 0;
538 
539 	if (vesamode == 0) {
540 
541 		printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
542 		xgifb_mode_idx = DEFAULT_MODE;
543 		if ((xgi_video_info.chip == XG21)
544 				&& ((xgi_video_info.disp_state & DISPTYPE_DISP2)
545 						== DISPTYPE_LCD)) {
546 			xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
547 		}
548 		return;
549 	}
550 
551 	vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
552 
553 	while (XGIbios_mode[i].mode_no != 0) {
554 		if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
555 				|| (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
556 			xgifb_mode_idx = i;
557 			j = 1;
558 			break;
559 		}
560 		i++;
561 	}
562 	if (!j)
563 		printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
564 }
565 
XGIfb_GetXG21LVDSData(void)566 static int XGIfb_GetXG21LVDSData(void)
567 {
568 	u8 tmp;
569 	unsigned char *pData;
570 	int i, j, k;
571 
572 	inXGIIDXREG(XGISR, 0x1e, tmp);
573 	outXGIIDXREG(XGISR, 0x1e, tmp | 4);
574 
575 	pData = xgi_video_info.mmio_vbase + 0x20000;
576 	if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
577 		i = pData[0x316] | (pData[0x317] << 8);
578 		j = pData[i - 1];
579 		if (j == 0xff)
580 			j = 1;
581 
582 		k = 0;
583 		do {
584 			XGI21_LCDCapList[k].LVDS_Capability = pData[i]
585 					| (pData[i + 1] << 8);
586 			XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
587 					+ 3] << 8);
588 			XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
589 					+ 5] << 8);
590 			XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
591 					+ 7] << 8);
592 			XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
593 					+ 9] << 8);
594 			XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
595 					+ 11] << 8);
596 			XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
597 					+ 13] << 8);
598 			XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
599 					| (pData[i + 15] << 8);
600 			XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
601 					| (pData[i + 17] << 8);
602 			XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
603 			XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
604 			XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
605 			XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
606 			XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
607 			XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
608 			XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
609 			i += 25;
610 			j--;
611 			k++;
612 		} while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
613 				/ sizeof(struct XGI21_LVDSCapStruct))));
614 		return 1;
615 	}
616 	return 0;
617 }
618 
XGIfb_GetXG21DefaultLVDSModeIdx(void)619 int XGIfb_GetXG21DefaultLVDSModeIdx(void)
620 {
621 
622 	int found_mode = 0;
623 	int XGIfb_mode_idx = 0;
624 
625 	found_mode = 0;
626 	while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
627 			&& (XGIbios_mode[XGIfb_mode_idx].xres
628 					<= XGI21_LCDCapList[0].LVDSHDE)) {
629 		if ((XGIbios_mode[XGIfb_mode_idx].xres
630 				== XGI21_LCDCapList[0].LVDSHDE)
631 				&& (XGIbios_mode[XGIfb_mode_idx].yres
632 						== XGI21_LCDCapList[0].LVDSVDE)
633 				&& (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
634 			XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
635 			found_mode = 1;
636 			break;
637 		}
638 		XGIfb_mode_idx++;
639 	}
640 	if (!found_mode)
641 		XGIfb_mode_idx = 0;
642 
643 	return XGIfb_mode_idx;
644 }
645 
XGIfb_validate_mode(int myindex)646 static int XGIfb_validate_mode(int myindex)
647 {
648 	u16 xres, yres;
649 
650 	if (xgi_video_info.chip == XG21) {
651 		if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
652 				== DISPTYPE_LCD) {
653 			xres = XGI21_LCDCapList[0].LVDSHDE;
654 			yres = XGI21_LCDCapList[0].LVDSVDE;
655 			if (XGIbios_mode[myindex].xres > xres)
656 				return -1;
657 			if (XGIbios_mode[myindex].yres > yres)
658 				return -1;
659 			if ((XGIbios_mode[myindex].xres < xres)
660 					&& (XGIbios_mode[myindex].yres < yres)) {
661 				if (XGIbios_mode[myindex].bpp > 8)
662 					return -1;
663 			}
664 
665 		}
666 		return myindex;
667 
668 	}
669 
670 	/* FIXME: for now, all is valid on XG27 */
671 	if (xgi_video_info.chip == XG27)
672 		return myindex;
673 
674 	if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
675 		return -1;
676 
677 	switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
678 	case DISPTYPE_LCD:
679 		switch (XGIhw_ext.ulCRT2LCDType) {
680 		case LCD_640x480:
681 			xres = 640;
682 			yres = 480;
683 			break;
684 		case LCD_800x600:
685 			xres = 800;
686 			yres = 600;
687 			break;
688 		case LCD_1024x600:
689 			xres = 1024;
690 			yres = 600;
691 			break;
692 		case LCD_1024x768:
693 			xres = 1024;
694 			yres = 768;
695 			break;
696 		case LCD_1152x768:
697 			xres = 1152;
698 			yres = 768;
699 			break;
700 		case LCD_1280x960:
701 			xres = 1280;
702 			yres = 960;
703 			break;
704 		case LCD_1280x768:
705 			xres = 1280;
706 			yres = 768;
707 			break;
708 		case LCD_1280x1024:
709 			xres = 1280;
710 			yres = 1024;
711 			break;
712 		case LCD_1400x1050:
713 			xres = 1400;
714 			yres = 1050;
715 			break;
716 		case LCD_1600x1200:
717 			xres = 1600;
718 			yres = 1200;
719 			break;
720 		/* case LCD_320x480: */ /* TW: FSTN */
721 			/*
722 			xres =  320;
723 			yres =  480;
724 			break;
725 			*/
726 		default:
727 			xres = 0;
728 			yres = 0;
729 			break;
730 		}
731 		if (XGIbios_mode[myindex].xres > xres)
732 			return -1;
733 		if (XGIbios_mode[myindex].yres > yres)
734 			return -1;
735 		if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
736 				(XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
737 			switch (XGIbios_mode[myindex].xres) {
738 			case 512:
739 				if (XGIbios_mode[myindex].yres != 512)
740 					return -1;
741 				if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
742 					return -1;
743 				break;
744 			case 640:
745 				if ((XGIbios_mode[myindex].yres != 400)
746 						&& (XGIbios_mode[myindex].yres
747 								!= 480))
748 					return -1;
749 				break;
750 			case 800:
751 				if (XGIbios_mode[myindex].yres != 600)
752 					return -1;
753 				break;
754 			case 1024:
755 				if ((XGIbios_mode[myindex].yres != 600)
756 						&& (XGIbios_mode[myindex].yres
757 								!= 768))
758 					return -1;
759 				if ((XGIbios_mode[myindex].yres == 600)
760 						&& (XGIhw_ext.ulCRT2LCDType
761 								!= LCD_1024x600))
762 					return -1;
763 				break;
764 			case 1152:
765 				if ((XGIbios_mode[myindex].yres) != 768)
766 					return -1;
767 				if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
768 					return -1;
769 				break;
770 			case 1280:
771 				if ((XGIbios_mode[myindex].yres != 768)
772 						&& (XGIbios_mode[myindex].yres
773 								!= 1024))
774 					return -1;
775 				if ((XGIbios_mode[myindex].yres == 768)
776 						&& (XGIhw_ext.ulCRT2LCDType
777 								!= LCD_1280x768))
778 					return -1;
779 				break;
780 			case 1400:
781 				if (XGIbios_mode[myindex].yres != 1050)
782 					return -1;
783 				break;
784 			case 1600:
785 				if (XGIbios_mode[myindex].yres != 1200)
786 					return -1;
787 				break;
788 			default:
789 				return -1;
790 			}
791 		} else {
792 			switch (XGIbios_mode[myindex].xres) {
793 			case 512:
794 				if (XGIbios_mode[myindex].yres != 512)
795 					return -1;
796 				break;
797 			case 640:
798 				if ((XGIbios_mode[myindex].yres != 400)
799 						&& (XGIbios_mode[myindex].yres
800 								!= 480))
801 					return -1;
802 				break;
803 			case 800:
804 				if (XGIbios_mode[myindex].yres != 600)
805 					return -1;
806 				break;
807 			case 1024:
808 				if (XGIbios_mode[myindex].yres != 768)
809 					return -1;
810 				break;
811 			case 1280:
812 				if ((XGIbios_mode[myindex].yres != 960)
813 						&& (XGIbios_mode[myindex].yres
814 								!= 1024))
815 					return -1;
816 				if (XGIbios_mode[myindex].yres == 960) {
817 					if (XGIhw_ext.ulCRT2LCDType
818 							== LCD_1400x1050)
819 						return -1;
820 				}
821 				break;
822 			case 1400:
823 				if (XGIbios_mode[myindex].yres != 1050)
824 					return -1;
825 				break;
826 			case 1600:
827 				if (XGIbios_mode[myindex].yres != 1200)
828 					return -1;
829 				break;
830 			default:
831 				return -1;
832 			}
833 		}
834 		break;
835 	case DISPTYPE_TV:
836 		switch (XGIbios_mode[myindex].xres) {
837 		case 512:
838 		case 640:
839 		case 800:
840 			break;
841 		case 720:
842 			if (xgi_video_info.TV_type == TVMODE_NTSC) {
843 				if (XGIbios_mode[myindex].yres != 480)
844 					return -1;
845 			} else if (xgi_video_info.TV_type == TVMODE_PAL) {
846 				if (XGIbios_mode[myindex].yres != 576)
847 					return -1;
848 			}
849 			/*  TW: LVDS/CHRONTEL does not support 720 */
850 			if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
851 					|| xgi_video_info.hasVB	== HASVB_CHRONTEL) {
852 				return -1;
853 			}
854 			break;
855 		case 1024:
856 			if (xgi_video_info.TV_type == TVMODE_NTSC) {
857 				if (XGIbios_mode[myindex].bpp == 32)
858 					return -1;
859 			}
860 			break;
861 		default:
862 			return -1;
863 		}
864 		break;
865 	case DISPTYPE_CRT2:
866 		if (XGIbios_mode[myindex].xres > 1280)
867 			return -1;
868 		break;
869 	}
870 	return myindex;
871 
872 }
873 
XGIfb_search_crt2type(const char * name)874 static void XGIfb_search_crt2type(const char *name)
875 {
876 	int i = 0;
877 
878 	if (name == NULL)
879 		return;
880 
881 	while (XGI_crt2type[i].type_no != -1) {
882 		if (!strcmp(name, XGI_crt2type[i].name)) {
883 			XGIfb_crt2type = XGI_crt2type[i].type_no;
884 			XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
885 			break;
886 		}
887 		i++;
888 	}
889 	if (XGIfb_crt2type < 0)
890 		printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
891 }
892 
XGIfb_search_refresh_rate(unsigned int rate)893 static u8 XGIfb_search_refresh_rate(unsigned int rate)
894 {
895 	u16 xres, yres;
896 	int i = 0;
897 
898 	xres = XGIbios_mode[xgifb_mode_idx].xres;
899 	yres = XGIbios_mode[xgifb_mode_idx].yres;
900 
901 	XGIfb_rate_idx = 0;
902 	while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
903 		if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
904 				== yres)) {
905 			if (XGIfb_vrate[i].refresh == rate) {
906 				XGIfb_rate_idx = XGIfb_vrate[i].idx;
907 				break;
908 			} else if (XGIfb_vrate[i].refresh > rate) {
909 				if ((XGIfb_vrate[i].refresh - rate) <= 3) {
910 					DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
911 							rate, XGIfb_vrate[i].refresh);
912 					XGIfb_rate_idx = XGIfb_vrate[i].idx;
913 					xgi_video_info.refresh_rate
914 							= XGIfb_vrate[i].refresh;
915 				} else if (((rate - XGIfb_vrate[i - 1].refresh)
916 						<= 2) && (XGIfb_vrate[i].idx
917 						!= 1)) {
918 					DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
919 							rate, XGIfb_vrate[i-1].refresh);
920 					XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
921 					xgi_video_info.refresh_rate
922 							= XGIfb_vrate[i - 1].refresh;
923 				}
924 				break;
925 			} else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
926 				DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
927 						rate, XGIfb_vrate[i].refresh);
928 				XGIfb_rate_idx = XGIfb_vrate[i].idx;
929 				break;
930 			}
931 		}
932 		i++;
933 	}
934 	if (XGIfb_rate_idx > 0) {
935 		return XGIfb_rate_idx;
936 	} else {
937 		printk(KERN_INFO
938 				"XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
939 		return 0;
940 	}
941 }
942 
XGIfb_search_tvstd(const char * name)943 static void XGIfb_search_tvstd(const char *name)
944 {
945 	int i = 0;
946 
947 	if (name == NULL)
948 		return;
949 
950 	while (XGI_tvtype[i].type_no != -1) {
951 		if (!strcmp(name, XGI_tvtype[i].name)) {
952 			XGIfb_tvmode = XGI_tvtype[i].type_no;
953 			break;
954 		}
955 		i++;
956 	}
957 }
958 
959 /* ----------- FBDev related routines for all series ----------- */
960 
XGIfb_bpp_to_var(struct fb_var_screeninfo * var)961 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
962 {
963 	switch (var->bits_per_pixel) {
964 	case 8:
965 		var->red.offset = var->green.offset = var->blue.offset = 0;
966 		var->red.length = var->green.length = var->blue.length = 6;
967 		xgi_video_info.video_cmap_len = 256;
968 		break;
969 	case 16:
970 		var->red.offset = 11;
971 		var->red.length = 5;
972 		var->green.offset = 5;
973 		var->green.length = 6;
974 		var->blue.offset = 0;
975 		var->blue.length = 5;
976 		var->transp.offset = 0;
977 		var->transp.length = 0;
978 		xgi_video_info.video_cmap_len = 16;
979 		break;
980 	case 32:
981 		var->red.offset = 16;
982 		var->red.length = 8;
983 		var->green.offset = 8;
984 		var->green.length = 8;
985 		var->blue.offset = 0;
986 		var->blue.length = 8;
987 		var->transp.offset = 24;
988 		var->transp.length = 8;
989 		xgi_video_info.video_cmap_len = 16;
990 		break;
991 	}
992 }
993 
XGIfb_do_set_var(struct fb_var_screeninfo * var,int isactive,struct fb_info * info)994 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
995 		struct fb_info *info)
996 {
997 
998 	unsigned int htotal = var->left_margin + var->xres + var->right_margin
999 			+ var->hsync_len;
1000 	unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1001 			+ var->vsync_len;
1002 #if defined(__powerpc__)
1003 	u8 sr_data, cr_data;
1004 #endif
1005 	unsigned int drate = 0, hrate = 0;
1006 	int found_mode = 0;
1007 	int old_mode;
1008 	/* unsigned char reg, reg1; */
1009 
1010 	DEBUGPRN("Inside do_set_var");
1011 	/* printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres, var->upper_margin, var->lower_margin, var->vsync_len); */
1012 
1013 	info->var.xres_virtual = var->xres_virtual;
1014 	info->var.yres_virtual = var->yres_virtual;
1015 	info->var.bits_per_pixel = var->bits_per_pixel;
1016 
1017 	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1018 		vtotal <<= 1;
1019 	else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1020 		vtotal <<= 2;
1021 	else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1022 		/* vtotal <<= 1; */
1023 		/* var->yres <<= 1; */
1024 	}
1025 
1026 	if (!htotal || !vtotal) {
1027 		DPRINTK("XGIfb: Invalid 'var' information\n");
1028 		return -EINVAL;
1029 	} printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1030 			var->pixclock, htotal, vtotal);
1031 
1032 	if (var->pixclock && htotal && vtotal) {
1033 		drate = 1000000000 / var->pixclock;
1034 		hrate = (drate * 1000) / htotal;
1035 		xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1036 				/ vtotal);
1037 	} else {
1038 		xgi_video_info.refresh_rate = 60;
1039 	}
1040 
1041 	printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1042 			var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
1043 
1044 	old_mode = xgifb_mode_idx;
1045 	xgifb_mode_idx = 0;
1046 
1047 	while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1048 			&& (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1049 		if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1050 				&& (XGIbios_mode[xgifb_mode_idx].yres
1051 						== var->yres)
1052 				&& (XGIbios_mode[xgifb_mode_idx].bpp
1053 						== var->bits_per_pixel)) {
1054 			XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1055 			found_mode = 1;
1056 			break;
1057 		}
1058 		xgifb_mode_idx++;
1059 	}
1060 
1061 	if (found_mode)
1062 		xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1063 	else
1064 		xgifb_mode_idx = -1;
1065 
1066 	if (xgifb_mode_idx < 0) {
1067 		printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
1068 				var->yres, var->bits_per_pixel);
1069 		xgifb_mode_idx = old_mode;
1070 		return -EINVAL;
1071 	}
1072 
1073 	if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1074 		XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1075 		xgi_video_info.refresh_rate = 60;
1076 	}
1077 
1078 	if (isactive) {
1079 
1080 		XGIfb_pre_setmode();
1081 		if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1082 			printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1083 			return -EINVAL;
1084 		}
1085 		info->fix.line_length = ((info->var.xres_virtual
1086 				* info->var.bits_per_pixel) >> 6);
1087 
1088 		outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1089 
1090 		outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1091 		outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
1092 
1093 		XGIfb_post_setmode();
1094 
1095 		DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1096 				XGIbios_mode[xgifb_mode_idx].xres,
1097 				XGIbios_mode[xgifb_mode_idx].yres,
1098 				XGIbios_mode[xgifb_mode_idx].bpp,
1099 				xgi_video_info.refresh_rate);
1100 
1101 		xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1102 		xgi_video_info.video_vwidth = info->var.xres_virtual;
1103 		xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1104 		xgi_video_info.video_vheight = info->var.yres_virtual;
1105 		xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1106 		xgi_video_info.org_x = xgi_video_info.org_y = 0;
1107 		xgi_video_info.video_linelength = info->var.xres_virtual
1108 				* (xgi_video_info.video_bpp >> 3);
1109 		switch (xgi_video_info.video_bpp) {
1110 		case 8:
1111 			xgi_video_info.DstColor = 0x0000;
1112 			xgi_video_info.XGI310_AccelDepth = 0x00000000;
1113 			xgi_video_info.video_cmap_len = 256;
1114 #if defined(__powerpc__)
1115 			inXGIIDXREG(XGICR, 0x4D, cr_data);
1116 			outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
1117 #endif
1118 			break;
1119 		case 16:
1120 			xgi_video_info.DstColor = 0x8000;
1121 			xgi_video_info.XGI310_AccelDepth = 0x00010000;
1122 #if defined(__powerpc__)
1123 			inXGIIDXREG(XGICR, 0x4D, cr_data);
1124 			outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1125 #endif
1126 			xgi_video_info.video_cmap_len = 16;
1127 			break;
1128 		case 32:
1129 			xgi_video_info.DstColor = 0xC000;
1130 			xgi_video_info.XGI310_AccelDepth = 0x00020000;
1131 			xgi_video_info.video_cmap_len = 16;
1132 #if defined(__powerpc__)
1133 			inXGIIDXREG(XGICR, 0x4D, cr_data);
1134 			outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1135 #endif
1136 			break;
1137 		default:
1138 			xgi_video_info.video_cmap_len = 16;
1139 			printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
1140 			break;
1141 		}
1142 	}
1143 	XGIfb_bpp_to_var(var); /*update ARGB info*/
1144 	DEBUGPRN("End of do_set_var");
1145 
1146 	dumpVGAReg();
1147 	return 0;
1148 }
1149 
1150 #ifdef XGIFB_PAN
XGIfb_pan_var(struct fb_var_screeninfo * var)1151 static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1152 {
1153 	unsigned int base;
1154 
1155 	/* printk("Inside pan_var"); */
1156 
1157 	if (var->xoffset > (var->xres_virtual - var->xres)) {
1158 		/* printk("Pan: xo: %d xv %d xr %d\n",
1159 			var->xoffset, var->xres_virtual, var->xres); */
1160 		return -EINVAL;
1161 	}
1162 	if (var->yoffset > (var->yres_virtual - var->yres)) {
1163 		/* printk("Pan: yo: %d yv %d yr %d\n",
1164 			var->yoffset, var->yres_virtual, var->yres); */
1165 		return -EINVAL;
1166 	}
1167 	base = var->yoffset * var->xres_virtual + var->xoffset;
1168 
1169 	/* calculate base bpp dep. */
1170 	switch (var->bits_per_pixel) {
1171 	case 16:
1172 		base >>= 1;
1173 		break;
1174 	case 32:
1175 		break;
1176 	case 8:
1177 	default:
1178 		base >>= 2;
1179 		break;
1180 	}
1181 
1182 	outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1183 
1184 	outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
1185 	outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1186 	outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
1187 	outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
1188 	setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1189 
1190 	if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1191 		orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1192 		outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1193 		outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1194 		outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1195 		setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1196 	}
1197 	/* printk("End of pan_var"); */
1198 	return 0;
1199 }
1200 #endif
1201 
XGIfb_open(struct fb_info * info,int user)1202 static int XGIfb_open(struct fb_info *info, int user)
1203 {
1204 	return 0;
1205 }
1206 
XGIfb_release(struct fb_info * info,int user)1207 static int XGIfb_release(struct fb_info *info, int user)
1208 {
1209 	return 0;
1210 }
1211 
XGIfb_get_cmap_len(const struct fb_var_screeninfo * var)1212 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1213 {
1214 	int rc = 16;
1215 
1216 	switch (var->bits_per_pixel) {
1217 	case 8:
1218 		rc = 256;
1219 		break;
1220 	case 16:
1221 		rc = 16;
1222 		break;
1223 	case 32:
1224 		rc = 16;
1225 		break;
1226 	}
1227 	return rc;
1228 }
1229 
XGIfb_setcolreg(unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp,struct fb_info * info)1230 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1231 		unsigned blue, unsigned transp, struct fb_info *info)
1232 {
1233 	if (regno >= XGIfb_get_cmap_len(&info->var))
1234 		return 1;
1235 
1236 	switch (info->var.bits_per_pixel) {
1237 	case 8:
1238 		outXGIREG(XGIDACA, regno);
1239 		outXGIREG(XGIDACD, (red >> 10));
1240 		outXGIREG(XGIDACD, (green >> 10));
1241 		outXGIREG(XGIDACD, (blue >> 10));
1242 		if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1243 			outXGIREG(XGIDAC2A, regno);
1244 			outXGIREG(XGIDAC2D, (red >> 8));
1245 			outXGIREG(XGIDAC2D, (green >> 8));
1246 			outXGIREG(XGIDAC2D, (blue >> 8));
1247 		}
1248 		break;
1249 	case 16:
1250 		((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1251 				| ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1252 				>> 11);
1253 		break;
1254 	case 32:
1255 		red >>= 8;
1256 		green >>= 8;
1257 		blue >>= 8;
1258 		((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1259 				<< 8) | (blue);
1260 		break;
1261 	}
1262 	return 0;
1263 }
1264 
XGIfb_set_par(struct fb_info * info)1265 static int XGIfb_set_par(struct fb_info *info)
1266 {
1267 	int err;
1268 
1269 	/* printk("XGIfb: inside set_par\n"); */
1270 	err = XGIfb_do_set_var(&info->var, 1, info);
1271 	if (err)
1272 		return err;
1273 	XGIfb_get_fix(&info->fix, -1, info);
1274 	/* printk("XGIfb: end of set_par\n"); */
1275 	return 0;
1276 }
1277 
XGIfb_check_var(struct fb_var_screeninfo * var,struct fb_info * info)1278 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1279 {
1280 	unsigned int htotal = var->left_margin + var->xres + var->right_margin
1281 			+ var->hsync_len;
1282 	unsigned int vtotal = 0;
1283 	unsigned int drate = 0, hrate = 0;
1284 	int found_mode = 0;
1285 	int refresh_rate, search_idx;
1286 
1287 	DEBUGPRN("Inside check_var");
1288 
1289 	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1290 		vtotal = var->upper_margin + var->yres + var->lower_margin
1291 				+ var->vsync_len;
1292 		vtotal <<= 1;
1293 	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1294 		vtotal = var->upper_margin + var->yres + var->lower_margin
1295 				+ var->vsync_len;
1296 		vtotal <<= 2;
1297 	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1298 		vtotal = var->upper_margin + (var->yres / 2)
1299 				+ var->lower_margin + var->vsync_len;
1300 	} else
1301 		vtotal = var->upper_margin + var->yres + var->lower_margin
1302 				+ var->vsync_len;
1303 
1304 	if (!(htotal) || !(vtotal))
1305 		XGIFAIL("XGIfb: no valid timing data");
1306 
1307 	if (var->pixclock && htotal && vtotal) {
1308 		drate = 1000000000 / var->pixclock;
1309 		hrate = (drate * 1000) / htotal;
1310 		xgi_video_info.refresh_rate = (unsigned int) (hrate * 2	/ vtotal);
1311 		printk(KERN_DEBUG
1312 			"%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1313 			"%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1314 			__func__, var->pixclock, htotal, vtotal,
1315 			__func__, drate, hrate, xgi_video_info.refresh_rate);
1316 	} else {
1317 		xgi_video_info.refresh_rate = 60;
1318 	}
1319 
1320 	/*
1321 	if ((var->pixclock) && (htotal)) {
1322 		drate = 1E12 / var->pixclock;
1323 		hrate = drate / htotal;
1324 		refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1325 	} else {
1326 		refresh_rate = 60;
1327 	}
1328 	*/
1329 	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1330 	if ((var->xres == 1024) && (var->yres == 600))
1331 		refresh_rate = 60;
1332 
1333 	search_idx = 0;
1334 	while ((XGIbios_mode[search_idx].mode_no != 0) &&
1335 		(XGIbios_mode[search_idx].xres <= var->xres)) {
1336 		if ((XGIbios_mode[search_idx].xres == var->xres) &&
1337 			(XGIbios_mode[search_idx].yres == var->yres) &&
1338 			(XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1339 			if (XGIfb_validate_mode(search_idx) > 0) {
1340 				found_mode = 1;
1341 				break;
1342 			}
1343 		}
1344 		search_idx++;
1345 	}
1346 
1347 	if (!found_mode) {
1348 
1349 		printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1350 			var->xres, var->yres, var->bits_per_pixel);
1351 		search_idx = 0;
1352 		while (XGIbios_mode[search_idx].mode_no != 0) {
1353 
1354 			if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1355 				(var->yres <= XGIbios_mode[search_idx].yres) &&
1356 				(var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1357 				if (XGIfb_validate_mode(search_idx) > 0) {
1358 					found_mode = 1;
1359 					break;
1360 				}
1361 			}
1362 			search_idx++;
1363 		}
1364 		if (found_mode) {
1365 			var->xres = XGIbios_mode[search_idx].xres;
1366 			var->yres = XGIbios_mode[search_idx].yres;
1367 			printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1368 				var->xres, var->yres, var->bits_per_pixel);
1369 
1370 		} else {
1371 			printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1372 				var->xres, var->yres, var->bits_per_pixel);
1373 			return -EINVAL;
1374 		}
1375 	}
1376 
1377 	/* TW: TODO: Check the refresh rate */
1378 
1379 	/* Adapt RGB settings */
1380 	XGIfb_bpp_to_var(var);
1381 
1382 	/* Sanity check for offsets */
1383 	if (var->xoffset < 0)
1384 		var->xoffset = 0;
1385 	if (var->yoffset < 0)
1386 		var->yoffset = 0;
1387 
1388 	if (!XGIfb_ypan) {
1389 		if (var->xres != var->xres_virtual)
1390 			var->xres_virtual = var->xres;
1391 		if (var->yres != var->yres_virtual)
1392 			var->yres_virtual = var->yres;
1393 	} /* else { */
1394 		/* TW: Now patch yres_virtual if we use panning */
1395 		/* May I do this? */
1396 		/* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1397 		/* if (var->yres_virtual <= var->yres) { */
1398 		/* TW: Paranoia check */
1399 		/* var->yres_virtual = var->yres; */
1400 		/* } */
1401 	/* } */
1402 
1403 	/* Truncate offsets to maximum if too high */
1404 	if (var->xoffset > var->xres_virtual - var->xres)
1405 		var->xoffset = var->xres_virtual - var->xres - 1;
1406 
1407 	if (var->yoffset > var->yres_virtual - var->yres)
1408 		var->yoffset = var->yres_virtual - var->yres - 1;
1409 
1410 	/* Set everything else to 0 */
1411 	var->red.msb_right =
1412 	var->green.msb_right =
1413 	var->blue.msb_right =
1414 	var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1415 
1416 	DEBUGPRN("end of check_var");
1417 	return 0;
1418 }
1419 
1420 #ifdef XGIFB_PAN
XGIfb_pan_display(struct fb_var_screeninfo * var,struct fb_info * info)1421 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1422 		struct fb_info *info)
1423 {
1424 	int err;
1425 
1426 	/* printk("\nInside pan_display:\n"); */
1427 
1428 	if (var->xoffset > (var->xres_virtual - var->xres))
1429 		return -EINVAL;
1430 	if (var->yoffset > (var->yres_virtual - var->yres))
1431 		return -EINVAL;
1432 
1433 	if (var->vmode & FB_VMODE_YWRAP) {
1434 		if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1435 				|| var->xoffset)
1436 			return -EINVAL;
1437 	} else {
1438 		if (var->xoffset + info->var.xres > info->var.xres_virtual
1439 				|| var->yoffset + info->var.yres
1440 						> info->var.yres_virtual)
1441 			return -EINVAL;
1442 	}
1443 	err = XGIfb_pan_var(var);
1444 	if (err < 0)
1445 		return err;
1446 
1447 	info->var.xoffset = var->xoffset;
1448 	info->var.yoffset = var->yoffset;
1449 	if (var->vmode & FB_VMODE_YWRAP)
1450 		info->var.vmode |= FB_VMODE_YWRAP;
1451 	else
1452 		info->var.vmode &= ~FB_VMODE_YWRAP;
1453 
1454 	/* printk("End of pan_display\n"); */
1455 	return 0;
1456 }
1457 #endif
1458 
XGIfb_blank(int blank,struct fb_info * info)1459 static int XGIfb_blank(int blank, struct fb_info *info)
1460 {
1461 	u8 reg;
1462 
1463 	inXGIIDXREG(XGICR, 0x17, reg);
1464 
1465 	if (blank > 0)
1466 		reg &= 0x7f;
1467 	else
1468 		reg |= 0x80;
1469 
1470 	outXGIIDXREG(XGICR, 0x17, reg);
1471 	outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1472 	outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1473 	return 0;
1474 }
1475 
1476 /* ----------- FBDev related routines for all series ---------- */
1477 
XGIfb_get_fix(struct fb_fix_screeninfo * fix,int con,struct fb_info * info)1478 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1479 		struct fb_info *info)
1480 {
1481 	DEBUGPRN("inside get_fix");
1482 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1483 
1484 	strcpy(fix->id, myid);
1485 
1486 	fix->smem_start = xgi_video_info.video_base;
1487 
1488 	fix->smem_len = xgi_video_info.video_size;
1489 
1490 	fix->type = video_type;
1491 	fix->type_aux = 0;
1492 	if (xgi_video_info.video_bpp == 8)
1493 		fix->visual = FB_VISUAL_PSEUDOCOLOR;
1494 	else
1495 		fix->visual = FB_VISUAL_DIRECTCOLOR;
1496 	fix->xpanstep = 0;
1497 #ifdef XGIFB_PAN
1498 	if (XGIfb_ypan)
1499 		fix->ypanstep = 1;
1500 #endif
1501 	fix->ywrapstep = 0;
1502 	fix->line_length = xgi_video_info.video_linelength;
1503 	fix->mmio_start = xgi_video_info.mmio_base;
1504 	fix->mmio_len = xgi_video_info.mmio_size;
1505 	fix->accel = FB_ACCEL_XGI_XABRE;
1506 
1507 	DEBUGPRN("end of get_fix");
1508 	return 0;
1509 }
1510 
1511 static struct fb_ops XGIfb_ops = {
1512 	.owner = THIS_MODULE,
1513 	.fb_open = XGIfb_open,
1514 	.fb_release = XGIfb_release,
1515 	.fb_check_var = XGIfb_check_var,
1516 	.fb_set_par = XGIfb_set_par,
1517 	.fb_setcolreg = XGIfb_setcolreg,
1518 #ifdef XGIFB_PAN
1519 	.fb_pan_display = XGIfb_pan_display,
1520 #endif
1521 	.fb_blank = XGIfb_blank,
1522 	.fb_fillrect = cfb_fillrect,
1523 	.fb_copyarea = cfb_copyarea,
1524 	.fb_imageblit = cfb_imageblit,
1525 	/* .fb_mmap = XGIfb_mmap, */
1526 };
1527 
1528 /* ---------------- Chip generation dependent routines ---------------- */
1529 
1530 /* for XGI 315/550/650/740/330 */
1531 
XGIfb_get_dram_size(void)1532 static int XGIfb_get_dram_size(void)
1533 {
1534 
1535 	u8 ChannelNum, tmp;
1536 	u8 reg = 0;
1537 
1538 	/* xorg driver sets 32MB * 1 channel */
1539 	if (xgi_video_info.chip == XG27)
1540 		outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1541 
1542 	inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1543 	switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1544 	case XGI_DRAM_SIZE_1MB:
1545 		xgi_video_info.video_size = 0x100000;
1546 		break;
1547 	case XGI_DRAM_SIZE_2MB:
1548 		xgi_video_info.video_size = 0x200000;
1549 		break;
1550 	case XGI_DRAM_SIZE_4MB:
1551 		xgi_video_info.video_size = 0x400000;
1552 		break;
1553 	case XGI_DRAM_SIZE_8MB:
1554 		xgi_video_info.video_size = 0x800000;
1555 		break;
1556 	case XGI_DRAM_SIZE_16MB:
1557 		xgi_video_info.video_size = 0x1000000;
1558 		break;
1559 	case XGI_DRAM_SIZE_32MB:
1560 		xgi_video_info.video_size = 0x2000000;
1561 		break;
1562 	case XGI_DRAM_SIZE_64MB:
1563 		xgi_video_info.video_size = 0x4000000;
1564 		break;
1565 	case XGI_DRAM_SIZE_128MB:
1566 		xgi_video_info.video_size = 0x8000000;
1567 		break;
1568 	case XGI_DRAM_SIZE_256MB:
1569 		xgi_video_info.video_size = 0x10000000;
1570 		break;
1571 	default:
1572 		return -1;
1573 	}
1574 
1575 	tmp = (reg & 0x0c) >> 2;
1576 	switch (xgi_video_info.chip) {
1577 	case XG20:
1578 	case XG21:
1579 	case XG27:
1580 		ChannelNum = 1;
1581 		break;
1582 
1583 	case XG42:
1584 		if (reg & 0x04)
1585 			ChannelNum = 2;
1586 		else
1587 			ChannelNum = 1;
1588 		break;
1589 
1590 	case XG45:
1591 		if (tmp == 1)
1592 			ChannelNum = 2;
1593 		else if (tmp == 2)
1594 			ChannelNum = 3;
1595 		else if (tmp == 3)
1596 			ChannelNum = 4;
1597 		else
1598 			ChannelNum = 1;
1599 		break;
1600 
1601 	case XG40:
1602 	default:
1603 		if (tmp == 2)
1604 			ChannelNum = 2;
1605 		else if (tmp == 3)
1606 			ChannelNum = 3;
1607 		else
1608 			ChannelNum = 1;
1609 		break;
1610 	}
1611 
1612 	xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1613 	/* PLiad fixed for benchmarking and fb set */
1614 	/* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1615 	/* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1616 
1617 	printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
1618 			xgi_video_info.video_size, ChannelNum);
1619 	return 0;
1620 
1621 }
1622 
XGIfb_detect_VB(void)1623 static void XGIfb_detect_VB(void)
1624 {
1625 	u8 cr32, temp = 0;
1626 
1627 	xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1628 
1629 	switch (xgi_video_info.hasVB) {
1630 	case HASVB_LVDS_CHRONTEL:
1631 	case HASVB_CHRONTEL:
1632 		break;
1633 	case HASVB_301:
1634 	case HASVB_302:
1635 		/* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1636 		break;
1637 	}
1638 
1639 	inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
1640 
1641 	if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1642 		XGIfb_crt1off = 0;
1643 	else {
1644 		if (cr32 & 0x5F)
1645 			XGIfb_crt1off = 1;
1646 		else
1647 			XGIfb_crt1off = 0;
1648 	}
1649 
1650 	if (XGIfb_crt2type != -1)
1651 		/* TW: Override with option */
1652 		xgi_video_info.disp_state = XGIfb_crt2type;
1653 	else if (cr32 & XGI_VB_TV)
1654 		xgi_video_info.disp_state = DISPTYPE_TV;
1655 	else if (cr32 & XGI_VB_LCD)
1656 		xgi_video_info.disp_state = DISPTYPE_LCD;
1657 	else if (cr32 & XGI_VB_CRT2)
1658 		xgi_video_info.disp_state = DISPTYPE_CRT2;
1659 	else
1660 		xgi_video_info.disp_state = 0;
1661 
1662 	if (XGIfb_tvplug != -1)
1663 		/* PR/TW: Override with option */
1664 		xgi_video_info.TV_plug = XGIfb_tvplug;
1665 	else if (cr32 & XGI_VB_HIVISION) {
1666 		xgi_video_info.TV_type = TVMODE_HIVISION;
1667 		xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1668 	} else if (cr32 & XGI_VB_SVIDEO)
1669 		xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1670 	else if (cr32 & XGI_VB_COMPOSITE)
1671 		xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1672 	else if (cr32 & XGI_VB_SCART)
1673 		xgi_video_info.TV_plug = TVPLUG_SCART;
1674 
1675 	if (xgi_video_info.TV_type == 0) {
1676 		inXGIIDXREG(XGICR, 0x38, temp);
1677 		if (temp & 0x10)
1678 			xgi_video_info.TV_type = TVMODE_PAL;
1679 		else
1680 			xgi_video_info.TV_type = TVMODE_NTSC;
1681 	}
1682 
1683 	/* TW: Copy forceCRT1 option to CRT1off if option is given */
1684 	if (XGIfb_forcecrt1 != -1) {
1685 		if (XGIfb_forcecrt1)
1686 			XGIfb_crt1off = 0;
1687 		else
1688 			XGIfb_crt1off = 1;
1689 	}
1690 }
1691 
XGIfb_get_VB_type(void)1692 static void XGIfb_get_VB_type(void)
1693 {
1694 	u8 reg;
1695 
1696 	if (!XGIfb_has_VB()) {
1697 		inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
1698 		switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1699 		case XGI310_EXTERNAL_CHIP_LVDS:
1700 			xgi_video_info.hasVB = HASVB_LVDS;
1701 			break;
1702 		case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1703 			xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1704 			break;
1705 		default:
1706 			break;
1707 		}
1708 	}
1709 }
1710 
XGIfb_has_VB(void)1711 static int XGIfb_has_VB(void)
1712 {
1713 	u8 vb_chipid;
1714 
1715 	inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
1716 	switch (vb_chipid) {
1717 	case 0x01:
1718 		xgi_video_info.hasVB = HASVB_301;
1719 		break;
1720 	case 0x02:
1721 		xgi_video_info.hasVB = HASVB_302;
1722 		break;
1723 	default:
1724 		xgi_video_info.hasVB = HASVB_NONE;
1725 		return 0;
1726 	}
1727 	return 1;
1728 }
1729 
1730 /* ------------------ Sensing routines ------------------ */
1731 
1732 /* TW: Determine and detect attached devices on XGI30x */
XGIDoSense(int tempbl,int tempbh,int tempcl,int tempch)1733 int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
1734 {
1735 	int temp, i;
1736 
1737 	outXGIIDXREG(XGIPART4, 0x11, tempbl);
1738 	temp = tempbh | tempcl;
1739 	setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
1740 	for (i = 0; i < 10; i++)
1741 		XGI_LongWait(&XGI_Pr);
1742 	tempch &= 0x7f;
1743 	inXGIIDXREG(XGIPART4, 0x03, temp);
1744 	temp ^= 0x0e;
1745 	temp &= tempch;
1746 	return temp;
1747 }
1748 
XGI_Sense30x(void)1749 void XGI_Sense30x(void)
1750 {
1751 	u8 backupP4_0d;
1752 	u8 testsvhs_tempbl, testsvhs_tempbh;
1753 	u8 testsvhs_tempcl, testsvhs_tempch;
1754 	u8 testcvbs_tempbl, testcvbs_tempbh;
1755 	u8 testcvbs_tempcl, testcvbs_tempch;
1756 	u8 testvga2_tempbl, testvga2_tempbh;
1757 	u8 testvga2_tempcl, testvga2_tempch;
1758 	int myflag, result;
1759 
1760 	inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
1761 	outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
1762 
1763 	testvga2_tempbh = 0x00;
1764 	testvga2_tempbl = 0xd1;
1765 	testsvhs_tempbh = 0x00;
1766 	testsvhs_tempbl = 0xb9;
1767 	testcvbs_tempbh = 0x00;
1768 	testcvbs_tempbl = 0xb3;
1769 	if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
1770 			!= VB_CHIP_302)) {
1771 		testvga2_tempbh = 0x01;
1772 		testvga2_tempbl = 0x90;
1773 		testsvhs_tempbh = 0x01;
1774 		testsvhs_tempbl = 0x6b;
1775 		testcvbs_tempbh = 0x01;
1776 		testcvbs_tempbl = 0x74;
1777 		if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
1778 				|| XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
1779 			testvga2_tempbh = 0x00;
1780 			testvga2_tempbl = 0x00;
1781 			testsvhs_tempbh = 0x02;
1782 			testsvhs_tempbl = 0x00;
1783 			testcvbs_tempbh = 0x01;
1784 			testcvbs_tempbl = 0x00;
1785 		}
1786 	}
1787 	if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
1788 			!= VB_CHIP_302LV) {
1789 		inXGIIDXREG(XGIPART4, 0x01, myflag);
1790 		if (myflag & 0x04) {
1791 			testvga2_tempbh = 0x00;
1792 			testvga2_tempbl = 0xfd;
1793 			testsvhs_tempbh = 0x00;
1794 			testsvhs_tempbl = 0xdd;
1795 			testcvbs_tempbh = 0x00;
1796 			testcvbs_tempbl = 0xee;
1797 		}
1798 	}
1799 	if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
1800 			== VB_CHIP_302LV)) {
1801 		testvga2_tempbh = 0x00;
1802 		testvga2_tempbl = 0x00;
1803 		testvga2_tempch = 0x00;
1804 		testvga2_tempcl = 0x00;
1805 		testsvhs_tempch = 0x04;
1806 		testsvhs_tempcl = 0x08;
1807 		testcvbs_tempch = 0x08;
1808 		testcvbs_tempcl = 0x08;
1809 	} else {
1810 		testvga2_tempch = 0x0e;
1811 		testvga2_tempcl = 0x08;
1812 		testsvhs_tempch = 0x06;
1813 		testsvhs_tempcl = 0x04;
1814 		testcvbs_tempch = 0x08;
1815 		testcvbs_tempcl = 0x04;
1816 	}
1817 
1818 	if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
1819 			|| testvga2_tempbl) {
1820 		result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
1821 				testvga2_tempcl, testvga2_tempch);
1822 		if (result) {
1823 			printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
1824 			orXGIIDXREG(XGICR, 0x32, 0x10);
1825 		}
1826 	}
1827 
1828 	result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
1829 			testsvhs_tempch);
1830 	if (result) {
1831 		printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
1832 		/* TW: So we can be sure that there IS a SVHS output */
1833 		xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1834 		orXGIIDXREG(XGICR, 0x32, 0x02);
1835 	}
1836 
1837 	if (!result) {
1838 		result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
1839 				testcvbs_tempcl, testcvbs_tempch);
1840 		if (result) {
1841 			printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
1842 			/* TW: So we can be sure that there IS a CVBS output */
1843 			xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1844 			orXGIIDXREG(XGICR, 0x32, 0x01);
1845 		}
1846 	}
1847 	XGIDoSense(0, 0, 0, 0);
1848 
1849 	outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
1850 }
1851 
1852 /* --------------------- SetMode routines ------------------------- */
1853 
XGIfb_pre_setmode(void)1854 static void XGIfb_pre_setmode(void)
1855 {
1856 	u8 cr30 = 0, cr31 = 0;
1857 
1858 	inXGIIDXREG(XGICR, 0x31, cr31);
1859 	cr31 &= ~0x60;
1860 
1861 	switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1862 	case DISPTYPE_CRT2:
1863 		cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1864 		cr31 |= XGI_DRIVER_MODE;
1865 		break;
1866 	case DISPTYPE_LCD:
1867 		cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
1868 		cr31 |= XGI_DRIVER_MODE;
1869 		break;
1870 	case DISPTYPE_TV:
1871 		if (xgi_video_info.TV_type == TVMODE_HIVISION)
1872 			cr30 = (XGI_VB_OUTPUT_HIVISION
1873 					| XGI_SIMULTANEOUS_VIEW_ENABLE);
1874 		else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
1875 			cr30 = (XGI_VB_OUTPUT_SVIDEO
1876 					| XGI_SIMULTANEOUS_VIEW_ENABLE);
1877 		else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
1878 			cr30 = (XGI_VB_OUTPUT_COMPOSITE
1879 					| XGI_SIMULTANEOUS_VIEW_ENABLE);
1880 		else if (xgi_video_info.TV_plug == TVPLUG_SCART)
1881 			cr30 = (XGI_VB_OUTPUT_SCART
1882 					| XGI_SIMULTANEOUS_VIEW_ENABLE);
1883 		cr31 |= XGI_DRIVER_MODE;
1884 
1885 		if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
1886 			cr31 |= 0x01;
1887 		else
1888 			cr31 &= ~0x01;
1889 		break;
1890 	default: /* disable CRT2 */
1891 		cr30 = 0x00;
1892 		cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
1893 	}
1894 
1895 	outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
1896 	outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
1897 	outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
1898 }
1899 
XGIfb_post_setmode(void)1900 static void XGIfb_post_setmode(void)
1901 {
1902 	u8 reg;
1903 	unsigned char doit = 1;
1904 	/*
1905 	outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
1906 	outXGIIDXREG(XGICR, 0x13, 0x00);
1907 	setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
1908 	*test*
1909 	*/
1910 	if (xgi_video_info.video_bpp == 8) {
1911 		/* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
1912 		if ((xgi_video_info.hasVB == HASVB_LVDS)
1913 				|| (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
1914 			doit = 0;
1915 		}
1916 		/* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
1917 		if (xgi_video_info.disp_state & DISPTYPE_LCD)
1918 			doit = 0;
1919 	}
1920 
1921 	/* TW: We can't switch off CRT1 if bridge is in slave mode */
1922 	if (xgi_video_info.hasVB != HASVB_NONE) {
1923 		inXGIIDXREG(XGIPART1, 0x00, reg);
1924 
1925 		if ((reg & 0x50) == 0x10)
1926 			doit = 0;
1927 
1928 	} else {
1929 		XGIfb_crt1off = 0;
1930 	}
1931 
1932 	inXGIIDXREG(XGICR, 0x17, reg);
1933 	if ((XGIfb_crt1off) && (doit))
1934 		reg &= ~0x80;
1935 	else
1936 		reg |= 0x80;
1937 	outXGIIDXREG(XGICR, 0x17, reg);
1938 
1939 	andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1940 
1941 	if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1942 			== HASVB_301)) {
1943 
1944 		inXGIIDXREG(XGIPART4, 0x01, reg);
1945 
1946 		if (reg < 0xB0) { /* Set filter for XGI301 */
1947 
1948 			switch (xgi_video_info.video_width) {
1949 			case 320:
1950 				filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
1951 				break;
1952 			case 640:
1953 				filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
1954 				break;
1955 			case 720:
1956 				filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
1957 				break;
1958 			case 800:
1959 				filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
1960 				break;
1961 			default:
1962 				filter = -1;
1963 				break;
1964 			}
1965 
1966 			orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1967 
1968 			if (xgi_video_info.TV_type == TVMODE_NTSC) {
1969 
1970 				andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
1971 
1972 				if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1973 
1974 					andXGIIDXREG(XGIPART2, 0x30, 0xdf);
1975 
1976 				} else if (xgi_video_info.TV_plug
1977 						== TVPLUG_COMPOSITE) {
1978 
1979 					orXGIIDXREG(XGIPART2, 0x30, 0x20);
1980 
1981 					switch (xgi_video_info.video_width) {
1982 					case 640:
1983 						outXGIIDXREG(XGIPART2, 0x35, 0xEB);
1984 						outXGIIDXREG(XGIPART2, 0x36, 0x04);
1985 						outXGIIDXREG(XGIPART2, 0x37, 0x25);
1986 						outXGIIDXREG(XGIPART2, 0x38, 0x18);
1987 						break;
1988 					case 720:
1989 						outXGIIDXREG(XGIPART2, 0x35, 0xEE);
1990 						outXGIIDXREG(XGIPART2, 0x36, 0x0C);
1991 						outXGIIDXREG(XGIPART2, 0x37, 0x22);
1992 						outXGIIDXREG(XGIPART2, 0x38, 0x08);
1993 						break;
1994 					case 800:
1995 						outXGIIDXREG(XGIPART2, 0x35, 0xEB);
1996 						outXGIIDXREG(XGIPART2, 0x36, 0x15);
1997 						outXGIIDXREG(XGIPART2, 0x37, 0x25);
1998 						outXGIIDXREG(XGIPART2, 0x38, 0xF6);
1999 						break;
2000 					}
2001 				}
2002 
2003 			} else if (xgi_video_info.TV_type == TVMODE_PAL) {
2004 
2005 				andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2006 
2007 				if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2008 
2009 					andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2010 
2011 				} else if (xgi_video_info.TV_plug
2012 						== TVPLUG_COMPOSITE) {
2013 
2014 					orXGIIDXREG(XGIPART2, 0x30, 0x20);
2015 
2016 					switch (xgi_video_info.video_width) {
2017 					case 640:
2018 						outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2019 						outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2020 						outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2021 						outXGIIDXREG(XGIPART2, 0x38, 0x32);
2022 						break;
2023 					case 720:
2024 						outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2025 						outXGIIDXREG(XGIPART2, 0x36, 0x00);
2026 						outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2027 						outXGIIDXREG(XGIPART2, 0x38, 0x20);
2028 						break;
2029 					case 800:
2030 						outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2031 						outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2032 						outXGIIDXREG(XGIPART2, 0x37, 0x14);
2033 						outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2034 						break;
2035 					}
2036 				}
2037 			}
2038 
2039 			if ((filter >= 0) && (filter <= 7)) {
2040 				DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2041 						XGI_TV_filter[filter_tb].filter[filter][0],
2042 						XGI_TV_filter[filter_tb].filter[filter][1],
2043 						XGI_TV_filter[filter_tb].filter[filter][2],
2044 						XGI_TV_filter[filter_tb].filter[filter][3]
2045 				);
2046 				outXGIIDXREG(
2047 						XGIPART2,
2048 						0x35,
2049 						(XGI_TV_filter[filter_tb].filter[filter][0]));
2050 				outXGIIDXREG(
2051 						XGIPART2,
2052 						0x36,
2053 						(XGI_TV_filter[filter_tb].filter[filter][1]));
2054 				outXGIIDXREG(
2055 						XGIPART2,
2056 						0x37,
2057 						(XGI_TV_filter[filter_tb].filter[filter][2]));
2058 				outXGIIDXREG(
2059 						XGIPART2,
2060 						0x38,
2061 						(XGI_TV_filter[filter_tb].filter[filter][3]));
2062 			}
2063 
2064 		}
2065 
2066 	}
2067 
2068 }
2069 
XGIfb_setup(char * options)2070 XGIINITSTATIC int __init XGIfb_setup(char *options)
2071 {
2072 	char *this_opt;
2073 
2074 	xgi_video_info.refresh_rate = 0;
2075 
2076 	printk(KERN_INFO "XGIfb: Options %s\n", options);
2077 
2078 	if (!options || !*options)
2079 		return 0;
2080 
2081 	while ((this_opt = strsep(&options, ",")) != NULL) {
2082 
2083 		if (!*this_opt)
2084 			continue;
2085 
2086 		if (!strncmp(this_opt, "mode:", 5)) {
2087 			XGIfb_search_mode(this_opt + 5);
2088 		} else if (!strncmp(this_opt, "vesa:", 5)) {
2089 			XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2090 		} else if (!strncmp(this_opt, "mode:", 5)) {
2091 			XGIfb_search_mode(this_opt + 5);
2092 		} else if (!strncmp(this_opt, "vesa:", 5)) {
2093 			XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2094 		} else if (!strncmp(this_opt, "vrate:", 6)) {
2095 			xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2096 		} else if (!strncmp(this_opt, "rate:", 5)) {
2097 			xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2098 		} else if (!strncmp(this_opt, "off", 3)) {
2099 			XGIfb_off = 1;
2100 		} else if (!strncmp(this_opt, "crt1off", 7)) {
2101 			XGIfb_crt1off = 1;
2102 		} else if (!strncmp(this_opt, "filter:", 7)) {
2103 			filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2104 		} else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2105 			XGIfb_search_crt2type(this_opt + 14);
2106 		} else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2107 			XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
2108 		} else if (!strncmp(this_opt, "tvmode:", 7)) {
2109 			XGIfb_search_tvstd(this_opt + 7);
2110 		} else if (!strncmp(this_opt, "tvstandard:", 11)) {
2111 			XGIfb_search_tvstd(this_opt + 7);
2112 		} else if (!strncmp(this_opt, "dstn", 4)) {
2113 			enable_dstn = 1;
2114 			/* TW: DSTN overrules forcecrt2type */
2115 			XGIfb_crt2type = DISPTYPE_LCD;
2116 		} else if (!strncmp(this_opt, "pdc:", 4)) {
2117 			XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2118 			if (XGIfb_pdc & ~0x3c) {
2119 				printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2120 				XGIfb_pdc = 0;
2121 			}
2122 		} else if (!strncmp(this_opt, "noypan", 6)) {
2123 			XGIfb_ypan = 0;
2124 		} else if (!strncmp(this_opt, "userom:", 7)) {
2125 			XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
2126 			/* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2127 			/* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
2128 		} else {
2129 			XGIfb_search_mode(this_opt);
2130 			/* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
2131 		}
2132 
2133 		/* TW: Panning only with acceleration */
2134 		XGIfb_ypan = 0;
2135 
2136 	}
2137 	printk("\nxgifb: outa xgifb_setup 3450");
2138 	return 0;
2139 }
2140 
xgifb_copy_rom(struct pci_dev * dev)2141 static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
2142 {
2143 	void __iomem *rom_address;
2144 	unsigned char *rom_copy;
2145 	size_t rom_size;
2146 
2147 	rom_address = pci_map_rom(dev, &rom_size);
2148 	if (rom_address == NULL)
2149 		return NULL;
2150 
2151 	rom_copy = vzalloc(XGIFB_ROM_SIZE);
2152 	if (rom_copy == NULL)
2153 		goto done;
2154 
2155 	rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2156 	memcpy_fromio(rom_copy, rom_address, rom_size);
2157 
2158 done:
2159 	pci_unmap_rom(dev, rom_address);
2160 	return rom_copy;
2161 }
2162 
xgifb_probe(struct pci_dev * pdev,const struct pci_device_id * ent)2163 static int __devinit xgifb_probe(struct pci_dev *pdev,
2164 		const struct pci_device_id *ent)
2165 {
2166 	u8 reg, reg1;
2167 	u8 CR48, CR38;
2168 	int ret;
2169 
2170 	if (XGIfb_off)
2171 		return -ENXIO;
2172 
2173 	XGIfb_registered = 0;
2174 
2175 	memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2176 	fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2177 	if (!fb_info)
2178 		return -ENOMEM;
2179 
2180 	xgi_video_info.chip_id = pdev->device;
2181 	pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
2182 	XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2183 
2184 	xgi_video_info.pcibus = pdev->bus->number;
2185 	xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2186 	xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2187 	xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2188 	xgi_video_info.subsysdevice = pdev->subsystem_device;
2189 
2190 	xgi_video_info.video_base = pci_resource_start(pdev, 0);
2191 	xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2192 	xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
2193 	xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2194 	XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2195 	/* XGI_Pr.RelIO  = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2196 	printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2197 			(unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2198 
2199 	if (pci_enable_device(pdev)) {
2200 		ret = -EIO;
2201 		goto error;
2202 	}
2203 
2204 	XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2205 
2206 	outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2207 	inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
2208 
2209 	if (reg1 != 0xa1) { /*I/O error */
2210 		printk("\nXGIfb: I/O error!!!");
2211 		ret = -EIO;
2212 		goto error;
2213 	}
2214 
2215 	switch (xgi_video_info.chip_id) {
2216 	case PCI_DEVICE_ID_XG_20:
2217 		orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2218 		inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
2219 		if (CR48&GPIOG_READ)
2220 			xgi_video_info.chip = XG21;
2221 		else
2222 			xgi_video_info.chip = XG20;
2223 		XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2224 		break;
2225 	case PCI_DEVICE_ID_XG_40:
2226 		xgi_video_info.chip = XG40;
2227 		XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2228 		break;
2229 	case PCI_DEVICE_ID_XG_41:
2230 		xgi_video_info.chip = XG41;
2231 		XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2232 		break;
2233 	case PCI_DEVICE_ID_XG_42:
2234 		xgi_video_info.chip = XG42;
2235 		XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2236 		break;
2237 	case PCI_DEVICE_ID_XG_27:
2238 		xgi_video_info.chip = XG27;
2239 		XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2240 		break;
2241 	default:
2242 		ret = -ENODEV;
2243 		goto error;
2244 	}
2245 
2246 	printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2247 	XGIhw_ext.jChipType = xgi_video_info.chip;
2248 
2249 	if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
2250 		XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
2251 		if (XGIhw_ext.pjVirtualRomBase)
2252 			printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
2253 		else
2254 			printk(KERN_INFO "XGIfb: Video ROM not found\n");
2255 	} else {
2256 		XGIhw_ext.pjVirtualRomBase = NULL;
2257 		printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
2258 	}
2259 	XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
2260 
2261 	if (XGIfb_get_dram_size()) {
2262 		printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
2263 		ret = -ENODEV;
2264 		goto error;
2265 	}
2266 
2267 	if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2268 		/* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
2269 		orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2270 		/* Enable 2D accelerator engine */
2271 		orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
2272 	}
2273 
2274 	XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2275 
2276 	if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
2277 		printk("unable request memory size %x", xgi_video_info.video_size);
2278 		printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2279 		printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
2280 		ret = -ENODEV;
2281 		goto error;
2282 	}
2283 
2284 	if (!request_mem_region(xgi_video_info.mmio_base,
2285 				xgi_video_info.mmio_size,
2286 				"XGIfb MMIO")) {
2287 		printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
2288 		ret = -ENODEV;
2289 		goto error_0;
2290 	}
2291 
2292 	xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2293 	ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
2294 	xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2295 					    xgi_video_info.mmio_size);
2296 
2297 	printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2298 			xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
2299 
2300 	printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
2301 	       xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2302 	       xgi_video_info.mmio_size / 1024);
2303 	printk("XGIfb: XGIInitNew() ...");
2304 	if (XGIInitNew(&XGIhw_ext))
2305 		printk("OK\n");
2306 	else
2307 		printk("Fail\n");
2308 
2309 	xgi_video_info.mtrr = (unsigned int) 0;
2310 
2311 	if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2312 		xgi_video_info.hasVB = HASVB_NONE;
2313 		if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
2314 			xgi_video_info.hasVB = HASVB_NONE;
2315 		} else if (xgi_video_info.chip == XG21) {
2316 			inXGIIDXREG(XGICR, 0x38, CR38);
2317 			if ((CR38&0xE0) == 0xC0) {
2318 				xgi_video_info.disp_state = DISPTYPE_LCD;
2319 				if (!XGIfb_GetXG21LVDSData()) {
2320 					int m;
2321 					for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2322 						if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2323 								(XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
2324 							xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
2325 						}
2326 					}
2327 				}
2328 			} else if ((CR38&0xE0) == 0x60) {
2329 				xgi_video_info.hasVB = HASVB_CHRONTEL;
2330 			} else {
2331 				xgi_video_info.hasVB = HASVB_NONE;
2332 			}
2333 		} else {
2334 			XGIfb_get_VB_type();
2335 		}
2336 
2337 		XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
2338 
2339 		XGIhw_ext.ulExternalChip = 0;
2340 
2341 		switch (xgi_video_info.hasVB) {
2342 		case HASVB_301:
2343 			inXGIIDXREG(XGIPART4, 0x01, reg);
2344 			if (reg >= 0xE0) {
2345 				XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2346 				printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2347 			} else if (reg >= 0xD0) {
2348 				XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2349 				printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2350 			}
2351 			/* else if (reg >= 0xB0) {
2352 				XGIhw_ext.ujVBChipID = VB_CHIP_301B;
2353 				inXGIIDXREG(XGIPART4, 0x23, reg1);
2354 				printk("XGIfb: XGI301B bridge detected\n");
2355 			} */
2356 			else {
2357 				XGIhw_ext.ujVBChipID = VB_CHIP_301;
2358 				printk("XGIfb: XGI301 bridge detected\n");
2359 			}
2360 			break;
2361 		case HASVB_302:
2362 			inXGIIDXREG(XGIPART4, 0x01, reg);
2363 			if (reg >= 0xE0) {
2364 				XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2365 				printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2366 			} else if (reg >= 0xD0) {
2367 				XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2368 				printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2369 			} else if (reg >= 0xB0) {
2370 				inXGIIDXREG(XGIPART4, 0x23, reg1);
2371 
2372 				XGIhw_ext.ujVBChipID = VB_CHIP_302B;
2373 
2374 			} else {
2375 				XGIhw_ext.ujVBChipID = VB_CHIP_302;
2376 				printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2377 			}
2378 			break;
2379 		case HASVB_LVDS:
2380 			XGIhw_ext.ulExternalChip = 0x1;
2381 			printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2382 			break;
2383 		case HASVB_TRUMPION:
2384 			XGIhw_ext.ulExternalChip = 0x2;
2385 			printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2386 			break;
2387 		case HASVB_CHRONTEL:
2388 			XGIhw_ext.ulExternalChip = 0x4;
2389 			printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2390 			break;
2391 		case HASVB_LVDS_CHRONTEL:
2392 			XGIhw_ext.ulExternalChip = 0x5;
2393 			printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2394 			break;
2395 		default:
2396 			printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2397 			break;
2398 		}
2399 
2400 		if (xgi_video_info.hasVB != HASVB_NONE)
2401 			XGIfb_detect_VB();
2402 
2403 		if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2404 			if (XGIfb_crt1off)
2405 				xgi_video_info.disp_state |= DISPMODE_SINGLE;
2406 			else
2407 				xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
2408 		} else {
2409 			xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
2410 		}
2411 
2412 		if (xgi_video_info.disp_state & DISPTYPE_LCD) {
2413 			if (!enable_dstn) {
2414 				inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
2415 				reg &= 0x0f;
2416 				XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
2417 
2418 			} else {
2419 				/* TW: FSTN/DSTN */
2420 				XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2421 			}
2422 		}
2423 
2424 		XGIfb_detectedpdc = 0;
2425 
2426 		XGIfb_detectedlcda = 0xff;
2427 
2428 		/* TW: Try to find about LCDA */
2429 
2430 		if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2431 				(XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2432 				(XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2433 			int tmp;
2434 			inXGIIDXREG(XGICR, 0x34, tmp);
2435 			if (tmp <= 0x13) {
2436 				/* Currently on LCDA? (Some BIOSes leave CR38) */
2437 				inXGIIDXREG(XGICR, 0x38, tmp);
2438 				if ((tmp & 0x03) == 0x03) {
2439 					/* XGI_Pr.XGI_UseLCDA = 1; */
2440 				} else {
2441 					/* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
2442 					inXGIIDXREG(XGICR, 0x35, tmp);
2443 					if (tmp & 0x01) {
2444 						/* XGI_Pr.XGI_UseLCDA = 1; */
2445 					} else {
2446 						inXGIIDXREG(XGICR, 0x30, tmp);
2447 						if (tmp & 0x20) {
2448 							inXGIIDXREG(XGIPART1, 0x13, tmp);
2449 							if (tmp & 0x04) {
2450 								/* XGI_Pr.XGI_UseLCDA = 1; */
2451 							}
2452 						}
2453 					}
2454 				}
2455 			}
2456 
2457 		}
2458 
2459 		if (xgifb_mode_idx >= 0)
2460 			xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2461 
2462 		if (xgifb_mode_idx < 0) {
2463 			switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2464 			case DISPTYPE_LCD:
2465 				xgifb_mode_idx = DEFAULT_LCDMODE;
2466 				if (xgi_video_info.chip == XG21)
2467 					xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
2468 				break;
2469 			case DISPTYPE_TV:
2470 				xgifb_mode_idx = DEFAULT_TVMODE;
2471 				break;
2472 			default:
2473 				xgifb_mode_idx = DEFAULT_MODE;
2474 				break;
2475 			}
2476 		}
2477 
2478 		XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2479 
2480 		if (xgi_video_info.refresh_rate == 0)
2481 			xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
2482 		if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
2483 			XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2484 			xgi_video_info.refresh_rate = 60;
2485 		}
2486 
2487 		xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2488 		xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
2489 		xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
2490 		xgi_video_info.org_x = xgi_video_info.org_y = 0;
2491 		xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
2492 		switch (xgi_video_info.video_bpp) {
2493 		case 8:
2494 			xgi_video_info.DstColor = 0x0000;
2495 			xgi_video_info.XGI310_AccelDepth = 0x00000000;
2496 			xgi_video_info.video_cmap_len = 256;
2497 			break;
2498 		case 16:
2499 			xgi_video_info.DstColor = 0x8000;
2500 			xgi_video_info.XGI310_AccelDepth = 0x00010000;
2501 			xgi_video_info.video_cmap_len = 16;
2502 			break;
2503 		case 32:
2504 			xgi_video_info.DstColor = 0xC000;
2505 			xgi_video_info.XGI310_AccelDepth = 0x00020000;
2506 			xgi_video_info.video_cmap_len = 16;
2507 			break;
2508 		default:
2509 			xgi_video_info.video_cmap_len = 16;
2510 			printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
2511 			break;
2512 		}
2513 
2514 		printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
2515 				xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
2516 				xgi_video_info.refresh_rate);
2517 
2518 		default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
2519 		default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
2520 		default_var.bits_per_pixel = xgi_video_info.video_bpp;
2521 
2522 		XGIfb_bpp_to_var(&default_var);
2523 
2524 		default_var.pixclock = (u32) (1000000000 /
2525 				XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2526 						XGIfb_mode_no, XGIfb_rate_idx));
2527 
2528 		if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2529 			XGIfb_mode_no, XGIfb_rate_idx,
2530 			&default_var.left_margin, &default_var.right_margin,
2531 			&default_var.upper_margin, &default_var.lower_margin,
2532 			&default_var.hsync_len, &default_var.vsync_len,
2533 			&default_var.sync, &default_var.vmode)) {
2534 
2535 			if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
2536 				default_var.yres <<= 1;
2537 				default_var.yres_virtual <<= 1;
2538 			} else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
2539 				default_var.pixclock >>= 1;
2540 				default_var.yres >>= 1;
2541 				default_var.yres_virtual >>= 1;
2542 			}
2543 
2544 		}
2545 
2546 		fb_info->flags = FBINFO_FLAG_DEFAULT;
2547 		fb_info->var = default_var;
2548 		fb_info->fix = XGIfb_fix;
2549 		fb_info->par = &xgi_video_info;
2550 		fb_info->screen_base = xgi_video_info.video_vbase;
2551 		fb_info->fbops = &XGIfb_ops;
2552 		XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2553 		fb_info->pseudo_palette = pseudo_palette;
2554 
2555 		fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2556 
2557 #ifdef CONFIG_MTRR
2558 		xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
2559 				(unsigned int) xgi_video_info.video_size,
2560 				MTRR_TYPE_WRCOMB, 1);
2561 		if (xgi_video_info.mtrr)
2562 			printk(KERN_INFO "XGIfb: Added MTRRs\n");
2563 #endif
2564 
2565 		if (register_framebuffer(fb_info) < 0) {
2566 			ret = -EINVAL;
2567 			goto error_1;
2568 		}
2569 
2570 		XGIfb_registered = 1;
2571 
2572 		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
2573 				fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
2574 
2575 	}
2576 
2577 	dumpVGAReg();
2578 
2579 	return 0;
2580 
2581 error_1:
2582 	iounmap(xgi_video_info.mmio_vbase);
2583 	iounmap(xgi_video_info.video_vbase);
2584 	release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2585 error_0:
2586 	release_mem_region(xgi_video_info.video_base,
2587 			   xgi_video_info.video_size);
2588 error:
2589 	vfree(XGIhw_ext.pjVirtualRomBase);
2590 	framebuffer_release(fb_info);
2591 	return ret;
2592 }
2593 
2594 /*****************************************************/
2595 /*                PCI DEVICE HANDLING                */
2596 /*****************************************************/
2597 
xgifb_remove(struct pci_dev * pdev)2598 static void __devexit xgifb_remove(struct pci_dev *pdev)
2599 {
2600 	unregister_framebuffer(fb_info);
2601 	iounmap(xgi_video_info.mmio_vbase);
2602 	iounmap(xgi_video_info.video_vbase);
2603 	release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2604 	release_mem_region(xgi_video_info.video_base,
2605 			   xgi_video_info.video_size);
2606 	vfree(XGIhw_ext.pjVirtualRomBase);
2607 	framebuffer_release(fb_info);
2608 	pci_set_drvdata(pdev, NULL);
2609 }
2610 
2611 static struct pci_driver xgifb_driver = {
2612 	.name = "xgifb",
2613 	.id_table = xgifb_pci_table,
2614 	.probe = xgifb_probe,
2615 	.remove = __devexit_p(xgifb_remove)
2616 };
2617 
xgifb_init(void)2618 XGIINITSTATIC int __init xgifb_init(void)
2619 {
2620 	char *option = NULL;
2621 
2622 	if (fb_get_options("xgifb", &option))
2623 		return -ENODEV;
2624 	XGIfb_setup(option);
2625 
2626 	return pci_register_driver(&xgifb_driver);
2627 }
2628 
2629 #ifndef MODULE
2630 module_init(xgifb_init);
2631 #endif
2632 
2633 /*****************************************************/
2634 /*                      MODULE                       */
2635 /*****************************************************/
2636 
2637 #ifdef MODULE
2638 
2639 static char *mode = NULL;
2640 static int vesa = 0;
2641 static unsigned int rate = 0;
2642 static unsigned int mem = 0;
2643 static char *forcecrt2type = NULL;
2644 static int forcecrt1 = -1;
2645 static int pdc = -1;
2646 static int pdc1 = -1;
2647 static int noypan = -1;
2648 static int userom = -1;
2649 static int useoem = -1;
2650 static char *tvstandard = NULL;
2651 static int nocrt2rate = 0;
2652 static int scalelcd = -1;
2653 static char *specialtiming = NULL;
2654 static int lvdshl = -1;
2655 static int tvxposoffset = 0, tvyposoffset = 0;
2656 #if !defined(__i386__) && !defined(__x86_64__)
2657 static int resetcard = 0;
2658 static int videoram = 0;
2659 #endif
2660 
2661 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2662 MODULE_LICENSE("GPL");
2663 MODULE_AUTHOR("XGITECH , Others");
2664 
2665 module_param(mem, int, 0);
2666 module_param(noypan, int, 0);
2667 module_param(userom, int, 0);
2668 module_param(useoem, int, 0);
2669 module_param(mode, charp, 0);
2670 module_param(vesa, int, 0);
2671 module_param(rate, int, 0);
2672 module_param(forcecrt1, int, 0);
2673 module_param(forcecrt2type, charp, 0);
2674 module_param(scalelcd, int, 0);
2675 module_param(pdc, int, 0);
2676 module_param(pdc1, int, 0);
2677 module_param(specialtiming, charp, 0);
2678 module_param(lvdshl, int, 0);
2679 module_param(tvstandard, charp, 0);
2680 module_param(tvxposoffset, int, 0);
2681 module_param(tvyposoffset, int, 0);
2682 module_param(filter, int, 0);
2683 module_param(nocrt2rate, int, 0);
2684 #if !defined(__i386__) && !defined(__x86_64__)
2685 module_param(resetcard, int, 0);
2686 module_param(videoram, int, 0);
2687 #endif
2688 
2689 MODULE_PARM_DESC(noypan,
2690 		"\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2691 		"will be performed by redrawing the screen. (default: 0)\n");
2692 
2693 MODULE_PARM_DESC(mode,
2694 		"\nSelects the desired default display mode in the format XxYxDepth,\n"
2695 		"eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2696 		"XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2697 		"number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
2698 
2699 MODULE_PARM_DESC(vesa,
2700 		"\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2701 		"0x117 (default: 0x0103)\n");
2702 
2703 MODULE_PARM_DESC(rate,
2704 		"\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2705 		"If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2706 		"will be ignored (default: 60)\n");
2707 
2708 MODULE_PARM_DESC(forcecrt1,
2709 		"\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2710 		"connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2711 		"0=CRT1 OFF) (default: [autodetected])\n");
2712 
2713 MODULE_PARM_DESC(forcecrt2type,
2714 		"\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2715 		"LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2716 		"overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2717 		"On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2718 		"be used instead of TV to override the TV detection. Furthermore, on systems\n"
2719 		"with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2720 		"YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2721 		"depends on the very hardware in use. (default: [autodetected])\n");
2722 
2723 MODULE_PARM_DESC(scalelcd,
2724 		"\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2725 		"native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2726 		"show black bars around the image, TMDS panels will probably do the scaling\n"
2727 		"themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
2728 
2729 MODULE_PARM_DESC(pdc,
2730 		"\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2731 		"should detect this correctly in most cases; however, sometimes this is not\n"
2732 		"possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2733 		"on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2734 		"try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2735 		"any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
2736 
2737 MODULE_PARM_DESC(pdc1,
2738 		"\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2739 		"series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2740 		"startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2741 		"implemented yet.\n");
2742 
2743 MODULE_PARM_DESC(specialtiming,
2744 		"\nPlease refer to documentation for more information on this option.\n");
2745 
2746 MODULE_PARM_DESC(lvdshl,
2747 		"\nPlease refer to documentation for more information on this option.\n");
2748 
2749 MODULE_PARM_DESC(tvstandard,
2750 		"\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2751 		"pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
2752 
2753 MODULE_PARM_DESC(tvxposoffset,
2754 		"\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2755 		"Default: 0\n");
2756 
2757 MODULE_PARM_DESC(tvyposoffset,
2758 		"\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2759 		"Default: 0\n");
2760 
2761 MODULE_PARM_DESC(filter,
2762 		"\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2763 		"(Possible values 0-7, default: [no filter])\n");
2764 
2765 MODULE_PARM_DESC(nocrt2rate,
2766 		"\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2767 		"CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
2768 
xgifb_init_module(void)2769 static int __init xgifb_init_module(void)
2770 {
2771 	printk("\nXGIfb_init_module");
2772 	if (mode)
2773 		XGIfb_search_mode(mode);
2774 	else if (vesa != -1)
2775 		XGIfb_search_vesamode(vesa);
2776 
2777 	return xgifb_init();
2778 }
2779 
xgifb_remove_module(void)2780 static void __exit xgifb_remove_module(void)
2781 {
2782 	pci_unregister_driver(&xgifb_driver);
2783 	printk(KERN_DEBUG "xgifb: Module unloaded\n");
2784 }
2785 
2786 module_init(xgifb_init_module);
2787 module_exit(xgifb_remove_module);
2788 
2789 #endif	/*  /MODULE  */
2790