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