[PATCH] spi: ads7836 uses spi_driver
[linux-2.6] / 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, struct file *file,
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         vma->vm_file = file;
1004
1005         /* look for the starting tile */
1006         tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1007         addr = vma->vm_start;
1008         offset &= TILE_MASK;
1009
1010         /* remap each tile separately */
1011         do {
1012                 phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1013                 if ((offset + size) < TILE_SIZE)
1014                         phys_size = size;
1015                 else
1016                         phys_size = TILE_SIZE - offset;
1017
1018                 if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1019                                                 phys_size, vma->vm_page_prot))
1020                         return -EAGAIN;
1021
1022                 offset = 0;
1023                 size -= phys_size;
1024                 addr += phys_size;
1025                 tile++;
1026         } while (size);
1027
1028         return 0;
1029 }
1030
1031 static struct fb_ops gbefb_ops = {
1032         .owner          = THIS_MODULE,
1033         .fb_check_var   = gbefb_check_var,
1034         .fb_set_par     = gbefb_set_par,
1035         .fb_setcolreg   = gbefb_setcolreg,
1036         .fb_mmap        = gbefb_mmap,
1037         .fb_blank       = gbefb_blank,
1038         .fb_fillrect    = cfb_fillrect,
1039         .fb_copyarea    = cfb_copyarea,
1040         .fb_imageblit   = cfb_imageblit,
1041 };
1042
1043 /*
1044  * sysfs
1045  */
1046
1047 static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1048 {
1049         return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
1050 }
1051
1052 static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1053
1054 static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1055 {
1056         return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1057 }
1058
1059 static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1060
1061 static void __devexit gbefb_remove_sysfs(struct device *dev)
1062 {
1063         device_remove_file(dev, &dev_attr_size);
1064         device_remove_file(dev, &dev_attr_revision);
1065 }
1066
1067 static void gbefb_create_sysfs(struct device *dev)
1068 {
1069         device_create_file(dev, &dev_attr_size);
1070         device_create_file(dev, &dev_attr_revision);
1071 }
1072
1073 /*
1074  * Initialization
1075  */
1076
1077 int __init gbefb_setup(char *options)
1078 {
1079         char *this_opt;
1080
1081         if (!options || !*options)
1082                 return 0;
1083
1084         while ((this_opt = strsep(&options, ",")) != NULL) {
1085                 if (!strncmp(this_opt, "monitor:", 8)) {
1086                         if (!strncmp(this_opt + 8, "crt", 3)) {
1087                                 flat_panel_enabled = 0;
1088                                 default_var = &default_var_CRT;
1089                                 default_mode = &default_mode_CRT;
1090                         } else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1091                                    !strncmp(this_opt + 8, "lcd", 3)) {
1092                                 flat_panel_enabled = 1;
1093                                 default_var = &default_var_LCD;
1094                                 default_mode = &default_mode_LCD;
1095                         }
1096                 } else if (!strncmp(this_opt, "mem:", 4)) {
1097                         gbe_mem_size = memparse(this_opt + 4, &this_opt);
1098                         if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1099                                 gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1100                         if (gbe_mem_size < TILE_SIZE)
1101                                 gbe_mem_size = TILE_SIZE;
1102                 } else
1103                         mode_option = this_opt;
1104         }
1105         return 0;
1106 }
1107
1108 static int __init gbefb_probe(struct platform_device *p_dev)
1109 {
1110         int i, ret = 0;
1111         struct fb_info *info;
1112         struct gbefb_par *par;
1113 #ifndef MODULE
1114         char *options = NULL;
1115 #endif
1116
1117         info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1118         if (!info)
1119                 return -ENOMEM;
1120
1121 #ifndef MODULE
1122         if (fb_get_options("gbefb", &options))
1123                 return -ENODEV;
1124         gbefb_setup(options);
1125 #endif
1126
1127         if (!request_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
1128                 printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
1129                 ret = -EBUSY;
1130                 goto out_release_framebuffer;
1131         }
1132
1133         gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
1134         if (!gbe) {
1135                 printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1136                 ret = -ENXIO;
1137                 goto out_release_mem_region;
1138         }
1139         gbe_revision = gbe->ctrlstat & 15;
1140
1141         gbe_tiles.cpu =
1142                 dma_alloc_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1143                                    &gbe_tiles.dma, GFP_KERNEL);
1144         if (!gbe_tiles.cpu) {
1145                 printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1146                 ret = -ENOMEM;
1147                 goto out_unmap;
1148         }
1149
1150         if (gbe_mem_phys) {
1151                 /* memory was allocated at boot time */
1152                 gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
1153                 if (!gbe_mem) {
1154                         printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1155                         ret = -ENOMEM;
1156                         goto out_tiles_free;
1157                 }
1158
1159                 gbe_dma_addr = 0;
1160         } else {
1161                 /* try to allocate memory with the classical allocator
1162                  * this has high chance to fail on low memory machines */
1163                 gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
1164                                              GFP_KERNEL);
1165                 if (!gbe_mem) {
1166                         printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1167                         ret = -ENOMEM;
1168                         goto out_tiles_free;
1169                 }
1170
1171                 gbe_mem_phys = (unsigned long) gbe_dma_addr;
1172         }
1173
1174 #ifdef CONFIG_X86
1175         mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
1176 #endif
1177
1178         /* map framebuffer memory into tiles table */
1179         for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1180                 gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1181
1182         info->fbops = &gbefb_ops;
1183         info->pseudo_palette = pseudo_palette;
1184         info->flags = FBINFO_DEFAULT;
1185         info->screen_base = gbe_mem;
1186         fb_alloc_cmap(&info->cmap, 256, 0);
1187
1188         /* reset GBE */
1189         gbe_reset();
1190
1191         par = info->par;
1192         /* turn on default video mode */
1193         if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
1194                          default_mode, 8) == 0)
1195                 par->var = *default_var;
1196         info->var = par->var;
1197         gbefb_check_var(&par->var, info);
1198         gbefb_encode_fix(&info->fix, &info->var);
1199
1200         if (register_framebuffer(info) < 0) {
1201                 printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
1202                 ret = -ENXIO;
1203                 goto out_gbe_unmap;
1204         }
1205
1206         platform_set_drvdata(p_dev, info);
1207         gbefb_create_sysfs(&p_dev->dev);
1208
1209         printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1210                info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
1211                gbe_mem_size >> 10);
1212
1213         return 0;
1214
1215 out_gbe_unmap:
1216         if (gbe_dma_addr)
1217                 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1218         else
1219                 iounmap(gbe_mem);
1220 out_tiles_free:
1221         dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1222                           (void *)gbe_tiles.cpu, gbe_tiles.dma);
1223 out_unmap:
1224         iounmap(gbe);
1225 out_release_mem_region:
1226         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1227 out_release_framebuffer:
1228         framebuffer_release(info);
1229
1230         return ret;
1231 }
1232
1233 static int __devexit gbefb_remove(struct platform_device* p_dev)
1234 {
1235         struct fb_info *info = platform_get_drvdata(p_dev);
1236
1237         unregister_framebuffer(info);
1238         gbe_turn_off();
1239         if (gbe_dma_addr)
1240                 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1241         else
1242                 iounmap(gbe_mem);
1243         dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1244                           (void *)gbe_tiles.cpu, gbe_tiles.dma);
1245         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1246         iounmap(gbe);
1247         gbefb_remove_sysfs(dev);
1248         framebuffer_release(info);
1249
1250         return 0;
1251 }
1252
1253 static struct platform_driver gbefb_driver = {
1254         .probe = gbefb_probe,
1255         .remove = __devexit_p(gbefb_remove),
1256         .driver = {
1257                 .name = "gbefb",
1258         },
1259 };
1260
1261 static struct platform_device *gbefb_device;
1262
1263 int __init gbefb_init(void)
1264 {
1265         int ret = platform_driver_register(&gbefb_driver);
1266         if (!ret) {
1267                 gbefb_device = platform_device_alloc("gbefb", 0);
1268                 if (gbefb_device) {
1269                         ret = platform_device_add(gbefb_device);
1270                 } else {
1271                         ret = -ENOMEM;
1272                 }
1273                 if (ret) {
1274                         platform_device_put(gbefb_device);
1275                         platform_driver_unregister(&gbefb_driver);
1276                 }
1277         }
1278         return ret;
1279 }
1280
1281 void __exit gbefb_exit(void)
1282 {
1283         platform_device_unregister(gbefb_device);
1284         platform_driver_unregister(&gbefb_driver);
1285 }
1286
1287 module_init(gbefb_init);
1288 module_exit(gbefb_exit);
1289
1290 MODULE_LICENSE("GPL");