drm/exynos: gsc: add device tree support and remove usage of static mappings
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 30 Nov 2015 13:53:18 +0000 (14:53 +0100)
committerInki Dae <daeinki@gmail.com>
Sun, 13 Dec 2015 13:22:53 +0000 (22:22 +0900)
This patch adds device tree support for exynos_drm_gsc. This patch
also fixed build issue on non-Exynos platforms, thus dependency on
!ARCH_MULTIPLATFORM can be now removed. The driver cannot be used
simultaneously with V4L2 Mem2Mem GScaller driver thought.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Documentation/devicetree/bindings/media/exynos5-gsc.txt
drivers/gpu/drm/exynos/Kconfig
drivers/gpu/drm/exynos/exynos_drm_gsc.c
drivers/gpu/drm/exynos/regs-gsc.h

index 0604d42..5fe9372 100644 (file)
@@ -7,6 +7,10 @@ Required properties:
 - reg: should contain G-Scaler physical address location and length.
 - interrupts: should contain G-Scaler interrupt number
 
 - reg: should contain G-Scaler physical address location and length.
 - interrupts: should contain G-Scaler interrupt number
 
+Optional properties:
+- samsung,sysreg: handle to syscon used to control the system registers to
+  set writeback input and destination
+
 Example:
 
 gsc_0:  gsc@0x13e00000 {
 Example:
 
 gsc_0:  gsc@0x13e00000 {
index 96e86cf..83efca9 100644 (file)
@@ -118,7 +118,7 @@ config DRM_EXYNOS_ROTATOR
 
 config DRM_EXYNOS_GSC
        bool "GScaler"
 
 config DRM_EXYNOS_GSC
        bool "GScaler"
-       depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !ARCH_MULTIPLATFORM
+       depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !VIDEO_SAMSUNG_EXYNOS_GSC
        help
          Choose this option if you want to use Exynos GSC for DRM.
 
        help
          Choose this option if you want to use Exynos GSC for DRM.
 
index ed55d37..7aecd23 100644 (file)
@@ -15,7 +15,8 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
-#include <plat/map-base.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include <drm/drmP.h>
 #include <drm/exynos_drm.h>
 
 #include <drm/drmP.h>
 #include <drm/exynos_drm.h>
@@ -126,6 +127,7 @@ struct gsc_capability {
  * @ippdrv: prepare initialization using ippdrv.
  * @regs_res: register resources.
  * @regs: memory mapped io registers.
  * @ippdrv: prepare initialization using ippdrv.
  * @regs_res: register resources.
  * @regs: memory mapped io registers.
+ * @sysreg: handle to SYSREG block regmap.
  * @lock: locking of operations.
  * @gsc_clk: gsc gate clock.
  * @sc: scaler infomations.
  * @lock: locking of operations.
  * @gsc_clk: gsc gate clock.
  * @sc: scaler infomations.
@@ -138,6 +140,7 @@ struct gsc_context {
        struct exynos_drm_ippdrv        ippdrv;
        struct resource *regs_res;
        void __iomem    *regs;
        struct exynos_drm_ippdrv        ippdrv;
        struct resource *regs_res;
        void __iomem    *regs;
+       struct regmap   *sysreg;
        struct mutex    lock;
        struct clk      *gsc_clk;
        struct gsc_scaler       sc;
        struct mutex    lock;
        struct clk      *gsc_clk;
        struct gsc_scaler       sc;
@@ -437,9 +440,12 @@ static int gsc_sw_reset(struct gsc_context *ctx)
 
 static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
 {
 
 static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
 {
-       u32 gscblk_cfg;
+       unsigned int gscblk_cfg;
 
 
-       gscblk_cfg = readl(SYSREG_GSCBLK_CFG1);
+       if (!ctx->sysreg)
+               return;
+
+       regmap_read(ctx->sysreg, SYSREG_GSCBLK_CFG1, &gscblk_cfg);
 
        if (enable)
                gscblk_cfg |= GSC_BLK_DISP1WB_DEST(ctx->id) |
 
        if (enable)
                gscblk_cfg |= GSC_BLK_DISP1WB_DEST(ctx->id) |
@@ -448,7 +454,7 @@ static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
        else
                gscblk_cfg |= GSC_BLK_PXLASYNC_LO_MASK_WB(ctx->id);
 
        else
                gscblk_cfg |= GSC_BLK_PXLASYNC_LO_MASK_WB(ctx->id);
 
-       writel(gscblk_cfg, SYSREG_GSCBLK_CFG1);
+       regmap_write(ctx->sysreg, SYSREG_GSCBLK_CFG1, gscblk_cfg);
 }
 
 static void gsc_handle_irq(struct gsc_context *ctx, bool enable,
 }
 
 static void gsc_handle_irq(struct gsc_context *ctx, bool enable,
@@ -1663,6 +1669,15 @@ static int gsc_probe(struct platform_device *pdev)
        if (!ctx)
                return -ENOMEM;
 
        if (!ctx)
                return -ENOMEM;
 
+       if (dev->of_node) {
+               ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
+                                                       "samsung,sysreg");
+               if (IS_ERR(ctx->sysreg)) {
+                       dev_warn(dev, "failed to get system register.\n");
+                       ctx->sysreg = NULL;
+               }
+       }
+
        /* clock control */
        ctx->gsc_clk = devm_clk_get(dev, "gscl");
        if (IS_ERR(ctx->gsc_clk)) {
        /* clock control */
        ctx->gsc_clk = devm_clk_get(dev, "gscl");
        if (IS_ERR(ctx->gsc_clk)) {
@@ -1796,6 +1811,12 @@ static const struct dev_pm_ops gsc_pm_ops = {
        SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL)
 };
 
        SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL)
 };
 
+static const struct of_device_id exynos_drm_gsc_of_match[] = {
+       { .compatible = "samsung,exynos5-gsc" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, exynos_drm_gsc_of_match);
+
 struct platform_driver gsc_driver = {
        .probe          = gsc_probe,
        .remove         = gsc_remove,
 struct platform_driver gsc_driver = {
        .probe          = gsc_probe,
        .remove         = gsc_remove,
@@ -1803,6 +1824,7 @@ struct platform_driver gsc_driver = {
                .name   = "exynos-drm-gsc",
                .owner  = THIS_MODULE,
                .pm     = &gsc_pm_ops,
                .name   = "exynos-drm-gsc",
                .owner  = THIS_MODULE,
                .pm     = &gsc_pm_ops,
+               .of_match_table = of_match_ptr(exynos_drm_gsc_of_match),
        },
 };
 
        },
 };
 
index 9ad5927..4704a99 100644 (file)
 #define GSC_CLK_GATE_MODE_SNOOP_CNT(x) ((x) << 0)
 
 /* SYSCON. GSCBLK_CFG */
 #define GSC_CLK_GATE_MODE_SNOOP_CNT(x) ((x) << 0)
 
 /* SYSCON. GSCBLK_CFG */
-#define SYSREG_GSCBLK_CFG1             (S3C_VA_SYS + 0x0224)
+#define SYSREG_GSCBLK_CFG1             0x0224
 #define GSC_BLK_DISP1WB_DEST(x)                (x << 10)
 #define GSC_BLK_SW_RESET_WB_DEST(x)    (1 << (18 + x))
 #define GSC_BLK_PXLASYNC_LO_MASK_WB(x) (0 << (14 + x))
 #define GSC_BLK_GSCL_WB_IN_SRC_SEL(x)  (1 << (2 * x))
 #define GSC_BLK_DISP1WB_DEST(x)                (x << 10)
 #define GSC_BLK_SW_RESET_WB_DEST(x)    (1 << (18 + x))
 #define GSC_BLK_PXLASYNC_LO_MASK_WB(x) (0 << (14 + x))
 #define GSC_BLK_GSCL_WB_IN_SRC_SEL(x)  (1 << (2 * x))
-#define SYSREG_GSCBLK_CFG2             (S3C_VA_SYS + 0x2000)
+#define SYSREG_GSCBLK_CFG2             0x2000
 #define PXLASYNC_LO_MASK_CAMIF_GSCL(x) (1 << (x))
 
 #endif /* EXYNOS_REGS_GSC_H_ */
 #define PXLASYNC_LO_MASK_CAMIF_GSCL(x) (1 << (x))
 
 #endif /* EXYNOS_REGS_GSC_H_ */