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 0604d42f38d1941526d47ad11a958a2a83797f97..5fe9372abb37b4aef45ae0ca2fd23f01bd3713c0 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
 
+Optional properties:
+- samsung,sysreg: handle to syscon used to control the system registers to
+  set writeback input and destination
+
 Example:
 
 gsc_0:  gsc@0x13e00000 {
index 96e86cf4455bce343263c4064246597c7a89d01c..83efca941388a73874a8da10412c77d9bc3801e4 100644 (file)
@@ -118,7 +118,7 @@ config DRM_EXYNOS_ROTATOR
 
 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.
 
index ed55d37b63308d35b980b91bb59be6f56ba3f25a..7aecd23cfa11a6638d783366b890fd33a9c0ea2e 100644 (file)
@@ -15,7 +15,8 @@
 #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>
@@ -126,6 +127,7 @@ struct gsc_capability {
  * @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.
@@ -138,6 +140,7 @@ struct gsc_context {
        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;
@@ -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)
 {
-       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) |
@@ -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);
 
-       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,
@@ -1663,6 +1669,15 @@ static int gsc_probe(struct platform_device *pdev)
        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)) {
@@ -1796,6 +1811,12 @@ static const struct dev_pm_ops gsc_pm_ops = {
        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,
@@ -1803,6 +1824,7 @@ struct platform_driver gsc_driver = {
                .name   = "exynos-drm-gsc",
                .owner  = THIS_MODULE,
                .pm     = &gsc_pm_ops,
+               .of_match_table = of_match_ptr(exynos_drm_gsc_of_match),
        },
 };
 
index 9ad592707aafd18e147887cfd0b15fddb711e8fe..4704a993cbb7f003a51b901ae9b291a9adc9fe09 100644 (file)
 #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 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_ */