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