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