<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/17 Sylwester Nawrocki <span dir="ltr"><<a href="mailto:s.nawrocki@samsung.com" target="_blank">s.nawrocki@samsung.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This patch adds OF initialization support for the FIMC driver.<br>
The binding documentation can be found at Documentation/devicetree/<br>
bindings/media/samsung-fimc.txt.<br>
<br>
The syscon regmap interface is used to serialize access to the<br>
shared CAMBLK registers from within the V4L2 FIMC-IS and the DRM<br>
FIMC drivers. The DRM driver uses this interface for setting up<br>
the FIFO data link between FIMD and FIMC IP blocks, while the V4L2<br>
one for setting up a data link between the camera ISP and FIMC for<br>
camera capture. The CAMBLK registers are not accessed any more<br>
through a statically mapped IO. Synchronized access to these<br>
registers is required for simultaneous operation of the camera<br>
ISP and the DRM IPP on Exynos4x12.<br>
<br>
Exynos4 is going to be a dt-only platform since 3.10, thus the<br>
driver data and driver_ids static data structures are removed.<br>
<br>
Camera input signal polarities are not currently parsed from the<br>
device tree.<br>
<br>
Signed-off-by: Sylwester Nawrocki <<a href="mailto:s.nawrocki@samsung.com">s.nawrocki@samsung.com</a>><br>
Signed-off-by: Kyungmin Park <<a href="mailto:kyungmin.park@samsung.com">kyungmin.park@samsung.com</a>><br>
---<br>
 drivers/gpu/drm/exynos/Kconfig           |    2 +-<br>
 drivers/gpu/drm/exynos/exynos_drm_fimc.c |  101 +++++++++++++++---------------<br>
 drivers/gpu/drm/exynos/regs-fimc.h       |    7 +--<br>
 3 files changed, 53 insertions(+), 57 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig<br>
index 406f32a..5c4be2a 100644<br>
--- a/drivers/gpu/drm/exynos/Kconfig<br>
+++ b/drivers/gpu/drm/exynos/Kconfig<br>
@@ -56,7 +56,7 @@ config DRM_EXYNOS_IPP<br>
<br>
 config DRM_EXYNOS_FIMC<br>
        bool "Exynos DRM FIMC"<br>
-       depends on DRM_EXYNOS_IPP<br>
+       depends on DRM_EXYNOS_IPP && MFD_SYSCON && OF<br>
        help<br>
          Choose this option if you want to use Exynos FIMC for DRM.<br>
<br>
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c<br>
index 9bea585..f25801e 100644<br>
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c<br>
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c<br>
@@ -12,11 +12,12 @@<br>
  *<br>
  */<br>
 #include <linux/kernel.h><br>
+#include <linux/mfd/syscon.h><br>
 #include <linux/module.h><br>
 #include <linux/platform_device.h><br>
+#include <linux/regmap.h><br>
 #include <linux/clk.h><br>
 #include <linux/pm_runtime.h><br>
-#include <plat/map-base.h><br>
<br>
 #include <drm/drmP.h><br>
 #include <drm/exynos_drm.h><br>
@@ -140,15 +141,6 @@ struct fimc_capability {<br>
 };<br>
<br>
 /*<br>
- * A structure of fimc driver data.<br>
- *<br>
- * @parent_clk: name of parent clock.<br>
- */<br>
-struct fimc_driverdata {<br>
-       char    *parent_clk;<br>
-};<br>
-<br>
-/*<br>
  * A structure of fimc context.<br>
  *<br>
  * @ippdrv: prepare initialization using ippdrv.<br>
@@ -158,6 +150,7 @@ struct fimc_driverdata {<br>
  * @lock: locking of operations.<br>
  * @clocks: fimc clocks.<br>
  * @clk_frequency: LCLK clock frequency.<br>
+ * @sysreg: handle to SYSREG block regmap.<br>
  * @sc: scaler infomations.<br>
  * @pol: porarity of writeback.<br>
  * @id: fimc id.<br>
@@ -172,8 +165,8 @@ struct fimc_context {<br>
        struct mutex    lock;<br>
        struct clk      *clocks[FIMC_CLKS_MAX];<br>
        u32             clk_frequency;<br>
+       struct regmap   *sysreg;<br>
        struct fimc_scaler      sc;<br>
-       struct fimc_driverdata  *ddata;<br>
        struct exynos_drm_ipp_pol       pol;<br>
        int     id;<br>
        int     irq;<br>
@@ -217,17 +210,13 @@ static void fimc_sw_reset(struct fimc_context *ctx)<br>
        fimc_write(0x0, EXYNOS_CIFCNTSEQ);<br>
 }<br>
<br>
-static void fimc_set_camblk_fimd0_wb(struct fimc_context *ctx)<br>
+static int fimc_set_camblk_fimd0_wb(struct fimc_context *ctx)<br>
 {<br>
-       u32 camblk_cfg;<br>
-<br>
        DRM_DEBUG_KMS("%s\n", __func__);<br>
<br>
-       camblk_cfg = readl(SYSREG_CAMERA_BLK);<br>
-       camblk_cfg &= ~(SYSREG_FIMD0WB_DEST_MASK);<br>
-       camblk_cfg |= ctx->id << (SYSREG_FIMD0WB_DEST_SHIFT);<br>
-<br>
-       writel(camblk_cfg, SYSREG_CAMERA_BLK);<br>
+       return regmap_update_bits(ctx->sysreg, SYSREG_CAMERA_BLK,<br>
+                                 SYSREG_FIMD0WB_DEST_MASK,<br>
+                                 ctx->id << SYSREG_FIMD0WB_DEST_SHIFT);<br>
 }<br>
<br>
 static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb)<br>
@@ -1628,7 +1617,9 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)<br>
                fimc_handle_lastend(ctx, true);<br>
<br>
                /* setup FIMD */<br>
-               fimc_set_camblk_fimd0_wb(ctx);<br>
+               ret = fimc_set_camblk_fimd0_wb(ctx);<br>
+               if (ret < 0)<br>
+                       return ret;<br>
<br>
                set_wb.enable = 1;<br>
                set_wb.refresh = property->refresh_rate;<br>
@@ -1784,26 +1775,50 @@ e_clk_free:<br>
        return ret;<br>
 }<br>
<br>
+static int fimc_parse_dt(struct fimc_context *ctx)<br>
+{<br>
+       struct device_node *node = ctx->dev->of_node;<br>
+<br>
+       if (!of_property_read_bool(node, "samsung,lcd-wb"))<br>
+               return -ENODEV;<br></blockquote><div><br><br>Isn't the above property really needed? This makes the use of write-back feature to be forced. I think some machines might not need this feature so their dts files have no that property.<br>
</div><div> So in this case, drm fimc driver probing will be failed. is that correct action and your intention?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+<br>
+       if (of_property_read_u32(node, "clock-frequency",<br>
+                                       &ctx->clk_frequency))<br>
+               ctx->clk_frequency = FIMC_DEFAULT_LCLK_FREQUENCY;<br>
+<br>
+       ctx->id = of_alias_get_id(node, "fimc");<br>
+       if (ctx->id < 0)<br>
+               return -EINVAL;<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
 static int fimc_probe(struct platform_device *pdev)<br>
 {<br>
        struct device *dev = &pdev->dev;<br>
        struct fimc_context *ctx;<br>
        struct resource *res;<br>
        struct exynos_drm_ippdrv *ippdrv;<br>
-       struct exynos_drm_fimc_pdata *pdata;<br>
-       struct fimc_driverdata *ddata;<br>
        int ret;<br>
<br>
-       pdata = pdev->dev.platform_data;<br>
-       if (!pdata) {<br>
-               dev_err(dev, "no platform data specified.\n");<br>
-               return -EINVAL;<br>
-       }<br>
+       if (!dev->of_node)<br>
+               return -ENODEV;<br>
<br>
        ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);<br>
        if (!ctx)<br>
                return -ENOMEM;<br>
<br>
+       ctx->dev = dev;<br>
+<br>
+       ret = fimc_parse_dt(ctx);<br>
+       if (ret < 0)<br>
+               return ret;<br>
+<br>
+       ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,<br>
+                                               "samsung,sysreg");<br>
+       if (IS_ERR(ctx->sysreg))<br>
+               return PTR_ERR(ctx->sysreg);<br>
+<br>
        /* resource memory */<br>
        ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);<br>
        ctx->regs = devm_ioremap_resource(dev, ctx->regs_res);<br>
@@ -1828,10 +1843,6 @@ static int fimc_probe(struct platform_device *pdev)<br>
        ret = fimc_setup_clocks(ctx);<br>
        if (ret < 0)<br>
                goto err_free_irq;<br>
-       /* context initailization */<br>
-       ctx->id = pdev->id;<br>
-       ctx->pol = pdata->pol;<br>
-       ctx->ddata = ddata;<br>
<br>
        ippdrv = &ctx->ippdrv;<br>
        ippdrv->dev = dev;<br>
@@ -1941,36 +1952,22 @@ static int fimc_runtime_resume(struct device *dev)<br>
 }<br>
 #endif<br>
<br>
-static struct fimc_driverdata exynos4210_fimc_data = {<br>
-       .parent_clk = "mout_mpll",<br>
-};<br>
-<br>
-static struct fimc_driverdata exynos4410_fimc_data = {<br>
-       .parent_clk = "mout_mpll_user",<br>
-};<br>
-<br>
-static struct platform_device_id fimc_driver_ids[] = {<br>
-       {<br>
-               .name           = "exynos4210-fimc",<br>
-               .driver_data    = (unsigned long)&exynos4210_fimc_data,<br>
-       }, {<br>
-               .name           = "exynos4412-fimc",<br>
-               .driver_data    = (unsigned long)&exynos4410_fimc_data,<br>
-       },<br>
-       {},<br>
-};<br>
-MODULE_DEVICE_TABLE(platform, fimc_driver_ids);<br>
-<br>
 static const struct dev_pm_ops fimc_pm_ops = {<br>
        SET_SYSTEM_SLEEP_PM_OPS(fimc_suspend, fimc_resume)<br>
        SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL)<br>
 };<br>
<br>
+static const struct of_device_id fimc_of_match[] = {<br>
+       { .compatible = "samsung,exynos4210-fimc" },<br>
+       { .compatible = "samsung,exynos4212-fimc" },<br>
+       { },<br>
+};<br>
+<br>
 struct platform_driver fimc_driver = {<br>
        .probe          = fimc_probe,<br>
        .remove         = fimc_remove,<br>
-       .id_table       = fimc_driver_ids,<br>
        .driver         = {<br>
+               .of_match_table = fimc_of_match,<br>
                .name   = "exynos-drm-fimc",<br>
                .owner  = THIS_MODULE,<br>
                .pm     = &fimc_pm_ops,<br>
diff --git a/drivers/gpu/drm/exynos/regs-fimc.h b/drivers/gpu/drm/exynos/regs-fimc.h<br>
index b4f9ca1..3049613 100644<br>
--- a/drivers/gpu/drm/exynos/regs-fimc.h<br>
+++ b/drivers/gpu/drm/exynos/regs-fimc.h<br>
@@ -661,9 +661,8 @@<br>
 #define EXYNOS_CLKSRC_SCLK                             (1 << 1)<br>
<br>
 /* SYSREG for FIMC writeback */<br>
-#define SYSREG_CAMERA_BLK                      (S3C_VA_SYS + 0x0218)<br>
-#define SYSREG_ISP_BLK                         (S3C_VA_SYS + 0x020c)<br>
-#define SYSREG_FIMD0WB_DEST_MASK       (0x3 << 23)<br>
-#define SYSREG_FIMD0WB_DEST_SHIFT      23<br>
+#define SYSREG_CAMERA_BLK                      (0x0218)<br>
+#define SYSREG_FIMD0WB_DEST_MASK               (0x3 << 23)<br>
+#define SYSREG_FIMD0WB_DEST_SHIFT              23<br>
<br>
 #endif /* EXYNOS_REGS_FIMC_H */<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.9.5<br>
<br>
_______________________________________________<br>
dri-devel mailing list<br>
<a href="mailto:dri-devel@lists.freedesktop.org">dri-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/dri-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/dri-devel</a><br>
</font></span></blockquote></div><br></div></div>