Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[cascardo/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/of_gpio.h>
17 #include <linux/pm_runtime.h>
18
19 #include <video/exynos5433_decon.h>
20
21 #include "exynos_drm_drv.h"
22 #include "exynos_drm_crtc.h"
23 #include "exynos_drm_plane.h"
24 #include "exynos_drm_iommu.h"
25
26 #define WINDOWS_NR      3
27 #define MIN_FB_WIDTH_FOR_16WORD_BURST   128
28
29 struct decon_context {
30         struct device                   *dev;
31         struct drm_device               *drm_dev;
32         struct exynos_drm_crtc          *crtc;
33         struct exynos_drm_plane         planes[WINDOWS_NR];
34         void __iomem                    *addr;
35         struct clk                      *clks[6];
36         unsigned int                    default_win;
37         unsigned long                   irq_flags;
38         int                             pipe;
39         bool                            suspended;
40
41 #define BIT_CLKS_ENABLED                0
42 #define BIT_IRQS_ENABLED                1
43         unsigned long                   enabled;
44         bool                            i80_if;
45         atomic_t                        win_updated;
46 };
47
48 static const char * const decon_clks_name[] = {
49         "aclk_decon",
50         "aclk_smmu_decon0x",
51         "aclk_xiu_decon0x",
52         "pclk_smmu_decon0x",
53         "sclk_decon_vclk",
54         "sclk_decon_eclk",
55 };
56
57 static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
58 {
59         struct decon_context *ctx = crtc->ctx;
60         u32 val;
61
62         if (ctx->suspended)
63                 return -EPERM;
64
65         if (test_and_set_bit(0, &ctx->irq_flags)) {
66                 val = VIDINTCON0_INTEN;
67                 if (ctx->i80_if)
68                         val |= VIDINTCON0_FRAMEDONE;
69                 else
70                         val |= VIDINTCON0_INTFRMEN;
71
72                 writel(val, ctx->addr + DECON_VIDINTCON0);
73         }
74
75         return 0;
76 }
77
78 static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
79 {
80         struct decon_context *ctx = crtc->ctx;
81
82         if (ctx->suspended)
83                 return;
84
85         if (test_and_clear_bit(0, &ctx->irq_flags))
86                 writel(0, ctx->addr + DECON_VIDINTCON0);
87 }
88
89 static void decon_setup_trigger(struct decon_context *ctx)
90 {
91         u32 val = TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
92                         TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN;
93         writel(val, ctx->addr + DECON_TRIGCON);
94 }
95
96 static void decon_commit(struct exynos_drm_crtc *crtc)
97 {
98         struct decon_context *ctx = crtc->ctx;
99         struct drm_display_mode *mode = &crtc->base.mode;
100         u32 val;
101
102         if (ctx->suspended)
103                 return;
104
105         /* enable clock gate */
106         val = CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F;
107         writel(val, ctx->addr + DECON_CMU);
108
109         /* lcd on and use command if */
110         val = VIDOUT_LCD_ON;
111         if (ctx->i80_if)
112                 val |= VIDOUT_COMMAND_IF;
113         else
114                 val |= VIDOUT_RGB_IF;
115         writel(val, ctx->addr + DECON_VIDOUTCON0);
116
117         val = VIDTCON2_LINEVAL(mode->vdisplay - 1) |
118                 VIDTCON2_HOZVAL(mode->hdisplay - 1);
119         writel(val, ctx->addr + DECON_VIDTCON2);
120
121         if (!ctx->i80_if) {
122                 val = VIDTCON00_VBPD_F(
123                                 mode->crtc_vtotal - mode->crtc_vsync_end) |
124                         VIDTCON00_VFPD_F(
125                                 mode->crtc_vsync_start - mode->crtc_vdisplay);
126                 writel(val, ctx->addr + DECON_VIDTCON00);
127
128                 val = VIDTCON01_VSPW_F(
129                                 mode->crtc_vsync_end - mode->crtc_vsync_start);
130                 writel(val, ctx->addr + DECON_VIDTCON01);
131
132                 val = VIDTCON10_HBPD_F(
133                                 mode->crtc_htotal - mode->crtc_hsync_end) |
134                         VIDTCON10_HFPD_F(
135                                 mode->crtc_hsync_start - mode->crtc_hdisplay);
136                 writel(val, ctx->addr + DECON_VIDTCON10);
137
138                 val = VIDTCON11_HSPW_F(
139                                 mode->crtc_hsync_end - mode->crtc_hsync_start);
140                 writel(val, ctx->addr + DECON_VIDTCON11);
141         }
142
143         decon_setup_trigger(ctx);
144
145         /* enable output and display signal */
146         val = VIDCON0_ENVID | VIDCON0_ENVID_F;
147         writel(val, ctx->addr + DECON_VIDCON0);
148 }
149
150 #define COORDINATE_X(x)         (((x) & 0xfff) << 12)
151 #define COORDINATE_Y(x)         ((x) & 0xfff)
152 #define OFFSIZE(x)              (((x) & 0x3fff) << 14)
153 #define PAGEWIDTH(x)            ((x) & 0x3fff)
154
155 static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win)
156 {
157         struct exynos_drm_plane *plane = &ctx->planes[win];
158         unsigned long val;
159
160         val = readl(ctx->addr + DECON_WINCONx(win));
161         val &= ~WINCONx_BPPMODE_MASK;
162
163         switch (plane->pixel_format) {
164         case DRM_FORMAT_XRGB1555:
165                 val |= WINCONx_BPPMODE_16BPP_I1555;
166                 val |= WINCONx_HAWSWP_F;
167                 val |= WINCONx_BURSTLEN_16WORD;
168                 break;
169         case DRM_FORMAT_RGB565:
170                 val |= WINCONx_BPPMODE_16BPP_565;
171                 val |= WINCONx_HAWSWP_F;
172                 val |= WINCONx_BURSTLEN_16WORD;
173                 break;
174         case DRM_FORMAT_XRGB8888:
175                 val |= WINCONx_BPPMODE_24BPP_888;
176                 val |= WINCONx_WSWP_F;
177                 val |= WINCONx_BURSTLEN_16WORD;
178                 break;
179         case DRM_FORMAT_ARGB8888:
180                 val |= WINCONx_BPPMODE_32BPP_A8888;
181                 val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F;
182                 val |= WINCONx_BURSTLEN_16WORD;
183                 break;
184         default:
185                 DRM_ERROR("Proper pixel format is not set\n");
186                 return;
187         }
188
189         DRM_DEBUG_KMS("bpp = %u\n", plane->bpp);
190
191         /*
192          * In case of exynos, setting dma-burst to 16Word causes permanent
193          * tearing for very small buffers, e.g. cursor buffer. Burst Mode
194          * switching which is based on plane size is not recommended as
195          * plane size varies a lot towards the end of the screen and rapid
196          * movement causes unstable DMA which results into iommu crash/tear.
197          */
198
199         if (plane->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
200                 val &= ~WINCONx_BURSTLEN_MASK;
201                 val |= WINCONx_BURSTLEN_8WORD;
202         }
203
204         writel(val, ctx->addr + DECON_WINCONx(win));
205 }
206
207 static void decon_shadow_protect_win(struct decon_context *ctx, int win,
208                                         bool protect)
209 {
210         u32 val;
211
212         val = readl(ctx->addr + DECON_SHADOWCON);
213
214         if (protect)
215                 val |= SHADOWCON_Wx_PROTECT(win);
216         else
217                 val &= ~SHADOWCON_Wx_PROTECT(win);
218
219         writel(val, ctx->addr + DECON_SHADOWCON);
220 }
221
222 static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
223 {
224         struct decon_context *ctx = crtc->ctx;
225         struct exynos_drm_plane *plane;
226         u32 val;
227
228         if (win < 0 || win >= WINDOWS_NR)
229                 return;
230
231         plane = &ctx->planes[win];
232
233         if (ctx->suspended)
234                 return;
235
236         decon_shadow_protect_win(ctx, win, true);
237
238         val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y);
239         writel(val, ctx->addr + DECON_VIDOSDxA(win));
240
241         val = COORDINATE_X(plane->crtc_x + plane->crtc_width - 1) |
242                 COORDINATE_Y(plane->crtc_y + plane->crtc_height - 1);
243         writel(val, ctx->addr + DECON_VIDOSDxB(win));
244
245         val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
246                 VIDOSD_Wx_ALPHA_B_F(0x0);
247         writel(val, ctx->addr + DECON_VIDOSDxC(win));
248
249         val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
250                 VIDOSD_Wx_ALPHA_B_F(0x0);
251         writel(val, ctx->addr + DECON_VIDOSDxD(win));
252
253         writel(plane->dma_addr[0], ctx->addr + DECON_VIDW0xADD0B0(win));
254
255         val = plane->dma_addr[0] + plane->pitch * plane->crtc_height;
256         writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
257
258         val = OFFSIZE(plane->pitch - plane->crtc_width * (plane->bpp >> 3))
259                 | PAGEWIDTH(plane->crtc_width * (plane->bpp >> 3));
260         writel(val, ctx->addr + DECON_VIDW0xADD2(win));
261
262         decon_win_set_pixfmt(ctx, win);
263
264         /* window enable */
265         val = readl(ctx->addr + DECON_WINCONx(win));
266         val |= WINCONx_ENWIN_F;
267         writel(val, ctx->addr + DECON_WINCONx(win));
268
269         decon_shadow_protect_win(ctx, win, false);
270
271         /* standalone update */
272         val = readl(ctx->addr + DECON_UPDATE);
273         val |= STANDALONE_UPDATE_F;
274         writel(val, ctx->addr + DECON_UPDATE);
275
276         if (ctx->i80_if)
277                 atomic_set(&ctx->win_updated, 1);
278 }
279
280 static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
281 {
282         struct decon_context *ctx = crtc->ctx;
283         struct exynos_drm_plane *plane;
284         u32 val;
285
286         if (win < 0 || win >= WINDOWS_NR)
287                 return;
288
289         plane = &ctx->planes[win];
290
291         if (ctx->suspended)
292                 return;
293
294         decon_shadow_protect_win(ctx, win, true);
295
296         /* window disable */
297         val = readl(ctx->addr + DECON_WINCONx(win));
298         val &= ~WINCONx_ENWIN_F;
299         writel(val, ctx->addr + DECON_WINCONx(win));
300
301         decon_shadow_protect_win(ctx, win, false);
302
303         /* standalone update */
304         val = readl(ctx->addr + DECON_UPDATE);
305         val |= STANDALONE_UPDATE_F;
306         writel(val, ctx->addr + DECON_UPDATE);
307 }
308
309 static void decon_swreset(struct decon_context *ctx)
310 {
311         unsigned int tries;
312
313         writel(0, ctx->addr + DECON_VIDCON0);
314         for (tries = 2000; tries; --tries) {
315                 if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_STOP_STATUS)
316                         break;
317                 udelay(10);
318         }
319
320         WARN(tries == 0, "failed to disable DECON\n");
321
322         writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0);
323         for (tries = 2000; tries; --tries) {
324                 if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_SWRESET)
325                         break;
326                 udelay(10);
327         }
328
329         WARN(tries == 0, "failed to software reset DECON\n");
330 }
331
332 static void decon_enable(struct exynos_drm_crtc *crtc)
333 {
334         struct decon_context *ctx = crtc->ctx;
335         int ret;
336         int i;
337
338         if (!ctx->suspended)
339                 return;
340
341         ctx->suspended = false;
342
343         pm_runtime_get_sync(ctx->dev);
344
345         for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
346                 ret = clk_prepare_enable(ctx->clks[i]);
347                 if (ret < 0)
348                         goto err;
349         }
350
351         set_bit(BIT_CLKS_ENABLED, &ctx->enabled);
352
353         /* if vblank was enabled status, enable it again. */
354         if (test_and_clear_bit(0, &ctx->irq_flags))
355                 decon_enable_vblank(ctx->crtc);
356
357         decon_commit(ctx->crtc);
358
359         return;
360 err:
361         while (--i >= 0)
362                 clk_disable_unprepare(ctx->clks[i]);
363
364         ctx->suspended = true;
365 }
366
367 static void decon_disable(struct exynos_drm_crtc *crtc)
368 {
369         struct decon_context *ctx = crtc->ctx;
370         int i;
371
372         if (ctx->suspended)
373                 return;
374
375         /*
376          * We need to make sure that all windows are disabled before we
377          * suspend that connector. Otherwise we might try to scan from
378          * a destroyed buffer later.
379          */
380         for (i = 0; i < WINDOWS_NR; i++)
381                 decon_win_disable(crtc, i);
382
383         decon_swreset(ctx);
384
385         for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++)
386                 clk_disable_unprepare(ctx->clks[i]);
387
388         clear_bit(BIT_CLKS_ENABLED, &ctx->enabled);
389
390         pm_runtime_put_sync(ctx->dev);
391
392         ctx->suspended = true;
393 }
394
395 void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
396 {
397         struct decon_context *ctx = crtc->ctx;
398         u32 val;
399
400         if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
401                 return;
402
403         if (atomic_add_unless(&ctx->win_updated, -1, 0)) {
404                 /* trigger */
405                 val = readl(ctx->addr + DECON_TRIGCON);
406                 val |= TRIGCON_SWTRIGCMD;
407                 writel(val, ctx->addr + DECON_TRIGCON);
408         }
409
410         drm_handle_vblank(ctx->drm_dev, ctx->pipe);
411 }
412
413 static void decon_clear_channels(struct exynos_drm_crtc *crtc)
414 {
415         struct decon_context *ctx = crtc->ctx;
416         int win, i, ret;
417         u32 val;
418
419         DRM_DEBUG_KMS("%s\n", __FILE__);
420
421         for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
422                 ret = clk_prepare_enable(ctx->clks[i]);
423                 if (ret < 0)
424                         goto err;
425         }
426
427         for (win = 0; win < WINDOWS_NR; win++) {
428                 /* shadow update disable */
429                 val = readl(ctx->addr + DECON_SHADOWCON);
430                 val |= SHADOWCON_Wx_PROTECT(win);
431                 writel(val, ctx->addr + DECON_SHADOWCON);
432
433                 /* window disable */
434                 val = readl(ctx->addr + DECON_WINCONx(win));
435                 val &= ~WINCONx_ENWIN_F;
436                 writel(val, ctx->addr + DECON_WINCONx(win));
437
438                 /* shadow update enable */
439                 val = readl(ctx->addr + DECON_SHADOWCON);
440                 val &= ~SHADOWCON_Wx_PROTECT(win);
441                 writel(val, ctx->addr + DECON_SHADOWCON);
442
443                 /* standalone update */
444                 val = readl(ctx->addr + DECON_UPDATE);
445                 val |= STANDALONE_UPDATE_F;
446                 writel(val, ctx->addr + DECON_UPDATE);
447         }
448         /* TODO: wait for possible vsync */
449         msleep(50);
450
451 err:
452         while (--i >= 0)
453                 clk_disable_unprepare(ctx->clks[i]);
454 }
455
456 static struct exynos_drm_crtc_ops decon_crtc_ops = {
457         .enable                 = decon_enable,
458         .disable                = decon_disable,
459         .commit                 = decon_commit,
460         .enable_vblank          = decon_enable_vblank,
461         .disable_vblank         = decon_disable_vblank,
462         .commit                 = decon_commit,
463         .win_commit             = decon_win_commit,
464         .win_disable            = decon_win_disable,
465         .te_handler             = decon_te_irq_handler,
466         .clear_channels         = decon_clear_channels,
467 };
468
469 static int decon_bind(struct device *dev, struct device *master, void *data)
470 {
471         struct decon_context *ctx = dev_get_drvdata(dev);
472         struct drm_device *drm_dev = data;
473         struct exynos_drm_private *priv = drm_dev->dev_private;
474         struct exynos_drm_plane *exynos_plane;
475         enum drm_plane_type type;
476         unsigned int zpos;
477         int ret;
478
479         ctx->drm_dev = drm_dev;
480         ctx->pipe = priv->pipe++;
481
482         for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
483                 type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY :
484                                                         DRM_PLANE_TYPE_OVERLAY;
485                 ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
486                                 1 << ctx->pipe, type, zpos);
487                 if (ret)
488                         return ret;
489         }
490
491         exynos_plane = &ctx->planes[ctx->default_win];
492         ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
493                                         ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD,
494                                         &decon_crtc_ops, ctx);
495         if (IS_ERR(ctx->crtc)) {
496                 ret = PTR_ERR(ctx->crtc);
497                 goto err;
498         }
499
500         ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, dev);
501         if (ret)
502                 goto err;
503
504         return ret;
505 err:
506         priv->pipe--;
507         return ret;
508 }
509
510 static void decon_unbind(struct device *dev, struct device *master, void *data)
511 {
512         struct decon_context *ctx = dev_get_drvdata(dev);
513
514         decon_disable(ctx->crtc);
515
516         /* detach this sub driver from iommu mapping if supported. */
517         if (is_drm_iommu_supported(ctx->drm_dev))
518                 drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
519 }
520
521 static const struct component_ops decon_component_ops = {
522         .bind   = decon_bind,
523         .unbind = decon_unbind,
524 };
525
526 static irqreturn_t decon_vsync_irq_handler(int irq, void *dev_id)
527 {
528         struct decon_context *ctx = dev_id;
529         u32 val;
530
531         if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
532                 goto out;
533
534         val = readl(ctx->addr + DECON_VIDINTCON1);
535         if (val & VIDINTCON1_INTFRMPEND) {
536                 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
537
538                 /* clear */
539                 writel(VIDINTCON1_INTFRMPEND, ctx->addr + DECON_VIDINTCON1);
540         }
541
542 out:
543         return IRQ_HANDLED;
544 }
545
546 static irqreturn_t decon_lcd_sys_irq_handler(int irq, void *dev_id)
547 {
548         struct decon_context *ctx = dev_id;
549         u32 val;
550
551         if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
552                 goto out;
553
554         val = readl(ctx->addr + DECON_VIDINTCON1);
555         if (val & VIDINTCON1_INTFRMDONEPEND) {
556                 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
557
558                 /* clear */
559                 writel(VIDINTCON1_INTFRMDONEPEND,
560                                 ctx->addr + DECON_VIDINTCON1);
561         }
562
563 out:
564         return IRQ_HANDLED;
565 }
566
567 static int exynos5433_decon_probe(struct platform_device *pdev)
568 {
569         struct device *dev = &pdev->dev;
570         struct decon_context *ctx;
571         struct resource *res;
572         int ret;
573         int i;
574
575         ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
576         if (!ctx)
577                 return -ENOMEM;
578
579         ctx->default_win = 0;
580         ctx->suspended = true;
581         ctx->dev = dev;
582         if (of_get_child_by_name(dev->of_node, "i80-if-timings"))
583                 ctx->i80_if = true;
584
585         for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
586                 struct clk *clk;
587
588                 clk = devm_clk_get(ctx->dev, decon_clks_name[i]);
589                 if (IS_ERR(clk))
590                         return PTR_ERR(clk);
591
592                 ctx->clks[i] = clk;
593         }
594
595         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
596         if (!res) {
597                 dev_err(dev, "cannot find IO resource\n");
598                 return -ENXIO;
599         }
600
601         ctx->addr = devm_ioremap_resource(dev, res);
602         if (IS_ERR(ctx->addr)) {
603                 dev_err(dev, "ioremap failed\n");
604                 return PTR_ERR(ctx->addr);
605         }
606
607         res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
608                         ctx->i80_if ? "lcd_sys" : "vsync");
609         if (!res) {
610                 dev_err(dev, "cannot find IRQ resource\n");
611                 return -ENXIO;
612         }
613
614         ret = devm_request_irq(dev, res->start, ctx->i80_if ?
615                         decon_lcd_sys_irq_handler : decon_vsync_irq_handler, 0,
616                         "drm_decon", ctx);
617         if (ret < 0) {
618                 dev_err(dev, "lcd_sys irq request failed\n");
619                 return ret;
620         }
621
622         platform_set_drvdata(pdev, ctx);
623
624         pm_runtime_enable(dev);
625
626         ret = component_add(dev, &decon_component_ops);
627         if (ret)
628                 goto err_disable_pm_runtime;
629
630         return 0;
631
632 err_disable_pm_runtime:
633         pm_runtime_disable(dev);
634
635         return ret;
636 }
637
638 static int exynos5433_decon_remove(struct platform_device *pdev)
639 {
640         pm_runtime_disable(&pdev->dev);
641
642         component_del(&pdev->dev, &decon_component_ops);
643
644         return 0;
645 }
646
647 static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
648         { .compatible = "samsung,exynos5433-decon" },
649         {},
650 };
651 MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
652
653 struct platform_driver exynos5433_decon_driver = {
654         .probe          = exynos5433_decon_probe,
655         .remove         = exynos5433_decon_remove,
656         .driver         = {
657                 .name   = "exynos5433-decon",
658                 .of_match_table = exynos5433_decon_driver_dt_match,
659         },
660 };