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