[PATCH 1/3] IPUv3: Add i.MX53 IPU support

jason.chen at freescale.com jason.chen at freescale.com
Tue Feb 15 03:56:13 EST 2011


From: Jason Chen <b02280 at freescale.com>

Signed-off-by: Jason Chen <b02280 at freescale.com>
---
 arch/arm/mach-mx5/board-mx51_babbage.c          |    2 +-
 arch/arm/mach-mx5/devices-imx51.h               |    3 -
 arch/arm/plat-mxc/devices/platform-imx_ipuv3.c  |   97 +++++++++++++++++++++--
 arch/arm/plat-mxc/include/mach/devices-common.h |    4 +-
 arch/arm/plat-mxc/include/mach/ipu-v3.h         |    1 +
 drivers/mfd/Kconfig                             |    6 +-
 drivers/mfd/imx-ipu-v3/ipu-common.c             |   66 +++------------
 drivers/mfd/imx-ipu-v3/ipu-prv.h                |   32 ++++----
 8 files changed, 126 insertions(+), 85 deletions(-)

diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index ff951f8..176b9bc 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -457,7 +457,7 @@ static void __init mxc_board_init(void)
 	gpio_request(GPIO_DVI_I2C, "dvi i2c");
 	gpio_direction_output(GPIO_DVI_I2C, 0);
 
-	imx51_add_ipuv3(&ipu_data);
+	imx_add_ipuv3(&ipu_data);
 }
 
 static void __init mx51_babbage_timer_init(void)
diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-mx5/devices-imx51.h
index 1bd73b3..065ac87 100644
--- a/arch/arm/mach-mx5/devices-imx51.h
+++ b/arch/arm/mach-mx5/devices-imx51.h
@@ -56,6 +56,3 @@ extern const struct imx_imx_keypad_data imx51_imx_keypad_data __initconst;
 #define imx51_add_imx_keypad(pdata)	\
 	imx_add_imx_keypad(&imx51_imx_keypad_data, pdata)
 
-extern const struct imx_ipuv3_data imx51_ipuv3_data __initconst;
-#define imx51_add_ipuv3(pdata)	\
-	imx_add_ipuv3(&imx51_ipuv3_data, pdata)
diff --git a/arch/arm/plat-mxc/devices/platform-imx_ipuv3.c b/arch/arm/plat-mxc/devices/platform-imx_ipuv3.c
index 2c6b913..c867f97 100644
--- a/arch/arm/plat-mxc/devices/platform-imx_ipuv3.c
+++ b/arch/arm/plat-mxc/devices/platform-imx_ipuv3.c
@@ -8,27 +8,93 @@
  */
 #include <mach/hardware.h>
 #include <mach/devices-common.h>
+#include <linux/clk.h>
 
-#define imx51_ipuv3_data_entry_single(soc)				\
+#define imx5_ipuv3_data_entry_single(soc)				\
 	{								\
 		.iobase = soc ## _IPU_CTRL_BASE_ADDR,			\
 		.irq_err = soc ## _INT_IPU_ERR,				\
 		.irq = soc ## _INT_IPU_SYN,				\
 	}
 
-#ifdef CONFIG_SOC_IMX51
-const struct imx_ipuv3_data imx51_ipuv3_data __initconst =
-	imx51_ipuv3_data_entry_single(MX51);
-#endif /* ifdef CONFIG_SOC_IMX35 */
+struct imx_ipuv3_data __initdata imx51_ipuv3_data =
+		imx5_ipuv3_data_entry_single(MX51);
+struct imx_ipuv3_data __initdata imx53_ipuv3_data =
+		imx5_ipuv3_data_entry_single(MX53);
 
-struct platform_device *__init imx_add_ipuv3(
+/*
+ * The MIPI HSC unit has been removed from the i.MX51 Reference Manual by
+ * the Freescale marketing division. However this did not remove the
+ * hardware from the chip which still needs to be configured...
+ */
+static int __init ipu_mipi_setup(void)
+{
+	struct clk *hsc_clk;
+	void __iomem *hsc_addr;
+	int ret = 0;
+
+	hsc_addr = ioremap(MX51_MIPI_HSC_BASE_ADDR, PAGE_SIZE);
+	if (!hsc_addr)
+		return -ENOMEM;
+
+	hsc_clk = clk_get_sys(NULL, "mipi_hsp");
+	if (IS_ERR(hsc_clk)) {
+		ret = PTR_ERR(hsc_clk);
+		goto unmap;
+	}
+	clk_enable(hsc_clk);
+
+	/* setup MIPI module to legacy mode */
+	__raw_writel(0xF00, hsc_addr);
+
+	/* CSI mode: reserved; DI control mode: legacy (from Freescale BSP) */
+	__raw_writel(__raw_readl(hsc_addr + 0x800) | 0x30ff,
+		hsc_addr + 0x800);
+
+	clk_disable(hsc_clk);
+	clk_put(hsc_clk);
+unmap:
+	iounmap(hsc_addr);
+
+	return ret;
+}
+
+int __init mx51_ipuv3_init(void)
+{
+	int ret = 0;
+	u32 val;
+
+	ret = ipu_mipi_setup();
+
+	/* hard reset the IPU */
+	val = readl(MX51_IO_ADDRESS(MX51_SRC_BASE_ADDR));
+	val |= 1 << 3;
+	writel(val, MX51_IO_ADDRESS(MX51_SRC_BASE_ADDR));
+
+	return ret;
+}
+
+int __init mx53_ipuv3_init(void)
+{
+	int ret = 0;
+	u32 val;
+
+	/* hard reset the IPU */
+	val = readl(MX53_IO_ADDRESS(MX53_SRC_BASE_ADDR));
+	val |= 1 << 3;
+	writel(val, MX53_IO_ADDRESS(MX53_SRC_BASE_ADDR));
+
+	return ret;
+}
+
+struct platform_device *__init _imx_add_ipuv3(
 		const struct imx_ipuv3_data *data,
 		const struct imx_ipuv3_platform_data *pdata)
 {
 	struct resource res[] = {
 		{
 			.start = data->iobase,
-			.end = data->iobase + SZ_512M - 1,
+			.end = data->iobase + data->iosize - 1,
 			.flags = IORESOURCE_MEM,
 		}, {
 			.start = data->irq_err,
@@ -45,3 +111,20 @@ struct platform_device *__init imx_add_ipuv3(
 			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
 
+struct platform_device *__init imx_add_ipuv3(
+		struct imx_ipuv3_platform_data *pdata)
+{
+	if (cpu_is_mx51()) {
+		imx51_ipuv3_data.iosize = SZ_512M;
+		pdata->init = mx51_ipuv3_init;
+		return _imx_add_ipuv3(&imx51_ipuv3_data, pdata);
+	} else if (cpu_is_mx53()) {
+		/* fix offset */
+		imx53_ipuv3_data.iobase -= 0x18000000;
+		imx51_ipuv3_data.iosize = SZ_128M;
+		pdata->init = mx53_ipuv3_init;
+		return _imx_add_ipuv3(&imx53_ipuv3_data, pdata);
+	} else
+		return ERR_PTR(-EINVAL);
+}
+
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 8f5197f..d9824a2 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -268,9 +268,9 @@ struct platform_device *__init imx_add_spi_imx(
 #include <mach/ipu-v3.h>
 struct imx_ipuv3_data {
 	resource_size_t iobase;
+	resource_size_t iosize;
 	resource_size_t irq_err;
 	resource_size_t irq;
 };
 struct platform_device *__init imx_add_ipuv3(
-		const struct imx_ipuv3_data *data,
-		const struct imx_ipuv3_platform_data *pdata);
+		struct imx_ipuv3_platform_data *pdata);
diff --git a/arch/arm/plat-mxc/include/mach/ipu-v3.h b/arch/arm/plat-mxc/include/mach/ipu-v3.h
index f8900b9..1a4a271 100644
--- a/arch/arm/plat-mxc/include/mach/ipu-v3.h
+++ b/arch/arm/plat-mxc/include/mach/ipu-v3.h
@@ -42,6 +42,7 @@ struct ipuv3_fb_platform_data {
 
 struct imx_ipuv3_platform_data {
 	int rev;
+	int (*init) (void);
 	struct ipuv3_fb_platform_data	*fb_head0_platform_data;
 	struct ipuv3_fb_platform_data	*fb_head1_platform_data;
 };
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d1aa701..0d218cd 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -625,11 +625,11 @@ config MFD_WL1273_CORE
 	  audio codec.
 
 config MFD_IMX_IPU_V3
-	tristate "Support the Image Processing Unit (IPU) found on the i.MX51"
-	depends on ARCH_MX51
+	tristate "Support the Image Processing Unit (IPUv3) found on the i.MX5X"
+	depends on ARCH_MX51 || ARCH_MX53
 	select MFD_CORE
 	help
-	  Say yes here to support the IPU on i.MX51.
+	  Say yes here to support the IPUv3 on i.MX5X.
 
 endif # MFD_SUPPORT
 
diff --git a/drivers/mfd/imx-ipu-v3/ipu-common.c b/drivers/mfd/imx-ipu-v3/ipu-common.c
index d96245f..3a026c0 100644
--- a/drivers/mfd/imx-ipu-v3/ipu-common.c
+++ b/drivers/mfd/imx-ipu-v3/ipu-common.c
@@ -345,15 +345,9 @@ ipu_color_space_t format_to_colorspace(u32 fmt)
 	}
 }
 
-static int ipu_reset(void)
+static int ipu_mem_reset(void)
 {
 	int timeout = 10000;
-	u32 val;
-
-	/* hard reset the IPU */
-	val = readl(MX51_IO_ADDRESS(MX51_SRC_BASE_ADDR));
-	val |= 1 << 3;
-	writel(val, MX51_IO_ADDRESS(MX51_SRC_BASE_ADDR));
 
 	ipu_cm_write(0x807FFFFF, IPU_MEM_RST);
 
@@ -366,43 +360,6 @@ static int ipu_reset(void)
 	return 0;
 }
 
-/*
- * The MIPI HSC unit has been removed from the i.MX51 Reference Manual by
- * the Freescale marketing division. However this did not remove the
- * hardware from the chip which still needs to be configured...
- */
-static int __devinit ipu_mipi_setup(void)
-{
-	struct clk *hsc_clk;
-	void __iomem *hsc_addr;
-	int ret = 0;
-
-	hsc_addr = ioremap(MX51_MIPI_HSC_BASE_ADDR, PAGE_SIZE);
-	if (!hsc_addr)
-		return -ENOMEM;
-
-	hsc_clk = clk_get_sys(NULL, "mipi_hsp");
-	if (IS_ERR(hsc_clk)) {
-		ret = PTR_ERR(hsc_clk);
-		goto unmap;
-	}
-	clk_enable(hsc_clk);
-
-	/* setup MIPI module to legacy mode */
-	__raw_writel(0xF00, hsc_addr);
-
-	/* CSI mode: reserved; DI control mode: legacy (from Freescale BSP) */
-	__raw_writel(__raw_readl(hsc_addr + 0x800) | 0x30ff,
-		hsc_addr + 0x800);
-
-	clk_disable(hsc_clk);
-	clk_put(hsc_clk);
-unmap:
-	iounmap(hsc_addr);
-
-	return ret;
-}
-
 static int ipu_submodules_init(struct platform_device *pdev,
 		unsigned long ipu_base, struct clk *ipu_clk)
 {
@@ -526,9 +483,9 @@ static int ipu_add_client_devices(struct platform_device *pdev)
 	fbdata = plat_data->fb_head0_platform_data;
 	if (fbdata) {
 		fbdata->ipu_channel_bg =
-			MX51_IPU_CHANNEL_MEM_BG_SYNC;
+			MX5_IPU_CHANNEL_MEM_BG_SYNC;
 		fbdata->ipu_channel_fg =
-			MX51_IPU_CHANNEL_MEM_FG_SYNC;
+			MX5_IPU_CHANNEL_MEM_FG_SYNC;
 		fbdata->dc_channel = 5;
 		fbdata->dp_channel = IPU_DP_FLOW_SYNC;
 
@@ -539,7 +496,7 @@ static int ipu_add_client_devices(struct platform_device *pdev)
 	fbdata = plat_data->fb_head1_platform_data;
 	if (fbdata) {
 		fbdata->ipu_channel_bg =
-			MX51_IPU_CHANNEL_MEM_DC_SYNC;
+			MX5_IPU_CHANNEL_MEM_DC_SYNC;
 		fbdata->ipu_channel_fg = -1;
 		fbdata->dc_channel = 1;
 		fbdata->dp_channel = -1;
@@ -554,6 +511,7 @@ static int ipu_add_client_devices(struct platform_device *pdev)
 static int __devinit ipu_probe(struct platform_device *pdev)
 {
 	struct resource *res;
+	struct imx_ipuv3_platform_data *plat_data = pdev->dev.platform_data;
 	unsigned long ipu_base;
 	int ret, irq1, irq2;
 
@@ -586,10 +544,6 @@ static int __devinit ipu_probe(struct platform_device *pdev)
 		goto failed_ioremap2;
 	}
 
-	ret = ipu_mipi_setup();
-	if (ret)
-		goto failed_mipi_setup;
-
 	ipu_clk = clk_get(&pdev->dev, "ipu");
 	if (IS_ERR(ipu_clk)) {
 		ret = PTR_ERR(ipu_clk);
@@ -613,7 +567,13 @@ static int __devinit ipu_probe(struct platform_device *pdev)
 		goto failed_request_irq2;
 	}
 
-	ipu_reset();
+	if (plat_data->init) {
+		ret = plat_data->init();
+		if (ret)
+			goto failed_plat_init;
+	}
+
+	ipu_mem_reset();
 
 	ret = ipu_submodules_init(pdev, ipu_base, ipu_clk);
 	if (ret)
@@ -634,6 +594,7 @@ static int __devinit ipu_probe(struct platform_device *pdev)
 
 failed_add_clients:
 	ipu_submodules_exit(pdev, ipu_base);
+failed_plat_init:
 failed_submodules_init:
 	free_irq(irq2, &pdev->dev);
 failed_request_irq2:
@@ -642,7 +603,6 @@ failed_request_irq2:
 failed_request_irq1:
 	clk_put(ipu_clk);
 failed_clk_get:
-failed_mipi_setup:
 	iounmap(ipu_idmac_reg);
 failed_ioremap2:
 	iounmap(ipu_cm_reg);
diff --git a/drivers/mfd/imx-ipu-v3/ipu-prv.h b/drivers/mfd/imx-ipu-v3/ipu-prv.h
index 339b554..8469337 100644
--- a/drivers/mfd/imx-ipu-v3/ipu-prv.h
+++ b/drivers/mfd/imx-ipu-v3/ipu-prv.h
@@ -21,22 +21,22 @@
 #include <linux/platform_device.h>
 #include <mach/hardware.h>
 
-#define MX51_IPU_CHANNEL_CSI0			 0
-#define MX51_IPU_CHANNEL_CSI1			 1
-#define MX51_IPU_CHANNEL_CSI2			 2
-#define MX51_IPU_CHANNEL_CSI3			 3
-#define MX51_IPU_CHANNEL_MEM_BG_SYNC		23
-#define MX51_IPU_CHANNEL_MEM_FG_SYNC		27
-#define MX51_IPU_CHANNEL_MEM_DC_SYNC		28
-#define MX51_IPU_CHANNEL_MEM_FG_SYNC_ALPHA	31
-#define MX51_IPU_CHANNEL_MEM_DC_ASYNC		41
-#define MX51_IPU_CHANNEL_ROT_ENC_MEM		45
-#define MX51_IPU_CHANNEL_ROT_VF_MEM		46
-#define MX51_IPU_CHANNEL_ROT_PP_MEM		47
-#define MX51_IPU_CHANNEL_ROT_ENC_MEM_OUT	48
-#define MX51_IPU_CHANNEL_ROT_VF_MEM_OUT		49
-#define MX51_IPU_CHANNEL_ROT_PP_MEM_OUT		50
-#define MX51_IPU_CHANNEL_MEM_BG_SYNC_ALPHA	51
+#define MX5_IPU_CHANNEL_CSI0			 0
+#define MX5_IPU_CHANNEL_CSI1			 1
+#define MX5_IPU_CHANNEL_CSI2			 2
+#define MX5_IPU_CHANNEL_CSI3			 3
+#define MX5_IPU_CHANNEL_MEM_BG_SYNC		23
+#define MX5_IPU_CHANNEL_MEM_FG_SYNC		27
+#define MX5_IPU_CHANNEL_MEM_DC_SYNC		28
+#define MX5_IPU_CHANNEL_MEM_FG_SYNC_ALPHA	31
+#define MX5_IPU_CHANNEL_MEM_DC_ASYNC		41
+#define MX5_IPU_CHANNEL_ROT_ENC_MEM		45
+#define MX5_IPU_CHANNEL_ROT_VF_MEM		46
+#define MX5_IPU_CHANNEL_ROT_PP_MEM		47
+#define MX5_IPU_CHANNEL_ROT_ENC_MEM_OUT	48
+#define MX5_IPU_CHANNEL_ROT_VF_MEM_OUT		49
+#define MX5_IPU_CHANNEL_ROT_PP_MEM_OUT		50
+#define MX5_IPU_CHANNEL_MEM_BG_SYNC_ALPHA	51
 
 #define IPU_DISP0_BASE		0x00000000
 #define IPU_MCU_T_DEFAULT	8
-- 
1.7.1





More information about the linux-arm-kernel mailing list