]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/exynos/exynos5433_drm_decon.c
21ab839ea29a2b96c94ae90d51f554d2af85fba1
[karo-tx-linux.git] / drivers / gpu / drm / exynos / exynos5433_drm_decon.c
1 /* drivers/gpu/drm/exynos5433_drm_decon.c
2  *
3  * Copyright (C) 2015 Samsung Electronics Co.Ltd
4  * Authors:
5  *      Joonyoung Shim <jy0922.shim@samsung.com>
6  *      Hyungwon Hwang <human.hwang@samsung.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundationr
11  */
12
13 #include <linux/platform_device.h>
14 #include <linux/clk.h>
15 #include <linux/component.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/of_device.h>
18 #include <linux/of_gpio.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regmap.h>
21
22 #include <video/exynos5433_decon.h>
23
24 #include "exynos_drm_drv.h"
25 #include "exynos_drm_crtc.h"
26 #include "exynos_drm_fb.h"
27 #include "exynos_drm_plane.h"
28 #include "exynos_drm_iommu.h"
29
30 #define DSD_CFG_MUX 0x1004
31 #define DSD_CFG_MUX_TE_UNMASK_GLOBAL BIT(13)
32
33 #define WINDOWS_NR      3
34 #define MIN_FB_WIDTH_FOR_16WORD_BURST   128
35
36 #define IFTYPE_I80      (1 << 0)
37 #define I80_HW_TRG      (1 << 1)
38 #define IFTYPE_HDMI     (1 << 2)
39
40 static const char * const decon_clks_name[] = {
41         "pclk",
42         "aclk_decon",
43         "aclk_smmu_decon0x",
44         "aclk_xiu_decon0x",
45         "pclk_smmu_decon0x",
46         "sclk_decon_vclk",
47         "sclk_decon_eclk",
48 };
49
50 enum decon_flag_bits {
51         BIT_CLKS_ENABLED,
52         BIT_IRQS_ENABLED,
53         BIT_WIN_UPDATED,
54         BIT_SUSPENDED,
55         BIT_REQUEST_UPDATE
56 };
57
58 struct decon_context {
59         struct device                   *dev;
60         struct drm_device               *drm_dev;
61         struct exynos_drm_crtc          *crtc;
62         struct exynos_drm_plane         planes[WINDOWS_NR];
63         struct exynos_drm_plane_config  configs[WINDOWS_NR];
64         void __iomem                    *addr;
65         struct regmap                   *sysreg;
66         struct clk                      *clks[ARRAY_SIZE(decon_clks_name)];
67         unsigned long                   flags;
68         unsigned long                   out_type;
69         int                             first_win;
70         spinlock_t                      vblank_lock;
71         u32                             frame_id;
72 };
73
74 static const uint32_t decon_formats[] = {
75         DRM_FORMAT_XRGB1555,
76         DRM_FORMAT_RGB565,
77         DRM_FORMAT_XRGB8888,
78         DRM_FORMAT_ARGB8888,
79 };
80
81 static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
82         DRM_PLANE_TYPE_PRIMARY,
83         DRM_PLANE_TYPE_OVERLAY,
84         DRM_PLANE_TYPE_CURSOR,
85 };
86
87 static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
88                                   u32 val)
89 {
90         val = (val & mask) | (readl(ctx->addr + reg) & ~mask);
91         writel(val, ctx->addr + reg);
92 }
93
94 static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
95 {
96         struct decon_context *ctx = crtc->ctx;
97         u32 val;
98
99         if (test_bit(BIT_SUSPENDED, &ctx->flags))
100                 return -EPERM;
101
102         if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
103                 val = VIDINTCON0_INTEN;
104                 if (ctx->out_type & IFTYPE_I80)
105                         val |= VIDINTCON0_FRAMEDONE;
106                 else
107                         val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;
108
109                 writel(val, ctx->addr + DECON_VIDINTCON0);
110         }
111
112         return 0;
113 }
114
115 static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
116 {
117         struct decon_context *ctx = crtc->ctx;
118
119         if (test_bit(BIT_SUSPENDED, &ctx->flags))
120                 return;
121
122         if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags))
123                 writel(0, ctx->addr + DECON_VIDINTCON0);
124 }
125
126 /* return number of starts/ends of frame transmissions since reset */
127 static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
128 {
129         u32 frm, pfrm, status, cnt = 2;
130
131         /* To get consistent result repeat read until frame id is stable.
132          * Usually the loop will be executed once, in rare cases when the loop
133          * is executed at frame change time 2nd pass will be needed.
134          */
135         frm = readl(ctx->addr + DECON_CRFMID);
136         do {
137                 status = readl(ctx->addr + DECON_VIDCON1);
138                 pfrm = frm;
139                 frm = readl(ctx->addr + DECON_CRFMID);
140         } while (frm != pfrm && --cnt);
141
142         /* CRFMID is incremented on BPORCH in case of I80 and on VSYNC in case
143          * of RGB, it should be taken into account.
144          */
145         if (!frm)
146                 return 0;
147
148         switch (status & (VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE)) {
149         case VIDCON1_VSTATUS_VS:
150                 if (!(ctx->out_type & IFTYPE_I80))
151                         --frm;
152                 break;
153         case VIDCON1_VSTATUS_BP:
154                 --frm;
155                 break;
156         case VIDCON1_I80_ACTIVE:
157         case VIDCON1_VSTATUS_AC:
158                 if (end)
159                         --frm;
160                 break;
161         default:
162                 break;
163         }
164
165         return frm;
166 }
167
168 static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc)
169 {
170         struct decon_context *ctx = crtc->ctx;
171
172         if (test_bit(BIT_SUSPENDED, &ctx->flags))
173                 return 0;
174
175         return decon_get_frame_count(ctx, false);
176 }
177
178 static void decon_setup_trigger(struct decon_context *ctx)
179 {
180         if (!(ctx->out_type & (IFTYPE_I80 | I80_HW_TRG)))
181                 return;
182
183         if (!(ctx->out_type & I80_HW_TRG)) {
184                 writel(TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
185                        TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN,
186                        ctx->addr + DECON_TRIGCON);
187                 return;
188         }
189
190         writel(TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F | TRIGCON_HWTRIGMASK
191                | TRIGCON_HWTRIGEN, ctx->addr + DECON_TRIGCON);
192
193         if (regmap_update_bits(ctx->sysreg, DSD_CFG_MUX,
194                                DSD_CFG_MUX_TE_UNMASK_GLOBAL, ~0))
195                 DRM_ERROR("Cannot update sysreg.\n");
196 }
197
198 static void decon_commit(struct exynos_drm_crtc *crtc)
199 {
200         struct decon_context *ctx = crtc->ctx;
201         struct drm_display_mode *m = &crtc->base.mode;
202         bool interlaced = false;
203         u32 val;
204
205         if (test_bit(BIT_SUSPENDED, &ctx->flags))
206                 return;
207
208         if (ctx->out_type & IFTYPE_HDMI) {
209                 m->crtc_hsync_start = m->crtc_hdisplay + 10;
210                 m->crtc_hsync_end = m->crtc_htotal - 92;
211                 m->crtc_vsync_start = m->crtc_vdisplay + 1;
212                 m->crtc_vsync_end = m->crtc_vsync_start + 1;
213                 if (m->flags & DRM_MODE_FLAG_INTERLACE)
214                         interlaced = true;
215         }
216
217         decon_setup_trigger(ctx);
218
219         /* lcd on and use command if */
220         val = VIDOUT_LCD_ON;
221         if (interlaced)
222                 val |= VIDOUT_INTERLACE_EN_F;
223         if (ctx->out_type & IFTYPE_I80) {
224                 val |= VIDOUT_COMMAND_IF;
225         } else {
226                 val |= VIDOUT_RGB_IF;
227         }
228
229         writel(val, ctx->addr + DECON_VIDOUTCON0);
230
231         if (interlaced)
232                 val = VIDTCON2_LINEVAL(m->vdisplay / 2 - 1) |
233                         VIDTCON2_HOZVAL(m->hdisplay - 1);
234         else
235                 val = VIDTCON2_LINEVAL(m->vdisplay - 1) |
236                         VIDTCON2_HOZVAL(m->hdisplay - 1);
237         writel(val, ctx->addr + DECON_VIDTCON2);
238
239         if (!(ctx->out_type & IFTYPE_I80)) {
240                 int vbp = m->crtc_vtotal - m->crtc_vsync_end;
241                 int vfp = m->crtc_vsync_start - m->crtc_vdisplay;
242
243                 if (interlaced)
244                         vbp = vbp / 2 - 1;
245                 val = VIDTCON00_VBPD_F(vbp - 1) | VIDTCON00_VFPD_F(vfp - 1);
246                 writel(val, ctx->addr + DECON_VIDTCON00);
247
248                 val = VIDTCON01_VSPW_F(
249                                 m->crtc_vsync_end - m->crtc_vsync_start - 1);
250                 writel(val, ctx->addr + DECON_VIDTCON01);
251
252                 val = VIDTCON10_HBPD_F(
253                                 m->crtc_htotal - m->crtc_hsync_end - 1) |
254                         VIDTCON10_HFPD_F(
255                                 m->crtc_hsync_start - m->crtc_hdisplay - 1);
256                 writel(val, ctx->addr + DECON_VIDTCON10);
257
258                 val = VIDTCON11_HSPW_F(
259                                 m->crtc_hsync_end - m->crtc_hsync_start - 1);
260                 writel(val, ctx->addr + DECON_VIDTCON11);
261         }
262
263         /* enable output and display signal */
264         decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0);
265
266         decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
267 }
268
269 static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
270                                  struct drm_framebuffer *fb)
271 {
272         unsigned long val;
273
274         val = readl(ctx->addr + DECON_WINCONx(win));
275         val &= ~WINCONx_BPPMODE_MASK;
276
277         switch (fb->format->format) {
278         case DRM_FORMAT_XRGB1555:
279                 val |= WINCONx_BPPMODE_16BPP_I1555;
280                 val |= WINCONx_HAWSWP_F;
281                 val |= WINCONx_BURSTLEN_16WORD;
282                 break;
283         case DRM_FORMAT_RGB565:
284                 val |= WINCONx_BPPMODE_16BPP_565;
285                 val |= WINCONx_HAWSWP_F;
286                 val |= WINCONx_BURSTLEN_16WORD;
287                 break;
288         case DRM_FORMAT_XRGB8888:
289                 val |= WINCONx_BPPMODE_24BPP_888;
290                 val |= WINCONx_WSWP_F;
291                 val |= WINCONx_BURSTLEN_16WORD;
292                 break;
293         case DRM_FORMAT_ARGB8888:
294                 val |= WINCONx_BPPMODE_32BPP_A8888;
295                 val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F;
296                 val |= WINCONx_BURSTLEN_16WORD;
297                 break;
298         default:
299                 DRM_ERROR("Proper pixel format is not set\n");
300                 return;
301         }
302
303         DRM_DEBUG_KMS("bpp = %u\n", fb->format->cpp[0] * 8);
304
305         /*
306          * In case of exynos, setting dma-burst to 16Word causes permanent
307          * tearing for very small buffers, e.g. cursor buffer. Burst Mode
308          * switching which is based on plane size is not recommended as
309          * plane size varies a lot towards the end of the screen and rapid
310          * movement causes unstable DMA which results into iommu crash/tear.
311          */
312
313         if (fb->width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
314                 val &= ~WINCONx_BURSTLEN_MASK;
315                 val |= WINCONx_BURSTLEN_8WORD;
316         }
317
318         writel(val, ctx->addr + DECON_WINCONx(win));
319 }
320
321 static void decon_shadow_protect_win(struct decon_context *ctx, int win,
322                                         bool protect)
323 {
324         decon_set_bits(ctx, DECON_SHADOWCON, SHADOWCON_Wx_PROTECT(win),
325                        protect ? ~0 : 0);
326 }
327
328 static void decon_atomic_begin(struct exynos_drm_crtc *crtc)
329 {
330         struct decon_context *ctx = crtc->ctx;
331         int i;
332
333         if (test_bit(BIT_SUSPENDED, &ctx->flags))
334                 return;
335
336         for (i = ctx->first_win; i < WINDOWS_NR; i++)
337                 decon_shadow_protect_win(ctx, i, true);
338 }
339
340 #define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s))
341 #define COORDINATE_X(x) BIT_VAL((x), 23, 12)
342 #define COORDINATE_Y(x) BIT_VAL((x), 11, 0)
343
344 static void decon_update_plane(struct exynos_drm_crtc *crtc,
345                                struct exynos_drm_plane *plane)
346 {
347         struct exynos_drm_plane_state *state =
348                                 to_exynos_plane_state(plane->base.state);
349         struct decon_context *ctx = crtc->ctx;
350         struct drm_framebuffer *fb = state->base.fb;
351         unsigned int win = plane->index;
352         unsigned int bpp = fb->format->cpp[0];
353         unsigned int pitch = fb->pitches[0];
354         dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0);
355         u32 val;
356
357         if (test_bit(BIT_SUSPENDED, &ctx->flags))
358                 return;
359
360         if (crtc->base.mode.flags & DRM_MODE_FLAG_INTERLACE) {
361                 val = COORDINATE_X(state->crtc.x) |
362                         COORDINATE_Y(state->crtc.y / 2);
363                 writel(val, ctx->addr + DECON_VIDOSDxA(win));
364
365                 val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
366                         COORDINATE_Y((state->crtc.y + state->crtc.h) / 2 - 1);
367                 writel(val, ctx->addr + DECON_VIDOSDxB(win));
368         } else {
369                 val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y);
370                 writel(val, ctx->addr + DECON_VIDOSDxA(win));
371
372                 val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
373                                 COORDINATE_Y(state->crtc.y + state->crtc.h - 1);
374                 writel(val, ctx->addr + DECON_VIDOSDxB(win));
375         }
376
377         val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
378                 VIDOSD_Wx_ALPHA_B_F(0x0);
379         writel(val, ctx->addr + DECON_VIDOSDxC(win));
380
381         val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
382                 VIDOSD_Wx_ALPHA_B_F(0x0);
383         writel(val, ctx->addr + DECON_VIDOSDxD(win));
384
385         writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win));
386
387         val = dma_addr + pitch * state->src.h;
388         writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
389
390         if (!(ctx->out_type & IFTYPE_HDMI))
391                 val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14)
392                         | BIT_VAL(state->crtc.w * bpp, 13, 0);
393         else
394                 val = BIT_VAL(pitch - state->crtc.w * bpp, 29, 15)
395                         | BIT_VAL(state->crtc.w * bpp, 14, 0);
396         writel(val, ctx->addr + DECON_VIDW0xADD2(win));
397
398         decon_win_set_pixfmt(ctx, win, fb);
399
400         /* window enable */
401         decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
402         set_bit(BIT_REQUEST_UPDATE, &ctx->flags);
403 }
404
405 static void decon_disable_plane(struct exynos_drm_crtc *crtc,
406                                 struct exynos_drm_plane *plane)
407 {
408         struct decon_context *ctx = crtc->ctx;
409         unsigned int win = plane->index;
410
411         if (test_bit(BIT_SUSPENDED, &ctx->flags))
412                 return;
413
414         decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
415         set_bit(BIT_REQUEST_UPDATE, &ctx->flags);
416 }
417
418 static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
419 {
420         struct decon_context *ctx = crtc->ctx;
421         unsigned long flags;
422         int i;
423
424         if (test_bit(BIT_SUSPENDED, &ctx->flags))
425                 return;
426
427         spin_lock_irqsave(&ctx->vblank_lock, flags);
428
429         for (i = ctx->first_win; i < WINDOWS_NR; i++)
430                 decon_shadow_protect_win(ctx, i, false);
431
432         if (test_and_clear_bit(BIT_REQUEST_UPDATE, &ctx->flags))
433                 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
434
435         if (ctx->out_type & IFTYPE_I80)
436                 set_bit(BIT_WIN_UPDATED, &ctx->flags);
437
438         ctx->frame_id = decon_get_frame_count(ctx, true);
439
440         exynos_crtc_handle_event(crtc);
441
442         spin_unlock_irqrestore(&ctx->vblank_lock, flags);
443 }
444
445 static void decon_swreset(struct decon_context *ctx)
446 {
447         unsigned int tries;
448         unsigned long flags;
449
450         writel(0, ctx->addr + DECON_VIDCON0);
451         for (tries = 2000; tries; --tries) {
452                 if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_STOP_STATUS)
453                         break;
454                 udelay(10);
455         }
456
457         writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0);
458         for (tries = 2000; tries; --tries) {
459                 if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_SWRESET)
460                         break;
461                 udelay(10);
462         }
463
464         WARN(tries == 0, "failed to software reset DECON\n");
465
466         spin_lock_irqsave(&ctx->vblank_lock, flags);
467         ctx->frame_id = 0;
468         spin_unlock_irqrestore(&ctx->vblank_lock, flags);
469
470         if (!(ctx->out_type & IFTYPE_HDMI))
471                 return;
472
473         writel(VIDCON0_CLKVALUP | VIDCON0_VLCKFREE, ctx->addr + DECON_VIDCON0);
474         decon_set_bits(ctx, DECON_CMU,
475                        CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F, ~0);
476         writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1);
477         writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN,
478                ctx->addr + DECON_CRCCTRL);
479 }
480
481 static void decon_enable(struct exynos_drm_crtc *crtc)
482 {
483         struct decon_context *ctx = crtc->ctx;
484
485         if (!test_and_clear_bit(BIT_SUSPENDED, &ctx->flags))
486                 return;
487
488         pm_runtime_get_sync(ctx->dev);
489
490         exynos_drm_pipe_clk_enable(crtc, true);
491
492         set_bit(BIT_CLKS_ENABLED, &ctx->flags);
493
494         decon_swreset(ctx);
495
496         /* if vblank was enabled status, enable it again. */
497         if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags))
498                 decon_enable_vblank(ctx->crtc);
499
500         decon_commit(ctx->crtc);
501 }
502
503 static void decon_disable(struct exynos_drm_crtc *crtc)
504 {
505         struct decon_context *ctx = crtc->ctx;
506         int i;
507
508         if (test_bit(BIT_SUSPENDED, &ctx->flags))
509                 return;
510
511         /*
512          * We need to make sure that all windows are disabled before we
513          * suspend that connector. Otherwise we might try to scan from
514          * a destroyed buffer later.
515          */
516         for (i = ctx->first_win; i < WINDOWS_NR; i++)
517                 decon_disable_plane(crtc, &ctx->planes[i]);
518
519         decon_swreset(ctx);
520
521         clear_bit(BIT_CLKS_ENABLED, &ctx->flags);
522
523         exynos_drm_pipe_clk_enable(crtc, false);
524
525         pm_runtime_put_sync(ctx->dev);
526
527         set_bit(BIT_SUSPENDED, &ctx->flags);
528 }
529
530 static void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
531 {
532         struct decon_context *ctx = crtc->ctx;
533
534         if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags) ||
535             (ctx->out_type & I80_HW_TRG))
536                 return;
537
538         if (test_and_clear_bit(BIT_WIN_UPDATED, &ctx->flags))
539                 decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0);
540 }
541
542 static void decon_clear_channels(struct exynos_drm_crtc *crtc)
543 {
544         struct decon_context *ctx = crtc->ctx;
545         int win, i, ret;
546
547         DRM_DEBUG_KMS("%s\n", __FILE__);
548
549         for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
550                 ret = clk_prepare_enable(ctx->clks[i]);
551                 if (ret < 0)
552                         goto err;
553         }
554
555         for (win = 0; win < WINDOWS_NR; win++) {
556                 decon_shadow_protect_win(ctx, win, true);
557                 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
558                 decon_shadow_protect_win(ctx, win, false);
559         }
560
561         decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
562
563         /* TODO: wait for possible vsync */
564         msleep(50);
565
566 err:
567         while (--i >= 0)
568                 clk_disable_unprepare(ctx->clks[i]);
569 }
570
571 static const struct exynos_drm_crtc_ops decon_crtc_ops = {
572         .enable                 = decon_enable,
573         .disable                = decon_disable,
574         .enable_vblank          = decon_enable_vblank,
575         .disable_vblank         = decon_disable_vblank,
576         .get_vblank_counter     = decon_get_vblank_counter,
577         .atomic_begin           = decon_atomic_begin,
578         .update_plane           = decon_update_plane,
579         .disable_plane          = decon_disable_plane,
580         .atomic_flush           = decon_atomic_flush,
581         .te_handler             = decon_te_irq_handler,
582 };
583
584 static int decon_bind(struct device *dev, struct device *master, void *data)
585 {
586         struct decon_context *ctx = dev_get_drvdata(dev);
587         struct drm_device *drm_dev = data;
588         struct exynos_drm_plane *exynos_plane;
589         enum exynos_drm_output_type out_type;
590         unsigned int win;
591         int ret;
592
593         ctx->drm_dev = drm_dev;
594         drm_dev->max_vblank_count = 0xffffffff;
595
596         for (win = ctx->first_win; win < WINDOWS_NR; win++) {
597                 int tmp = (win == ctx->first_win) ? 0 : win;
598
599                 ctx->configs[win].pixel_formats = decon_formats;
600                 ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats);
601                 ctx->configs[win].zpos = win;
602                 ctx->configs[win].type = decon_win_types[tmp];
603
604                 ret = exynos_plane_init(drm_dev, &ctx->planes[win], win,
605                                         &ctx->configs[win]);
606                 if (ret)
607                         return ret;
608         }
609
610         exynos_plane = &ctx->planes[ctx->first_win];
611         out_type = (ctx->out_type & IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI
612                                                   : EXYNOS_DISPLAY_TYPE_LCD;
613         ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
614                         out_type, &decon_crtc_ops, ctx);
615         if (IS_ERR(ctx->crtc))
616                 return PTR_ERR(ctx->crtc);
617
618         decon_clear_channels(ctx->crtc);
619
620         return drm_iommu_attach_device(drm_dev, dev);
621 }
622
623 static void decon_unbind(struct device *dev, struct device *master, void *data)
624 {
625         struct decon_context *ctx = dev_get_drvdata(dev);
626
627         decon_disable(ctx->crtc);
628
629         /* detach this sub driver from iommu mapping if supported. */
630         drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
631 }
632
633 static const struct component_ops decon_component_ops = {
634         .bind   = decon_bind,
635         .unbind = decon_unbind,
636 };
637
638 static void decon_handle_vblank(struct decon_context *ctx)
639 {
640         u32 frm;
641
642         spin_lock(&ctx->vblank_lock);
643
644         frm = decon_get_frame_count(ctx, true);
645
646         if (frm != ctx->frame_id) {
647                 /* handle only if incremented, take care of wrap-around */
648                 if ((s32)(frm - ctx->frame_id) > 0)
649                         drm_crtc_handle_vblank(&ctx->crtc->base);
650                 ctx->frame_id = frm;
651         }
652
653         spin_unlock(&ctx->vblank_lock);
654 }
655
656 static irqreturn_t decon_irq_handler(int irq, void *dev_id)
657 {
658         struct decon_context *ctx = dev_id;
659         u32 val;
660
661         if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
662                 goto out;
663
664         val = readl(ctx->addr + DECON_VIDINTCON1);
665         val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND;
666
667         if (val) {
668                 writel(val, ctx->addr + DECON_VIDINTCON1);
669                 if (ctx->out_type & IFTYPE_HDMI) {
670                         val = readl(ctx->addr + DECON_VIDOUTCON0);
671                         val &= VIDOUT_INTERLACE_EN_F | VIDOUT_INTERLACE_FIELD_F;
672                         if (val ==
673                             (VIDOUT_INTERLACE_EN_F | VIDOUT_INTERLACE_FIELD_F))
674                                 return IRQ_HANDLED;
675                 }
676                 decon_handle_vblank(ctx);
677         }
678
679 out:
680         return IRQ_HANDLED;
681 }
682
683 #ifdef CONFIG_PM
684 static int exynos5433_decon_suspend(struct device *dev)
685 {
686         struct decon_context *ctx = dev_get_drvdata(dev);
687         int i = ARRAY_SIZE(decon_clks_name);
688
689         while (--i >= 0)
690                 clk_disable_unprepare(ctx->clks[i]);
691
692         return 0;
693 }
694
695 static int exynos5433_decon_resume(struct device *dev)
696 {
697         struct decon_context *ctx = dev_get_drvdata(dev);
698         int i, ret;
699
700         for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
701                 ret = clk_prepare_enable(ctx->clks[i]);
702                 if (ret < 0)
703                         goto err;
704         }
705
706         return 0;
707
708 err:
709         while (--i >= 0)
710                 clk_disable_unprepare(ctx->clks[i]);
711
712         return ret;
713 }
714 #endif
715
716 static const struct dev_pm_ops exynos5433_decon_pm_ops = {
717         SET_RUNTIME_PM_OPS(exynos5433_decon_suspend, exynos5433_decon_resume,
718                            NULL)
719 };
720
721 static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
722         {
723                 .compatible = "samsung,exynos5433-decon",
724                 .data = (void *)I80_HW_TRG
725         },
726         {
727                 .compatible = "samsung,exynos5433-decon-tv",
728                 .data = (void *)(I80_HW_TRG | IFTYPE_HDMI)
729         },
730         {},
731 };
732 MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
733
734 static int exynos5433_decon_probe(struct platform_device *pdev)
735 {
736         struct device *dev = &pdev->dev;
737         struct decon_context *ctx;
738         struct resource *res;
739         int ret;
740         int i;
741
742         ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
743         if (!ctx)
744                 return -ENOMEM;
745
746         __set_bit(BIT_SUSPENDED, &ctx->flags);
747         ctx->dev = dev;
748         ctx->out_type = (unsigned long)of_device_get_match_data(dev);
749         spin_lock_init(&ctx->vblank_lock);
750
751         if (ctx->out_type & IFTYPE_HDMI) {
752                 ctx->first_win = 1;
753         } else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) {
754                 ctx->out_type |= IFTYPE_I80;
755         }
756
757         if (ctx->out_type & I80_HW_TRG) {
758                 ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
759                                                         "samsung,disp-sysreg");
760                 if (IS_ERR(ctx->sysreg)) {
761                         dev_err(dev, "failed to get system register\n");
762                         return PTR_ERR(ctx->sysreg);
763                 }
764         }
765
766         for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
767                 struct clk *clk;
768
769                 clk = devm_clk_get(ctx->dev, decon_clks_name[i]);
770                 if (IS_ERR(clk))
771                         return PTR_ERR(clk);
772
773                 ctx->clks[i] = clk;
774         }
775
776         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
777         if (!res) {
778                 dev_err(dev, "cannot find IO resource\n");
779                 return -ENXIO;
780         }
781
782         ctx->addr = devm_ioremap_resource(dev, res);
783         if (IS_ERR(ctx->addr)) {
784                 dev_err(dev, "ioremap failed\n");
785                 return PTR_ERR(ctx->addr);
786         }
787
788         res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
789                         (ctx->out_type & IFTYPE_I80) ? "lcd_sys" : "vsync");
790         if (!res) {
791                 dev_err(dev, "cannot find IRQ resource\n");
792                 return -ENXIO;
793         }
794
795         ret = devm_request_irq(dev, res->start, decon_irq_handler, 0,
796                                "drm_decon", ctx);
797         if (ret < 0) {
798                 dev_err(dev, "lcd_sys irq request failed\n");
799                 return ret;
800         }
801
802         platform_set_drvdata(pdev, ctx);
803
804         pm_runtime_enable(dev);
805
806         ret = component_add(dev, &decon_component_ops);
807         if (ret)
808                 goto err_disable_pm_runtime;
809
810         return 0;
811
812 err_disable_pm_runtime:
813         pm_runtime_disable(dev);
814
815         return ret;
816 }
817
818 static int exynos5433_decon_remove(struct platform_device *pdev)
819 {
820         pm_runtime_disable(&pdev->dev);
821
822         component_del(&pdev->dev, &decon_component_ops);
823
824         return 0;
825 }
826
827 struct platform_driver exynos5433_decon_driver = {
828         .probe          = exynos5433_decon_probe,
829         .remove         = exynos5433_decon_remove,
830         .driver         = {
831                 .name   = "exynos5433-decon",
832                 .pm     = &exynos5433_decon_pm_ops,
833                 .of_match_table = exynos5433_decon_driver_dt_match,
834         },
835 };