]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/video/gbefb.c
Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mv-sheeva.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 static 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 static struct fb_videomode *default_mode __initdata = &default_mode_CRT;
189 static 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 static 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         int ret;
916
917         /* Limit bpp to 8, 16, and 32 */
918         if (var->bits_per_pixel <= 8)
919                 var->bits_per_pixel = 8;
920         else if (var->bits_per_pixel <= 16)
921                 var->bits_per_pixel = 16;
922         else if (var->bits_per_pixel <= 32)
923                 var->bits_per_pixel = 32;
924         else
925                 return -EINVAL;
926
927         /* Check the mode can be mapped linearly with the tile table trick. */
928         /* This requires width x height x bytes/pixel be a multiple of 512 */
929         if ((var->xres * var->yres * var->bits_per_pixel) & 4095)
930                 return -EINVAL;
931
932         var->grayscale = 0;     /* No grayscale for now */
933
934         ret = compute_gbe_timing(var, &timing);
935         var->pixclock = ret;
936         if (ret < 0)
937                 return -EINVAL;
938
939         /* Adjust virtual resolution, if necessary */
940         if (var->xres > var->xres_virtual || (!ywrap && !ypan))
941                 var->xres_virtual = var->xres;
942         if (var->yres > var->yres_virtual || (!ywrap && !ypan))
943                 var->yres_virtual = var->yres;
944
945         if (var->vmode & FB_VMODE_CONUPDATE) {
946                 var->vmode |= FB_VMODE_YWRAP;
947                 var->xoffset = info->var.xoffset;
948                 var->yoffset = info->var.yoffset;
949         }
950
951         /* No grayscale for now */
952         var->grayscale = 0;
953
954         /* Memory limit */
955         line_length = var->xres_virtual * var->bits_per_pixel / 8;
956         if (line_length * var->yres_virtual > gbe_mem_size)
957                 return -ENOMEM; /* Virtual resolution too high */
958
959         switch (var->bits_per_pixel) {
960         case 8:
961                 var->red.offset = 0;
962                 var->red.length = 8;
963                 var->green.offset = 0;
964                 var->green.length = 8;
965                 var->blue.offset = 0;
966                 var->blue.length = 8;
967                 var->transp.offset = 0;
968                 var->transp.length = 0;
969                 break;
970         case 16:                /* RGB 1555 */
971                 var->red.offset = 10;
972                 var->red.length = 5;
973                 var->green.offset = 5;
974                 var->green.length = 5;
975                 var->blue.offset = 0;
976                 var->blue.length = 5;
977                 var->transp.offset = 0;
978                 var->transp.length = 0;
979                 break;
980         case 32:                /* RGB 8888 */
981                 var->red.offset = 24;
982                 var->red.length = 8;
983                 var->green.offset = 16;
984                 var->green.length = 8;
985                 var->blue.offset = 8;
986                 var->blue.length = 8;
987                 var->transp.offset = 0;
988                 var->transp.length = 8;
989                 break;
990         }
991         var->red.msb_right = 0;
992         var->green.msb_right = 0;
993         var->blue.msb_right = 0;
994         var->transp.msb_right = 0;
995
996         var->left_margin = timing.htotal - timing.hsync_end;
997         var->right_margin = timing.hsync_start - timing.width;
998         var->upper_margin = timing.vtotal - timing.vsync_end;
999         var->lower_margin = timing.vsync_start - timing.height;
1000         var->hsync_len = timing.hsync_end - timing.hsync_start;
1001         var->vsync_len = timing.vsync_end - timing.vsync_start;
1002
1003         return 0;
1004 }
1005
1006 static int gbefb_mmap(struct fb_info *info,
1007                         struct vm_area_struct *vma)
1008 {
1009         unsigned long size = vma->vm_end - vma->vm_start;
1010         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1011         unsigned long addr;
1012         unsigned long phys_addr, phys_size;
1013         u16 *tile;
1014
1015         /* check range */
1016         if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1017                 return -EINVAL;
1018         if (offset + size > gbe_mem_size)
1019                 return -EINVAL;
1020
1021         /* remap using the fastest write-through mode on architecture */
1022         /* try not polluting the cache when possible */
1023         pgprot_val(vma->vm_page_prot) =
1024                 pgprot_fb(pgprot_val(vma->vm_page_prot));
1025
1026         vma->vm_flags |= VM_IO | VM_RESERVED;
1027
1028         /* look for the starting tile */
1029         tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1030         addr = vma->vm_start;
1031         offset &= TILE_MASK;
1032
1033         /* remap each tile separately */
1034         do {
1035                 phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1036                 if ((offset + size) < TILE_SIZE)
1037                         phys_size = size;
1038                 else
1039                         phys_size = TILE_SIZE - offset;
1040
1041                 if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1042                                                 phys_size, vma->vm_page_prot))
1043                         return -EAGAIN;
1044
1045                 offset = 0;
1046                 size -= phys_size;
1047                 addr += phys_size;
1048                 tile++;
1049         } while (size);
1050
1051         return 0;
1052 }
1053
1054 static struct fb_ops gbefb_ops = {
1055         .owner          = THIS_MODULE,
1056         .fb_check_var   = gbefb_check_var,
1057         .fb_set_par     = gbefb_set_par,
1058         .fb_setcolreg   = gbefb_setcolreg,
1059         .fb_mmap        = gbefb_mmap,
1060         .fb_blank       = gbefb_blank,
1061         .fb_fillrect    = cfb_fillrect,
1062         .fb_copyarea    = cfb_copyarea,
1063         .fb_imageblit   = cfb_imageblit,
1064 };
1065
1066 /*
1067  * sysfs
1068  */
1069
1070 static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1071 {
1072         return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
1073 }
1074
1075 static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1076
1077 static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1078 {
1079         return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1080 }
1081
1082 static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1083
1084 static void __devexit gbefb_remove_sysfs(struct device *dev)
1085 {
1086         device_remove_file(dev, &dev_attr_size);
1087         device_remove_file(dev, &dev_attr_revision);
1088 }
1089
1090 static void gbefb_create_sysfs(struct device *dev)
1091 {
1092         device_create_file(dev, &dev_attr_size);
1093         device_create_file(dev, &dev_attr_revision);
1094 }
1095
1096 /*
1097  * Initialization
1098  */
1099
1100 static int __init gbefb_setup(char *options)
1101 {
1102         char *this_opt;
1103
1104         if (!options || !*options)
1105                 return 0;
1106
1107         while ((this_opt = strsep(&options, ",")) != NULL) {
1108                 if (!strncmp(this_opt, "monitor:", 8)) {
1109                         if (!strncmp(this_opt + 8, "crt", 3)) {
1110                                 flat_panel_enabled = 0;
1111                                 default_var = &default_var_CRT;
1112                                 default_mode = &default_mode_CRT;
1113                         } else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1114                                    !strncmp(this_opt + 8, "lcd", 3)) {
1115                                 flat_panel_enabled = 1;
1116                                 default_var = &default_var_LCD;
1117                                 default_mode = &default_mode_LCD;
1118                         }
1119                 } else if (!strncmp(this_opt, "mem:", 4)) {
1120                         gbe_mem_size = memparse(this_opt + 4, &this_opt);
1121                         if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1122                                 gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1123                         if (gbe_mem_size < TILE_SIZE)
1124                                 gbe_mem_size = TILE_SIZE;
1125                 } else
1126                         mode_option = this_opt;
1127         }
1128         return 0;
1129 }
1130
1131 static int __init gbefb_probe(struct platform_device *p_dev)
1132 {
1133         int i, ret = 0;
1134         struct fb_info *info;
1135         struct gbefb_par *par;
1136 #ifndef MODULE
1137         char *options = NULL;
1138 #endif
1139
1140         info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1141         if (!info)
1142                 return -ENOMEM;
1143
1144 #ifndef MODULE
1145         if (fb_get_options("gbefb", &options))
1146                 return -ENODEV;
1147         gbefb_setup(options);
1148 #endif
1149
1150         if (!request_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 *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
1157         if (!gbe) {
1158                 printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1159                 ret = -ENXIO;
1160                 goto out_release_mem_region;
1161         }
1162         gbe_revision = gbe->ctrlstat & 15;
1163
1164         gbe_tiles.cpu =
1165                 dma_alloc_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1166                                    &gbe_tiles.dma, GFP_KERNEL);
1167         if (!gbe_tiles.cpu) {
1168                 printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1169                 ret = -ENOMEM;
1170                 goto out_unmap;
1171         }
1172
1173         if (gbe_mem_phys) {
1174                 /* memory was allocated at boot time */
1175                 gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
1176                 if (!gbe_mem) {
1177                         printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1178                         ret = -ENOMEM;
1179                         goto out_tiles_free;
1180                 }
1181
1182                 gbe_dma_addr = 0;
1183         } else {
1184                 /* try to allocate memory with the classical allocator
1185                  * this has high chance to fail on low memory machines */
1186                 gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
1187                                              GFP_KERNEL);
1188                 if (!gbe_mem) {
1189                         printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1190                         ret = -ENOMEM;
1191                         goto out_tiles_free;
1192                 }
1193
1194                 gbe_mem_phys = (unsigned long) gbe_dma_addr;
1195         }
1196
1197 #ifdef CONFIG_X86
1198         mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
1199 #endif
1200
1201         /* map framebuffer memory into tiles table */
1202         for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1203                 gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1204
1205         info->fbops = &gbefb_ops;
1206         info->pseudo_palette = pseudo_palette;
1207         info->flags = FBINFO_DEFAULT;
1208         info->screen_base = gbe_mem;
1209         fb_alloc_cmap(&info->cmap, 256, 0);
1210
1211         /* reset GBE */
1212         gbe_reset();
1213
1214         par = info->par;
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         printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1233                info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
1234                gbe_mem_size >> 10);
1235
1236         return 0;
1237
1238 out_gbe_unmap:
1239         if (gbe_dma_addr)
1240                 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1241         else
1242                 iounmap(gbe_mem);
1243 out_tiles_free:
1244         dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1245                           (void *)gbe_tiles.cpu, gbe_tiles.dma);
1246 out_unmap:
1247         iounmap(gbe);
1248 out_release_mem_region:
1249         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1250 out_release_framebuffer:
1251         framebuffer_release(info);
1252
1253         return ret;
1254 }
1255
1256 static int __devexit gbefb_remove(struct platform_device* p_dev)
1257 {
1258         struct fb_info *info = platform_get_drvdata(p_dev);
1259
1260         unregister_framebuffer(info);
1261         gbe_turn_off();
1262         if (gbe_dma_addr)
1263                 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1264         else
1265                 iounmap(gbe_mem);
1266         dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1267                           (void *)gbe_tiles.cpu, gbe_tiles.dma);
1268         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1269         iounmap(gbe);
1270         gbefb_remove_sysfs(&p_dev->dev);
1271         framebuffer_release(info);
1272
1273         return 0;
1274 }
1275
1276 static struct platform_driver gbefb_driver = {
1277         .probe = gbefb_probe,
1278         .remove = __devexit_p(gbefb_remove),
1279         .driver = {
1280                 .name = "gbefb",
1281         },
1282 };
1283
1284 static struct platform_device *gbefb_device;
1285
1286 static int __init gbefb_init(void)
1287 {
1288         int ret = platform_driver_register(&gbefb_driver);
1289         if (!ret) {
1290                 gbefb_device = platform_device_alloc("gbefb", 0);
1291                 if (gbefb_device) {
1292                         ret = platform_device_add(gbefb_device);
1293                 } else {
1294                         ret = -ENOMEM;
1295                 }
1296                 if (ret) {
1297                         platform_device_put(gbefb_device);
1298                         platform_driver_unregister(&gbefb_driver);
1299                 }
1300         }
1301         return ret;
1302 }
1303
1304 static void __exit gbefb_exit(void)
1305 {
1306         platform_device_unregister(gbefb_device);
1307         platform_driver_unregister(&gbefb_driver);
1308 }
1309
1310 module_init(gbefb_init);
1311 module_exit(gbefb_exit);
1312
1313 MODULE_LICENSE("GPL");