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