Merge tag 'audit-pr-20190702' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoor...
[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         void *page;
461         int i;
462
463         for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {
464                 if (max_videosize < mode->xres * mode->yres)
465                         max_videosize = mode->xres * mode->yres;
466         }
467
468         max_videosize *= jzfb_get_controller_bpp(jzfb) >> 3;
469
470         jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev,
471                                         sizeof(*jzfb->framedesc),
472                                         &jzfb->framedesc_phys, GFP_KERNEL);
473
474         if (!jzfb->framedesc)
475                 return -ENOMEM;
476
477         jzfb->vidmem_size = PAGE_ALIGN(max_videosize);
478         jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev,
479                                         jzfb->vidmem_size,
480                                         &jzfb->vidmem_phys, GFP_KERNEL);
481
482         if (!jzfb->vidmem)
483                 goto err_free_framedesc;
484
485         for (page = jzfb->vidmem;
486                  page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
487                  page += PAGE_SIZE) {
488                 SetPageReserved(virt_to_page(page));
489         }
490
491         jzfb->framedesc->next = jzfb->framedesc_phys;
492         jzfb->framedesc->addr = jzfb->vidmem_phys;
493         jzfb->framedesc->id = 0xdeafbead;
494         jzfb->framedesc->cmd = 0;
495         jzfb->framedesc->cmd |= max_videosize / 4;
496
497         return 0;
498
499 err_free_framedesc:
500         dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
501                                 jzfb->framedesc, jzfb->framedesc_phys);
502         return -ENOMEM;
503 }
504
505 static void jzfb_free_devmem(struct jzfb *jzfb)
506 {
507         dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size,
508                                 jzfb->vidmem, jzfb->vidmem_phys);
509         dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
510                                 jzfb->framedesc, jzfb->framedesc_phys);
511 }
512
513 static struct  fb_ops jzfb_ops = {
514         .owner = THIS_MODULE,
515         .fb_check_var = jzfb_check_var,
516         .fb_set_par = jzfb_set_par,
517         .fb_blank = jzfb_blank,
518         .fb_fillrect    = sys_fillrect,
519         .fb_copyarea    = sys_copyarea,
520         .fb_imageblit   = sys_imageblit,
521         .fb_setcolreg = jzfb_setcolreg,
522 };
523
524 static int jzfb_probe(struct platform_device *pdev)
525 {
526         int ret;
527         struct jzfb *jzfb;
528         struct fb_info *fb;
529         struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data;
530         struct resource *mem;
531
532         if (!pdata) {
533                 dev_err(&pdev->dev, "Missing platform data\n");
534                 return -ENXIO;
535         }
536
537         fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
538         if (!fb) {
539                 dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
540                 return -ENOMEM;
541         }
542
543         fb->fbops = &jzfb_ops;
544         fb->flags = FBINFO_DEFAULT;
545
546         jzfb = fb->par;
547         jzfb->pdev = pdev;
548         jzfb->pdata = pdata;
549
550         jzfb->ldclk = devm_clk_get(&pdev->dev, "lcd");
551         if (IS_ERR(jzfb->ldclk)) {
552                 ret = PTR_ERR(jzfb->ldclk);
553                 dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
554                 goto err_framebuffer_release;
555         }
556
557         jzfb->lpclk = devm_clk_get(&pdev->dev, "lcd_pclk");
558         if (IS_ERR(jzfb->lpclk)) {
559                 ret = PTR_ERR(jzfb->lpclk);
560                 dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
561                 goto err_framebuffer_release;
562         }
563
564         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
565         jzfb->base = devm_ioremap_resource(&pdev->dev, mem);
566         if (IS_ERR(jzfb->base)) {
567                 ret = PTR_ERR(jzfb->base);
568                 goto err_framebuffer_release;
569         }
570
571         platform_set_drvdata(pdev, jzfb);
572
573         mutex_init(&jzfb->lock);
574
575         fb_videomode_to_modelist(pdata->modes, pdata->num_modes,
576                                  &fb->modelist);
577         fb_videomode_to_var(&fb->var, pdata->modes);
578         fb->var.bits_per_pixel = pdata->bpp;
579         jzfb_check_var(&fb->var, fb);
580
581         ret = jzfb_alloc_devmem(jzfb);
582         if (ret) {
583                 dev_err(&pdev->dev, "Failed to allocate video memory\n");
584                 goto err_framebuffer_release;
585         }
586
587         fb->fix = jzfb_fix;
588         fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8;
589         fb->fix.mmio_start = mem->start;
590         fb->fix.mmio_len = resource_size(mem);
591         fb->fix.smem_start = jzfb->vidmem_phys;
592         fb->fix.smem_len =  fb->fix.line_length * fb->var.yres;
593         fb->screen_base = jzfb->vidmem;
594         fb->pseudo_palette = jzfb->pseudo_palette;
595
596         fb_alloc_cmap(&fb->cmap, 256, 0);
597
598         clk_prepare_enable(jzfb->ldclk);
599         jzfb->is_enabled = 1;
600
601         writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
602
603         fb->mode = NULL;
604         jzfb_set_par(fb);
605
606         ret = register_framebuffer(fb);
607         if (ret) {
608                 dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
609                 goto err_free_devmem;
610         }
611
612         jzfb->fb = fb;
613
614         return 0;
615
616 err_free_devmem:
617         fb_dealloc_cmap(&fb->cmap);
618         jzfb_free_devmem(jzfb);
619 err_framebuffer_release:
620         framebuffer_release(fb);
621         return ret;
622 }
623
624 static int jzfb_remove(struct platform_device *pdev)
625 {
626         struct jzfb *jzfb = platform_get_drvdata(pdev);
627
628         jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb);
629
630         fb_dealloc_cmap(&jzfb->fb->cmap);
631         jzfb_free_devmem(jzfb);
632
633         framebuffer_release(jzfb->fb);
634
635         return 0;
636 }
637
638 #ifdef CONFIG_PM
639
640 static int jzfb_suspend(struct device *dev)
641 {
642         struct jzfb *jzfb = dev_get_drvdata(dev);
643
644         console_lock();
645         fb_set_suspend(jzfb->fb, 1);
646         console_unlock();
647
648         mutex_lock(&jzfb->lock);
649         if (jzfb->is_enabled)
650                 jzfb_disable(jzfb);
651         mutex_unlock(&jzfb->lock);
652
653         return 0;
654 }
655
656 static int jzfb_resume(struct device *dev)
657 {
658         struct jzfb *jzfb = dev_get_drvdata(dev);
659         clk_prepare_enable(jzfb->ldclk);
660
661         mutex_lock(&jzfb->lock);
662         if (jzfb->is_enabled)
663                 jzfb_enable(jzfb);
664         mutex_unlock(&jzfb->lock);
665
666         console_lock();
667         fb_set_suspend(jzfb->fb, 0);
668         console_unlock();
669
670         return 0;
671 }
672
673 static const struct dev_pm_ops jzfb_pm_ops = {
674         .suspend        = jzfb_suspend,
675         .resume         = jzfb_resume,
676         .poweroff       = jzfb_suspend,
677         .restore        = jzfb_resume,
678 };
679
680 #define JZFB_PM_OPS (&jzfb_pm_ops)
681
682 #else
683 #define JZFB_PM_OPS NULL
684 #endif
685
686 static struct platform_driver jzfb_driver = {
687         .probe = jzfb_probe,
688         .remove = jzfb_remove,
689         .driver = {
690                 .name = "jz4740-fb",
691                 .pm = JZFB_PM_OPS,
692         },
693 };
694 module_platform_driver(jzfb_driver);
695
696 MODULE_LICENSE("GPL");
697 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
698 MODULE_DESCRIPTION("JZ4740 SoC LCD framebuffer driver");
699 MODULE_ALIAS("platform:jz4740-fb");