]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/video/imxfb.c
Merge branch 'for-rmk' of git://gitorious.org/linux-gemini/mainline into devel
[linux-2.6-omap-h63xx.git] / drivers / video / imxfb.c
1 /*
2  *  Freescale i.MX Frame Buffer device driver
3  *
4  *  Copyright (C) 2004 Sascha Hauer, Pengutronix
5  *   Based on acornfb.c Copyright (C) Russell King.
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  * Please direct your questions and comments on this driver to the following
12  * email address:
13  *
14  *      linux-arm-kernel@lists.arm.linux.org.uk
15  */
16
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
21 #include <linux/interrupt.h>
22 #include <linux/slab.h>
23 #include <linux/mm.h>
24 #include <linux/fb.h>
25 #include <linux/delay.h>
26 #include <linux/init.h>
27 #include <linux/ioport.h>
28 #include <linux/cpufreq.h>
29 #include <linux/platform_device.h>
30 #include <linux/dma-mapping.h>
31 #include <linux/io.h>
32
33 #include <mach/imxfb.h>
34
35 /*
36  * Complain if VAR is out of range.
37  */
38 #define DEBUG_VAR 1
39
40 #define DRIVER_NAME "imx-fb"
41
42 #define LCDC_SSA        0x00
43
44 #define LCDC_SIZE       0x04
45 #define SIZE_XMAX(x)    ((((x) >> 4) & 0x3f) << 20)
46
47 #ifdef CONFIG_ARCH_MX1
48 #define SIZE_YMAX(y)    ((y) & 0x1ff)
49 #else
50 #define SIZE_YMAX(y)    ((y) & 0x3ff)
51 #endif
52
53 #define LCDC_VPW        0x08
54 #define VPW_VPW(x)      ((x) & 0x3ff)
55
56 #define LCDC_CPOS       0x0C
57 #define CPOS_CC1        (1<<31)
58 #define CPOS_CC0        (1<<30)
59 #define CPOS_OP         (1<<28)
60 #define CPOS_CXP(x)     (((x) & 3ff) << 16)
61
62 #ifdef CONFIG_ARCH_MX1
63 #define CPOS_CYP(y)     ((y) & 0x1ff)
64 #else
65 #define CPOS_CYP(y)     ((y) & 0x3ff)
66 #endif
67
68 #define LCDC_LCWHB      0x10
69 #define LCWHB_BK_EN     (1<<31)
70 #define LCWHB_CW(w)     (((w) & 0x1f) << 24)
71 #define LCWHB_CH(h)     (((h) & 0x1f) << 16)
72 #define LCWHB_BD(x)     ((x) & 0xff)
73
74 #define LCDC_LCHCC      0x14
75
76 #ifdef CONFIG_ARCH_MX1
77 #define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11)
78 #define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5)
79 #define LCHCC_CUR_COL_B(b) ((b) & 0x1f)
80 #else
81 #define LCHCC_CUR_COL_R(r) (((r) & 0x3f) << 12)
82 #define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 6)
83 #define LCHCC_CUR_COL_B(b) ((b) & 0x3f)
84 #endif
85
86 #define LCDC_PCR        0x18
87
88 #define LCDC_HCR        0x1C
89 #define HCR_H_WIDTH(x)  (((x) & 0x3f) << 26)
90 #define HCR_H_WAIT_1(x) (((x) & 0xff) << 8)
91 #define HCR_H_WAIT_2(x) ((x) & 0xff)
92
93 #define LCDC_VCR        0x20
94 #define VCR_V_WIDTH(x)  (((x) & 0x3f) << 26)
95 #define VCR_V_WAIT_1(x) (((x) & 0xff) << 8)
96 #define VCR_V_WAIT_2(x) ((x) & 0xff)
97
98 #define LCDC_POS        0x24
99 #define POS_POS(x)      ((x) & 1f)
100
101 #define LCDC_LSCR1      0x28
102 /* bit fields in imxfb.h */
103
104 #define LCDC_PWMR       0x2C
105 /* bit fields in imxfb.h */
106
107 #define LCDC_DMACR      0x30
108 /* bit fields in imxfb.h */
109
110 #define LCDC_RMCR       0x34
111
112 #ifdef CONFIG_ARCH_MX1
113 #define RMCR_LCDC_EN    (1<<1)
114 #else
115 #define RMCR_LCDC_EN    0
116 #endif
117
118 #define RMCR_SELF_REF   (1<<0)
119
120 #define LCDC_LCDICR     0x38
121 #define LCDICR_INT_SYN  (1<<2)
122 #define LCDICR_INT_CON  (1)
123
124 #define LCDC_LCDISR     0x40
125 #define LCDISR_UDR_ERR  (1<<3)
126 #define LCDISR_ERR_RES  (1<<2)
127 #define LCDISR_EOF      (1<<1)
128 #define LCDISR_BOF      (1<<0)
129
130 /*
131  * These are the bitfields for each
132  * display depth that we support.
133  */
134 struct imxfb_rgb {
135         struct fb_bitfield      red;
136         struct fb_bitfield      green;
137         struct fb_bitfield      blue;
138         struct fb_bitfield      transp;
139 };
140
141 struct imxfb_info {
142         struct platform_device  *pdev;
143         void __iomem            *regs;
144
145         u_int                   max_bpp;
146         u_int                   max_xres;
147         u_int                   max_yres;
148
149         /*
150          * These are the addresses we mapped
151          * the framebuffer memory region to.
152          */
153         dma_addr_t              map_dma;
154         u_char                  *map_cpu;
155         u_int                   map_size;
156
157         u_char                  *screen_cpu;
158         dma_addr_t              screen_dma;
159         u_int                   palette_size;
160
161         dma_addr_t              dbar1;
162         dma_addr_t              dbar2;
163
164         u_int                   pcr;
165         u_int                   pwmr;
166         u_int                   lscr1;
167         u_int                   dmacr;
168         u_int                   cmap_inverse:1,
169                                 cmap_static:1,
170                                 unused:30;
171
172         void (*lcd_power)(int);
173         void (*backlight_power)(int);
174 };
175
176 #define IMX_NAME        "IMX"
177
178 /*
179  * Minimum X and Y resolutions
180  */
181 #define MIN_XRES        64
182 #define MIN_YRES        64
183
184 /* Actually this really is 18bit support, the lowest 2 bits of each colour
185  * are unused in hardware. We claim to have 24bit support to make software
186  * like X work, which does not support 18bit.
187  */
188 static struct imxfb_rgb def_rgb_18 = {
189         .red    = {.offset = 16, .length = 8,},
190         .green  = {.offset = 8, .length = 8,},
191         .blue   = {.offset = 0, .length = 8,},
192         .transp = {.offset = 0, .length = 0,},
193 };
194
195 static struct imxfb_rgb def_rgb_16_tft = {
196         .red    = {.offset = 11, .length = 5,},
197         .green  = {.offset = 5, .length = 6,},
198         .blue   = {.offset = 0, .length = 5,},
199         .transp = {.offset = 0, .length = 0,},
200 };
201
202 static struct imxfb_rgb def_rgb_16_stn = {
203         .red    = {.offset = 8, .length = 4,},
204         .green  = {.offset = 4, .length = 4,},
205         .blue   = {.offset = 0, .length = 4,},
206         .transp = {.offset = 0, .length = 0,},
207 };
208
209 static struct imxfb_rgb def_rgb_8 = {
210         .red    = {.offset = 0, .length = 8,},
211         .green  = {.offset = 0, .length = 8,},
212         .blue   = {.offset = 0, .length = 8,},
213         .transp = {.offset = 0, .length = 0,},
214 };
215
216 static int imxfb_activate_var(struct fb_var_screeninfo *var,
217                 struct fb_info *info);
218
219 static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
220 {
221         chan &= 0xffff;
222         chan >>= 16 - bf->length;
223         return chan << bf->offset;
224 }
225
226 static int imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
227                 u_int trans, struct fb_info *info)
228 {
229         struct imxfb_info *fbi = info->par;
230         u_int val, ret = 1;
231
232 #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
233         if (regno < fbi->palette_size) {
234                 val = (CNVT_TOHW(red, 4) << 8) |
235                       (CNVT_TOHW(green,4) << 4) |
236                       CNVT_TOHW(blue,  4);
237
238                 writel(val, fbi->regs + 0x800 + (regno << 2));
239                 ret = 0;
240         }
241         return ret;
242 }
243
244 static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
245                    u_int trans, struct fb_info *info)
246 {
247         struct imxfb_info *fbi = info->par;
248         unsigned int val;
249         int ret = 1;
250
251         /*
252          * If inverse mode was selected, invert all the colours
253          * rather than the register number.  The register number
254          * is what you poke into the framebuffer to produce the
255          * colour you requested.
256          */
257         if (fbi->cmap_inverse) {
258                 red   = 0xffff - red;
259                 green = 0xffff - green;
260                 blue  = 0xffff - blue;
261         }
262
263         /*
264          * If greyscale is true, then we convert the RGB value
265          * to greyscale no mater what visual we are using.
266          */
267         if (info->var.grayscale)
268                 red = green = blue = (19595 * red + 38470 * green +
269                                         7471 * blue) >> 16;
270
271         switch (info->fix.visual) {
272         case FB_VISUAL_TRUECOLOR:
273                 /*
274                  * 12 or 16-bit True Colour.  We encode the RGB value
275                  * according to the RGB bitfield information.
276                  */
277                 if (regno < 16) {
278                         u32 *pal = info->pseudo_palette;
279
280                         val  = chan_to_field(red, &info->var.red);
281                         val |= chan_to_field(green, &info->var.green);
282                         val |= chan_to_field(blue, &info->var.blue);
283
284                         pal[regno] = val;
285                         ret = 0;
286                 }
287                 break;
288
289         case FB_VISUAL_STATIC_PSEUDOCOLOR:
290         case FB_VISUAL_PSEUDOCOLOR:
291                 ret = imxfb_setpalettereg(regno, red, green, blue, trans, info);
292                 break;
293         }
294
295         return ret;
296 }
297
298 /*
299  *  imxfb_check_var():
300  *    Round up in the following order: bits_per_pixel, xres,
301  *    yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
302  *    bitfields, horizontal timing, vertical timing.
303  */
304 static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
305 {
306         struct imxfb_info *fbi = info->par;
307         struct imxfb_rgb *rgb;
308
309         if (var->xres < MIN_XRES)
310                 var->xres = MIN_XRES;
311         if (var->yres < MIN_YRES)
312                 var->yres = MIN_YRES;
313         if (var->xres > fbi->max_xres)
314                 var->xres = fbi->max_xres;
315         if (var->yres > fbi->max_yres)
316                 var->yres = fbi->max_yres;
317         var->xres_virtual = max(var->xres_virtual, var->xres);
318         var->yres_virtual = max(var->yres_virtual, var->yres);
319
320         pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
321         switch (var->bits_per_pixel) {
322         case 32:
323                 rgb = &def_rgb_18;
324                 break;
325         case 16:
326         default:
327                 if (readl(fbi->regs + LCDC_PCR) & PCR_TFT)
328                         rgb = &def_rgb_16_tft;
329                 else
330                         rgb = &def_rgb_16_stn;
331                 break;
332         case 8:
333                 rgb = &def_rgb_8;
334                 break;
335         }
336
337         /*
338          * Copy the RGB parameters for this display
339          * from the machine specific parameters.
340          */
341         var->red    = rgb->red;
342         var->green  = rgb->green;
343         var->blue   = rgb->blue;
344         var->transp = rgb->transp;
345
346         pr_debug("RGBT length = %d:%d:%d:%d\n",
347                 var->red.length, var->green.length, var->blue.length,
348                 var->transp.length);
349
350         pr_debug("RGBT offset = %d:%d:%d:%d\n",
351                 var->red.offset, var->green.offset, var->blue.offset,
352                 var->transp.offset);
353
354         return 0;
355 }
356
357 /*
358  * imxfb_set_par():
359  *      Set the user defined part of the display for the specified console
360  */
361 static int imxfb_set_par(struct fb_info *info)
362 {
363         struct imxfb_info *fbi = info->par;
364         struct fb_var_screeninfo *var = &info->var;
365
366         if (var->bits_per_pixel == 16 || var->bits_per_pixel == 32)
367                 info->fix.visual = FB_VISUAL_TRUECOLOR;
368         else if (!fbi->cmap_static)
369                 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
370         else {
371                 /*
372                  * Some people have weird ideas about wanting static
373                  * pseudocolor maps.  I suspect their user space
374                  * applications are broken.
375                  */
376                 info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
377         }
378
379         info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
380         fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
381
382         imxfb_activate_var(var, info);
383
384         return 0;
385 }
386
387 static void imxfb_enable_controller(struct imxfb_info *fbi)
388 {
389         pr_debug("Enabling LCD controller\n");
390
391         writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
392
393         /* physical screen start address            */
394         writel(VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4),
395                 fbi->regs + LCDC_VPW);
396
397         /* panning offset 0 (0 pixel offset)        */
398         writel(0x00000000, fbi->regs + LCDC_POS);
399
400         /* disable hardware cursor */
401         writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1),
402                 fbi->regs + LCDC_CPOS);
403
404         writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR);
405
406         if (fbi->backlight_power)
407                 fbi->backlight_power(1);
408         if (fbi->lcd_power)
409                 fbi->lcd_power(1);
410 }
411
412 static void imxfb_disable_controller(struct imxfb_info *fbi)
413 {
414         pr_debug("Disabling LCD controller\n");
415
416         if (fbi->backlight_power)
417                 fbi->backlight_power(0);
418         if (fbi->lcd_power)
419                 fbi->lcd_power(0);
420
421         writel(0, fbi->regs + LCDC_RMCR);
422 }
423
424 static int imxfb_blank(int blank, struct fb_info *info)
425 {
426         struct imxfb_info *fbi = info->par;
427
428         pr_debug("imxfb_blank: blank=%d\n", blank);
429
430         switch (blank) {
431         case FB_BLANK_POWERDOWN:
432         case FB_BLANK_VSYNC_SUSPEND:
433         case FB_BLANK_HSYNC_SUSPEND:
434         case FB_BLANK_NORMAL:
435                 imxfb_disable_controller(fbi);
436                 break;
437
438         case FB_BLANK_UNBLANK:
439                 imxfb_enable_controller(fbi);
440                 break;
441         }
442         return 0;
443 }
444
445 static struct fb_ops imxfb_ops = {
446         .owner          = THIS_MODULE,
447         .fb_check_var   = imxfb_check_var,
448         .fb_set_par     = imxfb_set_par,
449         .fb_setcolreg   = imxfb_setcolreg,
450         .fb_fillrect    = cfb_fillrect,
451         .fb_copyarea    = cfb_copyarea,
452         .fb_imageblit   = cfb_imageblit,
453         .fb_blank       = imxfb_blank,
454 };
455
456 /*
457  * imxfb_activate_var():
458  *      Configures LCD Controller based on entries in var parameter.  Settings are
459  *      only written to the controller if changes were made.
460  */
461 static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
462 {
463         struct imxfb_info *fbi = info->par;
464         pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
465                 var->xres, var->hsync_len,
466                 var->left_margin, var->right_margin);
467         pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
468                 var->yres, var->vsync_len,
469                 var->upper_margin, var->lower_margin);
470
471 #if DEBUG_VAR
472         if (var->xres < 16        || var->xres > 1024)
473                 printk(KERN_ERR "%s: invalid xres %d\n",
474                         info->fix.id, var->xres);
475         if (var->hsync_len < 1    || var->hsync_len > 64)
476                 printk(KERN_ERR "%s: invalid hsync_len %d\n",
477                         info->fix.id, var->hsync_len);
478         if (var->left_margin > 255)
479                 printk(KERN_ERR "%s: invalid left_margin %d\n",
480                         info->fix.id, var->left_margin);
481         if (var->right_margin > 255)
482                 printk(KERN_ERR "%s: invalid right_margin %d\n",
483                         info->fix.id, var->right_margin);
484         if (var->yres < 1 || var->yres > 511)
485                 printk(KERN_ERR "%s: invalid yres %d\n",
486                         info->fix.id, var->yres);
487         if (var->vsync_len > 100)
488                 printk(KERN_ERR "%s: invalid vsync_len %d\n",
489                         info->fix.id, var->vsync_len);
490         if (var->upper_margin > 63)
491                 printk(KERN_ERR "%s: invalid upper_margin %d\n",
492                         info->fix.id, var->upper_margin);
493         if (var->lower_margin > 255)
494                 printk(KERN_ERR "%s: invalid lower_margin %d\n",
495                         info->fix.id, var->lower_margin);
496 #endif
497
498         writel(HCR_H_WIDTH(var->hsync_len - 1) |
499                 HCR_H_WAIT_1(var->right_margin - 1) |
500                 HCR_H_WAIT_2(var->left_margin - 3),
501                 fbi->regs + LCDC_HCR);
502
503         writel(VCR_V_WIDTH(var->vsync_len) |
504                 VCR_V_WAIT_1(var->lower_margin) |
505                 VCR_V_WAIT_2(var->upper_margin),
506                 fbi->regs + LCDC_VCR);
507
508         writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres),
509                         fbi->regs + LCDC_SIZE);
510         writel(fbi->pcr, fbi->regs + LCDC_PCR);
511         writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
512         writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
513         writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
514
515         return 0;
516 }
517
518 #ifdef CONFIG_PM
519 /*
520  * Power management hooks.  Note that we won't be called from IRQ context,
521  * unlike the blank functions above, so we may sleep.
522  */
523 static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
524 {
525         struct imxfb_info *fbi = platform_get_drvdata(dev);
526
527         pr_debug("%s\n", __func__);
528
529         imxfb_disable_controller(fbi);
530         return 0;
531 }
532
533 static int imxfb_resume(struct platform_device *dev)
534 {
535         struct imxfb_info *fbi = platform_get_drvdata(dev);
536
537         pr_debug("%s\n", __func__);
538
539         imxfb_enable_controller(fbi);
540         return 0;
541 }
542 #else
543 #define imxfb_suspend   NULL
544 #define imxfb_resume    NULL
545 #endif
546
547 static int __init imxfb_init_fbinfo(struct platform_device *pdev)
548 {
549         struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
550         struct fb_info *info = dev_get_drvdata(&pdev->dev);
551         struct imxfb_info *fbi = info->par;
552
553         pr_debug("%s\n",__func__);
554
555         info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
556         if (!info->pseudo_palette)
557                 return -ENOMEM;
558
559         memset(fbi, 0, sizeof(struct imxfb_info));
560
561         strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
562
563         info->fix.type                  = FB_TYPE_PACKED_PIXELS;
564         info->fix.type_aux              = 0;
565         info->fix.xpanstep              = 0;
566         info->fix.ypanstep              = 0;
567         info->fix.ywrapstep             = 0;
568         info->fix.accel                 = FB_ACCEL_NONE;
569
570         info->var.nonstd                = 0;
571         info->var.activate              = FB_ACTIVATE_NOW;
572         info->var.height                = -1;
573         info->var.width = -1;
574         info->var.accel_flags           = 0;
575         info->var.vmode                 = FB_VMODE_NONINTERLACED;
576
577         info->fbops                     = &imxfb_ops;
578         info->flags                     = FBINFO_FLAG_DEFAULT |
579                                           FBINFO_READS_FAST;
580
581         fbi->max_xres                   = pdata->xres;
582         info->var.xres                  = pdata->xres;
583         info->var.xres_virtual          = pdata->xres;
584         fbi->max_yres                   = pdata->yres;
585         info->var.yres                  = pdata->yres;
586         info->var.yres_virtual          = pdata->yres;
587         fbi->max_bpp                    = pdata->bpp;
588         info->var.bits_per_pixel        = pdata->bpp;
589         info->var.nonstd                = pdata->nonstd;
590         info->var.pixclock              = pdata->pixclock;
591         info->var.hsync_len             = pdata->hsync_len;
592         info->var.left_margin           = pdata->left_margin;
593         info->var.right_margin          = pdata->right_margin;
594         info->var.vsync_len             = pdata->vsync_len;
595         info->var.upper_margin          = pdata->upper_margin;
596         info->var.lower_margin          = pdata->lower_margin;
597         info->var.sync                  = pdata->sync;
598         info->var.grayscale             = pdata->cmap_greyscale;
599         fbi->cmap_inverse               = pdata->cmap_inverse;
600         fbi->cmap_static                = pdata->cmap_static;
601         fbi->pcr                        = pdata->pcr;
602         fbi->lscr1                      = pdata->lscr1;
603         fbi->dmacr                      = pdata->dmacr;
604         fbi->pwmr                       = pdata->pwmr;
605         fbi->lcd_power                  = pdata->lcd_power;
606         fbi->backlight_power            = pdata->backlight_power;
607         info->fix.smem_len              = fbi->max_xres * fbi->max_yres *
608                                           fbi->max_bpp / 8;
609
610         return 0;
611 }
612
613 static int __init imxfb_probe(struct platform_device *pdev)
614 {
615         struct imxfb_info *fbi;
616         struct fb_info *info;
617         struct imx_fb_platform_data *pdata;
618         struct resource *res;
619         int ret;
620
621         printk("i.MX Framebuffer driver\n");
622
623         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
624         if (!res)
625                 return -ENODEV;
626
627         pdata = pdev->dev.platform_data;
628         if (!pdata) {
629                 dev_err(&pdev->dev,"No platform_data available\n");
630                 return -ENOMEM;
631         }
632
633         info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
634         if (!info)
635                 return -ENOMEM;
636
637         fbi = info->par;
638
639         platform_set_drvdata(pdev, info);
640
641         ret = imxfb_init_fbinfo(pdev);
642         if (ret < 0)
643                 goto failed_init;
644
645         res = request_mem_region(res->start, resource_size(res),
646                                 DRIVER_NAME);
647         if (!res) {
648                 ret = -EBUSY;
649                 goto failed_req;
650         }
651
652         fbi->regs = ioremap(res->start, resource_size(res));
653         if (fbi->regs == NULL) {
654                 printk(KERN_ERR"Cannot map frame buffer registers\n");
655                 goto failed_ioremap;
656         }
657
658         if (!pdata->fixed_screen_cpu) {
659                 fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
660                 fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
661                                 fbi->map_size, &fbi->map_dma, GFP_KERNEL);
662
663                 if (!fbi->map_cpu) {
664                         dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
665                         ret = -ENOMEM;
666                         goto failed_map;
667                 }
668
669                 info->screen_base = fbi->map_cpu;
670                 fbi->screen_cpu = fbi->map_cpu;
671                 fbi->screen_dma = fbi->map_dma;
672                 info->fix.smem_start = fbi->screen_dma;
673         } else {
674                 /* Fixed framebuffer mapping enables location of the screen in eSRAM */
675                 fbi->map_cpu = pdata->fixed_screen_cpu;
676                 fbi->map_dma = pdata->fixed_screen_dma;
677                 info->screen_base = fbi->map_cpu;
678                 fbi->screen_cpu = fbi->map_cpu;
679                 fbi->screen_dma = fbi->map_dma;
680                 info->fix.smem_start = fbi->screen_dma;
681         }
682
683         if (pdata->init) {
684                 ret = pdata->init(fbi->pdev);
685                 if (ret)
686                         goto failed_platform_init;
687         }
688
689         /*
690          * This makes sure that our colour bitfield
691          * descriptors are correctly initialised.
692          */
693         imxfb_check_var(&info->var, info);
694
695         ret = fb_alloc_cmap(&info->cmap, 1 << info->var.bits_per_pixel, 0);
696         if (ret < 0)
697                 goto failed_cmap;
698
699         imxfb_set_par(info);
700         ret = register_framebuffer(info);
701         if (ret < 0) {
702                 dev_err(&pdev->dev, "failed to register framebuffer\n");
703                 goto failed_register;
704         }
705
706         imxfb_enable_controller(fbi);
707
708         return 0;
709
710 failed_register:
711         fb_dealloc_cmap(&info->cmap);
712 failed_cmap:
713         if (pdata->exit)
714                 pdata->exit(fbi->pdev);
715 failed_platform_init:
716         if (!pdata->fixed_screen_cpu)
717                 dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
718                         fbi->map_dma);
719 failed_map:
720         iounmap(fbi->regs);
721 failed_ioremap:
722         release_mem_region(res->start, res->end - res->start);
723 failed_req:
724         kfree(info->pseudo_palette);
725 failed_init:
726         platform_set_drvdata(pdev, NULL);
727         framebuffer_release(info);
728         return ret;
729 }
730
731 static int __devexit imxfb_remove(struct platform_device *pdev)
732 {
733         struct imx_fb_platform_data *pdata;
734         struct fb_info *info = platform_get_drvdata(pdev);
735         struct imxfb_info *fbi = info->par;
736         struct resource *res;
737
738         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
739
740         imxfb_disable_controller(fbi);
741
742         unregister_framebuffer(info);
743
744         pdata = pdev->dev.platform_data;
745         if (pdata->exit)
746                 pdata->exit(fbi->pdev);
747
748         fb_dealloc_cmap(&info->cmap);
749         kfree(info->pseudo_palette);
750         framebuffer_release(info);
751
752         iounmap(fbi->regs);
753         release_mem_region(res->start, res->end - res->start + 1);
754         platform_set_drvdata(pdev, NULL);
755
756         return 0;
757 }
758
759 void  imxfb_shutdown(struct platform_device * dev)
760 {
761         struct fb_info *info = platform_get_drvdata(dev);
762         struct imxfb_info *fbi = info->par;
763         imxfb_disable_controller(fbi);
764 }
765
766 static struct platform_driver imxfb_driver = {
767         .suspend        = imxfb_suspend,
768         .resume         = imxfb_resume,
769         .remove         = __devexit_p(imxfb_remove),
770         .shutdown       = imxfb_shutdown,
771         .driver         = {
772                 .name   = DRIVER_NAME,
773         },
774 };
775
776 int __init imxfb_init(void)
777 {
778         return platform_driver_probe(&imxfb_driver, imxfb_probe);
779 }
780
781 static void __exit imxfb_cleanup(void)
782 {
783         platform_driver_unregister(&imxfb_driver);
784 }
785
786 module_init(imxfb_init);
787 module_exit(imxfb_cleanup);
788
789 MODULE_DESCRIPTION("Motorola i.MX framebuffer driver");
790 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
791 MODULE_LICENSE("GPL");