drm/exynos: gsc: add device tree support
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 1 Jul 2015 05:02:46 +0000 (14:02 +0900)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Mon, 13 Apr 2015 10:44:50 +0000 (12:44 +0200)
This patch adds device tree support for exynos_drm_gsc. The gsc
driver is bound only when lcd-wb binding flag is set to gsc dt
node.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
Documentation/devicetree/bindings/media/exynos5-gsc.txt
drivers/gpu/drm/exynos/exynos_drm_gsc.c
drivers/gpu/drm/exynos/regs-gsc.h

index d526777a3abd04d244c46fdd729e3df93bb86917..9773af50bb0d823b0994f5dfcdce3318c479babd 100644 (file)
@@ -10,6 +10,8 @@ Required properties:
 Optional properties:
 - samsung,lcd-wb: this property must be present if the IP block has the LCD
   writeback input.
+- samsung,sysreg: handle to syscon used to control the system registers to
+  set writeback input and destination
 
 Example:
 
index 8040ed2a831f9a6f226baf8aee3ce00b213be8e6..b51057066e5f20ba64b39503c3442e3962cc051e 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,
@@ -1649,6 +1655,19 @@ static int gsc_probe(struct platform_device *pdev)
        if (!ctx)
                return -ENOMEM;
 
+       if (dev->of_node) {
+               /* Handle only devices that support the LCD Writeback path */
+               if (!of_property_read_bool(dev->of_node, "samsung,lcd-wb"))
+                       return -ENODEV;
+
+               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)) {
@@ -1783,6 +1802,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,
@@ -1790,6 +1815,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_ */