<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>