[go: nahoru, domu]

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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
9#include <linux/sizes.h>
10#include <linux/module.h>
11
12#ifdef CONFIG_MTRR
13#include <asm/mtrr.h>
14#endif
15
16#include "XGI_main.h"
17#include "vb_init.h"
18#include "vb_util.h"
19#include "vb_setmode.h"
20
21#define Index_CR_GPIO_Reg1 0x48
22#define Index_CR_GPIO_Reg3 0x4a
23
24#define GPIOG_EN    (1<<6)
25#define GPIOG_READ  (1<<1)
26
27static char *forcecrt2type;
28static char *mode;
29static int vesa = -1;
30static unsigned int refresh_rate;
31
32/* -------------------- Macro definitions ---------------------------- */
33
34#ifdef DEBUG
35static void dumpVGAReg(void)
36{
37	u8 i, reg;
38
39	xgifb_reg_set(XGISR, 0x05, 0x86);
40
41	for (i = 0; i < 0x4f; i++) {
42		reg = xgifb_reg_get(XGISR, i);
43		pr_debug("o 3c4 %x\n", i);
44		pr_debug("i 3c5 => %x\n", reg);
45	}
46
47	for (i = 0; i < 0xF0; i++) {
48		reg = xgifb_reg_get(XGICR, i);
49		pr_debug("o 3d4 %x\n", i);
50		pr_debug("i 3d5 => %x\n", reg);
51	}
52}
53#else
54static inline void dumpVGAReg(void)
55{
56}
57#endif
58
59/* --------------- Hardware Access Routines -------------------------- */
60
61static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
62		struct xgi_hw_device_info *HwDeviceExtension,
63		unsigned char modeno)
64{
65	unsigned short ModeNo = modeno;
66	unsigned short ModeIdIndex = 0, ClockIndex = 0;
67	unsigned short RefreshRateTableIndex = 0;
68	int Clock;
69
70	InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
71
72	XGI_SearchModeID(ModeNo, &ModeIdIndex);
73
74	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
75			ModeIdIndex, XGI_Pr);
76
77	ClockIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
78
79	Clock = XGI_VCLKData[ClockIndex].CLOCK * 1000;
80
81	return Clock;
82}
83
84static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
85		struct xgi_hw_device_info *HwDeviceExtension,
86		unsigned char modeno,
87		u32 *left_margin, u32 *right_margin, u32 *upper_margin,
88		u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
89		u32 *vmode)
90{
91	unsigned short ModeNo = modeno;
92	unsigned short ModeIdIndex, index = 0;
93	unsigned short RefreshRateTableIndex = 0;
94
95	unsigned short VRE, VBE, VRS, VDE;
96	unsigned short HRE, HBE, HRS, HDE;
97	unsigned char sr_data, cr_data, cr_data2;
98	int B, C, D, F, temp, j;
99
100	InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
101	if (!XGI_SearchModeID(ModeNo, &ModeIdIndex))
102		return 0;
103	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
104			ModeIdIndex, XGI_Pr);
105	index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
106
107	sr_data = XGI_CRT1Table[index].CR[5];
108
109	HDE = (XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3);
110
111	cr_data = XGI_CRT1Table[index].CR[3];
112
113	/* Horizontal retrace (=sync) start */
114	HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
115	F = HRS - HDE - 3;
116
117	sr_data = XGI_CRT1Table[index].CR[6];
118
119	cr_data = XGI_CRT1Table[index].CR[2];
120
121	cr_data2 = XGI_CRT1Table[index].CR[4];
122
123	/* Horizontal blank end */
124	HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
125			| ((unsigned short) (sr_data & 0x03) << 6);
126
127	/* Horizontal retrace (=sync) end */
128	HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
129
130	temp = HBE - ((HDE - 1) & 255);
131	B = (temp > 0) ? temp : (temp + 256);
132
133	temp = HRE - ((HDE + F + 3) & 63);
134	C = (temp > 0) ? temp : (temp + 64);
135
136	D = B - F - C;
137
138	*left_margin = D * 8;
139	*right_margin = F * 8;
140	*hsync_len = C * 8;
141
142	sr_data = XGI_CRT1Table[index].CR[14];
143
144	cr_data2 = XGI_CRT1Table[index].CR[9];
145
146	VDE = XGI330_RefIndex[RefreshRateTableIndex].YRes;
147
148	cr_data = XGI_CRT1Table[index].CR[10];
149
150	/* Vertical retrace (=sync) start */
151	VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
152			| ((unsigned short) (cr_data2 & 0x80) << 2)
153			| ((unsigned short) (sr_data & 0x08) << 7);
154	F = VRS + 1 - VDE;
155
156	cr_data = XGI_CRT1Table[index].CR[13];
157
158	/* Vertical blank end */
159	VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
160	temp = VBE - ((VDE - 1) & 511);
161	B = (temp > 0) ? temp : (temp + 512);
162
163	cr_data = XGI_CRT1Table[index].CR[11];
164
165	/* Vertical retrace (=sync) end */
166	VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
167	temp = VRE - ((VDE + F - 1) & 31);
168	C = (temp > 0) ? temp : (temp + 32);
169
170	D = B - F - C;
171
172	*upper_margin = D;
173	*lower_margin = F;
174	*vsync_len = C;
175
176	if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
177		*sync &= ~FB_SYNC_VERT_HIGH_ACT;
178	else
179		*sync |= FB_SYNC_VERT_HIGH_ACT;
180
181	if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
182		*sync &= ~FB_SYNC_HOR_HIGH_ACT;
183	else
184		*sync |= FB_SYNC_HOR_HIGH_ACT;
185
186	*vmode = FB_VMODE_NONINTERLACED;
187	if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
188		*vmode = FB_VMODE_INTERLACED;
189	else {
190		j = 0;
191		while (XGI330_EModeIDTable[j].Ext_ModeID != 0xff) {
192			if (XGI330_EModeIDTable[j].Ext_ModeID ==
193			    XGI330_RefIndex[RefreshRateTableIndex].ModeID) {
194				if (XGI330_EModeIDTable[j].Ext_ModeFlag &
195				    DoubleScanMode) {
196					*vmode = FB_VMODE_DOUBLE;
197				}
198				break;
199			}
200			j++;
201		}
202	}
203
204	return 1;
205}
206
207void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
208{
209	XGI_Pr->P3c4 = BaseAddr + 0x14;
210	XGI_Pr->P3d4 = BaseAddr + 0x24;
211	XGI_Pr->P3c0 = BaseAddr + 0x10;
212	XGI_Pr->P3ce = BaseAddr + 0x1e;
213	XGI_Pr->P3c2 = BaseAddr + 0x12;
214	XGI_Pr->P3cc = BaseAddr + 0x1c;
215	XGI_Pr->P3ca = BaseAddr + 0x1a;
216	XGI_Pr->P3c6 = BaseAddr + 0x16;
217	XGI_Pr->P3c7 = BaseAddr + 0x17;
218	XGI_Pr->P3c8 = BaseAddr + 0x18;
219	XGI_Pr->P3c9 = BaseAddr + 0x19;
220	XGI_Pr->P3da = BaseAddr + 0x2A;
221	XGI_Pr->Part0Port = BaseAddr + XGI_CRT2_PORT_00;
222	/* Digital video interface registers (LCD) */
223	XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04;
224	/* 301 TV Encoder registers */
225	XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10;
226	/* 301 Macrovision registers */
227	XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12;
228	/* 301 VGA2 (and LCD) registers */
229	XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14;
230	/* 301 palette address port registers */
231	XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
232
233}
234
235/* ------------------ Internal helper routines ----------------- */
236
237static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info)
238{
239	int i = 0;
240
241	while ((XGIbios_mode[i].mode_no != 0)
242	       && (XGIbios_mode[i].xres <= xgifb_info->lvds_data.LVDSHDE)) {
243		if ((XGIbios_mode[i].xres == xgifb_info->lvds_data.LVDSHDE)
244		    && (XGIbios_mode[i].yres == xgifb_info->lvds_data.LVDSVDE)
245		    && (XGIbios_mode[i].bpp == 8)) {
246			return i;
247		}
248		i++;
249	}
250
251	return -1;
252}
253
254static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info,
255			      const char *name)
256{
257	unsigned int xres;
258	unsigned int yres;
259	unsigned int bpp;
260	int i;
261
262	if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3)
263		goto invalid_mode;
264
265	if (bpp == 24)
266		bpp = 32; /* That's for people who mix up color and fb depth. */
267
268	for (i = 0; XGIbios_mode[i].mode_no != 0; i++)
269		if (XGIbios_mode[i].xres == xres &&
270		    XGIbios_mode[i].yres == yres &&
271		    XGIbios_mode[i].bpp == bpp) {
272			xgifb_info->mode_idx = i;
273			return;
274		}
275invalid_mode:
276	pr_info("Invalid mode '%s'\n", name);
277}
278
279static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info,
280				  unsigned int vesamode)
281{
282	int i = 0;
283
284	if (vesamode == 0)
285		goto invalid;
286
287	vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
288
289	while (XGIbios_mode[i].mode_no != 0) {
290		if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
291		    (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
292			xgifb_info->mode_idx = i;
293			return;
294		}
295		i++;
296	}
297
298invalid:
299	pr_info("Invalid VESA mode 0x%x'\n", vesamode);
300}
301
302static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
303{
304	u16 xres, yres;
305	struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
306	unsigned long required_mem;
307
308	if (xgifb_info->chip == XG21) {
309		if (xgifb_info->display2 == XGIFB_DISP_LCD) {
310			xres = xgifb_info->lvds_data.LVDSHDE;
311			yres = xgifb_info->lvds_data.LVDSVDE;
312			if (XGIbios_mode[myindex].xres > xres)
313				return -1;
314			if (XGIbios_mode[myindex].yres > yres)
315				return -1;
316			if ((XGIbios_mode[myindex].xres < xres) &&
317			    (XGIbios_mode[myindex].yres < yres)) {
318				if (XGIbios_mode[myindex].bpp > 8)
319					return -1;
320			}
321
322		}
323		goto check_memory;
324
325	}
326
327	/* FIXME: for now, all is valid on XG27 */
328	if (xgifb_info->chip == XG27)
329		goto check_memory;
330
331	if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
332		return -1;
333
334	switch (xgifb_info->display2) {
335	case XGIFB_DISP_LCD:
336		switch (hw_info->ulCRT2LCDType) {
337		case LCD_640x480:
338			xres = 640;
339			yres = 480;
340			break;
341		case LCD_800x600:
342			xres = 800;
343			yres = 600;
344			break;
345		case LCD_1024x600:
346			xres = 1024;
347			yres = 600;
348			break;
349		case LCD_1024x768:
350			xres = 1024;
351			yres = 768;
352			break;
353		case LCD_1152x768:
354			xres = 1152;
355			yres = 768;
356			break;
357		case LCD_1280x960:
358			xres = 1280;
359			yres = 960;
360			break;
361		case LCD_1280x768:
362			xres = 1280;
363			yres = 768;
364			break;
365		case LCD_1280x1024:
366			xres = 1280;
367			yres = 1024;
368			break;
369		case LCD_1400x1050:
370			xres = 1400;
371			yres = 1050;
372			break;
373		case LCD_1600x1200:
374			xres = 1600;
375			yres = 1200;
376			break;
377		default:
378			xres = 0;
379			yres = 0;
380			break;
381		}
382		if (XGIbios_mode[myindex].xres > xres)
383			return -1;
384		if (XGIbios_mode[myindex].yres > yres)
385			return -1;
386		if ((hw_info->ulExternalChip == 0x01) || /* LVDS */
387		    (hw_info->ulExternalChip == 0x05)) { /* LVDS+Chrontel */
388			switch (XGIbios_mode[myindex].xres) {
389			case 512:
390				if (XGIbios_mode[myindex].yres != 512)
391					return -1;
392				if (hw_info->ulCRT2LCDType == LCD_1024x600)
393					return -1;
394				break;
395			case 640:
396				if ((XGIbios_mode[myindex].yres != 400)
397						&& (XGIbios_mode[myindex].yres
398								!= 480))
399					return -1;
400				break;
401			case 800:
402				if (XGIbios_mode[myindex].yres != 600)
403					return -1;
404				break;
405			case 1024:
406				if ((XGIbios_mode[myindex].yres != 600) &&
407				    (XGIbios_mode[myindex].yres != 768))
408					return -1;
409				if ((XGIbios_mode[myindex].yres == 600) &&
410				    (hw_info->ulCRT2LCDType != LCD_1024x600))
411					return -1;
412				break;
413			case 1152:
414				if ((XGIbios_mode[myindex].yres) != 768)
415					return -1;
416				if (hw_info->ulCRT2LCDType != LCD_1152x768)
417					return -1;
418				break;
419			case 1280:
420				if ((XGIbios_mode[myindex].yres != 768) &&
421				    (XGIbios_mode[myindex].yres != 1024))
422					return -1;
423				if ((XGIbios_mode[myindex].yres == 768) &&
424				    (hw_info->ulCRT2LCDType != LCD_1280x768))
425					return -1;
426				break;
427			case 1400:
428				if (XGIbios_mode[myindex].yres != 1050)
429					return -1;
430				break;
431			case 1600:
432				if (XGIbios_mode[myindex].yres != 1200)
433					return -1;
434				break;
435			default:
436				return -1;
437			}
438		} else {
439			switch (XGIbios_mode[myindex].xres) {
440			case 512:
441				if (XGIbios_mode[myindex].yres != 512)
442					return -1;
443				break;
444			case 640:
445				if ((XGIbios_mode[myindex].yres != 400) &&
446				    (XGIbios_mode[myindex].yres != 480))
447					return -1;
448				break;
449			case 800:
450				if (XGIbios_mode[myindex].yres != 600)
451					return -1;
452				break;
453			case 1024:
454				if (XGIbios_mode[myindex].yres != 768)
455					return -1;
456				break;
457			case 1280:
458				if ((XGIbios_mode[myindex].yres != 960) &&
459				    (XGIbios_mode[myindex].yres != 1024))
460					return -1;
461				if (XGIbios_mode[myindex].yres == 960) {
462					if (hw_info->ulCRT2LCDType ==
463					    LCD_1400x1050)
464						return -1;
465				}
466				break;
467			case 1400:
468				if (XGIbios_mode[myindex].yres != 1050)
469					return -1;
470				break;
471			case 1600:
472				if (XGIbios_mode[myindex].yres != 1200)
473					return -1;
474				break;
475			default:
476				return -1;
477			}
478		}
479		break;
480	case XGIFB_DISP_TV:
481		switch (XGIbios_mode[myindex].xres) {
482		case 512:
483		case 640:
484		case 800:
485			break;
486		case 720:
487			if (xgifb_info->TV_type == TVMODE_NTSC) {
488				if (XGIbios_mode[myindex].yres != 480)
489					return -1;
490			} else if (xgifb_info->TV_type == TVMODE_PAL) {
491				if (XGIbios_mode[myindex].yres != 576)
492					return -1;
493			}
494			/* LVDS/CHRONTEL does not support 720 */
495			if (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL ||
496			    xgifb_info->hasVB == HASVB_CHRONTEL) {
497				return -1;
498			}
499			break;
500		case 1024:
501			if (xgifb_info->TV_type == TVMODE_NTSC) {
502				if (XGIbios_mode[myindex].bpp == 32)
503					return -1;
504			}
505			break;
506		default:
507			return -1;
508		}
509		break;
510	case XGIFB_DISP_CRT:
511		if (XGIbios_mode[myindex].xres > 1280)
512			return -1;
513		break;
514	case XGIFB_DISP_NONE:
515		break;
516	}
517
518check_memory:
519	required_mem = XGIbios_mode[myindex].xres * XGIbios_mode[myindex].yres *
520		       XGIbios_mode[myindex].bpp / 8;
521	if (required_mem > xgifb_info->video_size)
522		return -1;
523	return myindex;
524
525}
526
527static void XGIfb_search_crt2type(const char *name)
528{
529	int i = 0;
530
531	if (name == NULL)
532		return;
533
534	while (XGI_crt2type[i].type_no != -1) {
535		if (!strcmp(name, XGI_crt2type[i].name)) {
536			XGIfb_crt2type = XGI_crt2type[i].type_no;
537			XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
538			break;
539		}
540		i++;
541	}
542	if (XGIfb_crt2type < 0)
543		pr_info("Invalid CRT2 type: %s\n", name);
544}
545
546static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info,
547				    unsigned int rate)
548{
549	u16 xres, yres;
550	int i = 0;
551
552	xres = XGIbios_mode[xgifb_info->mode_idx].xres;
553	yres = XGIbios_mode[xgifb_info->mode_idx].yres;
554
555	xgifb_info->rate_idx = 0;
556	while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
557		if ((XGIfb_vrate[i].xres == xres) &&
558		    (XGIfb_vrate[i].yres == yres)) {
559			if (XGIfb_vrate[i].refresh == rate) {
560				xgifb_info->rate_idx = XGIfb_vrate[i].idx;
561				break;
562			} else if (XGIfb_vrate[i].refresh > rate) {
563				if ((XGIfb_vrate[i].refresh - rate) <= 3) {
564					pr_debug("Adjusting rate from %d up to %d\n",
565						 rate, XGIfb_vrate[i].refresh);
566					xgifb_info->rate_idx =
567						XGIfb_vrate[i].idx;
568					xgifb_info->refresh_rate =
569						XGIfb_vrate[i].refresh;
570				} else if (((rate - XGIfb_vrate[i - 1].refresh)
571						<= 2) && (XGIfb_vrate[i].idx
572						!= 1)) {
573					pr_debug("Adjusting rate from %d down to %d\n",
574						 rate,
575						 XGIfb_vrate[i-1].refresh);
576					xgifb_info->rate_idx =
577						XGIfb_vrate[i - 1].idx;
578					xgifb_info->refresh_rate =
579						XGIfb_vrate[i - 1].refresh;
580				}
581				break;
582			} else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
583				pr_debug("Adjusting rate from %d down to %d\n",
584					 rate, XGIfb_vrate[i].refresh);
585				xgifb_info->rate_idx = XGIfb_vrate[i].idx;
586				break;
587			}
588		}
589		i++;
590	}
591	if (xgifb_info->rate_idx > 0)
592		return xgifb_info->rate_idx;
593	pr_info("Unsupported rate %d for %dx%d\n",
594		rate, xres, yres);
595	return 0;
596}
597
598static void XGIfb_search_tvstd(const char *name)
599{
600	int i = 0;
601
602	if (name == NULL)
603		return;
604
605	while (XGI_tvtype[i].type_no != -1) {
606		if (!strcmp(name, XGI_tvtype[i].name)) {
607			XGIfb_tvmode = XGI_tvtype[i].type_no;
608			break;
609		}
610		i++;
611	}
612}
613
614/* ----------- FBDev related routines for all series ----------- */
615
616static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info,
617			     struct fb_var_screeninfo *var)
618{
619	switch (var->bits_per_pixel) {
620	case 8:
621		var->red.offset = var->green.offset = var->blue.offset = 0;
622		var->red.length = var->green.length = var->blue.length = 6;
623		xgifb_info->video_cmap_len = 256;
624		break;
625	case 16:
626		var->red.offset = 11;
627		var->red.length = 5;
628		var->green.offset = 5;
629		var->green.length = 6;
630		var->blue.offset = 0;
631		var->blue.length = 5;
632		var->transp.offset = 0;
633		var->transp.length = 0;
634		xgifb_info->video_cmap_len = 16;
635		break;
636	case 32:
637		var->red.offset = 16;
638		var->red.length = 8;
639		var->green.offset = 8;
640		var->green.length = 8;
641		var->blue.offset = 0;
642		var->blue.length = 8;
643		var->transp.offset = 24;
644		var->transp.length = 8;
645		xgifb_info->video_cmap_len = 16;
646		break;
647	}
648}
649
650/* --------------------- SetMode routines ------------------------- */
651
652static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info)
653{
654	u8 cr30 = 0, cr31 = 0;
655
656	cr31 = xgifb_reg_get(XGICR, 0x31);
657	cr31 &= ~0x60;
658
659	switch (xgifb_info->display2) {
660	case XGIFB_DISP_CRT:
661		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
662		cr31 |= SIS_DRIVER_MODE;
663		break;
664	case XGIFB_DISP_LCD:
665		cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
666		cr31 |= SIS_DRIVER_MODE;
667		break;
668	case XGIFB_DISP_TV:
669		if (xgifb_info->TV_type == TVMODE_HIVISION)
670			cr30 = (SIS_VB_OUTPUT_HIVISION
671					| SIS_SIMULTANEOUS_VIEW_ENABLE);
672		else if (xgifb_info->TV_plug == TVPLUG_SVIDEO)
673			cr30 = (SIS_VB_OUTPUT_SVIDEO
674					| SIS_SIMULTANEOUS_VIEW_ENABLE);
675		else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE)
676			cr30 = (SIS_VB_OUTPUT_COMPOSITE
677					| SIS_SIMULTANEOUS_VIEW_ENABLE);
678		else if (xgifb_info->TV_plug == TVPLUG_SCART)
679			cr30 = (SIS_VB_OUTPUT_SCART
680					| SIS_SIMULTANEOUS_VIEW_ENABLE);
681		cr31 |= SIS_DRIVER_MODE;
682
683		if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL)
684			cr31 |= 0x01;
685		else
686			cr31 &= ~0x01;
687		break;
688	default: /* disable CRT2 */
689		cr30 = 0x00;
690		cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
691	}
692
693	xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
694	xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
695	xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33,
696						(xgifb_info->rate_idx & 0x0F));
697}
698
699static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
700{
701	u8 reg;
702	unsigned char doit = 1;
703
704	if (xgifb_info->video_bpp == 8) {
705		/*
706		 * We can't switch off CRT1 on LVDS/Chrontel
707		 * in 8bpp Modes
708		 */
709		if ((xgifb_info->hasVB == HASVB_LVDS) ||
710		    (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL)) {
711			doit = 0;
712		}
713		/*
714		 * We can't switch off CRT1 on 301B-DH
715		 * in 8bpp Modes if using LCD
716		 */
717		if (xgifb_info->display2 == XGIFB_DISP_LCD)
718			doit = 0;
719	}
720
721	/* We can't switch off CRT1 if bridge is in slave mode */
722	if (xgifb_info->hasVB != HASVB_NONE) {
723		reg = xgifb_reg_get(XGIPART1, 0x00);
724
725		if ((reg & 0x50) == 0x10)
726			doit = 0;
727
728	} else {
729		XGIfb_crt1off = 0;
730	}
731
732	reg = xgifb_reg_get(XGICR, 0x17);
733	if ((XGIfb_crt1off) && (doit))
734		reg &= ~0x80;
735	else
736		reg |= 0x80;
737	xgifb_reg_set(XGICR, 0x17, reg);
738
739	xgifb_reg_and(XGISR, IND_SIS_RAMDAC_CONTROL, ~0x04);
740
741	if (xgifb_info->display2 == XGIFB_DISP_TV &&
742	    xgifb_info->hasVB == HASVB_301) {
743
744		reg = xgifb_reg_get(XGIPART4, 0x01);
745
746		if (reg < 0xB0) { /* Set filter for XGI301 */
747			int filter_tb;
748
749			switch (xgifb_info->video_width) {
750			case 320:
751				filter_tb = (xgifb_info->TV_type ==
752					     TVMODE_NTSC) ? 4 : 12;
753				break;
754			case 640:
755				filter_tb = (xgifb_info->TV_type ==
756					     TVMODE_NTSC) ? 5 : 13;
757				break;
758			case 720:
759				filter_tb = (xgifb_info->TV_type ==
760					     TVMODE_NTSC) ? 6 : 14;
761				break;
762			case 800:
763				filter_tb = (xgifb_info->TV_type ==
764					     TVMODE_NTSC) ? 7 : 15;
765				break;
766			default:
767				filter_tb = 0;
768				filter = -1;
769				break;
770			}
771			xgifb_reg_or(XGIPART1,
772				     SIS_CRT2_WENABLE_315,
773				     0x01);
774
775			if (xgifb_info->TV_type == TVMODE_NTSC) {
776
777				xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
778
779				if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
780
781					xgifb_reg_and(XGIPART2, 0x30, 0xdf);
782
783				} else if (xgifb_info->TV_plug
784						== TVPLUG_COMPOSITE) {
785
786					xgifb_reg_or(XGIPART2, 0x30, 0x20);
787
788					switch (xgifb_info->video_width) {
789					case 640:
790						xgifb_reg_set(XGIPART2,
791							      0x35,
792							      0xEB);
793						xgifb_reg_set(XGIPART2,
794							      0x36,
795							      0x04);
796						xgifb_reg_set(XGIPART2,
797							      0x37,
798							      0x25);
799						xgifb_reg_set(XGIPART2,
800							      0x38,
801							      0x18);
802						break;
803					case 720:
804						xgifb_reg_set(XGIPART2,
805							      0x35,
806							      0xEE);
807						xgifb_reg_set(XGIPART2,
808							      0x36,
809							      0x0C);
810						xgifb_reg_set(XGIPART2,
811							      0x37,
812							      0x22);
813						xgifb_reg_set(XGIPART2,
814							      0x38,
815							      0x08);
816						break;
817					case 800:
818						xgifb_reg_set(XGIPART2,
819							      0x35,
820							      0xEB);
821						xgifb_reg_set(XGIPART2,
822							      0x36,
823							      0x15);
824						xgifb_reg_set(XGIPART2,
825							      0x37,
826							      0x25);
827						xgifb_reg_set(XGIPART2,
828							      0x38,
829							      0xF6);
830						break;
831					}
832				}
833
834			} else if (xgifb_info->TV_type == TVMODE_PAL) {
835
836				xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
837
838				if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
839
840					xgifb_reg_and(XGIPART2, 0x30, 0xDF);
841
842				} else if (xgifb_info->TV_plug
843						== TVPLUG_COMPOSITE) {
844
845					xgifb_reg_or(XGIPART2, 0x30, 0x20);
846
847					switch (xgifb_info->video_width) {
848					case 640:
849						xgifb_reg_set(XGIPART2,
850							      0x35,
851							      0xF1);
852						xgifb_reg_set(XGIPART2,
853							      0x36,
854							      0xF7);
855						xgifb_reg_set(XGIPART2,
856							      0x37,
857							      0x1F);
858						xgifb_reg_set(XGIPART2,
859							      0x38,
860							      0x32);
861						break;
862					case 720:
863						xgifb_reg_set(XGIPART2,
864							      0x35,
865							      0xF3);
866						xgifb_reg_set(XGIPART2,
867							      0x36,
868							      0x00);
869						xgifb_reg_set(XGIPART2,
870							      0x37,
871							      0x1D);
872						xgifb_reg_set(XGIPART2,
873							      0x38,
874							      0x20);
875						break;
876					case 800:
877						xgifb_reg_set(XGIPART2,
878							      0x35,
879							      0xFC);
880						xgifb_reg_set(XGIPART2,
881							      0x36,
882							      0xFB);
883						xgifb_reg_set(XGIPART2,
884							      0x37,
885							      0x14);
886						xgifb_reg_set(XGIPART2,
887							      0x38,
888							      0x2A);
889						break;
890					}
891				}
892			}
893
894			if ((filter >= 0) && (filter <= 7)) {
895				pr_debug("FilterTable[%d]-%d: %*ph\n",
896					 filter_tb, filter,
897					 4, XGI_TV_filter[filter_tb].
898						   filter[filter]);
899				xgifb_reg_set(
900					XGIPART2,
901					0x35,
902					(XGI_TV_filter[filter_tb].
903						filter[filter][0]));
904				xgifb_reg_set(
905					XGIPART2,
906					0x36,
907					(XGI_TV_filter[filter_tb].
908						filter[filter][1]));
909				xgifb_reg_set(
910					XGIPART2,
911					0x37,
912					(XGI_TV_filter[filter_tb].
913						filter[filter][2]));
914				xgifb_reg_set(
915					XGIPART2,
916					0x38,
917					(XGI_TV_filter[filter_tb].
918						filter[filter][3]));
919			}
920		}
921	}
922}
923
924static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
925		struct fb_info *info)
926{
927	struct xgifb_video_info *xgifb_info = info->par;
928	struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
929	unsigned int htotal = var->left_margin + var->xres + var->right_margin
930			+ var->hsync_len;
931	unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
932			+ var->vsync_len;
933#if defined(__powerpc__)
934	u8 cr_data;
935#endif
936	unsigned int drate = 0, hrate = 0;
937	int found_mode = 0;
938	int old_mode;
939
940	info->var.xres_virtual = var->xres_virtual;
941	info->var.yres_virtual = var->yres_virtual;
942	info->var.bits_per_pixel = var->bits_per_pixel;
943
944	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
945		vtotal <<= 1;
946	else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
947		vtotal <<= 2;
948
949	if (!htotal || !vtotal) {
950		pr_debug("Invalid 'var' information\n");
951		return -EINVAL;
952	} pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n",
953			var->pixclock, htotal, vtotal);
954
955	if (var->pixclock && htotal && vtotal) {
956		drate = 1000000000 / var->pixclock;
957		hrate = (drate * 1000) / htotal;
958		xgifb_info->refresh_rate = (unsigned int) (hrate * 2
959				/ vtotal);
960	} else {
961		xgifb_info->refresh_rate = 60;
962	}
963
964	pr_debug("Change mode to %dx%dx%d-%dHz\n",
965	       var->xres,
966	       var->yres,
967	       var->bits_per_pixel,
968	       xgifb_info->refresh_rate);
969
970	old_mode = xgifb_info->mode_idx;
971	xgifb_info->mode_idx = 0;
972
973	while ((XGIbios_mode[xgifb_info->mode_idx].mode_no != 0) &&
974	       (XGIbios_mode[xgifb_info->mode_idx].xres <= var->xres)) {
975		if ((XGIbios_mode[xgifb_info->mode_idx].xres == var->xres) &&
976		    (XGIbios_mode[xgifb_info->mode_idx].yres == var->yres) &&
977		    (XGIbios_mode[xgifb_info->mode_idx].bpp
978						== var->bits_per_pixel)) {
979			found_mode = 1;
980			break;
981		}
982		xgifb_info->mode_idx++;
983	}
984
985	if (found_mode)
986		xgifb_info->mode_idx = XGIfb_validate_mode(xgifb_info,
987							xgifb_info->mode_idx);
988	else
989		xgifb_info->mode_idx = -1;
990
991	if (xgifb_info->mode_idx < 0) {
992		pr_err("Mode %dx%dx%d not supported\n",
993		       var->xres, var->yres, var->bits_per_pixel);
994		xgifb_info->mode_idx = old_mode;
995		return -EINVAL;
996	}
997
998	if (XGIfb_search_refresh_rate(xgifb_info,
999				      xgifb_info->refresh_rate) == 0) {
1000		xgifb_info->rate_idx = 1;
1001		xgifb_info->refresh_rate = 60;
1002	}
1003
1004	if (isactive) {
1005
1006		XGIfb_pre_setmode(xgifb_info);
1007		if (XGISetModeNew(xgifb_info, hw_info,
1008				  XGIbios_mode[xgifb_info->mode_idx].mode_no)
1009					== 0) {
1010			pr_err("Setting mode[0x%x] failed\n",
1011			       XGIbios_mode[xgifb_info->mode_idx].mode_no);
1012			return -EINVAL;
1013		}
1014		info->fix.line_length = ((info->var.xres_virtual
1015				* info->var.bits_per_pixel) >> 6);
1016
1017		xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
1018
1019		xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1020		xgifb_reg_set(XGISR,
1021			      0x0E,
1022			      (info->fix.line_length & 0xff00) >> 8);
1023
1024		XGIfb_post_setmode(xgifb_info);
1025
1026		pr_debug("Set new mode: %dx%dx%d-%d\n",
1027			 XGIbios_mode[xgifb_info->mode_idx].xres,
1028			 XGIbios_mode[xgifb_info->mode_idx].yres,
1029			 XGIbios_mode[xgifb_info->mode_idx].bpp,
1030			 xgifb_info->refresh_rate);
1031
1032		xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp;
1033		xgifb_info->video_vwidth = info->var.xres_virtual;
1034		xgifb_info->video_width =
1035			XGIbios_mode[xgifb_info->mode_idx].xres;
1036		xgifb_info->video_vheight = info->var.yres_virtual;
1037		xgifb_info->video_height =
1038			XGIbios_mode[xgifb_info->mode_idx].yres;
1039		xgifb_info->org_x = xgifb_info->org_y = 0;
1040		xgifb_info->video_linelength = info->var.xres_virtual
1041				* (xgifb_info->video_bpp >> 3);
1042		switch (xgifb_info->video_bpp) {
1043		case 8:
1044			xgifb_info->DstColor = 0x0000;
1045			xgifb_info->XGI310_AccelDepth = 0x00000000;
1046			xgifb_info->video_cmap_len = 256;
1047#if defined(__powerpc__)
1048			cr_data = xgifb_reg_get(XGICR, 0x4D);
1049			xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
1050#endif
1051			break;
1052		case 16:
1053			xgifb_info->DstColor = 0x8000;
1054			xgifb_info->XGI310_AccelDepth = 0x00010000;
1055#if defined(__powerpc__)
1056			cr_data = xgifb_reg_get(XGICR, 0x4D);
1057			xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1058#endif
1059			xgifb_info->video_cmap_len = 16;
1060			break;
1061		case 32:
1062			xgifb_info->DstColor = 0xC000;
1063			xgifb_info->XGI310_AccelDepth = 0x00020000;
1064			xgifb_info->video_cmap_len = 16;
1065#if defined(__powerpc__)
1066			cr_data = xgifb_reg_get(XGICR, 0x4D);
1067			xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1068#endif
1069			break;
1070		default:
1071			xgifb_info->video_cmap_len = 16;
1072			pr_err("Unsupported depth %d\n",
1073			       xgifb_info->video_bpp);
1074			break;
1075		}
1076	}
1077	XGIfb_bpp_to_var(xgifb_info, var); /*update ARGB info*/
1078
1079	dumpVGAReg();
1080	return 0;
1081}
1082
1083static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
1084{
1085	struct xgifb_video_info *xgifb_info = info->par;
1086	unsigned int base;
1087
1088	base = var->yoffset * info->var.xres_virtual + var->xoffset;
1089
1090	/* calculate base bpp dep. */
1091	switch (info->var.bits_per_pixel) {
1092	case 16:
1093		base >>= 1;
1094		break;
1095	case 32:
1096		break;
1097	case 8:
1098	default:
1099		base >>= 2;
1100		break;
1101	}
1102
1103	xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
1104
1105	xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1106	xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1107	xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1108	xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
1109	xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1110
1111	if (xgifb_info->display2 != XGIFB_DISP_NONE) {
1112		xgifb_reg_or(XGIPART1, SIS_CRT2_WENABLE_315, 0x01);
1113		xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1114		xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1115		xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1116		xgifb_reg_and_or(XGIPART1,
1117				 0x02,
1118				 0x7F,
1119				 ((base >> 24) & 0x01) << 7);
1120	}
1121	return 0;
1122}
1123
1124static int XGIfb_open(struct fb_info *info, int user)
1125{
1126	return 0;
1127}
1128
1129static int XGIfb_release(struct fb_info *info, int user)
1130{
1131	return 0;
1132}
1133
1134/* similar to sisfb_get_cmap_len */
1135static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1136{
1137	return (var->bits_per_pixel == 8) ? 256 : 16;
1138}
1139
1140static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1141		unsigned blue, unsigned transp, struct fb_info *info)
1142{
1143	struct xgifb_video_info *xgifb_info = info->par;
1144
1145	if (regno >= XGIfb_get_cmap_len(&info->var))
1146		return 1;
1147
1148	switch (info->var.bits_per_pixel) {
1149	case 8:
1150		outb(regno, XGIDACA);
1151		outb((red >> 10), XGIDACD);
1152		outb((green >> 10), XGIDACD);
1153		outb((blue >> 10), XGIDACD);
1154		if (xgifb_info->display2 != XGIFB_DISP_NONE) {
1155			outb(regno, XGIDAC2A);
1156			outb((red >> 8), XGIDAC2D);
1157			outb((green >> 8), XGIDAC2D);
1158			outb((blue >> 8), XGIDAC2D);
1159		}
1160		break;
1161	case 16:
1162		((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1163				| ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1164				>> 11);
1165		break;
1166	case 32:
1167		red >>= 8;
1168		green >>= 8;
1169		blue >>= 8;
1170		((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1171				<< 8) | (blue);
1172		break;
1173	}
1174	return 0;
1175}
1176
1177/* ----------- FBDev related routines for all series ---------- */
1178
1179static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1180		struct fb_info *info)
1181{
1182	struct xgifb_video_info *xgifb_info = info->par;
1183
1184	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1185
1186	strncpy(fix->id, "XGI", sizeof(fix->id) - 1);
1187
1188	/* if register_framebuffer has been called, we must lock */
1189	if (atomic_read(&info->count))
1190		mutex_lock(&info->mm_lock);
1191
1192	fix->smem_start = xgifb_info->video_base;
1193	fix->smem_len = xgifb_info->video_size;
1194
1195	/* if register_framebuffer has been called, we can unlock */
1196	if (atomic_read(&info->count))
1197		mutex_unlock(&info->mm_lock);
1198
1199	fix->type = FB_TYPE_PACKED_PIXELS;
1200	fix->type_aux = 0;
1201	if (xgifb_info->video_bpp == 8)
1202		fix->visual = FB_VISUAL_PSEUDOCOLOR;
1203	else
1204		fix->visual = FB_VISUAL_DIRECTCOLOR;
1205	fix->xpanstep = 0;
1206	if (XGIfb_ypan)
1207		fix->ypanstep = 1;
1208	fix->ywrapstep = 0;
1209	fix->line_length = xgifb_info->video_linelength;
1210	fix->mmio_start = xgifb_info->mmio_base;
1211	fix->mmio_len = xgifb_info->mmio_size;
1212	fix->accel = FB_ACCEL_SIS_XABRE;
1213
1214	return 0;
1215}
1216
1217static int XGIfb_set_par(struct fb_info *info)
1218{
1219	int err;
1220
1221	err = XGIfb_do_set_var(&info->var, 1, info);
1222	if (err)
1223		return err;
1224	XGIfb_get_fix(&info->fix, -1, info);
1225	return 0;
1226}
1227
1228static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1229{
1230	struct xgifb_video_info *xgifb_info = info->par;
1231	unsigned int htotal = var->left_margin + var->xres + var->right_margin
1232			+ var->hsync_len;
1233	unsigned int vtotal = 0;
1234	unsigned int drate = 0, hrate = 0;
1235	int found_mode = 0;
1236	int refresh_rate, search_idx;
1237
1238	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1239		vtotal = var->upper_margin + var->yres + var->lower_margin
1240				+ var->vsync_len;
1241		vtotal <<= 1;
1242	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1243		vtotal = var->upper_margin + var->yres + var->lower_margin
1244				+ var->vsync_len;
1245		vtotal <<= 2;
1246	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1247		vtotal = var->upper_margin + (var->yres / 2)
1248				+ var->lower_margin + var->vsync_len;
1249	} else
1250		vtotal = var->upper_margin + var->yres + var->lower_margin
1251				+ var->vsync_len;
1252
1253	if (!(htotal) || !(vtotal)) {
1254		pr_debug("No valid timing data\n");
1255		return -EINVAL;
1256	}
1257
1258	if (var->pixclock && htotal && vtotal) {
1259		drate = 1000000000 / var->pixclock;
1260		hrate = (drate * 1000) / htotal;
1261		xgifb_info->refresh_rate =
1262			(unsigned int) (hrate * 2 / vtotal);
1263		pr_debug(
1264			"%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1265			"%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1266			__func__, var->pixclock, htotal, vtotal,
1267			__func__, drate, hrate, xgifb_info->refresh_rate);
1268	} else {
1269		xgifb_info->refresh_rate = 60;
1270	}
1271
1272	/* Calculation wrong for 1024x600 - force it to 60Hz */
1273	if ((var->xres == 1024) && (var->yres == 600))
1274		refresh_rate = 60;
1275
1276	search_idx = 0;
1277	while ((XGIbios_mode[search_idx].mode_no != 0) &&
1278		(XGIbios_mode[search_idx].xres <= var->xres)) {
1279		if ((XGIbios_mode[search_idx].xres == var->xres) &&
1280			(XGIbios_mode[search_idx].yres == var->yres) &&
1281			(XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1282			if (XGIfb_validate_mode(xgifb_info, search_idx) > 0) {
1283				found_mode = 1;
1284				break;
1285			}
1286		}
1287		search_idx++;
1288	}
1289
1290	if (!found_mode) {
1291
1292		pr_err("%dx%dx%d is no valid mode\n",
1293			var->xres, var->yres, var->bits_per_pixel);
1294		search_idx = 0;
1295		while (XGIbios_mode[search_idx].mode_no != 0) {
1296			if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1297			    (var->yres <= XGIbios_mode[search_idx].yres) &&
1298			    (var->bits_per_pixel ==
1299			     XGIbios_mode[search_idx].bpp)) {
1300				if (XGIfb_validate_mode(xgifb_info,
1301							search_idx) > 0) {
1302					found_mode = 1;
1303					break;
1304				}
1305			}
1306			search_idx++;
1307		}
1308		if (found_mode) {
1309			var->xres = XGIbios_mode[search_idx].xres;
1310			var->yres = XGIbios_mode[search_idx].yres;
1311			pr_debug("Adapted to mode %dx%dx%d\n",
1312				var->xres, var->yres, var->bits_per_pixel);
1313
1314		} else {
1315			pr_err("Failed to find similar mode to %dx%dx%d\n",
1316				var->xres, var->yres, var->bits_per_pixel);
1317			return -EINVAL;
1318		}
1319	}
1320
1321	/* Adapt RGB settings */
1322	XGIfb_bpp_to_var(xgifb_info, var);
1323
1324	if (!XGIfb_ypan) {
1325		if (var->xres != var->xres_virtual)
1326			var->xres_virtual = var->xres;
1327		if (var->yres != var->yres_virtual)
1328			var->yres_virtual = var->yres;
1329	}
1330
1331	/* Truncate offsets to maximum if too high */
1332	if (var->xoffset > var->xres_virtual - var->xres)
1333		var->xoffset = var->xres_virtual - var->xres - 1;
1334
1335	if (var->yoffset > var->yres_virtual - var->yres)
1336		var->yoffset = var->yres_virtual - var->yres - 1;
1337
1338	/* Set everything else to 0 */
1339	var->red.msb_right =
1340	var->green.msb_right =
1341	var->blue.msb_right =
1342	var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1343
1344	return 0;
1345}
1346
1347static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1348		struct fb_info *info)
1349{
1350	int err;
1351
1352	if (var->xoffset > (info->var.xres_virtual - info->var.xres))
1353		return -EINVAL;
1354	if (var->yoffset > (info->var.yres_virtual - info->var.yres))
1355		return -EINVAL;
1356
1357	if (var->vmode & FB_VMODE_YWRAP) {
1358		if (var->yoffset >= info->var.yres_virtual || var->xoffset)
1359			return -EINVAL;
1360	} else if (var->xoffset + info->var.xres > info->var.xres_virtual
1361				|| var->yoffset + info->var.yres
1362						> info->var.yres_virtual) {
1363		return -EINVAL;
1364	}
1365	err = XGIfb_pan_var(var, info);
1366	if (err < 0)
1367		return err;
1368
1369	info->var.xoffset = var->xoffset;
1370	info->var.yoffset = var->yoffset;
1371	if (var->vmode & FB_VMODE_YWRAP)
1372		info->var.vmode |= FB_VMODE_YWRAP;
1373	else
1374		info->var.vmode &= ~FB_VMODE_YWRAP;
1375
1376	return 0;
1377}
1378
1379static int XGIfb_blank(int blank, struct fb_info *info)
1380{
1381	struct xgifb_video_info *xgifb_info = info->par;
1382	u8 reg;
1383
1384	reg = xgifb_reg_get(XGICR, 0x17);
1385
1386	if (blank > 0)
1387		reg &= 0x7f;
1388	else
1389		reg |= 0x80;
1390
1391	xgifb_reg_set(XGICR, 0x17, reg);
1392	xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1393	xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
1394	return 0;
1395}
1396
1397static struct fb_ops XGIfb_ops = {
1398	.owner = THIS_MODULE,
1399	.fb_open = XGIfb_open,
1400	.fb_release = XGIfb_release,
1401	.fb_check_var = XGIfb_check_var,
1402	.fb_set_par = XGIfb_set_par,
1403	.fb_setcolreg = XGIfb_setcolreg,
1404	.fb_pan_display = XGIfb_pan_display,
1405	.fb_blank = XGIfb_blank,
1406	.fb_fillrect = cfb_fillrect,
1407	.fb_copyarea = cfb_copyarea,
1408	.fb_imageblit = cfb_imageblit,
1409};
1410
1411/* ---------------- Chip generation dependent routines ---------------- */
1412
1413/* for XGI 315/550/650/740/330 */
1414
1415static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info)
1416{
1417
1418	u8 ChannelNum, tmp;
1419	u8 reg = 0;
1420
1421	/* xorg driver sets 32MB * 1 channel */
1422	if (xgifb_info->chip == XG27)
1423		xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51);
1424
1425	reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE);
1426	if (!reg)
1427		return -1;
1428
1429	switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1430	case XGI_DRAM_SIZE_1MB:
1431		xgifb_info->video_size = 0x100000;
1432		break;
1433	case XGI_DRAM_SIZE_2MB:
1434		xgifb_info->video_size = 0x200000;
1435		break;
1436	case XGI_DRAM_SIZE_4MB:
1437		xgifb_info->video_size = 0x400000;
1438		break;
1439	case XGI_DRAM_SIZE_8MB:
1440		xgifb_info->video_size = 0x800000;
1441		break;
1442	case XGI_DRAM_SIZE_16MB:
1443		xgifb_info->video_size = 0x1000000;
1444		break;
1445	case XGI_DRAM_SIZE_32MB:
1446		xgifb_info->video_size = 0x2000000;
1447		break;
1448	case XGI_DRAM_SIZE_64MB:
1449		xgifb_info->video_size = 0x4000000;
1450		break;
1451	case XGI_DRAM_SIZE_128MB:
1452		xgifb_info->video_size = 0x8000000;
1453		break;
1454	case XGI_DRAM_SIZE_256MB:
1455		xgifb_info->video_size = 0x10000000;
1456		break;
1457	default:
1458		return -1;
1459	}
1460
1461	tmp = (reg & 0x0c) >> 2;
1462	switch (xgifb_info->chip) {
1463	case XG20:
1464	case XG21:
1465	case XG27:
1466		ChannelNum = 1;
1467		break;
1468
1469	case XG42:
1470		if (reg & 0x04)
1471			ChannelNum = 2;
1472		else
1473			ChannelNum = 1;
1474		break;
1475
1476	case XG40:
1477	default:
1478		if (tmp == 2)
1479			ChannelNum = 2;
1480		else if (tmp == 3)
1481			ChannelNum = 3;
1482		else
1483			ChannelNum = 1;
1484		break;
1485	}
1486
1487	xgifb_info->video_size = xgifb_info->video_size * ChannelNum;
1488
1489	pr_info("SR14=%x DramSzie %x ChannelNum %x\n",
1490	       reg,
1491	       xgifb_info->video_size, ChannelNum);
1492	return 0;
1493
1494}
1495
1496static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
1497{
1498	u8 cr32, temp = 0;
1499
1500	xgifb_info->TV_plug = xgifb_info->TV_type = 0;
1501
1502	cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
1503
1504	if ((cr32 & SIS_CRT1) && !XGIfb_crt1off)
1505		XGIfb_crt1off = 0;
1506	else {
1507		if (cr32 & 0x5F)
1508			XGIfb_crt1off = 1;
1509		else
1510			XGIfb_crt1off = 0;
1511	}
1512
1513	if (!xgifb_info->display2_force) {
1514		if (cr32 & SIS_VB_TV)
1515			xgifb_info->display2 = XGIFB_DISP_TV;
1516		else if (cr32 & SIS_VB_LCD)
1517			xgifb_info->display2 = XGIFB_DISP_LCD;
1518		else if (cr32 & SIS_VB_CRT2)
1519			xgifb_info->display2 = XGIFB_DISP_CRT;
1520		else
1521			xgifb_info->display2 = XGIFB_DISP_NONE;
1522	}
1523
1524	if (XGIfb_tvplug != -1)
1525		/* Override with option */
1526		xgifb_info->TV_plug = XGIfb_tvplug;
1527	else if (cr32 & SIS_VB_HIVISION) {
1528		xgifb_info->TV_type = TVMODE_HIVISION;
1529		xgifb_info->TV_plug = TVPLUG_SVIDEO;
1530	} else if (cr32 & SIS_VB_SVIDEO)
1531		xgifb_info->TV_plug = TVPLUG_SVIDEO;
1532	else if (cr32 & SIS_VB_COMPOSITE)
1533		xgifb_info->TV_plug = TVPLUG_COMPOSITE;
1534	else if (cr32 & SIS_VB_SCART)
1535		xgifb_info->TV_plug = TVPLUG_SCART;
1536
1537	if (xgifb_info->TV_type == 0) {
1538		temp = xgifb_reg_get(XGICR, 0x38);
1539		if (temp & 0x10)
1540			xgifb_info->TV_type = TVMODE_PAL;
1541		else
1542			xgifb_info->TV_type = TVMODE_NTSC;
1543	}
1544
1545	/* Copy forceCRT1 option to CRT1off if option is given */
1546	if (XGIfb_forcecrt1 != -1) {
1547		if (XGIfb_forcecrt1)
1548			XGIfb_crt1off = 0;
1549		else
1550			XGIfb_crt1off = 1;
1551	}
1552}
1553
1554static int XGIfb_has_VB(struct xgifb_video_info *xgifb_info)
1555{
1556	u8 vb_chipid;
1557
1558	vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
1559	switch (vb_chipid) {
1560	case 0x01:
1561		xgifb_info->hasVB = HASVB_301;
1562		break;
1563	case 0x02:
1564		xgifb_info->hasVB = HASVB_302;
1565		break;
1566	default:
1567		xgifb_info->hasVB = HASVB_NONE;
1568		return 0;
1569	}
1570	return 1;
1571}
1572
1573static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info)
1574{
1575	u8 reg;
1576
1577	if (!XGIfb_has_VB(xgifb_info)) {
1578		reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1579		switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
1580		case SIS_EXTERNAL_CHIP_LVDS:
1581			xgifb_info->hasVB = HASVB_LVDS;
1582			break;
1583		case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
1584			xgifb_info->hasVB = HASVB_LVDS_CHRONTEL;
1585			break;
1586		default:
1587			break;
1588		}
1589	}
1590}
1591
1592static int __init xgifb_optval(char *fullopt, int validx)
1593{
1594	unsigned long lres;
1595
1596	if (kstrtoul(fullopt + validx, 0, &lres) < 0 || lres > INT_MAX) {
1597		pr_err("Invalid value for option: %s\n", fullopt);
1598		return 0;
1599	}
1600	return lres;
1601}
1602
1603static int __init XGIfb_setup(char *options)
1604{
1605	char *this_opt;
1606
1607	if (!options || !*options)
1608		return 0;
1609
1610	pr_info("Options: %s\n", options);
1611
1612	while ((this_opt = strsep(&options, ",")) != NULL) {
1613
1614		if (!*this_opt)
1615			continue;
1616
1617		if (!strncmp(this_opt, "mode:", 5)) {
1618			mode = this_opt + 5;
1619		} else if (!strncmp(this_opt, "vesa:", 5)) {
1620			vesa = xgifb_optval(this_opt, 5);
1621		} else if (!strncmp(this_opt, "vrate:", 6)) {
1622			refresh_rate = xgifb_optval(this_opt, 6);
1623		} else if (!strncmp(this_opt, "rate:", 5)) {
1624			refresh_rate = xgifb_optval(this_opt, 5);
1625		} else if (!strncmp(this_opt, "crt1off", 7)) {
1626			XGIfb_crt1off = 1;
1627		} else if (!strncmp(this_opt, "filter:", 7)) {
1628			filter = xgifb_optval(this_opt, 7);
1629		} else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1630			XGIfb_search_crt2type(this_opt + 14);
1631		} else if (!strncmp(this_opt, "forcecrt1:", 10)) {
1632			XGIfb_forcecrt1 = xgifb_optval(this_opt, 10);
1633		} else if (!strncmp(this_opt, "tvmode:", 7)) {
1634			XGIfb_search_tvstd(this_opt + 7);
1635		} else if (!strncmp(this_opt, "tvstandard:", 11)) {
1636			XGIfb_search_tvstd(this_opt + 7);
1637		} else if (!strncmp(this_opt, "dstn", 4)) {
1638			enable_dstn = 1;
1639			/* DSTN overrules forcecrt2type */
1640			XGIfb_crt2type = XGIFB_DISP_LCD;
1641		} else if (!strncmp(this_opt, "noypan", 6)) {
1642			XGIfb_ypan = 0;
1643		} else {
1644			mode = this_opt;
1645		}
1646	}
1647	return 0;
1648}
1649
1650static int xgifb_probe(struct pci_dev *pdev,
1651		const struct pci_device_id *ent)
1652{
1653	u8 reg, reg1;
1654	u8 CR48, CR38;
1655	int ret;
1656	struct fb_info *fb_info;
1657	struct xgifb_video_info *xgifb_info;
1658	struct xgi_hw_device_info *hw_info;
1659	unsigned long video_size_max;
1660
1661	fb_info = framebuffer_alloc(sizeof(*xgifb_info), &pdev->dev);
1662	if (!fb_info)
1663		return -ENOMEM;
1664
1665	xgifb_info = fb_info->par;
1666	hw_info = &xgifb_info->hw_info;
1667	xgifb_info->fb_info = fb_info;
1668	xgifb_info->chip_id = pdev->device;
1669	pci_read_config_byte(pdev,
1670			     PCI_REVISION_ID,
1671			     &xgifb_info->revision_id);
1672	hw_info->jChipRevision = xgifb_info->revision_id;
1673
1674	xgifb_info->pcibus = pdev->bus->number;
1675	xgifb_info->pcislot = PCI_SLOT(pdev->devfn);
1676	xgifb_info->pcifunc = PCI_FUNC(pdev->devfn);
1677	xgifb_info->subsysvendor = pdev->subsystem_vendor;
1678	xgifb_info->subsysdevice = pdev->subsystem_device;
1679
1680	video_size_max = pci_resource_len(pdev, 0);
1681	xgifb_info->video_base = pci_resource_start(pdev, 0);
1682	xgifb_info->mmio_base = pci_resource_start(pdev, 1);
1683	xgifb_info->mmio_size = pci_resource_len(pdev, 1);
1684	xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30;
1685	dev_info(&pdev->dev, "Relocate IO address: %Lx [%08lx]\n",
1686		 (u64) pci_resource_start(pdev, 2),
1687		 xgifb_info->vga_base);
1688
1689	if (pci_enable_device(pdev)) {
1690		ret = -EIO;
1691		goto error;
1692	}
1693
1694	if (XGIfb_crt2type != -1) {
1695		xgifb_info->display2 = XGIfb_crt2type;
1696		xgifb_info->display2_force = true;
1697	}
1698
1699	XGIRegInit(&xgifb_info->dev_info, xgifb_info->vga_base);
1700
1701	xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
1702	reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD);
1703
1704	if (reg1 != 0xa1) { /*I/O error */
1705		dev_err(&pdev->dev, "I/O error\n");
1706		ret = -EIO;
1707		goto error_disable;
1708	}
1709
1710	switch (xgifb_info->chip_id) {
1711	case PCI_DEVICE_ID_XGI_20:
1712		xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
1713		CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
1714		if (CR48&GPIOG_READ)
1715			xgifb_info->chip = XG21;
1716		else
1717			xgifb_info->chip = XG20;
1718		break;
1719	case PCI_DEVICE_ID_XGI_40:
1720		xgifb_info->chip = XG40;
1721		break;
1722	case PCI_DEVICE_ID_XGI_42:
1723		xgifb_info->chip = XG42;
1724		break;
1725	case PCI_DEVICE_ID_XGI_27:
1726		xgifb_info->chip = XG27;
1727		break;
1728	default:
1729		ret = -ENODEV;
1730		goto error_disable;
1731	}
1732
1733	dev_info(&pdev->dev, "chipid = %x\n", xgifb_info->chip);
1734	hw_info->jChipType = xgifb_info->chip;
1735
1736	if (XGIfb_get_dram_size(xgifb_info)) {
1737		xgifb_info->video_size = min_t(unsigned long, video_size_max,
1738						SZ_16M);
1739	} else if (xgifb_info->video_size > video_size_max) {
1740		xgifb_info->video_size = video_size_max;
1741	}
1742
1743	/* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
1744	xgifb_reg_or(XGISR,
1745		     IND_SIS_PCI_ADDRESS_SET,
1746		     (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
1747	/* Enable 2D accelerator engine */
1748	xgifb_reg_or(XGISR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
1749
1750	hw_info->ulVideoMemorySize = xgifb_info->video_size;
1751
1752	if (!request_mem_region(xgifb_info->video_base,
1753				xgifb_info->video_size,
1754				"XGIfb FB")) {
1755		dev_err(&pdev->dev, "Unable request memory size %x\n",
1756		       xgifb_info->video_size);
1757		dev_err(&pdev->dev,
1758			"Fatal error: Unable to reserve frame buffer memory. Is there another framebuffer driver active?\n");
1759		ret = -ENODEV;
1760		goto error_disable;
1761	}
1762
1763	if (!request_mem_region(xgifb_info->mmio_base,
1764				xgifb_info->mmio_size,
1765				"XGIfb MMIO")) {
1766		dev_err(&pdev->dev,
1767			"Fatal error: Unable to reserve MMIO region\n");
1768		ret = -ENODEV;
1769		goto error_0;
1770	}
1771
1772	xgifb_info->video_vbase = hw_info->pjVideoMemoryAddress =
1773	ioremap(xgifb_info->video_base, xgifb_info->video_size);
1774	xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base,
1775					    xgifb_info->mmio_size);
1776
1777	dev_info(&pdev->dev,
1778		 "Framebuffer at 0x%Lx, mapped to 0x%p, size %dk\n",
1779		 (u64) xgifb_info->video_base,
1780		 xgifb_info->video_vbase,
1781		 xgifb_info->video_size / 1024);
1782
1783	dev_info(&pdev->dev,
1784		 "MMIO at 0x%Lx, mapped to 0x%p, size %ldk\n",
1785		 (u64) xgifb_info->mmio_base, xgifb_info->mmio_vbase,
1786		 xgifb_info->mmio_size / 1024);
1787
1788	pci_set_drvdata(pdev, xgifb_info);
1789	if (!XGIInitNew(pdev))
1790		dev_err(&pdev->dev, "XGIInitNew() failed!\n");
1791
1792	xgifb_info->mtrr = -1;
1793
1794	xgifb_info->hasVB = HASVB_NONE;
1795	if ((xgifb_info->chip == XG20) ||
1796	    (xgifb_info->chip == XG27)) {
1797		xgifb_info->hasVB = HASVB_NONE;
1798	} else if (xgifb_info->chip == XG21) {
1799		CR38 = xgifb_reg_get(XGICR, 0x38);
1800		if ((CR38&0xE0) == 0xC0)
1801			xgifb_info->display2 = XGIFB_DISP_LCD;
1802		else if ((CR38&0xE0) == 0x60)
1803			xgifb_info->hasVB = HASVB_CHRONTEL;
1804		else
1805			xgifb_info->hasVB = HASVB_NONE;
1806	} else {
1807		XGIfb_get_VB_type(xgifb_info);
1808	}
1809
1810	hw_info->ujVBChipID = VB_CHIP_UNKNOWN;
1811
1812	hw_info->ulExternalChip = 0;
1813
1814	switch (xgifb_info->hasVB) {
1815	case HASVB_301:
1816		reg = xgifb_reg_get(XGIPART4, 0x01);
1817		if (reg >= 0xE0) {
1818			hw_info->ujVBChipID = VB_CHIP_302LV;
1819			dev_info(&pdev->dev,
1820				 "XGI302LV bridge detected (revision 0x%02x)\n",
1821				 reg);
1822		} else if (reg >= 0xD0) {
1823			hw_info->ujVBChipID = VB_CHIP_301LV;
1824			dev_info(&pdev->dev,
1825				 "XGI301LV bridge detected (revision 0x%02x)\n",
1826				 reg);
1827		} else {
1828			hw_info->ujVBChipID = VB_CHIP_301;
1829			dev_info(&pdev->dev, "XGI301 bridge detected\n");
1830		}
1831		break;
1832	case HASVB_302:
1833		reg = xgifb_reg_get(XGIPART4, 0x01);
1834		if (reg >= 0xE0) {
1835			hw_info->ujVBChipID = VB_CHIP_302LV;
1836			dev_info(&pdev->dev,
1837				 "XGI302LV bridge detected (revision 0x%02x)\n",
1838				 reg);
1839		} else if (reg >= 0xD0) {
1840			hw_info->ujVBChipID = VB_CHIP_301LV;
1841			dev_info(&pdev->dev,
1842				 "XGI302LV bridge detected (revision 0x%02x)\n",
1843				 reg);
1844		} else if (reg >= 0xB0) {
1845			reg1 = xgifb_reg_get(XGIPART4, 0x23);
1846
1847			hw_info->ujVBChipID = VB_CHIP_302B;
1848
1849		} else {
1850			hw_info->ujVBChipID = VB_CHIP_302;
1851			dev_info(&pdev->dev, "XGI302 bridge detected\n");
1852		}
1853		break;
1854	case HASVB_LVDS:
1855		hw_info->ulExternalChip = 0x1;
1856		dev_info(&pdev->dev, "LVDS transmitter detected\n");
1857		break;
1858	case HASVB_TRUMPION:
1859		hw_info->ulExternalChip = 0x2;
1860		dev_info(&pdev->dev, "Trumpion Zurac LVDS scaler detected\n");
1861		break;
1862	case HASVB_CHRONTEL:
1863		hw_info->ulExternalChip = 0x4;
1864		dev_info(&pdev->dev, "Chrontel TV encoder detected\n");
1865		break;
1866	case HASVB_LVDS_CHRONTEL:
1867		hw_info->ulExternalChip = 0x5;
1868		dev_info(&pdev->dev,
1869			 "LVDS transmitter and Chrontel TV encoder detected\n");
1870		break;
1871	default:
1872		dev_info(&pdev->dev, "No or unknown bridge type detected\n");
1873		break;
1874	}
1875
1876	if (xgifb_info->hasVB != HASVB_NONE)
1877		XGIfb_detect_VB(xgifb_info);
1878	else if (xgifb_info->chip != XG21)
1879		xgifb_info->display2 = XGIFB_DISP_NONE;
1880
1881	if (xgifb_info->display2 == XGIFB_DISP_LCD) {
1882		if (!enable_dstn) {
1883			reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
1884			reg &= 0x0f;
1885			hw_info->ulCRT2LCDType = XGI310paneltype[reg];
1886		}
1887	}
1888
1889	xgifb_info->mode_idx = -1;
1890
1891	if (mode)
1892		XGIfb_search_mode(xgifb_info, mode);
1893	else if (vesa != -1)
1894		XGIfb_search_vesamode(xgifb_info, vesa);
1895
1896	if (xgifb_info->mode_idx >= 0)
1897		xgifb_info->mode_idx =
1898			XGIfb_validate_mode(xgifb_info, xgifb_info->mode_idx);
1899
1900	if (xgifb_info->mode_idx < 0) {
1901		if (xgifb_info->display2 == XGIFB_DISP_LCD &&
1902		    xgifb_info->chip == XG21)
1903			xgifb_info->mode_idx =
1904				XGIfb_GetXG21DefaultLVDSModeIdx(xgifb_info);
1905		else
1906			xgifb_info->mode_idx = DEFAULT_MODE;
1907	}
1908
1909	if (xgifb_info->mode_idx < 0) {
1910		dev_err(&pdev->dev, "No supported video mode found\n");
1911		ret = -EINVAL;
1912		goto error_1;
1913	}
1914
1915	/* set default refresh rate */
1916	xgifb_info->refresh_rate = refresh_rate;
1917	if (xgifb_info->refresh_rate == 0)
1918		xgifb_info->refresh_rate = 60;
1919	if (XGIfb_search_refresh_rate(xgifb_info,
1920			xgifb_info->refresh_rate) == 0) {
1921		xgifb_info->rate_idx = 1;
1922		xgifb_info->refresh_rate = 60;
1923	}
1924
1925	xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp;
1926	xgifb_info->video_vwidth =
1927		xgifb_info->video_width =
1928			XGIbios_mode[xgifb_info->mode_idx].xres;
1929	xgifb_info->video_vheight =
1930		xgifb_info->video_height =
1931			XGIbios_mode[xgifb_info->mode_idx].yres;
1932	xgifb_info->org_x = xgifb_info->org_y = 0;
1933	xgifb_info->video_linelength =
1934		xgifb_info->video_width *
1935		(xgifb_info->video_bpp >> 3);
1936	switch (xgifb_info->video_bpp) {
1937	case 8:
1938		xgifb_info->DstColor = 0x0000;
1939		xgifb_info->XGI310_AccelDepth = 0x00000000;
1940		xgifb_info->video_cmap_len = 256;
1941		break;
1942	case 16:
1943		xgifb_info->DstColor = 0x8000;
1944		xgifb_info->XGI310_AccelDepth = 0x00010000;
1945		xgifb_info->video_cmap_len = 16;
1946		break;
1947	case 32:
1948		xgifb_info->DstColor = 0xC000;
1949		xgifb_info->XGI310_AccelDepth = 0x00020000;
1950		xgifb_info->video_cmap_len = 16;
1951		break;
1952	default:
1953		xgifb_info->video_cmap_len = 16;
1954		pr_info("Unsupported depth %d\n",
1955		       xgifb_info->video_bpp);
1956		break;
1957	}
1958
1959	pr_info("Default mode is %dx%dx%d (%dHz)\n",
1960	       xgifb_info->video_width,
1961	       xgifb_info->video_height,
1962	       xgifb_info->video_bpp,
1963	       xgifb_info->refresh_rate);
1964
1965	fb_info->var.red.length		= 8;
1966	fb_info->var.green.length	= 8;
1967	fb_info->var.blue.length	= 8;
1968	fb_info->var.activate		= FB_ACTIVATE_NOW;
1969	fb_info->var.height		= -1;
1970	fb_info->var.width		= -1;
1971	fb_info->var.vmode		= FB_VMODE_NONINTERLACED;
1972	fb_info->var.xres		= xgifb_info->video_width;
1973	fb_info->var.xres_virtual	= xgifb_info->video_width;
1974	fb_info->var.yres		= xgifb_info->video_height;
1975	fb_info->var.yres_virtual	= xgifb_info->video_height;
1976	fb_info->var.bits_per_pixel	= xgifb_info->video_bpp;
1977
1978	XGIfb_bpp_to_var(xgifb_info, &fb_info->var);
1979
1980	fb_info->var.pixclock = (u32) (1000000000 /
1981			XGIfb_mode_rate_to_dclock(&xgifb_info->dev_info,
1982				hw_info,
1983				XGIbios_mode[xgifb_info->mode_idx].mode_no));
1984
1985	if (XGIfb_mode_rate_to_ddata(&xgifb_info->dev_info, hw_info,
1986		XGIbios_mode[xgifb_info->mode_idx].mode_no,
1987		&fb_info->var.left_margin,
1988		&fb_info->var.right_margin,
1989		&fb_info->var.upper_margin,
1990		&fb_info->var.lower_margin,
1991		&fb_info->var.hsync_len,
1992		&fb_info->var.vsync_len,
1993		&fb_info->var.sync,
1994		&fb_info->var.vmode)) {
1995
1996		if ((fb_info->var.vmode & FB_VMODE_MASK) ==
1997		    FB_VMODE_INTERLACED) {
1998			fb_info->var.yres <<= 1;
1999			fb_info->var.yres_virtual <<= 1;
2000		} else if ((fb_info->var.vmode & FB_VMODE_MASK) ==
2001			   FB_VMODE_DOUBLE) {
2002			fb_info->var.pixclock >>= 1;
2003			fb_info->var.yres >>= 1;
2004			fb_info->var.yres_virtual >>= 1;
2005		}
2006
2007	}
2008
2009	fb_info->flags = FBINFO_FLAG_DEFAULT;
2010	fb_info->screen_base = xgifb_info->video_vbase;
2011	fb_info->fbops = &XGIfb_ops;
2012	XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2013	fb_info->pseudo_palette = xgifb_info->pseudo_palette;
2014
2015	fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2016
2017#ifdef CONFIG_MTRR
2018	xgifb_info->mtrr = mtrr_add(xgifb_info->video_base,
2019		xgifb_info->video_size, MTRR_TYPE_WRCOMB, 1);
2020	if (xgifb_info->mtrr >= 0)
2021		dev_info(&pdev->dev, "Added MTRR\n");
2022#endif
2023
2024	if (register_framebuffer(fb_info) < 0) {
2025		ret = -EINVAL;
2026		goto error_mtrr;
2027	}
2028
2029	dumpVGAReg();
2030
2031	return 0;
2032
2033error_mtrr:
2034#ifdef CONFIG_MTRR
2035	if (xgifb_info->mtrr >= 0)
2036		mtrr_del(xgifb_info->mtrr, xgifb_info->video_base,
2037			xgifb_info->video_size);
2038#endif /* CONFIG_MTRR */
2039error_1:
2040	iounmap(xgifb_info->mmio_vbase);
2041	iounmap(xgifb_info->video_vbase);
2042	release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
2043error_0:
2044	release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
2045error_disable:
2046	pci_disable_device(pdev);
2047error:
2048	framebuffer_release(fb_info);
2049	return ret;
2050}
2051
2052/*****************************************************/
2053/*                PCI DEVICE HANDLING                */
2054/*****************************************************/
2055
2056static void xgifb_remove(struct pci_dev *pdev)
2057{
2058	struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
2059	struct fb_info *fb_info = xgifb_info->fb_info;
2060
2061	unregister_framebuffer(fb_info);
2062#ifdef CONFIG_MTRR
2063	if (xgifb_info->mtrr >= 0)
2064		mtrr_del(xgifb_info->mtrr, xgifb_info->video_base,
2065			xgifb_info->video_size);
2066#endif /* CONFIG_MTRR */
2067	iounmap(xgifb_info->mmio_vbase);
2068	iounmap(xgifb_info->video_vbase);
2069	release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
2070	release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
2071	pci_disable_device(pdev);
2072	framebuffer_release(fb_info);
2073}
2074
2075static struct pci_driver xgifb_driver = {
2076	.name = "xgifb",
2077	.id_table = xgifb_pci_table,
2078	.probe = xgifb_probe,
2079	.remove = xgifb_remove
2080};
2081
2082
2083
2084/*****************************************************/
2085/*                      MODULE                       */
2086/*****************************************************/
2087
2088module_param(mode, charp, 0);
2089MODULE_PARM_DESC(mode,
2090	"Selects the desired default display mode in the format XxYxDepth (eg. 1024x768x16).");
2091
2092module_param(forcecrt2type, charp, 0);
2093MODULE_PARM_DESC(forcecrt2type,
2094	"Force the second display output type. Possible values are NONE, LCD, TV, VGA, SVIDEO or COMPOSITE.");
2095
2096module_param(vesa, int, 0);
2097MODULE_PARM_DESC(vesa,
2098	"Selects the desired default display mode by VESA mode number (eg. 0x117).");
2099
2100module_param(filter, int, 0);
2101MODULE_PARM_DESC(filter,
2102	"Selects TV flicker filter type (only for systems with a SiS301 video bridge). Possible values 0-7. Default: [no filter]).");
2103
2104static int __init xgifb_init(void)
2105{
2106	char *option = NULL;
2107
2108	if (forcecrt2type != NULL)
2109		XGIfb_search_crt2type(forcecrt2type);
2110	if (fb_get_options("xgifb", &option))
2111		return -ENODEV;
2112	XGIfb_setup(option);
2113
2114	return pci_register_driver(&xgifb_driver);
2115}
2116
2117static void __exit xgifb_remove_module(void)
2118{
2119	pci_unregister_driver(&xgifb_driver);
2120	pr_debug("Module unloaded\n");
2121}
2122
2123MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2124MODULE_LICENSE("GPL");
2125MODULE_AUTHOR("XGITECH , Others");
2126module_init(xgifb_init);
2127module_exit(xgifb_remove_module);
2128