MAINTAINERS: fix incorrect mail address of XFS maintainer
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / video / gbefb.c
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_X86
26 #include <asm/mtrr.h>
27 #endif
28 #ifdef CONFIG_MIPS
29 #include <asm/addrspace.h>
30 #endif
31 #include <asm/byteorder.h>
32 #include <asm/tlbflush.h>
33
34 #include <video/gbe.h>
35
36 static struct sgi_gbe *gbe;
37
38 struct 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
76 static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;
77 static void *gbe_mem;
78 static dma_addr_t gbe_dma_addr;
79 static unsigned long gbe_mem_phys;
80
81 static struct {
82         uint16_t *cpu;
83         dma_addr_t dma;
84 } gbe_tiles;
85
86 static int gbe_revision;
87
88 static int ypan, ywrap;
89
90 static uint32_t pseudo_palette[16];
91 static uint32_t gbe_cmap[256];
92 static int gbe_turned_on; /* 0 turned off, 1 turned on */
93
94 static char *mode_option = NULL;
95
96 /* default CRT mode */
97 static struct fb_var_screeninfo default_var_CRT = {
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 */
128 static struct fb_var_screeninfo default_var_LCD = {
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) */
160 static struct fb_videomode default_mode_CRT = {
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 */
175 static struct fb_videomode default_mode_LCD = {
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
189 static struct fb_videomode *default_mode = &default_mode_CRT;
190 static struct fb_var_screeninfo *default_var = &default_var_CRT;
191
192 static int flat_panel_enabled = 0;
193
194 static 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
209 static 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
321 static 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
383 static 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  */
400 static 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  */
423 static 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
456 struct gbe_pll_info {
457         int clock_rate;
458         int fvco_min;
459         int fvco_max;
460 };
461
462 static struct gbe_pll_info gbe_pll_table[2] = {
463         { 20, 80, 220 },
464         { 27, 80, 220 },
465 };
466
467 static 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
543 static 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
652 static 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
829 static 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
861 static 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  */
912 static 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
1007 static 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 (size > gbe_mem_size)
1020                 return -EINVAL;
1021         if (offset > gbe_mem_size - size)
1022                 return -EINVAL;
1023
1024         /* remap using the fastest write-through mode on architecture */
1025         /* try not polluting the cache when possible */
1026         pgprot_val(vma->vm_page_prot) =
1027                 pgprot_fb(pgprot_val(vma->vm_page_prot));
1028
1029         /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
1030
1031         /* look for the starting tile */
1032         tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1033         addr = vma->vm_start;
1034         offset &= TILE_MASK;
1035
1036         /* remap each tile separately */
1037         do {
1038                 phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1039                 if ((offset + size) < TILE_SIZE)
1040                         phys_size = size;
1041                 else
1042                         phys_size = TILE_SIZE - offset;
1043
1044                 if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1045                                                 phys_size, vma->vm_page_prot))
1046                         return -EAGAIN;
1047
1048                 offset = 0;
1049                 size -= phys_size;
1050                 addr += phys_size;
1051                 tile++;
1052         } while (size);
1053
1054         return 0;
1055 }
1056
1057 static struct fb_ops gbefb_ops = {
1058         .owner          = THIS_MODULE,
1059         .fb_check_var   = gbefb_check_var,
1060         .fb_set_par     = gbefb_set_par,
1061         .fb_setcolreg   = gbefb_setcolreg,
1062         .fb_mmap        = gbefb_mmap,
1063         .fb_blank       = gbefb_blank,
1064         .fb_fillrect    = cfb_fillrect,
1065         .fb_copyarea    = cfb_copyarea,
1066         .fb_imageblit   = cfb_imageblit,
1067 };
1068
1069 /*
1070  * sysfs
1071  */
1072
1073 static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1074 {
1075         return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
1076 }
1077
1078 static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1079
1080 static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1081 {
1082         return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1083 }
1084
1085 static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1086
1087 static void gbefb_remove_sysfs(struct device *dev)
1088 {
1089         device_remove_file(dev, &dev_attr_size);
1090         device_remove_file(dev, &dev_attr_revision);
1091 }
1092
1093 static void gbefb_create_sysfs(struct device *dev)
1094 {
1095         device_create_file(dev, &dev_attr_size);
1096         device_create_file(dev, &dev_attr_revision);
1097 }
1098
1099 /*
1100  * Initialization
1101  */
1102
1103 static int gbefb_setup(char *options)
1104 {
1105         char *this_opt;
1106
1107         if (!options || !*options)
1108                 return 0;
1109
1110         while ((this_opt = strsep(&options, ",")) != NULL) {
1111                 if (!strncmp(this_opt, "monitor:", 8)) {
1112                         if (!strncmp(this_opt + 8, "crt", 3)) {
1113                                 flat_panel_enabled = 0;
1114                                 default_var = &default_var_CRT;
1115                                 default_mode = &default_mode_CRT;
1116                         } else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1117                                    !strncmp(this_opt + 8, "lcd", 3)) {
1118                                 flat_panel_enabled = 1;
1119                                 default_var = &default_var_LCD;
1120                                 default_mode = &default_mode_LCD;
1121                         }
1122                 } else if (!strncmp(this_opt, "mem:", 4)) {
1123                         gbe_mem_size = memparse(this_opt + 4, &this_opt);
1124                         if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1125                                 gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1126                         if (gbe_mem_size < TILE_SIZE)
1127                                 gbe_mem_size = TILE_SIZE;
1128                 } else
1129                         mode_option = this_opt;
1130         }
1131         return 0;
1132 }
1133
1134 static int gbefb_probe(struct platform_device *p_dev)
1135 {
1136         int i, ret = 0;
1137         struct fb_info *info;
1138         struct gbefb_par *par;
1139 #ifndef MODULE
1140         char *options = NULL;
1141 #endif
1142
1143         info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1144         if (!info)
1145                 return -ENOMEM;
1146
1147 #ifndef MODULE
1148         if (fb_get_options("gbefb", &options)) {
1149                 ret = -ENODEV;
1150                 goto out_release_framebuffer;
1151         }
1152         gbefb_setup(options);
1153 #endif
1154
1155         if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
1156                 printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
1157                 ret = -EBUSY;
1158                 goto out_release_framebuffer;
1159         }
1160
1161         gbe = (struct sgi_gbe *) devm_ioremap(&p_dev->dev, GBE_BASE,
1162                                               sizeof(struct sgi_gbe));
1163         if (!gbe) {
1164                 printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1165                 ret = -ENXIO;
1166                 goto out_release_mem_region;
1167         }
1168         gbe_revision = gbe->ctrlstat & 15;
1169
1170         gbe_tiles.cpu =
1171                 dma_alloc_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1172                                    &gbe_tiles.dma, GFP_KERNEL);
1173         if (!gbe_tiles.cpu) {
1174                 printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1175                 ret = -ENOMEM;
1176                 goto out_release_mem_region;
1177         }
1178
1179         if (gbe_mem_phys) {
1180                 /* memory was allocated at boot time */
1181                 gbe_mem = devm_ioremap_nocache(&p_dev->dev, gbe_mem_phys,
1182                                                gbe_mem_size);
1183                 if (!gbe_mem) {
1184                         printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1185                         ret = -ENOMEM;
1186                         goto out_tiles_free;
1187                 }
1188
1189                 gbe_dma_addr = 0;
1190         } else {
1191                 /* try to allocate memory with the classical allocator
1192                  * this has high chance to fail on low memory machines */
1193                 gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
1194                                              GFP_KERNEL);
1195                 if (!gbe_mem) {
1196                         printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1197                         ret = -ENOMEM;
1198                         goto out_tiles_free;
1199                 }
1200
1201                 gbe_mem_phys = (unsigned long) gbe_dma_addr;
1202         }
1203
1204 #ifdef CONFIG_X86
1205         mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
1206 #endif
1207
1208         /* map framebuffer memory into tiles table */
1209         for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1210                 gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1211
1212         info->fbops = &gbefb_ops;
1213         info->pseudo_palette = pseudo_palette;
1214         info->flags = FBINFO_DEFAULT;
1215         info->screen_base = gbe_mem;
1216         fb_alloc_cmap(&info->cmap, 256, 0);
1217
1218         /* reset GBE */
1219         gbe_reset();
1220
1221         par = info->par;
1222         /* turn on default video mode */
1223         if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
1224                          default_mode, 8) == 0)
1225                 par->var = *default_var;
1226         info->var = par->var;
1227         gbefb_check_var(&par->var, info);
1228         gbefb_encode_fix(&info->fix, &info->var);
1229
1230         if (register_framebuffer(info) < 0) {
1231                 printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
1232                 ret = -ENXIO;
1233                 goto out_gbe_unmap;
1234         }
1235
1236         platform_set_drvdata(p_dev, info);
1237         gbefb_create_sysfs(&p_dev->dev);
1238
1239         fb_info(info, "%s rev %d @ 0x%08x using %dkB memory\n",
1240                 info->fix.id, gbe_revision, (unsigned)GBE_BASE,
1241                 gbe_mem_size >> 10);
1242
1243         return 0;
1244
1245 out_gbe_unmap:
1246         if (gbe_dma_addr)
1247                 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1248 out_tiles_free:
1249         dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1250                           (void *)gbe_tiles.cpu, gbe_tiles.dma);
1251 out_release_mem_region:
1252         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1253 out_release_framebuffer:
1254         framebuffer_release(info);
1255
1256         return ret;
1257 }
1258
1259 static int 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         dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1268                           (void *)gbe_tiles.cpu, gbe_tiles.dma);
1269         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1270         gbefb_remove_sysfs(&p_dev->dev);
1271         framebuffer_release(info);
1272
1273         return 0;
1274 }
1275
1276 static struct platform_driver gbefb_driver = {
1277         .probe = gbefb_probe,
1278         .remove = gbefb_remove,
1279         .driver = {
1280                 .name = "gbefb",
1281         },
1282 };
1283
1284 static struct platform_device *gbefb_device;
1285
1286 static int __init gbefb_init(void)
1287 {
1288         int ret = platform_driver_register(&gbefb_driver);
1289         if (!ret) {
1290                 gbefb_device = platform_device_alloc("gbefb", 0);
1291                 if (gbefb_device) {
1292                         ret = platform_device_add(gbefb_device);
1293                 } else {
1294                         ret = -ENOMEM;
1295                 }
1296                 if (ret) {
1297                         platform_device_put(gbefb_device);
1298                         platform_driver_unregister(&gbefb_driver);
1299                 }
1300         }
1301         return ret;
1302 }
1303
1304 static void __exit gbefb_exit(void)
1305 {
1306         platform_device_unregister(gbefb_device);
1307         platform_driver_unregister(&gbefb_driver);
1308 }
1309
1310 module_init(gbefb_init);
1311 module_exit(gbefb_exit);
1312
1313 MODULE_LICENSE("GPL");