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