1/*
2 *  SGI GBE frame buffer driver
3 *
4 *  Copyright (C) 1999 Silicon Graphics, Inc. - Jeffrey Newquist
5 *  Copyright (C) 2002 Vivien Chappelier <vivien.chappelier@linux-mips.org>
6 *
7 *  This file is subject to the terms and conditions of the GNU General Public
8 *  License. See the file COPYING in the main directory of this archive for
9 *  more details.
10 */
11
12#include <linux/delay.h>
13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h>
15#include <linux/errno.h>
16#include <linux/gfp.h>
17#include <linux/fb.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/kernel.h>
21#include <linux/mm.h>
22#include <linux/module.h>
23
24#ifdef CONFIG_X86
25#include <asm/mtrr.h>
26#endif
27#ifdef CONFIG_MIPS
28#include <asm/addrspace.h>
29#endif
30#include <asm/byteorder.h>
31#include <asm/io.h>
32#include <asm/tlbflush.h>
33
34#include <video/gbe.h>
35
36static struct sgi_gbe *gbe;
37
38struct gbefb_par {
39	struct fb_var_screeninfo var;
40	struct gbe_timing_info timing;
41	int valid;
42};
43
44#ifdef CONFIG_SGI_IP32
45#define GBE_BASE	0x16000000 /* SGI O2 */
46#endif
47
48#ifdef CONFIG_X86_VISWS
49#define GBE_BASE	0xd0000000 /* SGI Visual Workstation */
50#endif
51
52/* macro for fastest write-though access to the framebuffer */
53#ifdef CONFIG_MIPS
54#ifdef CONFIG_CPU_R10000
55#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
56#else
57#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
58#endif
59#endif
60#ifdef CONFIG_X86
61#define pgprot_fb(_prot) ((_prot) | _PAGE_PCD)
62#endif
63
64/*
65 *  RAM we reserve for the frame buffer. This defines the maximum screen
66 *  size
67 */
68#if CONFIG_FB_GBE_MEM > 8
69#error GBE Framebuffer cannot use more than 8MB of memory
70#endif
71
72#define TILE_SHIFT 16
73#define TILE_SIZE (1 << TILE_SHIFT)
74#define TILE_MASK (TILE_SIZE - 1)
75
76static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;
77static void *gbe_mem;
78static dma_addr_t gbe_dma_addr;
79static unsigned long gbe_mem_phys;
80
81static struct {
82	uint16_t *cpu;
83	dma_addr_t dma;
84} gbe_tiles;
85
86static int gbe_revision;
87
88static int ypan, ywrap;
89
90static uint32_t pseudo_palette[16];
91static uint32_t gbe_cmap[256];
92static int gbe_turned_on; /* 0 turned off, 1 turned on */
93
94static char *mode_option __devinitdata = NULL;
95
96/* default CRT mode */
97static struct fb_var_screeninfo default_var_CRT __devinitdata = {
98	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
99	.xres		= 640,
100	.yres		= 480,
101	.xres_virtual	= 640,
102	.yres_virtual	= 480,
103	.xoffset	= 0,
104	.yoffset	= 0,
105	.bits_per_pixel	= 8,
106	.grayscale	= 0,
107	.red		= { 0, 8, 0 },
108	.green		= { 0, 8, 0 },
109	.blue		= { 0, 8, 0 },
110	.transp		= { 0, 0, 0 },
111	.nonstd		= 0,
112	.activate	= 0,
113	.height		= -1,
114	.width		= -1,
115	.accel_flags	= 0,
116	.pixclock	= 39722,	/* picoseconds */
117	.left_margin	= 48,
118	.right_margin	= 16,
119	.upper_margin	= 33,
120	.lower_margin	= 10,
121	.hsync_len	= 96,
122	.vsync_len	= 2,
123	.sync		= 0,
124	.vmode		= FB_VMODE_NONINTERLACED,
125};
126
127/* default LCD mode */
128static struct fb_var_screeninfo default_var_LCD __devinitdata = {
129	/* 1600x1024, 8 bpp */
130	.xres		= 1600,
131	.yres		= 1024,
132	.xres_virtual	= 1600,
133	.yres_virtual	= 1024,
134	.xoffset	= 0,
135	.yoffset	= 0,
136	.bits_per_pixel	= 8,
137	.grayscale	= 0,
138	.red		= { 0, 8, 0 },
139	.green		= { 0, 8, 0 },
140	.blue		= { 0, 8, 0 },
141	.transp		= { 0, 0, 0 },
142	.nonstd		= 0,
143	.activate	= 0,
144	.height		= -1,
145	.width		= -1,
146	.accel_flags	= 0,
147	.pixclock	= 9353,
148	.left_margin	= 20,
149	.right_margin	= 30,
150	.upper_margin	= 37,
151	.lower_margin	= 3,
152	.hsync_len	= 20,
153	.vsync_len	= 3,
154	.sync		= 0,
155	.vmode		= FB_VMODE_NONINTERLACED
156};
157
158/* default modedb mode */
159/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
160static struct fb_videomode default_mode_CRT __devinitdata = {
161	.refresh	= 60,
162	.xres		= 640,
163	.yres		= 480,
164	.pixclock	= 39722,
165	.left_margin	= 48,
166	.right_margin	= 16,
167	.upper_margin	= 33,
168	.lower_margin	= 10,
169	.hsync_len	= 96,
170	.vsync_len	= 2,
171	.sync		= 0,
172	.vmode		= FB_VMODE_NONINTERLACED,
173};
174/* 1600x1024 SGI flatpanel 1600sw */
175static struct fb_videomode default_mode_LCD __devinitdata = {
176	/* 1600x1024, 8 bpp */
177	.xres		= 1600,
178	.yres		= 1024,
179	.pixclock	= 9353,
180	.left_margin	= 20,
181	.right_margin	= 30,
182	.upper_margin	= 37,
183	.lower_margin	= 3,
184	.hsync_len	= 20,
185	.vsync_len	= 3,
186	.vmode		= FB_VMODE_NONINTERLACED,
187};
188
189static struct fb_videomode *default_mode __devinitdata = &default_mode_CRT;
190static struct fb_var_screeninfo *default_var __devinitdata = &default_var_CRT;
191
192static int flat_panel_enabled = 0;
193
194static void gbe_reset(void)
195{
196	/* Turn on dotclock PLL */
197	gbe->ctrlstat = 0x300aa000;
198}
199
200
201/*
202 * Function:	gbe_turn_off
203 * Parameters:	(None)
204 * Description:	This should turn off the monitor and gbe.  This is used
205 *              when switching between the serial console and the graphics
206 *              console.
207 */
208
209static void gbe_turn_off(void)
210{
211	int i;
212	unsigned int val, x, y, vpixen_off;
213
214	gbe_turned_on = 0;
215
216	/* check if pixel counter is on */
217	val = gbe->vt_xy;
218	if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)
219		return;
220
221	/* turn off DMA */
222	val = gbe->ovr_control;
223	SET_GBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, val, 0);
224	gbe->ovr_control = val;
225	udelay(1000);
226	val = gbe->frm_control;
227	SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
228	gbe->frm_control = val;
229	udelay(1000);
230	val = gbe->did_control;
231	SET_GBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, val, 0);
232	gbe->did_control = val;
233	udelay(1000);
234
235	/* We have to wait through two vertical retrace periods before
236	 * the pixel DMA is turned off for sure. */
237	for (i = 0; i < 10000; i++) {
238		val = gbe->frm_inhwctrl;
239		if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val)) {
240			udelay(10);
241		} else {
242			val = gbe->ovr_inhwctrl;
243			if (GET_GBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, val)) {
244				udelay(10);
245			} else {
246				val = gbe->did_inhwctrl;
247				if (GET_GBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, val)) {
248					udelay(10);
249				} else
250					break;
251			}
252		}
253	}
254	if (i == 10000)
255		printk(KERN_ERR "gbefb: turn off DMA timed out\n");
256
257	/* wait for vpixen_off */
258	val = gbe->vt_vpixen;
259	vpixen_off = GET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val);
260
261	for (i = 0; i < 100000; i++) {
262		val = gbe->vt_xy;
263		x = GET_GBE_FIELD(VT_XY, X, val);
264		y = GET_GBE_FIELD(VT_XY, Y, val);
265		if (y < vpixen_off)
266			break;
267		udelay(1);
268	}
269	if (i == 100000)
270		printk(KERN_ERR
271		       "gbefb: wait for vpixen_off timed out\n");
272	for (i = 0; i < 10000; i++) {
273		val = gbe->vt_xy;
274		x = GET_GBE_FIELD(VT_XY, X, val);
275		y = GET_GBE_FIELD(VT_XY, Y, val);
276		if (y > vpixen_off)
277			break;
278		udelay(1);
279	}
280	if (i == 10000)
281		printk(KERN_ERR "gbefb: wait for vpixen_off timed out\n");
282
283	/* turn off pixel counter */
284	val = 0;
285	SET_GBE_FIELD(VT_XY, FREEZE, val, 1);
286	gbe->vt_xy = val;
287	udelay(10000);
288	for (i = 0; i < 10000; i++) {
289		val = gbe->vt_xy;
290		if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)
291			udelay(10);
292		else
293			break;
294	}
295	if (i == 10000)
296		printk(KERN_ERR "gbefb: turn off pixel clock timed out\n");
297
298	/* turn off dot clock */
299	val = gbe->dotclock;
300	SET_GBE_FIELD(DOTCLK, RUN, val, 0);
301	gbe->dotclock = val;
302	udelay(10000);
303	for (i = 0; i < 10000; i++) {
304		val = gbe->dotclock;
305		if (GET_GBE_FIELD(DOTCLK, RUN, val))
306			udelay(10);
307		else
308			break;
309	}
310	if (i == 10000)
311		printk(KERN_ERR "gbefb: turn off dotclock timed out\n");
312
313	/* reset the frame DMA FIFO */
314	val = gbe->frm_size_tile;
315	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 1);
316	gbe->frm_size_tile = val;
317	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 0);
318	gbe->frm_size_tile = val;
319}
320
321static void gbe_turn_on(void)
322{
323	unsigned int val, i;
324
325	/*
326	 * Check if pixel counter is off, for unknown reason this
327	 * code hangs Visual Workstations
328	 */
329	if (gbe_revision < 2) {
330		val = gbe->vt_xy;
331		if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 0)
332			return;
333	}
334
335	/* turn on dot clock */
336	val = gbe->dotclock;
337	SET_GBE_FIELD(DOTCLK, RUN, val, 1);
338	gbe->dotclock = val;
339	udelay(10000);
340	for (i = 0; i < 10000; i++) {
341		val = gbe->dotclock;
342		if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)
343			udelay(10);
344		else
345			break;
346	}
347	if (i == 10000)
348		printk(KERN_ERR "gbefb: turn on dotclock timed out\n");
349
350	/* turn on pixel counter */
351	val = 0;
352	SET_GBE_FIELD(VT_XY, FREEZE, val, 0);
353	gbe->vt_xy = val;
354	udelay(10000);
355	for (i = 0; i < 10000; i++) {
356		val = gbe->vt_xy;
357		if (GET_GBE_FIELD(VT_XY, FREEZE, val))
358			udelay(10);
359		else
360			break;
361	}
362	if (i == 10000)
363		printk(KERN_ERR "gbefb: turn on pixel clock timed out\n");
364
365	/* turn on DMA */
366	val = gbe->frm_control;
367	SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 1);
368	gbe->frm_control = val;
369	udelay(1000);
370	for (i = 0; i < 10000; i++) {
371		val = gbe->frm_inhwctrl;
372		if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val) != 1)
373			udelay(10);
374		else
375			break;
376	}
377	if (i == 10000)
378		printk(KERN_ERR "gbefb: turn on DMA timed out\n");
379
380	gbe_turned_on = 1;
381}
382
383static void gbe_loadcmap(void)
384{
385	int i, j;
386
387	for (i = 0; i < 256; i++) {
388		for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
389			udelay(10);
390		if (j == 1000)
391			printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
392
393		gbe->cmap[i] = gbe_cmap[i];
394	}
395}
396
397/*
398 *  Blank the display.
399 */
400static int gbefb_blank(int blank, struct fb_info *info)
401{
402	/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
403	switch (blank) {
404	case FB_BLANK_UNBLANK:		/* unblank */
405		gbe_turn_on();
406		gbe_loadcmap();
407		break;
408
409	case FB_BLANK_NORMAL:		/* blank */
410		gbe_turn_off();
411		break;
412
413	default:
414		/* Nothing */
415		break;
416	}
417	return 0;
418}
419
420/*
421 *  Setup flatpanel related registers.
422 */
423static void gbefb_setup_flatpanel(struct gbe_timing_info *timing)
424{
425	int fp_wid, fp_hgt, fp_vbs, fp_vbe;
426	u32 outputVal = 0;
427
428	SET_GBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
429		(timing->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
430	SET_GBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
431		(timing->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
432	gbe->vt_flags = outputVal;
433
434	/* Turn on the flat panel */
435	fp_wid = 1600;
436	fp_hgt = 1024;
437	fp_vbs = 0;
438	fp_vbe = 1600;
439	timing->pll_m = 4;
440	timing->pll_n = 1;
441	timing->pll_p = 0;
442
443	outputVal = 0;
444	SET_GBE_FIELD(FP_DE, ON, outputVal, fp_vbs);
445	SET_GBE_FIELD(FP_DE, OFF, outputVal, fp_vbe);
446	gbe->fp_de = outputVal;
447	outputVal = 0;
448	SET_GBE_FIELD(FP_HDRV, OFF, outputVal, fp_wid);
449	gbe->fp_hdrv = outputVal;
450	outputVal = 0;
451	SET_GBE_FIELD(FP_VDRV, ON, outputVal, 1);
452	SET_GBE_FIELD(FP_VDRV, OFF, outputVal, fp_hgt + 1);
453	gbe->fp_vdrv = outputVal;
454}
455
456struct gbe_pll_info {
457	int clock_rate;
458	int fvco_min;
459	int fvco_max;
460};
461
462static struct gbe_pll_info gbe_pll_table[2] = {
463	{ 20, 80, 220 },
464	{ 27, 80, 220 },
465};
466
467static int compute_gbe_timing(struct fb_var_screeninfo *var,
468			      struct gbe_timing_info *timing)
469{
470	int pll_m, pll_n, pll_p, error, best_m, best_n, best_p, best_error;
471	int pixclock;
472	struct gbe_pll_info *gbe_pll;
473
474	if (gbe_revision < 2)
475		gbe_pll = &gbe_pll_table[0];
476	else
477		gbe_pll = &gbe_pll_table[1];
478
479	/* Determine valid resolution and timing
480	 * GBE crystal runs at 20Mhz or 27Mhz
481	 * pll_m, pll_n, pll_p define the following frequencies
482	 * fvco = pll_m * 20Mhz / pll_n
483	 * fout = fvco / (2**pll_p) */
484	best_error = 1000000000;
485	best_n = best_m = best_p = 0;
486	for (pll_p = 0; pll_p < 4; pll_p++)
487		for (pll_m = 1; pll_m < 256; pll_m++)
488			for (pll_n = 1; pll_n < 64; pll_n++) {
489				pixclock = (1000000 / gbe_pll->clock_rate) *
490						(pll_n << pll_p) / pll_m;
491
492				error = var->pixclock - pixclock;
493
494				if (error < 0)
495					error = -error;
496
497				if (error < best_error &&
498				    pll_m / pll_n >
499				    gbe_pll->fvco_min / gbe_pll->clock_rate &&
500 				    pll_m / pll_n <
501				    gbe_pll->fvco_max / gbe_pll->clock_rate) {
502					best_error = error;
503					best_m = pll_m;
504					best_n = pll_n;
505					best_p = pll_p;
506				}
507			}
508
509	if (!best_n || !best_m)
510		return -EINVAL;	/* Resolution to high */
511
512	pixclock = (1000000 / gbe_pll->clock_rate) *
513		(best_n << best_p) / best_m;
514
515	/* set video timing information */
516	if (timing) {
517		timing->width = var->xres;
518		timing->height = var->yres;
519		timing->pll_m = best_m;
520		timing->pll_n = best_n;
521		timing->pll_p = best_p;
522		timing->cfreq = gbe_pll->clock_rate * 1000 * timing->pll_m /
523			(timing->pll_n << timing->pll_p);
524		timing->htotal = var->left_margin + var->xres +
525				var->right_margin + var->hsync_len;
526		timing->vtotal = var->upper_margin + var->yres +
527				var->lower_margin + var->vsync_len;
528		timing->fields_sec = 1000 * timing->cfreq / timing->htotal *
529				1000 / timing->vtotal;
530		timing->hblank_start = var->xres;
531		timing->vblank_start = var->yres;
532		timing->hblank_end = timing->htotal;
533		timing->hsync_start = var->xres + var->right_margin + 1;
534		timing->hsync_end = timing->hsync_start + var->hsync_len;
535		timing->vblank_end = timing->vtotal;
536		timing->vsync_start = var->yres + var->lower_margin + 1;
537		timing->vsync_end = timing->vsync_start + var->vsync_len;
538	}
539
540	return pixclock;
541}
542
543static void gbe_set_timing_info(struct gbe_timing_info *timing)
544{
545	int temp;
546	unsigned int val;
547
548	/* setup dot clock PLL */
549	val = 0;
550	SET_GBE_FIELD(DOTCLK, M, val, timing->pll_m - 1);
551	SET_GBE_FIELD(DOTCLK, N, val, timing->pll_n - 1);
552	SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);
553	SET_GBE_FIELD(DOTCLK, RUN, val, 0);	/* do not start yet */
554	gbe->dotclock = val;
555	udelay(10000);
556
557	/* setup pixel counter */
558	val = 0;
559	SET_GBE_FIELD(VT_XYMAX, MAXX, val, timing->htotal);
560	SET_GBE_FIELD(VT_XYMAX, MAXY, val, timing->vtotal);
561	gbe->vt_xymax = val;
562
563	/* setup video timing signals */
564	val = 0;
565	SET_GBE_FIELD(VT_VSYNC, VSYNC_ON, val, timing->vsync_start);
566	SET_GBE_FIELD(VT_VSYNC, VSYNC_OFF, val, timing->vsync_end);
567	gbe->vt_vsync = val;
568	val = 0;
569	SET_GBE_FIELD(VT_HSYNC, HSYNC_ON, val, timing->hsync_start);
570	SET_GBE_FIELD(VT_HSYNC, HSYNC_OFF, val, timing->hsync_end);
571	gbe->vt_hsync = val;
572	val = 0;
573	SET_GBE_FIELD(VT_VBLANK, VBLANK_ON, val, timing->vblank_start);
574	SET_GBE_FIELD(VT_VBLANK, VBLANK_OFF, val, timing->vblank_end);
575	gbe->vt_vblank = val;
576	val = 0;
577	SET_GBE_FIELD(VT_HBLANK, HBLANK_ON, val,
578		      timing->hblank_start - 5);
579	SET_GBE_FIELD(VT_HBLANK, HBLANK_OFF, val,
580		      timing->hblank_end - 3);
581	gbe->vt_hblank = val;
582
583	/* setup internal timing signals */
584	val = 0;
585	SET_GBE_FIELD(VT_VCMAP, VCMAP_ON, val, timing->vblank_start);
586	SET_GBE_FIELD(VT_VCMAP, VCMAP_OFF, val, timing->vblank_end);
587	gbe->vt_vcmap = val;
588	val = 0;
589	SET_GBE_FIELD(VT_HCMAP, HCMAP_ON, val, timing->hblank_start);
590	SET_GBE_FIELD(VT_HCMAP, HCMAP_OFF, val, timing->hblank_end);
591	gbe->vt_hcmap = val;
592
593	val = 0;
594	temp = timing->vblank_start - timing->vblank_end - 1;
595	if (temp > 0)
596		temp = -temp;
597
598	if (flat_panel_enabled)
599		gbefb_setup_flatpanel(timing);
600
601	SET_GBE_FIELD(DID_START_XY, DID_STARTY, val, (u32) temp);
602	if (timing->hblank_end >= 20)
603		SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
604			      timing->hblank_end - 20);
605	else
606		SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
607			      timing->htotal - (20 - timing->hblank_end));
608	gbe->did_start_xy = val;
609
610	val = 0;
611	SET_GBE_FIELD(CRS_START_XY, CRS_STARTY, val, (u32) (temp + 1));
612	if (timing->hblank_end >= GBE_CRS_MAGIC)
613		SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
614			      timing->hblank_end - GBE_CRS_MAGIC);
615	else
616		SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
617			      timing->htotal - (GBE_CRS_MAGIC -
618						timing->hblank_end));
619	gbe->crs_start_xy = val;
620
621	val = 0;
622	SET_GBE_FIELD(VC_START_XY, VC_STARTY, val, (u32) temp);
623	SET_GBE_FIELD(VC_START_XY, VC_STARTX, val, timing->hblank_end - 4);
624	gbe->vc_start_xy = val;
625
626	val = 0;
627	temp = timing->hblank_end - GBE_PIXEN_MAGIC_ON;
628	if (temp < 0)
629		temp += timing->htotal;	/* allow blank to wrap around */
630
631	SET_GBE_FIELD(VT_HPIXEN, HPIXEN_ON, val, temp);
632	SET_GBE_FIELD(VT_HPIXEN, HPIXEN_OFF, val,
633		      ((temp + timing->width -
634			GBE_PIXEN_MAGIC_OFF) % timing->htotal));
635	gbe->vt_hpixen = val;
636
637	val = 0;
638	SET_GBE_FIELD(VT_VPIXEN, VPIXEN_ON, val, timing->vblank_end);
639	SET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val, timing->vblank_start);
640	gbe->vt_vpixen = val;
641
642	/* turn off sync on green */
643	val = 0;
644	SET_GBE_FIELD(VT_FLAGS, SYNC_LOW, val, 1);
645	gbe->vt_flags = val;
646}
647
648/*
649 *  Set the hardware according to 'par'.
650 */
651
652static int gbefb_set_par(struct fb_info *info)
653{
654	int i;
655	unsigned int val;
656	int wholeTilesX, partTilesX, maxPixelsPerTileX;
657	int height_pix;
658	int xpmax, ypmax;	/* Monitor resolution */
659	int bytesPerPixel;	/* Bytes per pixel */
660	struct gbefb_par *par = (struct gbefb_par *) info->par;
661
662	compute_gbe_timing(&info->var, &par->timing);
663
664	bytesPerPixel = info->var.bits_per_pixel / 8;
665	info->fix.line_length = info->var.xres_virtual * bytesPerPixel;
666	xpmax = par->timing.width;
667	ypmax = par->timing.height;
668
669	/* turn off GBE */
670	gbe_turn_off();
671
672	/* set timing info */
673	gbe_set_timing_info(&par->timing);
674
675	/* initialize DIDs */
676	val = 0;
677	switch (bytesPerPixel) {
678	case 1:
679		SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8);
680		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
681		break;
682	case 2:
683		SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5);
684		info->fix.visual = FB_VISUAL_TRUECOLOR;
685		break;
686	case 4:
687		SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8);
688		info->fix.visual = FB_VISUAL_TRUECOLOR;
689		break;
690	}
691	SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH);
692
693	for (i = 0; i < 32; i++)
694		gbe->mode_regs[i] = val;
695
696	/* Initialize interrupts */
697	gbe->vt_intr01 = 0xffffffff;
698	gbe->vt_intr23 = 0xffffffff;
699
700	/* HACK:
701	   The GBE hardware uses a tiled memory to screen mapping. Tiles are
702	   blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
703	   16bit and 32 bit modes (64 kB). They cover the screen with partial
704	   tiles on the right and/or bottom of the screen if needed.
705	   For example in 640x480 8 bit mode the mapping is:
706
707	   <-------- 640 ----->
708	   <---- 512 ----><128|384 offscreen>
709	   ^  ^
710	   | 128    [tile 0]        [tile 1]
711	   |  v
712	   ^
713	   4 128    [tile 2]        [tile 3]
714	   8  v
715	   0  ^
716	   128    [tile 4]        [tile 5]
717	   |  v
718	   |  ^
719	   v  96    [tile 6]        [tile 7]
720	   32 offscreen
721
722	   Tiles have the advantage that they can be allocated individually in
723	   memory. However, this mapping is not linear at all, which is not
724	   really convenient. In order to support linear addressing, the GBE
725	   DMA hardware is fooled into thinking the screen is only one tile
726	   large and but has a greater height, so that the DMA transfer covers
727	   the same region.
728	   Tiles are still allocated as independent chunks of 64KB of
729	   continuous physical memory and remapped so that the kernel sees the
730	   framebuffer as a continuous virtual memory. The GBE tile table is
731	   set up so that each tile references one of these 64k blocks:
732
733	   GBE -> tile list    framebuffer           TLB   <------------ CPU
734	          [ tile 0 ] -> [ 64KB ]  <- [ 16x 4KB page entries ]     ^
735	             ...           ...              ...       linear virtual FB
736	          [ tile n ] -> [ 64KB ]  <- [ 16x 4KB page entries ]     v
737
738
739	   The GBE hardware is then told that the buffer is 512*tweaked_height,
740	   with tweaked_height = real_width*real_height/pixels_per_tile.
741	   Thus the GBE hardware will scan the first tile, filing the first 64k
742	   covered region of the screen, and then will proceed to the next
743	   tile, until the whole screen is covered.
744
745	   Here is what would happen at 640x480 8bit:
746
747	   normal tiling               linear
748	   ^   11111111111111112222    11111111111111111111  ^
749	   128 11111111111111112222    11111111111111111111 102 lines
750	       11111111111111112222    11111111111111111111  v
751	   V   11111111111111112222    11111111222222222222
752	       33333333333333334444    22222222222222222222
753	       33333333333333334444    22222222222222222222
754	       <      512     >        <  256 >               102*640+256 = 64k
755
756	   NOTE: The only mode for which this is not working is 800x600 8bit,
757	   as 800*600/512 = 937.5 which is not integer and thus causes
758	   flickering.
759	   I guess this is not so important as one can use 640x480 8bit or
760	   800x600 16bit anyway.
761	 */
762
763	/* Tell gbe about the tiles table location */
764	/* tile_ptr -> [ tile 1 ] -> FB mem */
765	/*             [ tile 2 ] -> FB mem */
766	/*               ...                */
767	val = 0;
768	SET_GBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, val, gbe_tiles.dma >> 9);
769	SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0); /* do not start */
770	SET_GBE_FIELD(FRM_CONTROL, FRM_LINEAR, val, 0);
771	gbe->frm_control = val;
772
773	maxPixelsPerTileX = 512 / bytesPerPixel;
774	wholeTilesX = 1;
775	partTilesX = 0;
776
777	/* Initialize the framebuffer */
778	val = 0;
779	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, val, wholeTilesX);
780	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_RHS, val, partTilesX);
781
782	switch (bytesPerPixel) {
783	case 1:
784		SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
785			      GBE_FRM_DEPTH_8);
786		break;
787	case 2:
788		SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
789			      GBE_FRM_DEPTH_16);
790		break;
791	case 4:
792		SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
793			      GBE_FRM_DEPTH_32);
794		break;
795	}
796	gbe->frm_size_tile = val;
797
798	/* compute tweaked height */
799	height_pix = xpmax * ypmax / maxPixelsPerTileX;
800
801	val = 0;
802	SET_GBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, val, height_pix);
803	gbe->frm_size_pixel = val;
804
805	/* turn off DID and overlay DMA */
806	gbe->did_control = 0;
807	gbe->ovr_width_tile = 0;
808
809	/* Turn off mouse cursor */
810	gbe->crs_ctl = 0;
811
812	/* Turn on GBE */
813	gbe_turn_on();
814
815	/* Initialize the gamma map */
816	udelay(10);
817	for (i = 0; i < 256; i++)
818		gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8);
819
820	/* Initialize the color map */
821	for (i = 0; i < 256; i++)
822		gbe_cmap[i] = (i << 8) | (i << 16) | (i << 24);
823
824	gbe_loadcmap();
825
826	return 0;
827}
828
829static void gbefb_encode_fix(struct fb_fix_screeninfo *fix,
830			     struct fb_var_screeninfo *var)
831{
832	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
833	strcpy(fix->id, "SGI GBE");
834	fix->smem_start = (unsigned long) gbe_mem;
835	fix->smem_len = gbe_mem_size;
836	fix->type = FB_TYPE_PACKED_PIXELS;
837	fix->type_aux = 0;
838	fix->accel = FB_ACCEL_NONE;
839	switch (var->bits_per_pixel) {
840	case 8:
841		fix->visual = FB_VISUAL_PSEUDOCOLOR;
842		break;
843	default:
844		fix->visual = FB_VISUAL_TRUECOLOR;
845		break;
846	}
847	fix->ywrapstep = 0;
848	fix->xpanstep = 0;
849	fix->ypanstep = 0;
850	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
851	fix->mmio_start = GBE_BASE;
852	fix->mmio_len = sizeof(struct sgi_gbe);
853}
854
855/*
856 *  Set a single color register. The values supplied are already
857 *  rounded down to the hardware's capabilities (according to the
858 *  entries in the var structure). Return != 0 for invalid regno.
859 */
860
861static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green,
862			     unsigned blue, unsigned transp,
863			     struct fb_info *info)
864{
865	int i;
866
867	if (regno > 255)
868		return 1;
869	red >>= 8;
870	green >>= 8;
871	blue >>= 8;
872
873	if (info->var.bits_per_pixel <= 8) {
874		gbe_cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
875		if (gbe_turned_on) {
876			/* wait for the color map FIFO to have a free entry */
877			for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
878				udelay(10);
879			if (i == 1000) {
880				printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
881				return 1;
882			}
883			gbe->cmap[regno] = gbe_cmap[regno];
884		}
885	} else if (regno < 16) {
886		switch (info->var.bits_per_pixel) {
887		case 15:
888		case 16:
889			red >>= 3;
890			green >>= 3;
891			blue >>= 3;
892			pseudo_palette[regno] =
893				(red << info->var.red.offset) |
894				(green << info->var.green.offset) |
895				(blue << info->var.blue.offset);
896			break;
897		case 32:
898			pseudo_palette[regno] =
899				(red << info->var.red.offset) |
900				(green << info->var.green.offset) |
901				(blue << info->var.blue.offset);
902			break;
903		}
904	}
905
906	return 0;
907}
908
909/*
910 *  Check video mode validity, eventually modify var to best match.
911 */
912static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
913{
914	unsigned int line_length;
915	struct gbe_timing_info timing;
916	int ret;
917
918	/* Limit bpp to 8, 16, and 32 */
919	if (var->bits_per_pixel <= 8)
920		var->bits_per_pixel = 8;
921	else if (var->bits_per_pixel <= 16)
922		var->bits_per_pixel = 16;
923	else if (var->bits_per_pixel <= 32)
924		var->bits_per_pixel = 32;
925	else
926		return -EINVAL;
927
928	/* Check the mode can be mapped linearly with the tile table trick. */
929	/* This requires width x height x bytes/pixel be a multiple of 512 */
930	if ((var->xres * var->yres * var->bits_per_pixel) & 4095)
931		return -EINVAL;
932
933	var->grayscale = 0;	/* No grayscale for now */
934
935	ret = compute_gbe_timing(var, &timing);
936	var->pixclock = ret;
937	if (ret < 0)
938		return -EINVAL;
939
940	/* Adjust virtual resolution, if necessary */
941	if (var->xres > var->xres_virtual || (!ywrap && !ypan))
942		var->xres_virtual = var->xres;
943	if (var->yres > var->yres_virtual || (!ywrap && !ypan))
944		var->yres_virtual = var->yres;
945
946	if (var->vmode & FB_VMODE_CONUPDATE) {
947		var->vmode |= FB_VMODE_YWRAP;
948		var->xoffset = info->var.xoffset;
949		var->yoffset = info->var.yoffset;
950	}
951
952	/* No grayscale for now */
953	var->grayscale = 0;
954
955	/* Memory limit */
956	line_length = var->xres_virtual * var->bits_per_pixel / 8;
957	if (line_length * var->yres_virtual > gbe_mem_size)
958		return -ENOMEM;	/* Virtual resolution too high */
959
960	switch (var->bits_per_pixel) {
961	case 8:
962		var->red.offset = 0;
963		var->red.length = 8;
964		var->green.offset = 0;
965		var->green.length = 8;
966		var->blue.offset = 0;
967		var->blue.length = 8;
968		var->transp.offset = 0;
969		var->transp.length = 0;
970		break;
971	case 16:		/* RGB 1555 */
972		var->red.offset = 10;
973		var->red.length = 5;
974		var->green.offset = 5;
975		var->green.length = 5;
976		var->blue.offset = 0;
977		var->blue.length = 5;
978		var->transp.offset = 0;
979		var->transp.length = 0;
980		break;
981	case 32:		/* RGB 8888 */
982		var->red.offset = 24;
983		var->red.length = 8;
984		var->green.offset = 16;
985		var->green.length = 8;
986		var->blue.offset = 8;
987		var->blue.length = 8;
988		var->transp.offset = 0;
989		var->transp.length = 8;
990		break;
991	}
992	var->red.msb_right = 0;
993	var->green.msb_right = 0;
994	var->blue.msb_right = 0;
995	var->transp.msb_right = 0;
996
997	var->left_margin = timing.htotal - timing.hsync_end;
998	var->right_margin = timing.hsync_start - timing.width;
999	var->upper_margin = timing.vtotal - timing.vsync_end;
1000	var->lower_margin = timing.vsync_start - timing.height;
1001	var->hsync_len = timing.hsync_end - timing.hsync_start;
1002	var->vsync_len = timing.vsync_end - timing.vsync_start;
1003
1004	return 0;
1005}
1006
1007static int gbefb_mmap(struct fb_info *info,
1008			struct vm_area_struct *vma)
1009{
1010	unsigned long size = vma->vm_end - vma->vm_start;
1011	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1012	unsigned long addr;
1013	unsigned long phys_addr, phys_size;
1014	u16 *tile;
1015
1016	/* check range */
1017	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1018		return -EINVAL;
1019	if (offset + size > gbe_mem_size)
1020		return -EINVAL;
1021
1022	/* remap using the fastest write-through mode on architecture */
1023	/* try not polluting the cache when possible */
1024	pgprot_val(vma->vm_page_prot) =
1025		pgprot_fb(pgprot_val(vma->vm_page_prot));
1026
1027	vma->vm_flags |= VM_IO | VM_RESERVED;
1028
1029	/* look for the starting tile */
1030	tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1031	addr = vma->vm_start;
1032	offset &= TILE_MASK;
1033
1034	/* remap each tile separately */
1035	do {
1036		phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1037		if ((offset + size) < TILE_SIZE)
1038			phys_size = size;
1039		else
1040			phys_size = TILE_SIZE - offset;
1041
1042		if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1043						phys_size, vma->vm_page_prot))
1044			return -EAGAIN;
1045
1046		offset = 0;
1047		size -= phys_size;
1048		addr += phys_size;
1049		tile++;
1050	} while (size);
1051
1052	return 0;
1053}
1054
1055static struct fb_ops gbefb_ops = {
1056	.owner		= THIS_MODULE,
1057	.fb_check_var	= gbefb_check_var,
1058	.fb_set_par	= gbefb_set_par,
1059	.fb_setcolreg	= gbefb_setcolreg,
1060	.fb_mmap	= gbefb_mmap,
1061	.fb_blank	= gbefb_blank,
1062	.fb_fillrect	= cfb_fillrect,
1063	.fb_copyarea	= cfb_copyarea,
1064	.fb_imageblit	= cfb_imageblit,
1065};
1066
1067/*
1068 * sysfs
1069 */
1070
1071static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1072{
1073	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
1074}
1075
1076static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1077
1078static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1079{
1080	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1081}
1082
1083static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1084
1085static void __devexit gbefb_remove_sysfs(struct device *dev)
1086{
1087	device_remove_file(dev, &dev_attr_size);
1088	device_remove_file(dev, &dev_attr_revision);
1089}
1090
1091static void gbefb_create_sysfs(struct device *dev)
1092{
1093	device_create_file(dev, &dev_attr_size);
1094	device_create_file(dev, &dev_attr_revision);
1095}
1096
1097/*
1098 * Initialization
1099 */
1100
1101static int __devinit gbefb_setup(char *options)
1102{
1103	char *this_opt;
1104
1105	if (!options || !*options)
1106		return 0;
1107
1108	while ((this_opt = strsep(&options, ",")) != NULL) {
1109		if (!strncmp(this_opt, "monitor:", 8)) {
1110			if (!strncmp(this_opt + 8, "crt", 3)) {
1111				flat_panel_enabled = 0;
1112				default_var = &default_var_CRT;
1113				default_mode = &default_mode_CRT;
1114			} else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1115				   !strncmp(this_opt + 8, "lcd", 3)) {
1116				flat_panel_enabled = 1;
1117				default_var = &default_var_LCD;
1118				default_mode = &default_mode_LCD;
1119			}
1120		} else if (!strncmp(this_opt, "mem:", 4)) {
1121			gbe_mem_size = memparse(this_opt + 4, &this_opt);
1122			if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1123				gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1124			if (gbe_mem_size < TILE_SIZE)
1125				gbe_mem_size = TILE_SIZE;
1126		} else
1127			mode_option = this_opt;
1128	}
1129	return 0;
1130}
1131
1132static int __devinit gbefb_probe(struct platform_device *p_dev)
1133{
1134	int i, ret = 0;
1135	struct fb_info *info;
1136	struct gbefb_par *par;
1137#ifndef MODULE
1138	char *options = NULL;
1139#endif
1140
1141	info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1142	if (!info)
1143		return -ENOMEM;
1144
1145#ifndef MODULE
1146	if (fb_get_options("gbefb", &options)) {
1147		ret = -ENODEV;
1148		goto out_release_framebuffer;
1149	}
1150	gbefb_setup(options);
1151#endif
1152
1153	if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
1154		printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
1155		ret = -EBUSY;
1156		goto out_release_framebuffer;
1157	}
1158
1159	gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
1160	if (!gbe) {
1161		printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1162		ret = -ENXIO;
1163		goto out_release_mem_region;
1164	}
1165	gbe_revision = gbe->ctrlstat & 15;
1166
1167	gbe_tiles.cpu =
1168		dma_alloc_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1169				   &gbe_tiles.dma, GFP_KERNEL);
1170	if (!gbe_tiles.cpu) {
1171		printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1172		ret = -ENOMEM;
1173		goto out_unmap;
1174	}
1175
1176	if (gbe_mem_phys) {
1177		/* memory was allocated at boot time */
1178		gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
1179		if (!gbe_mem) {
1180			printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1181			ret = -ENOMEM;
1182			goto out_tiles_free;
1183		}
1184
1185		gbe_dma_addr = 0;
1186	} else {
1187		/* try to allocate memory with the classical allocator
1188		 * this has high chance to fail on low memory machines */
1189		gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
1190					     GFP_KERNEL);
1191		if (!gbe_mem) {
1192			printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1193			ret = -ENOMEM;
1194			goto out_tiles_free;
1195		}
1196
1197		gbe_mem_phys = (unsigned long) gbe_dma_addr;
1198	}
1199
1200#ifdef CONFIG_X86
1201	mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
1202#endif
1203
1204	/* map framebuffer memory into tiles table */
1205	for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1206		gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1207
1208	info->fbops = &gbefb_ops;
1209	info->pseudo_palette = pseudo_palette;
1210	info->flags = FBINFO_DEFAULT;
1211	info->screen_base = gbe_mem;
1212	fb_alloc_cmap(&info->cmap, 256, 0);
1213
1214	/* reset GBE */
1215	gbe_reset();
1216
1217	par = info->par;
1218	/* turn on default video mode */
1219	if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
1220			 default_mode, 8) == 0)
1221		par->var = *default_var;
1222	info->var = par->var;
1223	gbefb_check_var(&par->var, info);
1224	gbefb_encode_fix(&info->fix, &info->var);
1225
1226	if (register_framebuffer(info) < 0) {
1227		printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
1228		ret = -ENXIO;
1229		goto out_gbe_unmap;
1230	}
1231
1232	platform_set_drvdata(p_dev, info);
1233	gbefb_create_sysfs(&p_dev->dev);
1234
1235	printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1236	       info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
1237	       gbe_mem_size >> 10);
1238
1239	return 0;
1240
1241out_gbe_unmap:
1242	if (gbe_dma_addr)
1243		dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1244	else
1245		iounmap(gbe_mem);
1246out_tiles_free:
1247	dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1248			  (void *)gbe_tiles.cpu, gbe_tiles.dma);
1249out_unmap:
1250	iounmap(gbe);
1251out_release_mem_region:
1252	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1253out_release_framebuffer:
1254	framebuffer_release(info);
1255
1256	return ret;
1257}
1258
1259static int __devexit gbefb_remove(struct platform_device* p_dev)
1260{
1261	struct fb_info *info = platform_get_drvdata(p_dev);
1262
1263	unregister_framebuffer(info);
1264	gbe_turn_off();
1265	if (gbe_dma_addr)
1266		dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1267	else
1268		iounmap(gbe_mem);
1269	dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1270			  (void *)gbe_tiles.cpu, gbe_tiles.dma);
1271	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1272	iounmap(gbe);
1273	gbefb_remove_sysfs(&p_dev->dev);
1274	framebuffer_release(info);
1275
1276	return 0;
1277}
1278
1279static struct platform_driver gbefb_driver = {
1280	.probe = gbefb_probe,
1281	.remove = __devexit_p(gbefb_remove),
1282	.driver	= {
1283		.name = "gbefb",
1284	},
1285};
1286
1287static struct platform_device *gbefb_device;
1288
1289static int __init gbefb_init(void)
1290{
1291	int ret = platform_driver_register(&gbefb_driver);
1292	if (!ret) {
1293		gbefb_device = platform_device_alloc("gbefb", 0);
1294		if (gbefb_device) {
1295			ret = platform_device_add(gbefb_device);
1296		} else {
1297			ret = -ENOMEM;
1298		}
1299		if (ret) {
1300			platform_device_put(gbefb_device);
1301			platform_driver_unregister(&gbefb_driver);
1302		}
1303	}
1304	return ret;
1305}
1306
1307static void __exit gbefb_exit(void)
1308{
1309	platform_device_unregister(gbefb_device);
1310	platform_driver_unregister(&gbefb_driver);
1311}
1312
1313module_init(gbefb_init);
1314module_exit(gbefb_exit);
1315
1316MODULE_LICENSE("GPL");
1317