drm/exynos: decon: add sysreg support
authorInki Dae <inki.dae@samsung.com>
Wed, 30 Mar 2016 08:46:22 +0000 (17:46 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 14 Dec 2016 04:49:29 +0000 (13:49 +0900)
This patch adds sysreg support to control display block,
and makes te unmask bit of display block to be set
according to trigger mode defined already.

This is required for HW trigger mode support.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos5433_drm_decon.c

index 4aef738..679b29c 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/component.h>
 #include <linux/of_gpio.h>
 #include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include <video/exynos5433_decon.h>
 
@@ -41,6 +43,8 @@ struct exynos5433_decon_driver_data {
        enum exynos_drm_trigger_type trg_type;
        unsigned int nr_window;
        unsigned int first_win;
+       unsigned int lcdblk_offset;
+       unsigned int lcdblk_te_unmask_shift;
 };
 
 struct decon_context {
@@ -49,6 +53,7 @@ struct decon_context {
        struct exynos_drm_crtc          *crtc;
        struct exynos_drm_plane         planes[WINDOWS_NR];
        void __iomem                    *addr;
+       struct regmap                   *sysreg;
        struct clk                      *clks[ARRAY_SIZE(decon_clks_name)];
        int                             pipe;
        bool                            suspended;
@@ -204,6 +209,19 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
                val = VIDTCON11_HSPW_F(
                                mode->crtc_hsync_end - mode->crtc_hsync_start - 1);
                writel(val, ctx->addr + DECON_VIDTCON11);
+       } else {
+               struct exynos5433_decon_driver_data *drv_data =
+                                                       ctx->drv_data;
+               unsigned int te_unmask = drv_data->trg_type;
+
+               /* set te unmask */
+               if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
+                   drv_data->lcdblk_offset,
+                   0x1 << drv_data->lcdblk_te_unmask_shift,
+                   te_unmask << drv_data->lcdblk_te_unmask_shift)) {
+                       DRM_ERROR("Failed to update sysreg.\n");
+                       return;
+               }
        }
 
        if (ctx->i80_if)
@@ -785,6 +803,13 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
            drv_data->type == EXYNOS_DISPLAY_TYPE_HDMI)
                ctx->i80_if = true;
 
+       ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
+                                                       "samsung,disp-sysreg");
+       if (IS_ERR(ctx->sysreg)) {
+               dev_warn(dev, "failed to get system register.\n");
+               ctx->sysreg = NULL;
+       }
+
        for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
                struct clk *clk;
 
@@ -841,12 +866,16 @@ static const struct exynos5433_decon_driver_data exynos5433_decon_int_driver_dat
        .type = EXYNOS_DISPLAY_TYPE_LCD,
        .trg_type = EXYNOS_DISPLAY_HW_TRIGGER,
        .first_win = 0,
+       .lcdblk_offset = 0x1004,
+       .lcdblk_te_unmask_shift = 13,
 };
 
 static const struct exynos5433_decon_driver_data exynos5433_decon_ext_driver_data = {
        .type = EXYNOS_DISPLAY_TYPE_HDMI,
        .trg_type = EXYNOS_DISPLAY_HW_TRIGGER,
        .first_win = 1,
+       .lcdblk_offset = 0x1004,
+       .lcdblk_te_unmask_shift = 13,
 };
 
 static const struct of_device_id exynos5433_decon_driver_dt_match[] = {