Merge tag 'iomap-5.3-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
[linux-2.6-microblaze.git] / drivers / video / fbdev / jz4740_fb.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
4  *      JZ4740 SoC LCD framebuffer driver
5  */
6
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/mutex.h>
10 #include <linux/platform_device.h>
11 #include <linux/pinctrl/consumer.h>
12
13 #include <linux/clk.h>
14 #include <linux/delay.h>
15
16 #include <linux/console.h>
17 #include <linux/fb.h>
18
19 #include <linux/dma-mapping.h>
20
21 #include <asm/mach-jz4740/jz4740_fb.h>
22
23 #define JZ_REG_LCD_CFG          0x00
24 #define JZ_REG_LCD_VSYNC        0x04
25 #define JZ_REG_LCD_HSYNC        0x08
26 #define JZ_REG_LCD_VAT          0x0C
27 #define JZ_REG_LCD_DAH          0x10
28 #define JZ_REG_LCD_DAV          0x14
29 #define JZ_REG_LCD_PS           0x18
30 #define JZ_REG_LCD_CLS          0x1C
31 #define JZ_REG_LCD_SPL          0x20
32 #define JZ_REG_LCD_REV          0x24
33 #define JZ_REG_LCD_CTRL         0x30
34 #define JZ_REG_LCD_STATE        0x34
35 #define JZ_REG_LCD_IID          0x38
36 #define JZ_REG_LCD_DA0          0x40
37 #define JZ_REG_LCD_SA0          0x44
38 #define JZ_REG_LCD_FID0         0x48
39 #define JZ_REG_LCD_CMD0         0x4C
40 #define JZ_REG_LCD_DA1          0x50
41 #define JZ_REG_LCD_SA1          0x54
42 #define JZ_REG_LCD_FID1         0x58
43 #define JZ_REG_LCD_CMD1         0x5C
44
45 #define JZ_LCD_CFG_SLCD                 BIT(31)
46 #define JZ_LCD_CFG_PS_DISABLE           BIT(23)
47 #define JZ_LCD_CFG_CLS_DISABLE          BIT(22)
48 #define JZ_LCD_CFG_SPL_DISABLE          BIT(21)
49 #define JZ_LCD_CFG_REV_DISABLE          BIT(20)
50 #define JZ_LCD_CFG_HSYNCM               BIT(19)
51 #define JZ_LCD_CFG_PCLKM                BIT(18)
52 #define JZ_LCD_CFG_INV                  BIT(17)
53 #define JZ_LCD_CFG_SYNC_DIR             BIT(16)
54 #define JZ_LCD_CFG_PS_POLARITY          BIT(15)
55 #define JZ_LCD_CFG_CLS_POLARITY         BIT(14)
56 #define JZ_LCD_CFG_SPL_POLARITY         BIT(13)
57 #define JZ_LCD_CFG_REV_POLARITY         BIT(12)
58 #define JZ_LCD_CFG_HSYNC_ACTIVE_LOW     BIT(11)
59 #define JZ_LCD_CFG_PCLK_FALLING_EDGE    BIT(10)
60 #define JZ_LCD_CFG_DE_ACTIVE_LOW        BIT(9)
61 #define JZ_LCD_CFG_VSYNC_ACTIVE_LOW     BIT(8)
62 #define JZ_LCD_CFG_18_BIT               BIT(7)
63 #define JZ_LCD_CFG_PDW                  (BIT(5) | BIT(4))
64 #define JZ_LCD_CFG_MODE_MASK 0xf
65
66 #define JZ_LCD_CTRL_BURST_4             (0x0 << 28)
67 #define JZ_LCD_CTRL_BURST_8             (0x1 << 28)
68 #define JZ_LCD_CTRL_BURST_16            (0x2 << 28)
69 #define JZ_LCD_CTRL_RGB555              BIT(27)
70 #define JZ_LCD_CTRL_OFUP                BIT(26)
71 #define JZ_LCD_CTRL_FRC_GRAYSCALE_16    (0x0 << 24)
72 #define JZ_LCD_CTRL_FRC_GRAYSCALE_4     (0x1 << 24)
73 #define JZ_LCD_CTRL_FRC_GRAYSCALE_2     (0x2 << 24)
74 #define JZ_LCD_CTRL_PDD_MASK            (0xff << 16)
75 #define JZ_LCD_CTRL_EOF_IRQ             BIT(13)
76 #define JZ_LCD_CTRL_SOF_IRQ             BIT(12)
77 #define JZ_LCD_CTRL_OFU_IRQ             BIT(11)
78 #define JZ_LCD_CTRL_IFU0_IRQ            BIT(10)
79 #define JZ_LCD_CTRL_IFU1_IRQ            BIT(9)
80 #define JZ_LCD_CTRL_DD_IRQ              BIT(8)
81 #define JZ_LCD_CTRL_QDD_IRQ             BIT(7)
82 #define JZ_LCD_CTRL_REVERSE_ENDIAN      BIT(6)
83 #define JZ_LCD_CTRL_LSB_FISRT           BIT(5)
84 #define JZ_LCD_CTRL_DISABLE             BIT(4)
85 #define JZ_LCD_CTRL_ENABLE              BIT(3)
86 #define JZ_LCD_CTRL_BPP_1               0x0
87 #define JZ_LCD_CTRL_BPP_2               0x1
88 #define JZ_LCD_CTRL_BPP_4               0x2
89 #define JZ_LCD_CTRL_BPP_8               0x3
90 #define JZ_LCD_CTRL_BPP_15_16           0x4
91 #define JZ_LCD_CTRL_BPP_18_24           0x5
92
93 #define JZ_LCD_CMD_SOF_IRQ BIT(31)
94 #define JZ_LCD_CMD_EOF_IRQ BIT(30)
95 #define JZ_LCD_CMD_ENABLE_PAL BIT(28)
96
97 #define JZ_LCD_SYNC_MASK 0x3ff
98
99 #define JZ_LCD_STATE_DISABLED BIT(0)
100
101 struct jzfb_framedesc {
102         uint32_t next;
103         uint32_t addr;
104         uint32_t id;
105         uint32_t cmd;
106 } __packed;
107
108 struct jzfb {
109         struct fb_info *fb;
110         struct platform_device *pdev;
111         void __iomem *base;
112         struct resource *mem;
113         struct jz4740_fb_platform_data *pdata;
114
115         size_t vidmem_size;
116         void *vidmem;
117         dma_addr_t vidmem_phys;
118         struct jzfb_framedesc *framedesc;
119         dma_addr_t framedesc_phys;
120
121         struct clk *ldclk;
122         struct clk *lpclk;
123
124         unsigned is_enabled:1;
125         struct mutex lock;
126
127         uint32_t pseudo_palette[16];
128 };
129
130 static const struct fb_fix_screeninfo jzfb_fix = {
131         .id             = "JZ4740 FB",
132         .type           = FB_TYPE_PACKED_PIXELS,
133         .visual         = FB_VISUAL_TRUECOLOR,
134         .xpanstep       = 0,
135         .ypanstep       = 0,
136         .ywrapstep      = 0,
137         .accel          = FB_ACCEL_NONE,
138 };
139
140 /* Based on CNVT_TOHW macro from skeletonfb.c */
141 static inline uint32_t jzfb_convert_color_to_hw(unsigned val,
142         struct fb_bitfield *bf)
143 {
144         return (((val << bf->length) + 0x7FFF - val) >> 16) << bf->offset;
145 }
146
147 static int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green,
148                         unsigned blue, unsigned transp, struct fb_info *fb)
149 {
150         uint32_t color;
151
152         if (regno >= 16)
153                 return -EINVAL;
154
155         color = jzfb_convert_color_to_hw(red, &fb->var.red);
156         color |= jzfb_convert_color_to_hw(green, &fb->var.green);
157         color |= jzfb_convert_color_to_hw(blue, &fb->var.blue);
158         color |= jzfb_convert_color_to_hw(transp, &fb->var.transp);
159
160         ((uint32_t *)(fb->pseudo_palette))[regno] = color;
161
162         return 0;
163 }
164
165 static int jzfb_get_controller_bpp(struct jzfb *jzfb)
166 {
167         switch (jzfb->pdata->bpp) {
168         case 18:
169         case 24:
170                 return 32;
171         case 15:
172                 return 16;
173         default:
174                 return jzfb->pdata->bpp;
175         }
176 }
177
178 static struct fb_videomode *jzfb_get_mode(struct jzfb *jzfb,
179         struct fb_var_screeninfo *var)
180 {
181         size_t i;
182         struct fb_videomode *mode = jzfb->pdata->modes;
183
184         for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) {
185                 if (mode->xres == var->xres && mode->yres == var->yres)
186                         return mode;
187         }
188
189         return NULL;
190 }
191
192 static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
193 {
194         struct jzfb *jzfb = fb->par;
195         struct fb_videomode *mode;
196
197         if (var->bits_per_pixel != jzfb_get_controller_bpp(jzfb) &&
198                 var->bits_per_pixel != jzfb->pdata->bpp)
199                 return -EINVAL;
200
201         mode = jzfb_get_mode(jzfb, var);
202         if (mode == NULL)
203                 return -EINVAL;
204
205         fb_videomode_to_var(var, mode);
206
207         switch (jzfb->pdata->bpp) {
208         case 8:
209                 break;
210         case 15:
211                 var->red.offset = 10;
212                 var->red.length = 5;
213                 var->green.offset = 6;
214                 var->green.length = 5;
215                 var->blue.offset = 0;
216                 var->blue.length = 5;
217                 break;
218         case 16:
219                 var->red.offset = 11;
220                 var->red.length = 5;
221                 var->green.offset = 5;
222                 var->green.length = 6;
223                 var->blue.offset = 0;
224                 var->blue.length = 5;
225                 break;
226         case 18:
227                 var->red.offset = 16;
228                 var->red.length = 6;
229                 var->green.offset = 8;
230                 var->green.length = 6;
231                 var->blue.offset = 0;
232                 var->blue.length = 6;
233                 var->bits_per_pixel = 32;
234                 break;
235         case 32:
236         case 24:
237                 var->transp.offset = 24;
238                 var->transp.length = 8;
239                 var->red.offset = 16;
240                 var->red.length = 8;
241                 var->green.offset = 8;
242                 var->green.length = 8;
243                 var->blue.offset = 0;
244                 var->blue.length = 8;
245                 var->bits_per_pixel = 32;
246                 break;
247         default:
248                 break;
249         }
250
251         return 0;
252 }
253
254 static int jzfb_set_par(struct fb_info *info)
255 {
256         struct jzfb *jzfb = info->par;
257         struct jz4740_fb_platform_data *pdata = jzfb->pdata;
258         struct fb_var_screeninfo *var = &info->var;
259         struct fb_videomode *mode;
260         uint16_t hds, vds;
261         uint16_t hde, vde;
262         uint16_t ht, vt;
263         uint32_t ctrl;
264         uint32_t cfg;
265         unsigned long rate;
266
267         mode = jzfb_get_mode(jzfb, var);
268         if (mode == NULL)
269                 return -EINVAL;
270
271         if (mode == info->mode)
272                 return 0;
273
274         info->mode = mode;
275
276         hds = mode->hsync_len + mode->left_margin;
277         hde = hds + mode->xres;
278         ht = hde + mode->right_margin;
279
280         vds = mode->vsync_len + mode->upper_margin;
281         vde = vds + mode->yres;
282         vt = vde + mode->lower_margin;
283
284         ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16;
285
286         switch (pdata->bpp) {
287         case 1:
288                 ctrl |= JZ_LCD_CTRL_BPP_1;
289                 break;
290         case 2:
291                 ctrl |= JZ_LCD_CTRL_BPP_2;
292                 break;
293         case 4:
294                 ctrl |= JZ_LCD_CTRL_BPP_4;
295                 break;
296         case 8:
297                 ctrl |= JZ_LCD_CTRL_BPP_8;
298         break;
299         case 15:
300                 ctrl |= JZ_LCD_CTRL_RGB555; /* Falltrough */
301         case 16:
302                 ctrl |= JZ_LCD_CTRL_BPP_15_16;
303                 break;
304         case 18:
305         case 24:
306         case 32:
307                 ctrl |= JZ_LCD_CTRL_BPP_18_24;
308                 break;
309         default:
310                 break;
311         }
312
313         cfg = pdata->lcd_type & 0xf;
314
315         if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
316                 cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
317
318         if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
319                 cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW;
320
321         if (pdata->pixclk_falling_edge)
322                 cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE;
323
324         if (pdata->date_enable_active_low)
325                 cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW;
326
327         if (pdata->lcd_type == JZ_LCD_TYPE_GENERIC_18_BIT)
328                 cfg |= JZ_LCD_CFG_18_BIT;
329
330         if (mode->pixclock) {
331                 rate = PICOS2KHZ(mode->pixclock) * 1000;
332                 mode->refresh = rate / vt / ht;
333         } else {
334                 if (pdata->lcd_type == JZ_LCD_TYPE_8BIT_SERIAL)
335                         rate = mode->refresh * (vt + 2 * mode->xres) * ht;
336                 else
337                         rate = mode->refresh * vt * ht;
338
339                 mode->pixclock = KHZ2PICOS(rate / 1000);
340         }
341
342         mutex_lock(&jzfb->lock);
343         if (!jzfb->is_enabled)
344                 clk_enable(jzfb->ldclk);
345         else
346                 ctrl |= JZ_LCD_CTRL_ENABLE;
347
348         switch (pdata->lcd_type) {
349         case JZ_LCD_TYPE_SPECIAL_TFT_1:
350         case JZ_LCD_TYPE_SPECIAL_TFT_2:
351         case JZ_LCD_TYPE_SPECIAL_TFT_3:
352                 writel(pdata->special_tft_config.spl, jzfb->base + JZ_REG_LCD_SPL);
353                 writel(pdata->special_tft_config.cls, jzfb->base + JZ_REG_LCD_CLS);
354                 writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_PS);
355                 writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_REV);
356                 break;
357         default:
358                 cfg |= JZ_LCD_CFG_PS_DISABLE;
359                 cfg |= JZ_LCD_CFG_CLS_DISABLE;
360                 cfg |= JZ_LCD_CFG_SPL_DISABLE;
361                 cfg |= JZ_LCD_CFG_REV_DISABLE;
362                 break;
363         }
364
365         writel(mode->hsync_len, jzfb->base + JZ_REG_LCD_HSYNC);
366         writel(mode->vsync_len, jzfb->base + JZ_REG_LCD_VSYNC);
367
368         writel((ht << 16) | vt, jzfb->base + JZ_REG_LCD_VAT);
369
370         writel((hds << 16) | hde, jzfb->base + JZ_REG_LCD_DAH);
371         writel((vds << 16) | vde, jzfb->base + JZ_REG_LCD_DAV);
372
373         writel(cfg, jzfb->base + JZ_REG_LCD_CFG);
374
375         writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
376
377         if (!jzfb->is_enabled)
378                 clk_disable_unprepare(jzfb->ldclk);
379
380         mutex_unlock(&jzfb->lock);
381
382         clk_set_rate(jzfb->lpclk, rate);
383         clk_set_rate(jzfb->ldclk, rate * 3);
384
385         return 0;
386 }
387
388 static void jzfb_enable(struct jzfb *jzfb)
389 {
390         uint32_t ctrl;
391
392         clk_prepare_enable(jzfb->ldclk);
393
394         pinctrl_pm_select_default_state(&jzfb->pdev->dev);
395
396         writel(0, jzfb->base + JZ_REG_LCD_STATE);
397
398         writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
399
400         ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
401         ctrl |= JZ_LCD_CTRL_ENABLE;
402         ctrl &= ~JZ_LCD_CTRL_DISABLE;
403         writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
404 }
405
406 static void jzfb_disable(struct jzfb *jzfb)
407 {
408         uint32_t ctrl;
409
410         ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
411         ctrl |= JZ_LCD_CTRL_DISABLE;
412         writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
413         do {
414                 ctrl = readl(jzfb->base + JZ_REG_LCD_STATE);
415         } while (!(ctrl & JZ_LCD_STATE_DISABLED));
416
417         pinctrl_pm_select_sleep_state(&jzfb->pdev->dev);
418
419         clk_disable_unprepare(jzfb->ldclk);
420 }
421
422 static int jzfb_blank(int blank_mode, struct fb_info *info)
423 {
424         struct jzfb *jzfb = info->par;
425
426         switch (blank_mode) {
427         case FB_BLANK_UNBLANK:
428                 mutex_lock(&jzfb->lock);
429                 if (jzfb->is_enabled) {
430                         mutex_unlock(&jzfb->lock);
431                         return 0;
432                 }
433
434                 jzfb_enable(jzfb);
435                 jzfb->is_enabled = 1;
436
437                 mutex_unlock(&jzfb->lock);
438                 break;
439         default:
440                 mutex_lock(&jzfb->lock);
441                 if (!jzfb->is_enabled) {
442                         mutex_unlock(&jzfb->lock);
443                         return 0;
444                 }
445
446                 jzfb_disable(jzfb);
447                 jzfb->is_enabled = 0;
448
449                 mutex_unlock(&jzfb->lock);
450                 break;
451         }
452
453         return 0;
454 }
455
456 static int jzfb_alloc_devmem(struct jzfb *jzfb)
457 {
458         int max_videosize = 0;
459         struct fb_videomode *mode = jzfb->pdata->modes;
460         int i;
461
462         for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {
463                 if (max_videosize < mode->xres * mode->yres)
464                         max_videosize = mode->xres * mode->yres;
465         }
466
467         max_videosize *= jzfb_get_controller_bpp(jzfb) >> 3;
468
469         jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev,
470                                         sizeof(*jzfb->framedesc),
471                                         &jzfb->framedesc_phys, GFP_KERNEL);
472
473         if (!jzfb->framedesc)
474                 return -ENOMEM;
475
476         jzfb->vidmem_size = PAGE_ALIGN(max_videosize);
477         jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev,
478                                         jzfb->vidmem_size,
479                                         &jzfb->vidmem_phys, GFP_KERNEL);
480
481         if (!jzfb->vidmem)
482                 goto err_free_framedesc;
483
484         jzfb->framedesc->next = jzfb->framedesc_phys;
485         jzfb->framedesc->addr = jzfb->vidmem_phys;
486         jzfb->framedesc->id = 0xdeafbead;
487         jzfb->framedesc->cmd = 0;
488         jzfb->framedesc->cmd |= max_videosize / 4;
489
490         return 0;
491
492 err_free_framedesc:
493         dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
494                                 jzfb->framedesc, jzfb->framedesc_phys);
495         return -ENOMEM;
496 }
497
498 static void jzfb_free_devmem(struct jzfb *jzfb)
499 {
500         dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size,
501                                 jzfb->vidmem, jzfb->vidmem_phys);
502         dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
503                                 jzfb->framedesc, jzfb->framedesc_phys);
504 }
505
506 static struct  fb_ops jzfb_ops = {
507         .owner = THIS_MODULE,
508         .fb_check_var = jzfb_check_var,
509         .fb_set_par = jzfb_set_par,
510         .fb_blank = jzfb_blank,
511         .fb_fillrect    = sys_fillrect,
512         .fb_copyarea    = sys_copyarea,
513         .fb_imageblit   = sys_imageblit,
514         .fb_setcolreg = jzfb_setcolreg,
515 };
516
517 static int jzfb_probe(struct platform_device *pdev)
518 {
519         int ret;
520         struct jzfb *jzfb;
521         struct fb_info *fb;
522         struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data;
523         struct resource *mem;
524
525         if (!pdata) {
526                 dev_err(&pdev->dev, "Missing platform data\n");
527                 return -ENXIO;
528         }
529
530         fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
531         if (!fb)
532                 return -ENOMEM;
533
534         fb->fbops = &jzfb_ops;
535         fb->flags = FBINFO_DEFAULT;
536
537         jzfb = fb->par;
538         jzfb->pdev = pdev;
539         jzfb->pdata = pdata;
540
541         jzfb->ldclk = devm_clk_get(&pdev->dev, "lcd");
542         if (IS_ERR(jzfb->ldclk)) {
543                 ret = PTR_ERR(jzfb->ldclk);
544                 dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
545                 goto err_framebuffer_release;
546         }
547
548         jzfb->lpclk = devm_clk_get(&pdev->dev, "lcd_pclk");
549         if (IS_ERR(jzfb->lpclk)) {
550                 ret = PTR_ERR(jzfb->lpclk);
551                 dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
552                 goto err_framebuffer_release;
553         }
554
555         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
556         jzfb->base = devm_ioremap_resource(&pdev->dev, mem);
557         if (IS_ERR(jzfb->base)) {
558                 ret = PTR_ERR(jzfb->base);
559                 goto err_framebuffer_release;
560         }
561
562         platform_set_drvdata(pdev, jzfb);
563
564         mutex_init(&jzfb->lock);
565
566         fb_videomode_to_modelist(pdata->modes, pdata->num_modes,
567                                  &fb->modelist);
568         fb_videomode_to_var(&fb->var, pdata->modes);
569         fb->var.bits_per_pixel = pdata->bpp;
570         jzfb_check_var(&fb->var, fb);
571
572         ret = jzfb_alloc_devmem(jzfb);
573         if (ret) {
574                 dev_err(&pdev->dev, "Failed to allocate video memory\n");
575                 goto err_framebuffer_release;
576         }
577
578         fb->fix = jzfb_fix;
579         fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8;
580         fb->fix.mmio_start = mem->start;
581         fb->fix.mmio_len = resource_size(mem);
582         fb->fix.smem_start = jzfb->vidmem_phys;
583         fb->fix.smem_len =  fb->fix.line_length * fb->var.yres;
584         fb->screen_base = jzfb->vidmem;
585         fb->pseudo_palette = jzfb->pseudo_palette;
586
587         fb_alloc_cmap(&fb->cmap, 256, 0);
588
589         clk_prepare_enable(jzfb->ldclk);
590         jzfb->is_enabled = 1;
591
592         writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
593
594         fb->mode = NULL;
595         jzfb_set_par(fb);
596
597         ret = register_framebuffer(fb);
598         if (ret) {
599                 dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
600                 goto err_free_devmem;
601         }
602
603         jzfb->fb = fb;
604
605         return 0;
606
607 err_free_devmem:
608         fb_dealloc_cmap(&fb->cmap);
609         jzfb_free_devmem(jzfb);
610 err_framebuffer_release:
611         framebuffer_release(fb);
612         return ret;
613 }
614
615 static int jzfb_remove(struct platform_device *pdev)
616 {
617         struct jzfb *jzfb = platform_get_drvdata(pdev);
618
619         jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb);
620
621         fb_dealloc_cmap(&jzfb->fb->cmap);
622         jzfb_free_devmem(jzfb);
623
624         framebuffer_release(jzfb->fb);
625
626         return 0;
627 }
628
629 #ifdef CONFIG_PM
630
631 static int jzfb_suspend(struct device *dev)
632 {
633         struct jzfb *jzfb = dev_get_drvdata(dev);
634
635         console_lock();
636         fb_set_suspend(jzfb->fb, 1);
637         console_unlock();
638
639         mutex_lock(&jzfb->lock);
640         if (jzfb->is_enabled)
641                 jzfb_disable(jzfb);
642         mutex_unlock(&jzfb->lock);
643
644         return 0;
645 }
646
647 static int jzfb_resume(struct device *dev)
648 {
649         struct jzfb *jzfb = dev_get_drvdata(dev);
650         clk_prepare_enable(jzfb->ldclk);
651
652         mutex_lock(&jzfb->lock);
653         if (jzfb->is_enabled)
654                 jzfb_enable(jzfb);
655         mutex_unlock(&jzfb->lock);
656
657         console_lock();
658         fb_set_suspend(jzfb->fb, 0);
659         console_unlock();
660
661         return 0;
662 }
663
664 static const struct dev_pm_ops jzfb_pm_ops = {
665         .suspend        = jzfb_suspend,
666         .resume         = jzfb_resume,
667         .poweroff       = jzfb_suspend,
668         .restore        = jzfb_resume,
669 };
670
671 #define JZFB_PM_OPS (&jzfb_pm_ops)
672
673 #else
674 #define JZFB_PM_OPS NULL
675 #endif
676
677 static struct platform_driver jzfb_driver = {
678         .probe = jzfb_probe,
679         .remove = jzfb_remove,
680         .driver = {
681                 .name = "jz4740-fb",
682                 .pm = JZFB_PM_OPS,
683         },
684 };
685 module_platform_driver(jzfb_driver);
686
687 MODULE_LICENSE("GPL");
688 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
689 MODULE_DESCRIPTION("JZ4740 SoC LCD framebuffer driver");
690 MODULE_ALIAS("platform:jz4740-fb");