ASoC: wm8962: balance pm_runtime_enable
[linux-drm-fsl-dcu.git] / drivers / gpu / drm / exynos / exynos7_drm_decon.c
1 /* drivers/gpu/drm/exynos/exynos7_drm_decon.c
2  *
3  * Copyright (C) 2014 Samsung Electronics Co.Ltd
4  * Authors:
5  *      Akshu Agarwal <akshua@gmail.com>
6  *      Ajay Kumar <ajaykumar.rs@samsung.com>
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  *
13  */
14 #include <drm/drmP.h>
15 #include <drm/exynos_drm.h>
16
17 #include <linux/clk.h>
18 #include <linux/component.h>
19 #include <linux/kernel.h>
20 #include <linux/of.h>
21 #include <linux/of_address.h>
22 #include <linux/of_device.h>
23 #include <linux/platform_device.h>
24 #include <linux/pm_runtime.h>
25
26 #include <video/of_display_timing.h>
27 #include <video/of_videomode.h>
28 #include <video/exynos7_decon.h>
29
30 #include "exynos_drm_crtc.h"
31 #include "exynos_drm_plane.h"
32 #include "exynos_drm_drv.h"
33 #include "exynos_drm_fbdev.h"
34 #include "exynos_drm_iommu.h"
35
36 /*
37  * DECON stands for Display and Enhancement controller.
38  */
39
40 #define DECON_DEFAULT_FRAMERATE 60
41 #define MIN_FB_WIDTH_FOR_16WORD_BURST 128
42
43 #define WINDOWS_NR      2
44
45 struct decon_context {
46         struct device                   *dev;
47         struct drm_device               *drm_dev;
48         struct exynos_drm_crtc          *crtc;
49         struct exynos_drm_plane         planes[WINDOWS_NR];
50         struct clk                      *pclk;
51         struct clk                      *aclk;
52         struct clk                      *eclk;
53         struct clk                      *vclk;
54         void __iomem                    *regs;
55         unsigned int                    default_win;
56         unsigned long                   irq_flags;
57         bool                            i80_if;
58         bool                            suspended;
59         int                             pipe;
60         wait_queue_head_t               wait_vsync_queue;
61         atomic_t                        wait_vsync_event;
62
63         struct exynos_drm_panel_info panel;
64         struct drm_encoder *encoder;
65 };
66
67 static const struct of_device_id decon_driver_dt_match[] = {
68         {.compatible = "samsung,exynos7-decon"},
69         {},
70 };
71 MODULE_DEVICE_TABLE(of, decon_driver_dt_match);
72
73 static const uint32_t decon_formats[] = {
74         DRM_FORMAT_RGB565,
75         DRM_FORMAT_XRGB8888,
76         DRM_FORMAT_XBGR8888,
77         DRM_FORMAT_RGBX8888,
78         DRM_FORMAT_BGRX8888,
79         DRM_FORMAT_ARGB8888,
80         DRM_FORMAT_ABGR8888,
81         DRM_FORMAT_RGBA8888,
82         DRM_FORMAT_BGRA8888,
83 };
84
85 static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
86 {
87         struct decon_context *ctx = crtc->ctx;
88
89         if (ctx->suspended)
90                 return;
91
92         atomic_set(&ctx->wait_vsync_event, 1);
93
94         /*
95          * wait for DECON to signal VSYNC interrupt or return after
96          * timeout which is set to 50ms (refresh rate of 20).
97          */
98         if (!wait_event_timeout(ctx->wait_vsync_queue,
99                                 !atomic_read(&ctx->wait_vsync_event),
100                                 HZ/20))
101                 DRM_DEBUG_KMS("vblank wait timed out.\n");
102 }
103
104 static void decon_clear_channels(struct exynos_drm_crtc *crtc)
105 {
106         struct decon_context *ctx = crtc->ctx;
107         unsigned int win, ch_enabled = 0;
108
109         DRM_DEBUG_KMS("%s\n", __FILE__);
110
111         /* Check if any channel is enabled. */
112         for (win = 0; win < WINDOWS_NR; win++) {
113                 u32 val = readl(ctx->regs + WINCON(win));
114
115                 if (val & WINCONx_ENWIN) {
116                         val &= ~WINCONx_ENWIN;
117                         writel(val, ctx->regs + WINCON(win));
118                         ch_enabled = 1;
119                 }
120         }
121
122         /* Wait for vsync, as disable channel takes effect at next vsync */
123         if (ch_enabled) {
124                 unsigned int state = ctx->suspended;
125
126                 ctx->suspended = 0;
127                 decon_wait_for_vblank(ctx->crtc);
128                 ctx->suspended = state;
129         }
130 }
131
132 static int decon_ctx_initialize(struct decon_context *ctx,
133                         struct drm_device *drm_dev)
134 {
135         struct exynos_drm_private *priv = drm_dev->dev_private;
136         int ret;
137
138         ctx->drm_dev = drm_dev;
139         ctx->pipe = priv->pipe++;
140
141         decon_clear_channels(ctx->crtc);
142
143         ret = drm_iommu_attach_device(drm_dev, ctx->dev);
144         if (ret)
145                 priv->pipe--;
146
147         return ret;
148 }
149
150 static void decon_ctx_remove(struct decon_context *ctx)
151 {
152         /* detach this sub driver from iommu mapping if supported. */
153         drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
154 }
155
156 static u32 decon_calc_clkdiv(struct decon_context *ctx,
157                 const struct drm_display_mode *mode)
158 {
159         unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
160         u32 clkdiv;
161
162         /* Find the clock divider value that gets us closest to ideal_clk */
163         clkdiv = DIV_ROUND_UP(clk_get_rate(ctx->vclk), ideal_clk);
164
165         return (clkdiv < 0x100) ? clkdiv : 0xff;
166 }
167
168 static bool decon_mode_fixup(struct exynos_drm_crtc *crtc,
169                 const struct drm_display_mode *mode,
170                 struct drm_display_mode *adjusted_mode)
171 {
172         if (adjusted_mode->vrefresh == 0)
173                 adjusted_mode->vrefresh = DECON_DEFAULT_FRAMERATE;
174
175         return true;
176 }
177
178 static void decon_commit(struct exynos_drm_crtc *crtc)
179 {
180         struct decon_context *ctx = crtc->ctx;
181         struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
182         u32 val, clkdiv;
183
184         if (ctx->suspended)
185                 return;
186
187         /* nothing to do if we haven't set the mode yet */
188         if (mode->htotal == 0 || mode->vtotal == 0)
189                 return;
190
191         if (!ctx->i80_if) {
192                 int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
193               /* setup vertical timing values. */
194                 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
195                 vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
196                 vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
197
198                 val = VIDTCON0_VBPD(vbpd - 1) | VIDTCON0_VFPD(vfpd - 1);
199                 writel(val, ctx->regs + VIDTCON0);
200
201                 val = VIDTCON1_VSPW(vsync_len - 1);
202                 writel(val, ctx->regs + VIDTCON1);
203
204                 /* setup horizontal timing values.  */
205                 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
206                 hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
207                 hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
208
209                 /* setup horizontal timing values.  */
210                 val = VIDTCON2_HBPD(hbpd - 1) | VIDTCON2_HFPD(hfpd - 1);
211                 writel(val, ctx->regs + VIDTCON2);
212
213                 val = VIDTCON3_HSPW(hsync_len - 1);
214                 writel(val, ctx->regs + VIDTCON3);
215         }
216
217         /* setup horizontal and vertical display size. */
218         val = VIDTCON4_LINEVAL(mode->vdisplay - 1) |
219                VIDTCON4_HOZVAL(mode->hdisplay - 1);
220         writel(val, ctx->regs + VIDTCON4);
221
222         writel(mode->vdisplay - 1, ctx->regs + LINECNT_OP_THRESHOLD);
223
224         /*
225          * fields of register with prefix '_F' would be updated
226          * at vsync(same as dma start)
227          */
228         val = VIDCON0_ENVID | VIDCON0_ENVID_F;
229         writel(val, ctx->regs + VIDCON0);
230
231         clkdiv = decon_calc_clkdiv(ctx, mode);
232         if (clkdiv > 1) {
233                 val = VCLKCON1_CLKVAL_NUM_VCLK(clkdiv - 1);
234                 writel(val, ctx->regs + VCLKCON1);
235                 writel(val, ctx->regs + VCLKCON2);
236         }
237
238         val = readl(ctx->regs + DECON_UPDATE);
239         val |= DECON_UPDATE_STANDALONE_F;
240         writel(val, ctx->regs + DECON_UPDATE);
241 }
242
243 static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
244 {
245         struct decon_context *ctx = crtc->ctx;
246         u32 val;
247
248         if (ctx->suspended)
249                 return -EPERM;
250
251         if (!test_and_set_bit(0, &ctx->irq_flags)) {
252                 val = readl(ctx->regs + VIDINTCON0);
253
254                 val |= VIDINTCON0_INT_ENABLE;
255
256                 if (!ctx->i80_if) {
257                         val |= VIDINTCON0_INT_FRAME;
258                         val &= ~VIDINTCON0_FRAMESEL0_MASK;
259                         val |= VIDINTCON0_FRAMESEL0_VSYNC;
260                 }
261
262                 writel(val, ctx->regs + VIDINTCON0);
263         }
264
265         return 0;
266 }
267
268 static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
269 {
270         struct decon_context *ctx = crtc->ctx;
271         u32 val;
272
273         if (ctx->suspended)
274                 return;
275
276         if (test_and_clear_bit(0, &ctx->irq_flags)) {
277                 val = readl(ctx->regs + VIDINTCON0);
278
279                 val &= ~VIDINTCON0_INT_ENABLE;
280                 if (!ctx->i80_if)
281                         val &= ~VIDINTCON0_INT_FRAME;
282
283                 writel(val, ctx->regs + VIDINTCON0);
284         }
285 }
286
287 static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
288                                  struct drm_framebuffer *fb)
289 {
290         unsigned long val;
291         int padding;
292
293         val = readl(ctx->regs + WINCON(win));
294         val &= ~WINCONx_BPPMODE_MASK;
295
296         switch (fb->pixel_format) {
297         case DRM_FORMAT_RGB565:
298                 val |= WINCONx_BPPMODE_16BPP_565;
299                 val |= WINCONx_BURSTLEN_16WORD;
300                 break;
301         case DRM_FORMAT_XRGB8888:
302                 val |= WINCONx_BPPMODE_24BPP_xRGB;
303                 val |= WINCONx_BURSTLEN_16WORD;
304                 break;
305         case DRM_FORMAT_XBGR8888:
306                 val |= WINCONx_BPPMODE_24BPP_xBGR;
307                 val |= WINCONx_BURSTLEN_16WORD;
308                 break;
309         case DRM_FORMAT_RGBX8888:
310                 val |= WINCONx_BPPMODE_24BPP_RGBx;
311                 val |= WINCONx_BURSTLEN_16WORD;
312                 break;
313         case DRM_FORMAT_BGRX8888:
314                 val |= WINCONx_BPPMODE_24BPP_BGRx;
315                 val |= WINCONx_BURSTLEN_16WORD;
316                 break;
317         case DRM_FORMAT_ARGB8888:
318                 val |= WINCONx_BPPMODE_32BPP_ARGB | WINCONx_BLD_PIX |
319                         WINCONx_ALPHA_SEL;
320                 val |= WINCONx_BURSTLEN_16WORD;
321                 break;
322         case DRM_FORMAT_ABGR8888:
323                 val |= WINCONx_BPPMODE_32BPP_ABGR | WINCONx_BLD_PIX |
324                         WINCONx_ALPHA_SEL;
325                 val |= WINCONx_BURSTLEN_16WORD;
326                 break;
327         case DRM_FORMAT_RGBA8888:
328                 val |= WINCONx_BPPMODE_32BPP_RGBA | WINCONx_BLD_PIX |
329                         WINCONx_ALPHA_SEL;
330                 val |= WINCONx_BURSTLEN_16WORD;
331                 break;
332         case DRM_FORMAT_BGRA8888:
333                 val |= WINCONx_BPPMODE_32BPP_BGRA | WINCONx_BLD_PIX |
334                         WINCONx_ALPHA_SEL;
335                 val |= WINCONx_BURSTLEN_16WORD;
336                 break;
337         default:
338                 DRM_DEBUG_KMS("invalid pixel size so using unpacked 24bpp.\n");
339
340                 val |= WINCONx_BPPMODE_24BPP_xRGB;
341                 val |= WINCONx_BURSTLEN_16WORD;
342                 break;
343         }
344
345         DRM_DEBUG_KMS("bpp = %d\n", fb->bits_per_pixel);
346
347         /*
348          * In case of exynos, setting dma-burst to 16Word causes permanent
349          * tearing for very small buffers, e.g. cursor buffer. Burst Mode
350          * switching which is based on plane size is not recommended as
351          * plane size varies a lot towards the end of the screen and rapid
352          * movement causes unstable DMA which results into iommu crash/tear.
353          */
354
355         padding = (fb->pitches[0] / (fb->bits_per_pixel >> 3)) - fb->width;
356         if (fb->width + padding < MIN_FB_WIDTH_FOR_16WORD_BURST) {
357                 val &= ~WINCONx_BURSTLEN_MASK;
358                 val |= WINCONx_BURSTLEN_8WORD;
359         }
360
361         writel(val, ctx->regs + WINCON(win));
362 }
363
364 static void decon_win_set_colkey(struct decon_context *ctx, unsigned int win)
365 {
366         unsigned int keycon0 = 0, keycon1 = 0;
367
368         keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F |
369                         WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0);
370
371         keycon1 = WxKEYCON1_COLVAL(0xffffffff);
372
373         writel(keycon0, ctx->regs + WKEYCON0_BASE(win));
374         writel(keycon1, ctx->regs + WKEYCON1_BASE(win));
375 }
376
377 /**
378  * shadow_protect_win() - disable updating values from shadow registers at vsync
379  *
380  * @win: window to protect registers for
381  * @protect: 1 to protect (disable updates)
382  */
383 static void decon_shadow_protect_win(struct decon_context *ctx,
384                                      unsigned int win, bool protect)
385 {
386         u32 bits, val;
387
388         bits = SHADOWCON_WINx_PROTECT(win);
389
390         val = readl(ctx->regs + SHADOWCON);
391         if (protect)
392                 val |= bits;
393         else
394                 val &= ~bits;
395         writel(val, ctx->regs + SHADOWCON);
396 }
397
398 static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
399                                         struct exynos_drm_plane *plane)
400 {
401         struct decon_context *ctx = crtc->ctx;
402
403         if (ctx->suspended)
404                 return;
405
406         decon_shadow_protect_win(ctx, plane->zpos, true);
407 }
408
409 static void decon_update_plane(struct exynos_drm_crtc *crtc,
410                                struct exynos_drm_plane *plane)
411 {
412         struct decon_context *ctx = crtc->ctx;
413         struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
414         struct drm_plane_state *state = plane->base.state;
415         int padding;
416         unsigned long val, alpha;
417         unsigned int last_x;
418         unsigned int last_y;
419         unsigned int win = plane->zpos;
420         unsigned int bpp = state->fb->bits_per_pixel >> 3;
421         unsigned int pitch = state->fb->pitches[0];
422
423         if (ctx->suspended)
424                 return;
425
426         /*
427          * SHADOWCON/PRTCON register is used for enabling timing.
428          *
429          * for example, once only width value of a register is set,
430          * if the dma is started then decon hardware could malfunction so
431          * with protect window setting, the register fields with prefix '_F'
432          * wouldn't be updated at vsync also but updated once unprotect window
433          * is set.
434          */
435
436         /* buffer start address */
437         val = (unsigned long)plane->dma_addr[0];
438         writel(val, ctx->regs + VIDW_BUF_START(win));
439
440         padding = (pitch / bpp) - state->fb->width;
441
442         /* buffer size */
443         writel(state->fb->width + padding, ctx->regs + VIDW_WHOLE_X(win));
444         writel(state->fb->height, ctx->regs + VIDW_WHOLE_Y(win));
445
446         /* offset from the start of the buffer to read */
447         writel(plane->src_x, ctx->regs + VIDW_OFFSET_X(win));
448         writel(plane->src_y, ctx->regs + VIDW_OFFSET_Y(win));
449
450         DRM_DEBUG_KMS("start addr = 0x%lx\n",
451                         (unsigned long)val);
452         DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
453                         plane->crtc_w, plane->crtc_h);
454
455         /*
456          * OSD position.
457          * In case the window layout goes of LCD layout, DECON fails.
458          */
459         if ((plane->crtc_x + plane->crtc_w) > mode->hdisplay)
460                 plane->crtc_x = mode->hdisplay - plane->crtc_w;
461         if ((plane->crtc_y + plane->crtc_h) > mode->vdisplay)
462                 plane->crtc_y = mode->vdisplay - plane->crtc_h;
463
464         val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) |
465                 VIDOSDxA_TOPLEFT_Y(plane->crtc_y);
466         writel(val, ctx->regs + VIDOSD_A(win));
467
468         last_x = plane->crtc_x + plane->crtc_w;
469         if (last_x)
470                 last_x--;
471         last_y = plane->crtc_y + plane->crtc_h;
472         if (last_y)
473                 last_y--;
474
475         val = VIDOSDxB_BOTRIGHT_X(last_x) | VIDOSDxB_BOTRIGHT_Y(last_y);
476
477         writel(val, ctx->regs + VIDOSD_B(win));
478
479         DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
480                         plane->crtc_x, plane->crtc_y, last_x, last_y);
481
482         /* OSD alpha */
483         alpha = VIDOSDxC_ALPHA0_R_F(0x0) |
484                         VIDOSDxC_ALPHA0_G_F(0x0) |
485                         VIDOSDxC_ALPHA0_B_F(0x0);
486
487         writel(alpha, ctx->regs + VIDOSD_C(win));
488
489         alpha = VIDOSDxD_ALPHA1_R_F(0xff) |
490                         VIDOSDxD_ALPHA1_G_F(0xff) |
491                         VIDOSDxD_ALPHA1_B_F(0xff);
492
493         writel(alpha, ctx->regs + VIDOSD_D(win));
494
495         decon_win_set_pixfmt(ctx, win, state->fb);
496
497         /* hardware window 0 doesn't support color key. */
498         if (win != 0)
499                 decon_win_set_colkey(ctx, win);
500
501         /* wincon */
502         val = readl(ctx->regs + WINCON(win));
503         val |= WINCONx_TRIPLE_BUF_MODE;
504         val |= WINCONx_ENWIN;
505         writel(val, ctx->regs + WINCON(win));
506
507         /* Enable DMA channel and unprotect windows */
508         decon_shadow_protect_win(ctx, win, false);
509
510         val = readl(ctx->regs + DECON_UPDATE);
511         val |= DECON_UPDATE_STANDALONE_F;
512         writel(val, ctx->regs + DECON_UPDATE);
513 }
514
515 static void decon_disable_plane(struct exynos_drm_crtc *crtc,
516                                 struct exynos_drm_plane *plane)
517 {
518         struct decon_context *ctx = crtc->ctx;
519         unsigned int win = plane->zpos;
520         u32 val;
521
522         if (ctx->suspended)
523                 return;
524
525         /* protect windows */
526         decon_shadow_protect_win(ctx, win, true);
527
528         /* wincon */
529         val = readl(ctx->regs + WINCON(win));
530         val &= ~WINCONx_ENWIN;
531         writel(val, ctx->regs + WINCON(win));
532
533         val = readl(ctx->regs + DECON_UPDATE);
534         val |= DECON_UPDATE_STANDALONE_F;
535         writel(val, ctx->regs + DECON_UPDATE);
536 }
537
538 static void decon_atomic_flush(struct exynos_drm_crtc *crtc,
539                                         struct exynos_drm_plane *plane)
540 {
541         struct decon_context *ctx = crtc->ctx;
542
543         if (ctx->suspended)
544                 return;
545
546         decon_shadow_protect_win(ctx, plane->zpos, false);
547 }
548
549 static void decon_init(struct decon_context *ctx)
550 {
551         u32 val;
552
553         writel(VIDCON0_SWRESET, ctx->regs + VIDCON0);
554
555         val = VIDOUTCON0_DISP_IF_0_ON;
556         if (!ctx->i80_if)
557                 val |= VIDOUTCON0_RGBIF;
558         writel(val, ctx->regs + VIDOUTCON0);
559
560         writel(VCLKCON0_CLKVALUP | VCLKCON0_VCLKFREE, ctx->regs + VCLKCON0);
561
562         if (!ctx->i80_if)
563                 writel(VIDCON1_VCLK_HOLD, ctx->regs + VIDCON1(0));
564 }
565
566 static void decon_enable(struct exynos_drm_crtc *crtc)
567 {
568         struct decon_context *ctx = crtc->ctx;
569         int ret;
570
571         if (!ctx->suspended)
572                 return;
573
574         ctx->suspended = false;
575
576         pm_runtime_get_sync(ctx->dev);
577
578         ret = clk_prepare_enable(ctx->pclk);
579         if (ret < 0) {
580                 DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret);
581                 return;
582         }
583
584         ret = clk_prepare_enable(ctx->aclk);
585         if (ret < 0) {
586                 DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret);
587                 return;
588         }
589
590         ret = clk_prepare_enable(ctx->eclk);
591         if  (ret < 0) {
592                 DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret);
593                 return;
594         }
595
596         ret = clk_prepare_enable(ctx->vclk);
597         if  (ret < 0) {
598                 DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret);
599                 return;
600         }
601
602         decon_init(ctx);
603
604         /* if vblank was enabled status, enable it again. */
605         if (test_and_clear_bit(0, &ctx->irq_flags))
606                 decon_enable_vblank(ctx->crtc);
607
608         decon_commit(ctx->crtc);
609 }
610
611 static void decon_disable(struct exynos_drm_crtc *crtc)
612 {
613         struct decon_context *ctx = crtc->ctx;
614         int i;
615
616         if (ctx->suspended)
617                 return;
618
619         /*
620          * We need to make sure that all windows are disabled before we
621          * suspend that connector. Otherwise we might try to scan from
622          * a destroyed buffer later.
623          */
624         for (i = 0; i < WINDOWS_NR; i++)
625                 decon_disable_plane(crtc, &ctx->planes[i]);
626
627         clk_disable_unprepare(ctx->vclk);
628         clk_disable_unprepare(ctx->eclk);
629         clk_disable_unprepare(ctx->aclk);
630         clk_disable_unprepare(ctx->pclk);
631
632         pm_runtime_put_sync(ctx->dev);
633
634         ctx->suspended = true;
635 }
636
637 static const struct exynos_drm_crtc_ops decon_crtc_ops = {
638         .enable = decon_enable,
639         .disable = decon_disable,
640         .mode_fixup = decon_mode_fixup,
641         .commit = decon_commit,
642         .enable_vblank = decon_enable_vblank,
643         .disable_vblank = decon_disable_vblank,
644         .wait_for_vblank = decon_wait_for_vblank,
645         .atomic_begin = decon_atomic_begin,
646         .update_plane = decon_update_plane,
647         .disable_plane = decon_disable_plane,
648         .atomic_flush = decon_atomic_flush,
649 };
650
651
652 static irqreturn_t decon_irq_handler(int irq, void *dev_id)
653 {
654         struct decon_context *ctx = (struct decon_context *)dev_id;
655         u32 val, clear_bit;
656         int win;
657
658         val = readl(ctx->regs + VIDINTCON1);
659
660         clear_bit = ctx->i80_if ? VIDINTCON1_INT_I80 : VIDINTCON1_INT_FRAME;
661         if (val & clear_bit)
662                 writel(clear_bit, ctx->regs + VIDINTCON1);
663
664         /* check the crtc is detached already from encoder */
665         if (ctx->pipe < 0 || !ctx->drm_dev)
666                 goto out;
667
668         if (!ctx->i80_if) {
669                 drm_crtc_handle_vblank(&ctx->crtc->base);
670                 for (win = 0 ; win < WINDOWS_NR ; win++) {
671                         struct exynos_drm_plane *plane = &ctx->planes[win];
672
673                         if (!plane->pending_fb)
674                                 continue;
675
676                         exynos_drm_crtc_finish_update(ctx->crtc, plane);
677                 }
678
679                 /* set wait vsync event to zero and wake up queue. */
680                 if (atomic_read(&ctx->wait_vsync_event)) {
681                         atomic_set(&ctx->wait_vsync_event, 0);
682                         wake_up(&ctx->wait_vsync_queue);
683                 }
684         }
685 out:
686         return IRQ_HANDLED;
687 }
688
689 static int decon_bind(struct device *dev, struct device *master, void *data)
690 {
691         struct decon_context *ctx = dev_get_drvdata(dev);
692         struct drm_device *drm_dev = data;
693         struct exynos_drm_plane *exynos_plane;
694         enum drm_plane_type type;
695         unsigned int zpos;
696         int ret;
697
698         ret = decon_ctx_initialize(ctx, drm_dev);
699         if (ret) {
700                 DRM_ERROR("decon_ctx_initialize failed.\n");
701                 return ret;
702         }
703
704         for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
705                 type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY :
706                                                 DRM_PLANE_TYPE_OVERLAY;
707                 ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
708                                         1 << ctx->pipe, type, decon_formats,
709                                         ARRAY_SIZE(decon_formats), zpos);
710                 if (ret)
711                         return ret;
712         }
713
714         exynos_plane = &ctx->planes[ctx->default_win];
715         ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
716                                            ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD,
717                                            &decon_crtc_ops, ctx);
718         if (IS_ERR(ctx->crtc)) {
719                 decon_ctx_remove(ctx);
720                 return PTR_ERR(ctx->crtc);
721         }
722
723         if (ctx->encoder)
724                 exynos_dpi_bind(drm_dev, ctx->encoder);
725
726         return 0;
727
728 }
729
730 static void decon_unbind(struct device *dev, struct device *master,
731                         void *data)
732 {
733         struct decon_context *ctx = dev_get_drvdata(dev);
734
735         decon_disable(ctx->crtc);
736
737         if (ctx->encoder)
738                 exynos_dpi_remove(ctx->encoder);
739
740         decon_ctx_remove(ctx);
741 }
742
743 static const struct component_ops decon_component_ops = {
744         .bind   = decon_bind,
745         .unbind = decon_unbind,
746 };
747
748 static int decon_probe(struct platform_device *pdev)
749 {
750         struct device *dev = &pdev->dev;
751         struct decon_context *ctx;
752         struct device_node *i80_if_timings;
753         struct resource *res;
754         int ret;
755
756         if (!dev->of_node)
757                 return -ENODEV;
758
759         ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
760         if (!ctx)
761                 return -ENOMEM;
762
763         ctx->dev = dev;
764         ctx->suspended = true;
765
766         i80_if_timings = of_get_child_by_name(dev->of_node, "i80-if-timings");
767         if (i80_if_timings)
768                 ctx->i80_if = true;
769         of_node_put(i80_if_timings);
770
771         ctx->regs = of_iomap(dev->of_node, 0);
772         if (!ctx->regs)
773                 return -ENOMEM;
774
775         ctx->pclk = devm_clk_get(dev, "pclk_decon0");
776         if (IS_ERR(ctx->pclk)) {
777                 dev_err(dev, "failed to get bus clock pclk\n");
778                 ret = PTR_ERR(ctx->pclk);
779                 goto err_iounmap;
780         }
781
782         ctx->aclk = devm_clk_get(dev, "aclk_decon0");
783         if (IS_ERR(ctx->aclk)) {
784                 dev_err(dev, "failed to get bus clock aclk\n");
785                 ret = PTR_ERR(ctx->aclk);
786                 goto err_iounmap;
787         }
788
789         ctx->eclk = devm_clk_get(dev, "decon0_eclk");
790         if (IS_ERR(ctx->eclk)) {
791                 dev_err(dev, "failed to get eclock\n");
792                 ret = PTR_ERR(ctx->eclk);
793                 goto err_iounmap;
794         }
795
796         ctx->vclk = devm_clk_get(dev, "decon0_vclk");
797         if (IS_ERR(ctx->vclk)) {
798                 dev_err(dev, "failed to get vclock\n");
799                 ret = PTR_ERR(ctx->vclk);
800                 goto err_iounmap;
801         }
802
803         res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
804                                            ctx->i80_if ? "lcd_sys" : "vsync");
805         if (!res) {
806                 dev_err(dev, "irq request failed.\n");
807                 ret = -ENXIO;
808                 goto err_iounmap;
809         }
810
811         ret = devm_request_irq(dev, res->start, decon_irq_handler,
812                                                         0, "drm_decon", ctx);
813         if (ret) {
814                 dev_err(dev, "irq request failed.\n");
815                 goto err_iounmap;
816         }
817
818         init_waitqueue_head(&ctx->wait_vsync_queue);
819         atomic_set(&ctx->wait_vsync_event, 0);
820
821         platform_set_drvdata(pdev, ctx);
822
823         ctx->encoder = exynos_dpi_probe(dev);
824         if (IS_ERR(ctx->encoder)) {
825                 ret = PTR_ERR(ctx->encoder);
826                 goto err_iounmap;
827         }
828
829         pm_runtime_enable(dev);
830
831         ret = component_add(dev, &decon_component_ops);
832         if (ret)
833                 goto err_disable_pm_runtime;
834
835         return ret;
836
837 err_disable_pm_runtime:
838         pm_runtime_disable(dev);
839
840 err_iounmap:
841         iounmap(ctx->regs);
842
843         return ret;
844 }
845
846 static int decon_remove(struct platform_device *pdev)
847 {
848         struct decon_context *ctx = dev_get_drvdata(&pdev->dev);
849
850         pm_runtime_disable(&pdev->dev);
851
852         iounmap(ctx->regs);
853
854         component_del(&pdev->dev, &decon_component_ops);
855
856         return 0;
857 }
858
859 struct platform_driver decon_driver = {
860         .probe          = decon_probe,
861         .remove         = decon_remove,
862         .driver         = {
863                 .name   = "exynos-decon",
864                 .of_match_table = decon_driver_dt_match,
865         },
866 };