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