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