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