All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC] ARM: Exynos4: Integrate IOMMU aware DMA-mapping
@ 2012-04-11 14:36 ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-11 14:36 UTC (permalink / raw)
  To: linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu
  Cc: Marek Szyprowski, Kyungmin Park, Arnd Bergmann, Joerg Roedel,
	Russell King - ARM Linux, Chunsang Jeong, Krishna Reddy,
	KyongHo Cho, Andrzej Pietrasiewicz, Benjamin Herrenschmidt,
	Konrad Rzeszutek Wilk, Hiroshi Doyu, Subash Patel

Hi!

This is an example of the IOMMU aware DMA-mapping implementation usage
on a Samsung Exynos4 based NURI board. The ARM DMA-mapping IOMMU aware
implementation is available in the [1] thread: 

This patch essentially registers DMA-mmaping/IOMMU support for FIMC and
MFC devices and performs some tweaks in clocks hierarchy to get SYSMMU
driver working correctly.

The drivers have been tested with mainline V4L2 drivers for FIMC and MFC
hardware.

For easier testing I've created a separate kernel branch with all
required prerequisite patches. It is based on lastest kgene/for-next
branch and is available on my git repository:

git://git.linaro.org/people/mszyprowski/linux-dma-mapping.git 3.4-rc2-arm-dma-v8-samsung

This patch requires the following items:
1. ARM DMA-mapping patches [1]
2. Exynos SYSMMU driver v12 [2]
3. Exynos SYSMMU driver runtime pm fixes
4. Exynos4 gen_pd power domain driver fixes

Runtime pm and power domain patches are required on Samsung Nuri board,
but might be optional on boards where bootloader doesn't disable all
devices on boot.

[1] http://www.spinics.net/lists/linux-arch/msg17331.html
[2] https://lkml.org/lkml/2012/3/15/51

Best regards
Marek Szyprowski
Samsung Poland R&D Center


Patch summary:

Marek Szyprowski (1):
  ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface

 arch/arm/mach-exynos/Kconfig               |    1 +
 arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
 arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
 arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
 drivers/iommu/Kconfig                      |    1 +
 5 files changed, 84 insertions(+), 29 deletions(-)

-- 
1.7.1.569.g6f426

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH/RFC] ARM: Exynos4: Integrate IOMMU aware DMA-mapping
@ 2012-04-11 14:36 ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-11 14:36 UTC (permalink / raw)
  To: linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu
  Cc: Marek Szyprowski, Kyungmin Park, Arnd Bergmann, Joerg Roedel,
	Russell King - ARM Linux, Chunsang Jeong, Krishna Reddy,
	KyongHo Cho, Andrzej Pietrasiewicz, Benjamin Herrenschmidt,
	Konrad Rzeszutek Wilk, Hiroshi Doyu, Subash Patel

Hi!

This is an example of the IOMMU aware DMA-mapping implementation usage
on a Samsung Exynos4 based NURI board. The ARM DMA-mapping IOMMU aware
implementation is available in the [1] thread: 

This patch essentially registers DMA-mmaping/IOMMU support for FIMC and
MFC devices and performs some tweaks in clocks hierarchy to get SYSMMU
driver working correctly.

The drivers have been tested with mainline V4L2 drivers for FIMC and MFC
hardware.

For easier testing I've created a separate kernel branch with all
required prerequisite patches. It is based on lastest kgene/for-next
branch and is available on my git repository:

git://git.linaro.org/people/mszyprowski/linux-dma-mapping.git 3.4-rc2-arm-dma-v8-samsung

This patch requires the following items:
1. ARM DMA-mapping patches [1]
2. Exynos SYSMMU driver v12 [2]
3. Exynos SYSMMU driver runtime pm fixes
4. Exynos4 gen_pd power domain driver fixes

Runtime pm and power domain patches are required on Samsung Nuri board,
but might be optional on boards where bootloader doesn't disable all
devices on boot.

[1] http://www.spinics.net/lists/linux-arch/msg17331.html
[2] https://lkml.org/lkml/2012/3/15/51

Best regards
Marek Szyprowski
Samsung Poland R&D Center


Patch summary:

Marek Szyprowski (1):
  ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface

 arch/arm/mach-exynos/Kconfig               |    1 +
 arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
 arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
 arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
 drivers/iommu/Kconfig                      |    1 +
 5 files changed, 84 insertions(+), 29 deletions(-)

-- 
1.7.1.569.g6f426

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH/RFC] ARM: Exynos4: Integrate IOMMU aware DMA-mapping
@ 2012-04-11 14:36 ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-11 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

This is an example of the IOMMU aware DMA-mapping implementation usage
on a Samsung Exynos4 based NURI board. The ARM DMA-mapping IOMMU aware
implementation is available in the [1] thread: 

This patch essentially registers DMA-mmaping/IOMMU support for FIMC and
MFC devices and performs some tweaks in clocks hierarchy to get SYSMMU
driver working correctly.

The drivers have been tested with mainline V4L2 drivers for FIMC and MFC
hardware.

For easier testing I've created a separate kernel branch with all
required prerequisite patches. It is based on lastest kgene/for-next
branch and is available on my git repository:

git://git.linaro.org/people/mszyprowski/linux-dma-mapping.git 3.4-rc2-arm-dma-v8-samsung

This patch requires the following items:
1. ARM DMA-mapping patches [1]
2. Exynos SYSMMU driver v12 [2]
3. Exynos SYSMMU driver runtime pm fixes
4. Exynos4 gen_pd power domain driver fixes

Runtime pm and power domain patches are required on Samsung Nuri board,
but might be optional on boards where bootloader doesn't disable all
devices on boot.

[1] http://www.spinics.net/lists/linux-arch/msg17331.html
[2] https://lkml.org/lkml/2012/3/15/51

Best regards
Marek Szyprowski
Samsung Poland R&D Center


Patch summary:

Marek Szyprowski (1):
  ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface

 arch/arm/mach-exynos/Kconfig               |    1 +
 arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
 arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
 arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
 drivers/iommu/Kconfig                      |    1 +
 5 files changed, 84 insertions(+), 29 deletions(-)

-- 
1.7.1.569.g6f426

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-11 14:36   ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-11 14:36 UTC (permalink / raw)
  To: linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu
  Cc: Marek Szyprowski, Kyungmin Park, Arnd Bergmann, Joerg Roedel,
	Russell King - ARM Linux, Chunsang Jeong, Krishna Reddy,
	KyongHo Cho, Andrzej Pietrasiewicz, Benjamin Herrenschmidt,
	Konrad Rzeszutek Wilk, Hiroshi Doyu, Subash Patel

This patch provides an provides setup code which assigns IOMMU controllers
to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them.
It has been tested on Samsung Exynos4 platform, NURI board.

Most of the work is done in the s5p_sysmmu_late_init() function, which
first assigns SYSMMU controller to respective client device and then
creates IO address space mapping structures. In this example 128 MiB of
address space is created at 0x20000000 for most of the devices. IO address
allocation precision is set to 2^4 pages, so all small allocations will be
aligned to 64 pages. This reduces the size of the io address space bitmap
to 4 KiB.

To solve the clock dependency issues, parent clocks have been added to each
SYSMMU controller bus clock. This models the true hardware behavior,
because client's device bus clock also gates the respective sysmmu bus
clock.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-exynos/Kconfig               |    1 +
 arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
 arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
 arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
 drivers/iommu/Kconfig                      |    1 +
 5 files changed, 84 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 801c738..25b9ba5 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -288,6 +288,7 @@ config MACH_NURI
 	select S5P_DEV_USB_EHCI
 	select S5P_SETUP_MIPIPHY
 	select EXYNOS4_DEV_DMA
+	select EXYNOS_DEV_SYSMMU
 	select EXYNOS4_SETUP_FIMC
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
index 29ae4df..fe459a3 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = {
 
 static struct clk exynos4_init_clocks_off[] = {
 	{
-		.name		= "timers",
-		.parent		= &exynos4_clk_aclk_100.clk,
-		.enable		= exynos4_clk_ip_peril_ctrl,
-		.ctrlbit	= (1<<24),
-	}, {
-		.name		= "csis",
-		.devname	= "s5p-mipi-csis.0",
-		.enable		= exynos4_clk_ip_cam_ctrl,
-		.ctrlbit	= (1 << 4),
-		.parent		= &exynos4_clk_gate_cam,
-	}, {
-		.name		= "csis",
-		.devname	= "s5p-mipi-csis.1",
-		.enable		= exynos4_clk_ip_cam_ctrl,
-		.ctrlbit	= (1 << 5),
-		.parent		= &exynos4_clk_gate_cam,
-	}, {
-		.name		= "jpeg",
-		.id		= 0,
-		.enable		= exynos4_clk_ip_cam_ctrl,
-		.ctrlbit	= (1 << 6),
-		.parent		= &exynos4_clk_gate_cam,
-	}, {
 		.name		= "fimc",
 		.devname	= "exynos4-fimc.0",
 		.enable		= exynos4_clk_ip_cam_ctrl,
@@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = {
 		.ctrlbit	= (1 << 3),
 		.parent		= &exynos4_clk_gate_cam,
 	}, {
+		.name		= "mfc",
+		.devname	= "s5p-mfc",
+		.enable		= exynos4_clk_ip_mfc_ctrl,
+		.ctrlbit	= (1 << 0),
+		.parent		= &exynos4_clk_gate_mfc,
+	}, {
+		.name		= "timers",
+		.parent		= &exynos4_clk_aclk_100.clk,
+		.enable		= exynos4_clk_ip_peril_ctrl,
+		.ctrlbit	= (1<<24),
+	}, {
+		.name		= "csis",
+		.devname	= "s5p-mipi-csis.0",
+		.enable		= exynos4_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 4),
+		.parent		= &exynos4_clk_gate_cam,
+	}, {
+		.name		= "csis",
+		.devname	= "s5p-mipi-csis.1",
+		.enable		= exynos4_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 5),
+		.parent		= &exynos4_clk_gate_cam,
+	}, {
+		.name		= "jpeg",
+		.id		= 0,
+		.enable		= exynos4_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 6),
+		.parent		= &exynos4_clk_gate_cam,
+	}, {
 		.name		= "hsmmc",
 		.devname	= "exynos4-sdhci.0",
 		.parent		= &exynos4_clk_aclk_133.clk,
@@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = {
 		.ctrlbit	= (1 << 0),
 		.parent		= &exynos4_clk_gate_lcd0,
 	}, {
-		.name		= "mfc",
-		.devname	= "s5p-mfc",
-		.enable		= exynos4_clk_ip_mfc_ctrl,
-		.ctrlbit	= (1 << 0),
-		.parent		= &exynos4_clk_gate_mfc,
-	}, {
 		.name		= "i2c",
 		.devname	= "s3c2440-i2c.0",
 		.parent		= &exynos4_clk_aclk_100.clk,
@@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = {
 		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
 		.enable		= exynos4_clk_ip_mfc_ctrl,
 		.ctrlbit	= (1 << 1),
+		.parent		= &exynos4_init_clocks_off[4],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
 		.enable		= exynos4_clk_ip_mfc_ctrl,
 		.ctrlbit	= (1 << 2),
+		.parent		= &exynos4_init_clocks_off[4],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(tv, 2),
@@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = {
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 7),
+		.parent		= &exynos4_init_clocks_off[0],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 8),
+		.parent		= &exynos4_init_clocks_off[1],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 9),
+		.parent		= &exynos4_init_clocks_off[2],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc3, 8),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 10),
+		.parent		= &exynos4_init_clocks_off[3],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimd0, 10),
diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
index 3544638..31f2d6ca 100644
--- a/arch/arm/mach-exynos/dev-sysmmu.c
+++ b/arch/arm/mach-exynos/dev-sysmmu.c
@@ -12,12 +12,15 @@
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <plat/cpu.h>
+#include <plat/devs.h>
 
 #include <mach/map.h>
 #include <mach/irqs.h>
 #include <mach/sysmmu.h>
+#include <asm/dma-iommu.h>
 
 static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
 
@@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void)
  * see pm_domain.c, which use arch_initcall()
  */
 core_initcall(init_sysmmu_platform_device);
+#ifdef CONFIG_ARM_DMA_USE_IOMMU
+int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
+				    unsigned int size, int order)
+{
+	struct dma_iommu_mapping *mapping;
+	if (!client)
+		return 0;
+	mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
+	if (!mapping)
+		return -ENOMEM;
+	client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL);
+	dma_set_max_seg_size(client, 0xffffffffu);
+	arm_iommu_attach_device(client, mapping);
+	return 0;
+}
+
+/*
+ * s5p_sysmmu_late_init
+ * Create DMA-mapping IOMMU context for specified devices. This function must
+ * be called later, once SYSMMU driver gets registered and probed.
+ */
+static int __init s5p_sysmmu_late_init(void)
+{
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc_l.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc_r.dev);
+
+	s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
+
+	return 0;
+}
+device_initcall(s5p_sysmmu_late_init);
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
index 998daf2..07cae3a 100644
--- a/arch/arm/mach-exynos/include/mach/sysmmu.h
+++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
@@ -57,6 +57,9 @@ static inline void platform_set_sysmmu(
 }
 #endif
 
+int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
+				    unsigned int size, int order);
+
 #else /* !CONFIG_EXYNOS_DEV_SYSMMU */
 #define platform_set_sysmmu(dev, sysmmu) do { } while (0)
 #endif
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 3b745bb..223e31e 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -166,6 +166,7 @@ config EXYNOS_IOMMU
 	bool "Exynos IOMMU Support"
 	depends on EXYNOS_DEV_SYSMMU
 	select IOMMU_API
+	select ARM_DMA_USE_IOMMU
 	help
 	  Support for the IOMMU(System MMU) of Samsung Exynos application
 	  processor family. This enables H/W multimedia accellerators to see
-- 
1.7.1.569.g6f426

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-11 14:36   ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-11 14:36 UTC (permalink / raw)
  To: linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu
  Cc: Marek Szyprowski, Kyungmin Park, Arnd Bergmann, Joerg Roedel,
	Russell King - ARM Linux, Chunsang Jeong, Krishna Reddy,
	KyongHo Cho, Andrzej Pietrasiewicz, Benjamin Herrenschmidt,
	Konrad Rzeszutek Wilk, Hiroshi Doyu, Subash Patel

This patch provides an provides setup code which assigns IOMMU controllers
to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them.
It has been tested on Samsung Exynos4 platform, NURI board.

Most of the work is done in the s5p_sysmmu_late_init() function, which
first assigns SYSMMU controller to respective client device and then
creates IO address space mapping structures. In this example 128 MiB of
address space is created at 0x20000000 for most of the devices. IO address
allocation precision is set to 2^4 pages, so all small allocations will be
aligned to 64 pages. This reduces the size of the io address space bitmap
to 4 KiB.

To solve the clock dependency issues, parent clocks have been added to each
SYSMMU controller bus clock. This models the true hardware behavior,
because client's device bus clock also gates the respective sysmmu bus
clock.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-exynos/Kconfig               |    1 +
 arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
 arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
 arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
 drivers/iommu/Kconfig                      |    1 +
 5 files changed, 84 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 801c738..25b9ba5 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -288,6 +288,7 @@ config MACH_NURI
 	select S5P_DEV_USB_EHCI
 	select S5P_SETUP_MIPIPHY
 	select EXYNOS4_DEV_DMA
+	select EXYNOS_DEV_SYSMMU
 	select EXYNOS4_SETUP_FIMC
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
index 29ae4df..fe459a3 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = {
 
 static struct clk exynos4_init_clocks_off[] = {
 	{
-		.name		= "timers",
-		.parent		= &exynos4_clk_aclk_100.clk,
-		.enable		= exynos4_clk_ip_peril_ctrl,
-		.ctrlbit	= (1<<24),
-	}, {
-		.name		= "csis",
-		.devname	= "s5p-mipi-csis.0",
-		.enable		= exynos4_clk_ip_cam_ctrl,
-		.ctrlbit	= (1 << 4),
-		.parent		= &exynos4_clk_gate_cam,
-	}, {
-		.name		= "csis",
-		.devname	= "s5p-mipi-csis.1",
-		.enable		= exynos4_clk_ip_cam_ctrl,
-		.ctrlbit	= (1 << 5),
-		.parent		= &exynos4_clk_gate_cam,
-	}, {
-		.name		= "jpeg",
-		.id		= 0,
-		.enable		= exynos4_clk_ip_cam_ctrl,
-		.ctrlbit	= (1 << 6),
-		.parent		= &exynos4_clk_gate_cam,
-	}, {
 		.name		= "fimc",
 		.devname	= "exynos4-fimc.0",
 		.enable		= exynos4_clk_ip_cam_ctrl,
@@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = {
 		.ctrlbit	= (1 << 3),
 		.parent		= &exynos4_clk_gate_cam,
 	}, {
+		.name		= "mfc",
+		.devname	= "s5p-mfc",
+		.enable		= exynos4_clk_ip_mfc_ctrl,
+		.ctrlbit	= (1 << 0),
+		.parent		= &exynos4_clk_gate_mfc,
+	}, {
+		.name		= "timers",
+		.parent		= &exynos4_clk_aclk_100.clk,
+		.enable		= exynos4_clk_ip_peril_ctrl,
+		.ctrlbit	= (1<<24),
+	}, {
+		.name		= "csis",
+		.devname	= "s5p-mipi-csis.0",
+		.enable		= exynos4_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 4),
+		.parent		= &exynos4_clk_gate_cam,
+	}, {
+		.name		= "csis",
+		.devname	= "s5p-mipi-csis.1",
+		.enable		= exynos4_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 5),
+		.parent		= &exynos4_clk_gate_cam,
+	}, {
+		.name		= "jpeg",
+		.id		= 0,
+		.enable		= exynos4_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 6),
+		.parent		= &exynos4_clk_gate_cam,
+	}, {
 		.name		= "hsmmc",
 		.devname	= "exynos4-sdhci.0",
 		.parent		= &exynos4_clk_aclk_133.clk,
@@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = {
 		.ctrlbit	= (1 << 0),
 		.parent		= &exynos4_clk_gate_lcd0,
 	}, {
-		.name		= "mfc",
-		.devname	= "s5p-mfc",
-		.enable		= exynos4_clk_ip_mfc_ctrl,
-		.ctrlbit	= (1 << 0),
-		.parent		= &exynos4_clk_gate_mfc,
-	}, {
 		.name		= "i2c",
 		.devname	= "s3c2440-i2c.0",
 		.parent		= &exynos4_clk_aclk_100.clk,
@@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = {
 		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
 		.enable		= exynos4_clk_ip_mfc_ctrl,
 		.ctrlbit	= (1 << 1),
+		.parent		= &exynos4_init_clocks_off[4],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
 		.enable		= exynos4_clk_ip_mfc_ctrl,
 		.ctrlbit	= (1 << 2),
+		.parent		= &exynos4_init_clocks_off[4],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(tv, 2),
@@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = {
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 7),
+		.parent		= &exynos4_init_clocks_off[0],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 8),
+		.parent		= &exynos4_init_clocks_off[1],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 9),
+		.parent		= &exynos4_init_clocks_off[2],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc3, 8),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 10),
+		.parent		= &exynos4_init_clocks_off[3],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimd0, 10),
diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
index 3544638..31f2d6ca 100644
--- a/arch/arm/mach-exynos/dev-sysmmu.c
+++ b/arch/arm/mach-exynos/dev-sysmmu.c
@@ -12,12 +12,15 @@
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <plat/cpu.h>
+#include <plat/devs.h>
 
 #include <mach/map.h>
 #include <mach/irqs.h>
 #include <mach/sysmmu.h>
+#include <asm/dma-iommu.h>
 
 static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
 
@@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void)
  * see pm_domain.c, which use arch_initcall()
  */
 core_initcall(init_sysmmu_platform_device);
+#ifdef CONFIG_ARM_DMA_USE_IOMMU
+int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
+				    unsigned int size, int order)
+{
+	struct dma_iommu_mapping *mapping;
+	if (!client)
+		return 0;
+	mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
+	if (!mapping)
+		return -ENOMEM;
+	client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL);
+	dma_set_max_seg_size(client, 0xffffffffu);
+	arm_iommu_attach_device(client, mapping);
+	return 0;
+}
+
+/*
+ * s5p_sysmmu_late_init
+ * Create DMA-mapping IOMMU context for specified devices. This function must
+ * be called later, once SYSMMU driver gets registered and probed.
+ */
+static int __init s5p_sysmmu_late_init(void)
+{
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc_l.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc_r.dev);
+
+	s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
+
+	return 0;
+}
+device_initcall(s5p_sysmmu_late_init);
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
index 998daf2..07cae3a 100644
--- a/arch/arm/mach-exynos/include/mach/sysmmu.h
+++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
@@ -57,6 +57,9 @@ static inline void platform_set_sysmmu(
 }
 #endif
 
+int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
+				    unsigned int size, int order);
+
 #else /* !CONFIG_EXYNOS_DEV_SYSMMU */
 #define platform_set_sysmmu(dev, sysmmu) do { } while (0)
 #endif
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 3b745bb..223e31e 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -166,6 +166,7 @@ config EXYNOS_IOMMU
 	bool "Exynos IOMMU Support"
 	depends on EXYNOS_DEV_SYSMMU
 	select IOMMU_API
+	select ARM_DMA_USE_IOMMU
 	help
 	  Support for the IOMMU(System MMU) of Samsung Exynos application
 	  processor family. This enables H/W multimedia accellerators to see
-- 
1.7.1.569.g6f426


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-11 14:36   ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-11 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

This patch provides an provides setup code which assigns IOMMU controllers
to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them.
It has been tested on Samsung Exynos4 platform, NURI board.

Most of the work is done in the s5p_sysmmu_late_init() function, which
first assigns SYSMMU controller to respective client device and then
creates IO address space mapping structures. In this example 128 MiB of
address space is created at 0x20000000 for most of the devices. IO address
allocation precision is set to 2^4 pages, so all small allocations will be
aligned to 64 pages. This reduces the size of the io address space bitmap
to 4 KiB.

To solve the clock dependency issues, parent clocks have been added to each
SYSMMU controller bus clock. This models the true hardware behavior,
because client's device bus clock also gates the respective sysmmu bus
clock.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-exynos/Kconfig               |    1 +
 arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
 arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
 arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
 drivers/iommu/Kconfig                      |    1 +
 5 files changed, 84 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 801c738..25b9ba5 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -288,6 +288,7 @@ config MACH_NURI
 	select S5P_DEV_USB_EHCI
 	select S5P_SETUP_MIPIPHY
 	select EXYNOS4_DEV_DMA
+	select EXYNOS_DEV_SYSMMU
 	select EXYNOS4_SETUP_FIMC
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
index 29ae4df..fe459a3 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = {
 
 static struct clk exynos4_init_clocks_off[] = {
 	{
-		.name		= "timers",
-		.parent		= &exynos4_clk_aclk_100.clk,
-		.enable		= exynos4_clk_ip_peril_ctrl,
-		.ctrlbit	= (1<<24),
-	}, {
-		.name		= "csis",
-		.devname	= "s5p-mipi-csis.0",
-		.enable		= exynos4_clk_ip_cam_ctrl,
-		.ctrlbit	= (1 << 4),
-		.parent		= &exynos4_clk_gate_cam,
-	}, {
-		.name		= "csis",
-		.devname	= "s5p-mipi-csis.1",
-		.enable		= exynos4_clk_ip_cam_ctrl,
-		.ctrlbit	= (1 << 5),
-		.parent		= &exynos4_clk_gate_cam,
-	}, {
-		.name		= "jpeg",
-		.id		= 0,
-		.enable		= exynos4_clk_ip_cam_ctrl,
-		.ctrlbit	= (1 << 6),
-		.parent		= &exynos4_clk_gate_cam,
-	}, {
 		.name		= "fimc",
 		.devname	= "exynos4-fimc.0",
 		.enable		= exynos4_clk_ip_cam_ctrl,
@@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = {
 		.ctrlbit	= (1 << 3),
 		.parent		= &exynos4_clk_gate_cam,
 	}, {
+		.name		= "mfc",
+		.devname	= "s5p-mfc",
+		.enable		= exynos4_clk_ip_mfc_ctrl,
+		.ctrlbit	= (1 << 0),
+		.parent		= &exynos4_clk_gate_mfc,
+	}, {
+		.name		= "timers",
+		.parent		= &exynos4_clk_aclk_100.clk,
+		.enable		= exynos4_clk_ip_peril_ctrl,
+		.ctrlbit	= (1<<24),
+	}, {
+		.name		= "csis",
+		.devname	= "s5p-mipi-csis.0",
+		.enable		= exynos4_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 4),
+		.parent		= &exynos4_clk_gate_cam,
+	}, {
+		.name		= "csis",
+		.devname	= "s5p-mipi-csis.1",
+		.enable		= exynos4_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 5),
+		.parent		= &exynos4_clk_gate_cam,
+	}, {
+		.name		= "jpeg",
+		.id		= 0,
+		.enable		= exynos4_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 6),
+		.parent		= &exynos4_clk_gate_cam,
+	}, {
 		.name		= "hsmmc",
 		.devname	= "exynos4-sdhci.0",
 		.parent		= &exynos4_clk_aclk_133.clk,
@@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = {
 		.ctrlbit	= (1 << 0),
 		.parent		= &exynos4_clk_gate_lcd0,
 	}, {
-		.name		= "mfc",
-		.devname	= "s5p-mfc",
-		.enable		= exynos4_clk_ip_mfc_ctrl,
-		.ctrlbit	= (1 << 0),
-		.parent		= &exynos4_clk_gate_mfc,
-	}, {
 		.name		= "i2c",
 		.devname	= "s3c2440-i2c.0",
 		.parent		= &exynos4_clk_aclk_100.clk,
@@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = {
 		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
 		.enable		= exynos4_clk_ip_mfc_ctrl,
 		.ctrlbit	= (1 << 1),
+		.parent		= &exynos4_init_clocks_off[4],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
 		.enable		= exynos4_clk_ip_mfc_ctrl,
 		.ctrlbit	= (1 << 2),
+		.parent		= &exynos4_init_clocks_off[4],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(tv, 2),
@@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = {
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 7),
+		.parent		= &exynos4_init_clocks_off[0],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 8),
+		.parent		= &exynos4_init_clocks_off[1],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 9),
+		.parent		= &exynos4_init_clocks_off[2],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimc3, 8),
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 10),
+		.parent		= &exynos4_init_clocks_off[3],
 	}, {
 		.name		= SYSMMU_CLOCK_NAME,
 		.devname	= SYSMMU_CLOCK_DEVNAME(fimd0, 10),
diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
index 3544638..31f2d6ca 100644
--- a/arch/arm/mach-exynos/dev-sysmmu.c
+++ b/arch/arm/mach-exynos/dev-sysmmu.c
@@ -12,12 +12,15 @@
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <plat/cpu.h>
+#include <plat/devs.h>
 
 #include <mach/map.h>
 #include <mach/irqs.h>
 #include <mach/sysmmu.h>
+#include <asm/dma-iommu.h>
 
 static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
 
@@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void)
  * see pm_domain.c, which use arch_initcall()
  */
 core_initcall(init_sysmmu_platform_device);
+#ifdef CONFIG_ARM_DMA_USE_IOMMU
+int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
+				    unsigned int size, int order)
+{
+	struct dma_iommu_mapping *mapping;
+	if (!client)
+		return 0;
+	mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
+	if (!mapping)
+		return -ENOMEM;
+	client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL);
+	dma_set_max_seg_size(client, 0xffffffffu);
+	arm_iommu_attach_device(client, mapping);
+	return 0;
+}
+
+/*
+ * s5p_sysmmu_late_init
+ * Create DMA-mapping IOMMU context for specified devices. This function must
+ * be called later, once SYSMMU driver gets registered and probed.
+ */
+static int __init s5p_sysmmu_late_init(void)
+{
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc_l.dev);
+	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc_r.dev);
+
+	s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
+	s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
+
+	return 0;
+}
+device_initcall(s5p_sysmmu_late_init);
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
index 998daf2..07cae3a 100644
--- a/arch/arm/mach-exynos/include/mach/sysmmu.h
+++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
@@ -57,6 +57,9 @@ static inline void platform_set_sysmmu(
 }
 #endif
 
+int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
+				    unsigned int size, int order);
+
 #else /* !CONFIG_EXYNOS_DEV_SYSMMU */
 #define platform_set_sysmmu(dev, sysmmu) do { } while (0)
 #endif
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 3b745bb..223e31e 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -166,6 +166,7 @@ config EXYNOS_IOMMU
 	bool "Exynos IOMMU Support"
 	depends on EXYNOS_DEV_SYSMMU
 	select IOMMU_API
+	select ARM_DMA_USE_IOMMU
 	help
 	  Support for the IOMMU(System MMU) of Samsung Exynos application
 	  processor family. This enables H/W multimedia accellerators to see
-- 
1.7.1.569.g6f426

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12  9:05     ` Subash Patel
  0 siblings, 0 replies; 24+ messages in thread
From: Subash Patel @ 2012-04-12  9:05 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu,
	Kyungmin Park, Arnd Bergmann, Joerg Roedel,
	Russell King - ARM Linux, Chunsang Jeong, Krishna Reddy,
	KyongHo Cho, Andrzej Pietrasiewicz, Benjamin Herrenschmidt,
	Konrad Rzeszutek Wilk, Hiroshi Doyu

Hello Marek,

On 04/11/2012 08:06 PM, Marek Szyprowski wrote:
> This patch provides an provides setup code which assigns IOMMU controllers
> to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them.
> It has been tested on Samsung Exynos4 platform, NURI board.
>
> Most of the work is done in the s5p_sysmmu_late_init() function, which
> first assigns SYSMMU controller to respective client device and then
> creates IO address space mapping structures. In this example 128 MiB of
> address space is created at 0x20000000 for most of the devices. IO address
> allocation precision is set to 2^4 pages, so all small allocations will be
> aligned to 64 pages. This reduces the size of the io address space bitmap
> to 4 KiB.
>
> To solve the clock dependency issues, parent clocks have been added to each
> SYSMMU controller bus clock. This models the true hardware behavior,
> because client's device bus clock also gates the respective sysmmu bus
> clock.
>
> Signed-off-by: Marek Szyprowski<m.szyprowski@samsung.com>
> Acked-by: Kyungmin Park<kyungmin.park@samsung.com>
> ---
>   arch/arm/mach-exynos/Kconfig               |    1 +
>   arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
>   arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
>   arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
>   drivers/iommu/Kconfig                      |    1 +
>   5 files changed, 84 insertions(+), 29 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> index 801c738..25b9ba5 100644
> --- a/arch/arm/mach-exynos/Kconfig
> +++ b/arch/arm/mach-exynos/Kconfig
> @@ -288,6 +288,7 @@ config MACH_NURI
>   	select S5P_DEV_USB_EHCI
>   	select S5P_SETUP_MIPIPHY
>   	select EXYNOS4_DEV_DMA
> +	select EXYNOS_DEV_SYSMMU
>   	select EXYNOS4_SETUP_FIMC
>   	select EXYNOS4_SETUP_FIMD0
>   	select EXYNOS4_SETUP_I2C1
> diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
> index 29ae4df..fe459a3 100644
> --- a/arch/arm/mach-exynos/clock-exynos4.c
> +++ b/arch/arm/mach-exynos/clock-exynos4.c
> @@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = {
>
>   static struct clk exynos4_init_clocks_off[] = {
>   	{
> -		.name		= "timers",
> -		.parent		=&exynos4_clk_aclk_100.clk,
> -		.enable		= exynos4_clk_ip_peril_ctrl,
> -		.ctrlbit	= (1<<24),
> -	}, {
> -		.name		= "csis",
> -		.devname	= "s5p-mipi-csis.0",
> -		.enable		= exynos4_clk_ip_cam_ctrl,
> -		.ctrlbit	= (1<<  4),
> -		.parent		=&exynos4_clk_gate_cam,
> -	}, {
> -		.name		= "csis",
> -		.devname	= "s5p-mipi-csis.1",
> -		.enable		= exynos4_clk_ip_cam_ctrl,
> -		.ctrlbit	= (1<<  5),
> -		.parent		=&exynos4_clk_gate_cam,
> -	}, {
> -		.name		= "jpeg",
> -		.id		= 0,
> -		.enable		= exynos4_clk_ip_cam_ctrl,
> -		.ctrlbit	= (1<<  6),
> -		.parent		=&exynos4_clk_gate_cam,
> -	}, {
>   		.name		= "fimc",
>   		.devname	= "exynos4-fimc.0",
>   		.enable		= exynos4_clk_ip_cam_ctrl,
> @@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.ctrlbit	= (1<<  3),
>   		.parent		=&exynos4_clk_gate_cam,
>   	}, {
> +		.name		= "mfc",
> +		.devname	= "s5p-mfc",
> +		.enable		= exynos4_clk_ip_mfc_ctrl,
> +		.ctrlbit	= (1<<  0),
> +		.parent		=&exynos4_clk_gate_mfc,
> +	}, {
> +		.name		= "timers",
> +		.parent		=&exynos4_clk_aclk_100.clk,
> +		.enable		= exynos4_clk_ip_peril_ctrl,
> +		.ctrlbit	= (1<<24),
> +	}, {
> +		.name		= "csis",
> +		.devname	= "s5p-mipi-csis.0",
> +		.enable		= exynos4_clk_ip_cam_ctrl,
> +		.ctrlbit	= (1<<  4),
> +		.parent		=&exynos4_clk_gate_cam,
> +	}, {
> +		.name		= "csis",
> +		.devname	= "s5p-mipi-csis.1",
> +		.enable		= exynos4_clk_ip_cam_ctrl,
> +		.ctrlbit	= (1<<  5),
> +		.parent		=&exynos4_clk_gate_cam,
> +	}, {
> +		.name		= "jpeg",
> +		.id		= 0,
> +		.enable		= exynos4_clk_ip_cam_ctrl,
> +		.ctrlbit	= (1<<  6),
> +		.parent		=&exynos4_clk_gate_cam,
> +	}, {
>   		.name		= "hsmmc",
>   		.devname	= "exynos4-sdhci.0",
>   		.parent		=&exynos4_clk_aclk_133.clk,
> @@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.ctrlbit	= (1<<  0),
>   		.parent		=&exynos4_clk_gate_lcd0,
>   	}, {
> -		.name		= "mfc",
> -		.devname	= "s5p-mfc",
> -		.enable		= exynos4_clk_ip_mfc_ctrl,
> -		.ctrlbit	= (1<<  0),
> -		.parent		=&exynos4_clk_gate_mfc,
> -	}, {
>   		.name		= "i2c",
>   		.devname	= "s3c2440-i2c.0",
>   		.parent		=&exynos4_clk_aclk_100.clk,
> @@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
>   		.enable		= exynos4_clk_ip_mfc_ctrl,
>   		.ctrlbit	= (1<<  1),
> +		.parent		=&exynos4_init_clocks_off[4],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
>   		.enable		= exynos4_clk_ip_mfc_ctrl,
>   		.ctrlbit	= (1<<  2),
> +		.parent		=&exynos4_init_clocks_off[4],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(tv, 2),
> @@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  7),
> +		.parent		=&exynos4_init_clocks_off[0],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  8),
> +		.parent		=&exynos4_init_clocks_off[1],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  9),
> +		.parent		=&exynos4_init_clocks_off[2],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc3, 8),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  10),
> +		.parent		=&exynos4_init_clocks_off[3],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimd0, 10),
> diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
> index 3544638..31f2d6ca 100644
> --- a/arch/arm/mach-exynos/dev-sysmmu.c
> +++ b/arch/arm/mach-exynos/dev-sysmmu.c
> @@ -12,12 +12,15 @@
>
>   #include<linux/platform_device.h>
>   #include<linux/dma-mapping.h>
> +#include<linux/slab.h>
>
>   #include<plat/cpu.h>
> +#include<plat/devs.h>
>
>   #include<mach/map.h>
>   #include<mach/irqs.h>
>   #include<mach/sysmmu.h>
> +#include<asm/dma-iommu.h>
>
>   static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
>
> @@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void)
>    * see pm_domain.c, which use arch_initcall()
>    */
>   core_initcall(init_sysmmu_platform_device);
> +#ifdef CONFIG_ARM_DMA_USE_IOMMU
> +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
> +				    unsigned int size, int order)
> +{
> +	struct dma_iommu_mapping *mapping;
> +	if (!client)
> +		return 0;
> +	mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
> +	if (!mapping)
> +		return -ENOMEM;
> +	client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL);
> +	dma_set_max_seg_size(client, 0xffffffffu);
> +	arm_iommu_attach_device(client, mapping);
> +	return 0;
> +}
> +
> +/*
> + * s5p_sysmmu_late_init
> + * Create DMA-mapping IOMMU context for specified devices. This function must
> + * be called later, once SYSMMU driver gets registered and probed.
> + */
> +static int __init s5p_sysmmu_late_init(void)
> +{
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> +
> +	s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> +
> +	return 0;
> +}
> +device_initcall(s5p_sysmmu_late_init);

Shouldn't these things be specific to a SoC? With this RFC, it happens 
that you will predefine the IOMMU attachment and mapping information for 
devices in common location (dev-sysmmu.c)? This may lead to problems 
because there are some IP's with SYSMMU support in exynos5, but not 
available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used 
to do above declaration in individual machine file, which I think was 
more meaningful.

> +#endif
> diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
> index 998daf2..07cae3a 100644
> --- a/arch/arm/mach-exynos/include/mach/sysmmu.h
> +++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
> @@ -57,6 +57,9 @@ static inline void platform_set_sysmmu(
>   }
>   #endif
>
> +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
> +				    unsigned int size, int order);
> +
>   #else /* !CONFIG_EXYNOS_DEV_SYSMMU */
>   #define platform_set_sysmmu(dev, sysmmu) do { } while (0)
>   #endif
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 3b745bb..223e31e 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -166,6 +166,7 @@ config EXYNOS_IOMMU
>   	bool "Exynos IOMMU Support"
>   	depends on EXYNOS_DEV_SYSMMU
>   	select IOMMU_API
> +	select ARM_DMA_USE_IOMMU
>   	help
>   	  Support for the IOMMU(System MMU) of Samsung Exynos application
>   	  processor family. This enables H/W multimedia accellerators to see
Regards,
Subash

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12  9:05     ` Subash Patel
  0 siblings, 0 replies; 24+ messages in thread
From: Subash Patel @ 2012-04-12  9:05 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu,
	Kyungmin Park, Arnd Bergmann, Joerg Roedel,
	Russell King - ARM Linux, Chunsang Jeong, Krishna Reddy,
	KyongHo Cho, Andrzej Pietrasiewicz, Benjamin Herrenschmidt,
	Konrad Rzeszutek Wilk, Hiroshi Doyu

Hello Marek,

On 04/11/2012 08:06 PM, Marek Szyprowski wrote:
> This patch provides an provides setup code which assigns IOMMU controllers
> to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them.
> It has been tested on Samsung Exynos4 platform, NURI board.
>
> Most of the work is done in the s5p_sysmmu_late_init() function, which
> first assigns SYSMMU controller to respective client device and then
> creates IO address space mapping structures. In this example 128 MiB of
> address space is created at 0x20000000 for most of the devices. IO address
> allocation precision is set to 2^4 pages, so all small allocations will be
> aligned to 64 pages. This reduces the size of the io address space bitmap
> to 4 KiB.
>
> To solve the clock dependency issues, parent clocks have been added to each
> SYSMMU controller bus clock. This models the true hardware behavior,
> because client's device bus clock also gates the respective sysmmu bus
> clock.
>
> Signed-off-by: Marek Szyprowski<m.szyprowski@samsung.com>
> Acked-by: Kyungmin Park<kyungmin.park@samsung.com>
> ---
>   arch/arm/mach-exynos/Kconfig               |    1 +
>   arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
>   arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
>   arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
>   drivers/iommu/Kconfig                      |    1 +
>   5 files changed, 84 insertions(+), 29 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> index 801c738..25b9ba5 100644
> --- a/arch/arm/mach-exynos/Kconfig
> +++ b/arch/arm/mach-exynos/Kconfig
> @@ -288,6 +288,7 @@ config MACH_NURI
>   	select S5P_DEV_USB_EHCI
>   	select S5P_SETUP_MIPIPHY
>   	select EXYNOS4_DEV_DMA
> +	select EXYNOS_DEV_SYSMMU
>   	select EXYNOS4_SETUP_FIMC
>   	select EXYNOS4_SETUP_FIMD0
>   	select EXYNOS4_SETUP_I2C1
> diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
> index 29ae4df..fe459a3 100644
> --- a/arch/arm/mach-exynos/clock-exynos4.c
> +++ b/arch/arm/mach-exynos/clock-exynos4.c
> @@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = {
>
>   static struct clk exynos4_init_clocks_off[] = {
>   	{
> -		.name		= "timers",
> -		.parent		=&exynos4_clk_aclk_100.clk,
> -		.enable		= exynos4_clk_ip_peril_ctrl,
> -		.ctrlbit	= (1<<24),
> -	}, {
> -		.name		= "csis",
> -		.devname	= "s5p-mipi-csis.0",
> -		.enable		= exynos4_clk_ip_cam_ctrl,
> -		.ctrlbit	= (1<<  4),
> -		.parent		=&exynos4_clk_gate_cam,
> -	}, {
> -		.name		= "csis",
> -		.devname	= "s5p-mipi-csis.1",
> -		.enable		= exynos4_clk_ip_cam_ctrl,
> -		.ctrlbit	= (1<<  5),
> -		.parent		=&exynos4_clk_gate_cam,
> -	}, {
> -		.name		= "jpeg",
> -		.id		= 0,
> -		.enable		= exynos4_clk_ip_cam_ctrl,
> -		.ctrlbit	= (1<<  6),
> -		.parent		=&exynos4_clk_gate_cam,
> -	}, {
>   		.name		= "fimc",
>   		.devname	= "exynos4-fimc.0",
>   		.enable		= exynos4_clk_ip_cam_ctrl,
> @@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.ctrlbit	= (1<<  3),
>   		.parent		=&exynos4_clk_gate_cam,
>   	}, {
> +		.name		= "mfc",
> +		.devname	= "s5p-mfc",
> +		.enable		= exynos4_clk_ip_mfc_ctrl,
> +		.ctrlbit	= (1<<  0),
> +		.parent		=&exynos4_clk_gate_mfc,
> +	}, {
> +		.name		= "timers",
> +		.parent		=&exynos4_clk_aclk_100.clk,
> +		.enable		= exynos4_clk_ip_peril_ctrl,
> +		.ctrlbit	= (1<<24),
> +	}, {
> +		.name		= "csis",
> +		.devname	= "s5p-mipi-csis.0",
> +		.enable		= exynos4_clk_ip_cam_ctrl,
> +		.ctrlbit	= (1<<  4),
> +		.parent		=&exynos4_clk_gate_cam,
> +	}, {
> +		.name		= "csis",
> +		.devname	= "s5p-mipi-csis.1",
> +		.enable		= exynos4_clk_ip_cam_ctrl,
> +		.ctrlbit	= (1<<  5),
> +		.parent		=&exynos4_clk_gate_cam,
> +	}, {
> +		.name		= "jpeg",
> +		.id		= 0,
> +		.enable		= exynos4_clk_ip_cam_ctrl,
> +		.ctrlbit	= (1<<  6),
> +		.parent		=&exynos4_clk_gate_cam,
> +	}, {
>   		.name		= "hsmmc",
>   		.devname	= "exynos4-sdhci.0",
>   		.parent		=&exynos4_clk_aclk_133.clk,
> @@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.ctrlbit	= (1<<  0),
>   		.parent		=&exynos4_clk_gate_lcd0,
>   	}, {
> -		.name		= "mfc",
> -		.devname	= "s5p-mfc",
> -		.enable		= exynos4_clk_ip_mfc_ctrl,
> -		.ctrlbit	= (1<<  0),
> -		.parent		=&exynos4_clk_gate_mfc,
> -	}, {
>   		.name		= "i2c",
>   		.devname	= "s3c2440-i2c.0",
>   		.parent		=&exynos4_clk_aclk_100.clk,
> @@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
>   		.enable		= exynos4_clk_ip_mfc_ctrl,
>   		.ctrlbit	= (1<<  1),
> +		.parent		=&exynos4_init_clocks_off[4],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
>   		.enable		= exynos4_clk_ip_mfc_ctrl,
>   		.ctrlbit	= (1<<  2),
> +		.parent		=&exynos4_init_clocks_off[4],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(tv, 2),
> @@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  7),
> +		.parent		=&exynos4_init_clocks_off[0],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  8),
> +		.parent		=&exynos4_init_clocks_off[1],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  9),
> +		.parent		=&exynos4_init_clocks_off[2],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc3, 8),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  10),
> +		.parent		=&exynos4_init_clocks_off[3],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimd0, 10),
> diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
> index 3544638..31f2d6ca 100644
> --- a/arch/arm/mach-exynos/dev-sysmmu.c
> +++ b/arch/arm/mach-exynos/dev-sysmmu.c
> @@ -12,12 +12,15 @@
>
>   #include<linux/platform_device.h>
>   #include<linux/dma-mapping.h>
> +#include<linux/slab.h>
>
>   #include<plat/cpu.h>
> +#include<plat/devs.h>
>
>   #include<mach/map.h>
>   #include<mach/irqs.h>
>   #include<mach/sysmmu.h>
> +#include<asm/dma-iommu.h>
>
>   static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
>
> @@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void)
>    * see pm_domain.c, which use arch_initcall()
>    */
>   core_initcall(init_sysmmu_platform_device);
> +#ifdef CONFIG_ARM_DMA_USE_IOMMU
> +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
> +				    unsigned int size, int order)
> +{
> +	struct dma_iommu_mapping *mapping;
> +	if (!client)
> +		return 0;
> +	mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
> +	if (!mapping)
> +		return -ENOMEM;
> +	client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL);
> +	dma_set_max_seg_size(client, 0xffffffffu);
> +	arm_iommu_attach_device(client, mapping);
> +	return 0;
> +}
> +
> +/*
> + * s5p_sysmmu_late_init
> + * Create DMA-mapping IOMMU context for specified devices. This function must
> + * be called later, once SYSMMU driver gets registered and probed.
> + */
> +static int __init s5p_sysmmu_late_init(void)
> +{
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> +
> +	s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> +
> +	return 0;
> +}
> +device_initcall(s5p_sysmmu_late_init);

Shouldn't these things be specific to a SoC? With this RFC, it happens 
that you will predefine the IOMMU attachment and mapping information for 
devices in common location (dev-sysmmu.c)? This may lead to problems 
because there are some IP's with SYSMMU support in exynos5, but not 
available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used 
to do above declaration in individual machine file, which I think was 
more meaningful.

> +#endif
> diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
> index 998daf2..07cae3a 100644
> --- a/arch/arm/mach-exynos/include/mach/sysmmu.h
> +++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
> @@ -57,6 +57,9 @@ static inline void platform_set_sysmmu(
>   }
>   #endif
>
> +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
> +				    unsigned int size, int order);
> +
>   #else /* !CONFIG_EXYNOS_DEV_SYSMMU */
>   #define platform_set_sysmmu(dev, sysmmu) do { } while (0)
>   #endif
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 3b745bb..223e31e 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -166,6 +166,7 @@ config EXYNOS_IOMMU
>   	bool "Exynos IOMMU Support"
>   	depends on EXYNOS_DEV_SYSMMU
>   	select IOMMU_API
> +	select ARM_DMA_USE_IOMMU
>   	help
>   	  Support for the IOMMU(System MMU) of Samsung Exynos application
>   	  processor family. This enables H/W multimedia accellerators to see
Regards,
Subash

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12  9:05     ` Subash Patel
  0 siblings, 0 replies; 24+ messages in thread
From: Subash Patel @ 2012-04-12  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Marek,

On 04/11/2012 08:06 PM, Marek Szyprowski wrote:
> This patch provides an provides setup code which assigns IOMMU controllers
> to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them.
> It has been tested on Samsung Exynos4 platform, NURI board.
>
> Most of the work is done in the s5p_sysmmu_late_init() function, which
> first assigns SYSMMU controller to respective client device and then
> creates IO address space mapping structures. In this example 128 MiB of
> address space is created at 0x20000000 for most of the devices. IO address
> allocation precision is set to 2^4 pages, so all small allocations will be
> aligned to 64 pages. This reduces the size of the io address space bitmap
> to 4 KiB.
>
> To solve the clock dependency issues, parent clocks have been added to each
> SYSMMU controller bus clock. This models the true hardware behavior,
> because client's device bus clock also gates the respective sysmmu bus
> clock.
>
> Signed-off-by: Marek Szyprowski<m.szyprowski@samsung.com>
> Acked-by: Kyungmin Park<kyungmin.park@samsung.com>
> ---
>   arch/arm/mach-exynos/Kconfig               |    1 +
>   arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
>   arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
>   arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
>   drivers/iommu/Kconfig                      |    1 +
>   5 files changed, 84 insertions(+), 29 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> index 801c738..25b9ba5 100644
> --- a/arch/arm/mach-exynos/Kconfig
> +++ b/arch/arm/mach-exynos/Kconfig
> @@ -288,6 +288,7 @@ config MACH_NURI
>   	select S5P_DEV_USB_EHCI
>   	select S5P_SETUP_MIPIPHY
>   	select EXYNOS4_DEV_DMA
> +	select EXYNOS_DEV_SYSMMU
>   	select EXYNOS4_SETUP_FIMC
>   	select EXYNOS4_SETUP_FIMD0
>   	select EXYNOS4_SETUP_I2C1
> diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
> index 29ae4df..fe459a3 100644
> --- a/arch/arm/mach-exynos/clock-exynos4.c
> +++ b/arch/arm/mach-exynos/clock-exynos4.c
> @@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = {
>
>   static struct clk exynos4_init_clocks_off[] = {
>   	{
> -		.name		= "timers",
> -		.parent		=&exynos4_clk_aclk_100.clk,
> -		.enable		= exynos4_clk_ip_peril_ctrl,
> -		.ctrlbit	= (1<<24),
> -	}, {
> -		.name		= "csis",
> -		.devname	= "s5p-mipi-csis.0",
> -		.enable		= exynos4_clk_ip_cam_ctrl,
> -		.ctrlbit	= (1<<  4),
> -		.parent		=&exynos4_clk_gate_cam,
> -	}, {
> -		.name		= "csis",
> -		.devname	= "s5p-mipi-csis.1",
> -		.enable		= exynos4_clk_ip_cam_ctrl,
> -		.ctrlbit	= (1<<  5),
> -		.parent		=&exynos4_clk_gate_cam,
> -	}, {
> -		.name		= "jpeg",
> -		.id		= 0,
> -		.enable		= exynos4_clk_ip_cam_ctrl,
> -		.ctrlbit	= (1<<  6),
> -		.parent		=&exynos4_clk_gate_cam,
> -	}, {
>   		.name		= "fimc",
>   		.devname	= "exynos4-fimc.0",
>   		.enable		= exynos4_clk_ip_cam_ctrl,
> @@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.ctrlbit	= (1<<  3),
>   		.parent		=&exynos4_clk_gate_cam,
>   	}, {
> +		.name		= "mfc",
> +		.devname	= "s5p-mfc",
> +		.enable		= exynos4_clk_ip_mfc_ctrl,
> +		.ctrlbit	= (1<<  0),
> +		.parent		=&exynos4_clk_gate_mfc,
> +	}, {
> +		.name		= "timers",
> +		.parent		=&exynos4_clk_aclk_100.clk,
> +		.enable		= exynos4_clk_ip_peril_ctrl,
> +		.ctrlbit	= (1<<24),
> +	}, {
> +		.name		= "csis",
> +		.devname	= "s5p-mipi-csis.0",
> +		.enable		= exynos4_clk_ip_cam_ctrl,
> +		.ctrlbit	= (1<<  4),
> +		.parent		=&exynos4_clk_gate_cam,
> +	}, {
> +		.name		= "csis",
> +		.devname	= "s5p-mipi-csis.1",
> +		.enable		= exynos4_clk_ip_cam_ctrl,
> +		.ctrlbit	= (1<<  5),
> +		.parent		=&exynos4_clk_gate_cam,
> +	}, {
> +		.name		= "jpeg",
> +		.id		= 0,
> +		.enable		= exynos4_clk_ip_cam_ctrl,
> +		.ctrlbit	= (1<<  6),
> +		.parent		=&exynos4_clk_gate_cam,
> +	}, {
>   		.name		= "hsmmc",
>   		.devname	= "exynos4-sdhci.0",
>   		.parent		=&exynos4_clk_aclk_133.clk,
> @@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.ctrlbit	= (1<<  0),
>   		.parent		=&exynos4_clk_gate_lcd0,
>   	}, {
> -		.name		= "mfc",
> -		.devname	= "s5p-mfc",
> -		.enable		= exynos4_clk_ip_mfc_ctrl,
> -		.ctrlbit	= (1<<  0),
> -		.parent		=&exynos4_clk_gate_mfc,
> -	}, {
>   		.name		= "i2c",
>   		.devname	= "s3c2440-i2c.0",
>   		.parent		=&exynos4_clk_aclk_100.clk,
> @@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
>   		.enable		= exynos4_clk_ip_mfc_ctrl,
>   		.ctrlbit	= (1<<  1),
> +		.parent		=&exynos4_init_clocks_off[4],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
>   		.enable		= exynos4_clk_ip_mfc_ctrl,
>   		.ctrlbit	= (1<<  2),
> +		.parent		=&exynos4_init_clocks_off[4],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(tv, 2),
> @@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = {
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  7),
> +		.parent		=&exynos4_init_clocks_off[0],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  8),
> +		.parent		=&exynos4_init_clocks_off[1],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  9),
> +		.parent		=&exynos4_init_clocks_off[2],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc3, 8),
>   		.enable		= exynos4_clk_ip_cam_ctrl,
>   		.ctrlbit	= (1<<  10),
> +		.parent		=&exynos4_init_clocks_off[3],
>   	}, {
>   		.name		= SYSMMU_CLOCK_NAME,
>   		.devname	= SYSMMU_CLOCK_DEVNAME(fimd0, 10),
> diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
> index 3544638..31f2d6ca 100644
> --- a/arch/arm/mach-exynos/dev-sysmmu.c
> +++ b/arch/arm/mach-exynos/dev-sysmmu.c
> @@ -12,12 +12,15 @@
>
>   #include<linux/platform_device.h>
>   #include<linux/dma-mapping.h>
> +#include<linux/slab.h>
>
>   #include<plat/cpu.h>
> +#include<plat/devs.h>
>
>   #include<mach/map.h>
>   #include<mach/irqs.h>
>   #include<mach/sysmmu.h>
> +#include<asm/dma-iommu.h>
>
>   static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
>
> @@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void)
>    * see pm_domain.c, which use arch_initcall()
>    */
>   core_initcall(init_sysmmu_platform_device);
> +#ifdef CONFIG_ARM_DMA_USE_IOMMU
> +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
> +				    unsigned int size, int order)
> +{
> +	struct dma_iommu_mapping *mapping;
> +	if (!client)
> +		return 0;
> +	mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
> +	if (!mapping)
> +		return -ENOMEM;
> +	client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL);
> +	dma_set_max_seg_size(client, 0xffffffffu);
> +	arm_iommu_attach_device(client, mapping);
> +	return 0;
> +}
> +
> +/*
> + * s5p_sysmmu_late_init
> + * Create DMA-mapping IOMMU context for specified devices. This function must
> + * be called later, once SYSMMU driver gets registered and probed.
> + */
> +static int __init s5p_sysmmu_late_init(void)
> +{
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> +
> +	s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> +	s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> +
> +	return 0;
> +}
> +device_initcall(s5p_sysmmu_late_init);

Shouldn't these things be specific to a SoC? With this RFC, it happens 
that you will predefine the IOMMU attachment and mapping information for 
devices in common location (dev-sysmmu.c)? This may lead to problems 
because there are some IP's with SYSMMU support in exynos5, but not 
available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used 
to do above declaration in individual machine file, which I think was 
more meaningful.

> +#endif
> diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
> index 998daf2..07cae3a 100644
> --- a/arch/arm/mach-exynos/include/mach/sysmmu.h
> +++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
> @@ -57,6 +57,9 @@ static inline void platform_set_sysmmu(
>   }
>   #endif
>
> +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
> +				    unsigned int size, int order);
> +
>   #else /* !CONFIG_EXYNOS_DEV_SYSMMU */
>   #define platform_set_sysmmu(dev, sysmmu) do { } while (0)
>   #endif
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 3b745bb..223e31e 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -166,6 +166,7 @@ config EXYNOS_IOMMU
>   	bool "Exynos IOMMU Support"
>   	depends on EXYNOS_DEV_SYSMMU
>   	select IOMMU_API
> +	select ARM_DMA_USE_IOMMU
>   	help
>   	  Support for the IOMMU(System MMU) of Samsung Exynos application
>   	  processor family. This enables H/W multimedia accellerators to see
Regards,
Subash

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
  2012-04-12  9:05     ` Subash Patel
  (?)
@ 2012-04-12  9:18       ` Marek Szyprowski
  -1 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-12  9:18 UTC (permalink / raw)
  To: 'Subash Patel'
  Cc: linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu,
	'Kyungmin Park', 'Arnd Bergmann',
	'Joerg Roedel', 'Russell King - ARM Linux',
	'Chunsang Jeong', 'Krishna Reddy',
	'KyongHo Cho',
	Andrzej Pietrasiewicz, 'Benjamin Herrenschmidt',
	'Konrad Rzeszutek Wilk', 'Hiroshi Doyu'

Hi Subash,

On Thursday, April 12, 2012 11:06 AM Subash Patel wrote:

> On 04/11/2012 08:06 PM, Marek Szyprowski wrote:
> > This patch provides an provides setup code which assigns IOMMU controllers
> > to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them.
> > It has been tested on Samsung Exynos4 platform, NURI board.
> >
> > Most of the work is done in the s5p_sysmmu_late_init() function, which
> > first assigns SYSMMU controller to respective client device and then
> > creates IO address space mapping structures. In this example 128 MiB of
> > address space is created at 0x20000000 for most of the devices. IO address
> > allocation precision is set to 2^4 pages, so all small allocations will be
> > aligned to 64 pages. This reduces the size of the io address space bitmap
> > to 4 KiB.
> >
> > To solve the clock dependency issues, parent clocks have been added to each
> > SYSMMU controller bus clock. This models the true hardware behavior,
> > because client's device bus clock also gates the respective sysmmu bus
> > clock.
> >
> > Signed-off-by: Marek Szyprowski<m.szyprowski@samsung.com>
> > Acked-by: Kyungmin Park<kyungmin.park@samsung.com>
> > ---
> >   arch/arm/mach-exynos/Kconfig               |    1 +
> >   arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
> >   arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
> >   arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
> >   drivers/iommu/Kconfig                      |    1 +
> >   5 files changed, 84 insertions(+), 29 deletions(-)
> >
> > diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> > index 801c738..25b9ba5 100644
> > --- a/arch/arm/mach-exynos/Kconfig
> > +++ b/arch/arm/mach-exynos/Kconfig
> > @@ -288,6 +288,7 @@ config MACH_NURI
> >   	select S5P_DEV_USB_EHCI
> >   	select S5P_SETUP_MIPIPHY
> >   	select EXYNOS4_DEV_DMA
> > +	select EXYNOS_DEV_SYSMMU
> >   	select EXYNOS4_SETUP_FIMC
> >   	select EXYNOS4_SETUP_FIMD0
> >   	select EXYNOS4_SETUP_I2C1
> > diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
> > index 29ae4df..fe459a3 100644
> > --- a/arch/arm/mach-exynos/clock-exynos4.c
> > +++ b/arch/arm/mach-exynos/clock-exynos4.c
> > @@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = {
> >
> >   static struct clk exynos4_init_clocks_off[] = {
> >   	{
> > -		.name		= "timers",
> > -		.parent		=&exynos4_clk_aclk_100.clk,
> > -		.enable		= exynos4_clk_ip_peril_ctrl,
> > -		.ctrlbit	= (1<<24),
> > -	}, {
> > -		.name		= "csis",
> > -		.devname	= "s5p-mipi-csis.0",
> > -		.enable		= exynos4_clk_ip_cam_ctrl,
> > -		.ctrlbit	= (1<<  4),
> > -		.parent		=&exynos4_clk_gate_cam,
> > -	}, {
> > -		.name		= "csis",
> > -		.devname	= "s5p-mipi-csis.1",
> > -		.enable		= exynos4_clk_ip_cam_ctrl,
> > -		.ctrlbit	= (1<<  5),
> > -		.parent		=&exynos4_clk_gate_cam,
> > -	}, {
> > -		.name		= "jpeg",
> > -		.id		= 0,
> > -		.enable		= exynos4_clk_ip_cam_ctrl,
> > -		.ctrlbit	= (1<<  6),
> > -		.parent		=&exynos4_clk_gate_cam,
> > -	}, {
> >   		.name		= "fimc",
> >   		.devname	= "exynos4-fimc.0",
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> > @@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.ctrlbit	= (1<<  3),
> >   		.parent		=&exynos4_clk_gate_cam,
> >   	}, {
> > +		.name		= "mfc",
> > +		.devname	= "s5p-mfc",
> > +		.enable		= exynos4_clk_ip_mfc_ctrl,
> > +		.ctrlbit	= (1<<  0),
> > +		.parent		=&exynos4_clk_gate_mfc,
> > +	}, {
> > +		.name		= "timers",
> > +		.parent		=&exynos4_clk_aclk_100.clk,
> > +		.enable		= exynos4_clk_ip_peril_ctrl,
> > +		.ctrlbit	= (1<<24),
> > +	}, {
> > +		.name		= "csis",
> > +		.devname	= "s5p-mipi-csis.0",
> > +		.enable		= exynos4_clk_ip_cam_ctrl,
> > +		.ctrlbit	= (1<<  4),
> > +		.parent		=&exynos4_clk_gate_cam,
> > +	}, {
> > +		.name		= "csis",
> > +		.devname	= "s5p-mipi-csis.1",
> > +		.enable		= exynos4_clk_ip_cam_ctrl,
> > +		.ctrlbit	= (1<<  5),
> > +		.parent		=&exynos4_clk_gate_cam,
> > +	}, {
> > +		.name		= "jpeg",
> > +		.id		= 0,
> > +		.enable		= exynos4_clk_ip_cam_ctrl,
> > +		.ctrlbit	= (1<<  6),
> > +		.parent		=&exynos4_clk_gate_cam,
> > +	}, {
> >   		.name		= "hsmmc",
> >   		.devname	= "exynos4-sdhci.0",
> >   		.parent		=&exynos4_clk_aclk_133.clk,
> > @@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.ctrlbit	= (1<<  0),
> >   		.parent		=&exynos4_clk_gate_lcd0,
> >   	}, {
> > -		.name		= "mfc",
> > -		.devname	= "s5p-mfc",
> > -		.enable		= exynos4_clk_ip_mfc_ctrl,
> > -		.ctrlbit	= (1<<  0),
> > -		.parent		=&exynos4_clk_gate_mfc,
> > -	}, {
> >   		.name		= "i2c",
> >   		.devname	= "s3c2440-i2c.0",
> >   		.parent		=&exynos4_clk_aclk_100.clk,
> > @@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
> >   		.enable		= exynos4_clk_ip_mfc_ctrl,
> >   		.ctrlbit	= (1<<  1),
> > +		.parent		=&exynos4_init_clocks_off[4],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
> >   		.enable		= exynos4_clk_ip_mfc_ctrl,
> >   		.ctrlbit	= (1<<  2),
> > +		.parent		=&exynos4_init_clocks_off[4],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(tv, 2),
> > @@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  7),
> > +		.parent		=&exynos4_init_clocks_off[0],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  8),
> > +		.parent		=&exynos4_init_clocks_off[1],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  9),
> > +		.parent		=&exynos4_init_clocks_off[2],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc3, 8),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  10),
> > +		.parent		=&exynos4_init_clocks_off[3],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimd0, 10),
> > diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
> > index 3544638..31f2d6ca 100644
> > --- a/arch/arm/mach-exynos/dev-sysmmu.c
> > +++ b/arch/arm/mach-exynos/dev-sysmmu.c
> > @@ -12,12 +12,15 @@
> >
> >   #include<linux/platform_device.h>
> >   #include<linux/dma-mapping.h>
> > +#include<linux/slab.h>
> >
> >   #include<plat/cpu.h>
> > +#include<plat/devs.h>
> >
> >   #include<mach/map.h>
> >   #include<mach/irqs.h>
> >   #include<mach/sysmmu.h>
> > +#include<asm/dma-iommu.h>
> >
> >   static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
> >
> > @@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void)
> >    * see pm_domain.c, which use arch_initcall()
> >    */
> >   core_initcall(init_sysmmu_platform_device);
> > +#ifdef CONFIG_ARM_DMA_USE_IOMMU
> > +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
> > +				    unsigned int size, int order)
> > +{
> > +	struct dma_iommu_mapping *mapping;
> > +	if (!client)
> > +		return 0;
> > +	mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
> > +	if (!mapping)
> > +		return -ENOMEM;
> > +	client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL);
> > +	dma_set_max_seg_size(client, 0xffffffffu);
> > +	arm_iommu_attach_device(client, mapping);
> > +	return 0;
> > +}
> > +
> > +/*
> > + * s5p_sysmmu_late_init
> > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > + * be called later, once SYSMMU driver gets registered and probed.
> > + */
> > +static int __init s5p_sysmmu_late_init(void)
> > +{
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > +
> > +	s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > +
> > +	return 0;
> > +}
> > +device_initcall(s5p_sysmmu_late_init);
> 
> Shouldn't these things be specific to a SoC? With this RFC, it happens
> that you will predefine the IOMMU attachment and mapping information for
> devices in common location (dev-sysmmu.c)? This may lead to problems
> because there are some IP's with SYSMMU support in exynos5, but not
> available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> to do above declaration in individual machine file, which I think was
> more meaningful.

Right, I simplified the code too much. Keeping these definitions inside machine 
files was a better idea. I completely forgot that Exynos sub-platform now covers
both Exynos4 and Exynos5 SoC families.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12  9:18       ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-12  9:18 UTC (permalink / raw)
  To: 'Subash Patel'
  Cc: linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu,
	'Kyungmin Park', 'Arnd Bergmann',
	'Joerg Roedel', 'Russell King - ARM Linux',
	'Chunsang Jeong', 'Krishna Reddy',
	'KyongHo Cho',
	Andrzej Pietrasiewicz, 'Benjamin Herrenschmidt',
	'Konrad Rzeszutek Wilk', 'Hiroshi Doyu'

Hi Subash,

On Thursday, April 12, 2012 11:06 AM Subash Patel wrote:

> On 04/11/2012 08:06 PM, Marek Szyprowski wrote:
> > This patch provides an provides setup code which assigns IOMMU controllers
> > to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them.
> > It has been tested on Samsung Exynos4 platform, NURI board.
> >
> > Most of the work is done in the s5p_sysmmu_late_init() function, which
> > first assigns SYSMMU controller to respective client device and then
> > creates IO address space mapping structures. In this example 128 MiB of
> > address space is created at 0x20000000 for most of the devices. IO address
> > allocation precision is set to 2^4 pages, so all small allocations will be
> > aligned to 64 pages. This reduces the size of the io address space bitmap
> > to 4 KiB.
> >
> > To solve the clock dependency issues, parent clocks have been added to each
> > SYSMMU controller bus clock. This models the true hardware behavior,
> > because client's device bus clock also gates the respective sysmmu bus
> > clock.
> >
> > Signed-off-by: Marek Szyprowski<m.szyprowski@samsung.com>
> > Acked-by: Kyungmin Park<kyungmin.park@samsung.com>
> > ---
> >   arch/arm/mach-exynos/Kconfig               |    1 +
> >   arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
> >   arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
> >   arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
> >   drivers/iommu/Kconfig                      |    1 +
> >   5 files changed, 84 insertions(+), 29 deletions(-)
> >
> > diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> > index 801c738..25b9ba5 100644
> > --- a/arch/arm/mach-exynos/Kconfig
> > +++ b/arch/arm/mach-exynos/Kconfig
> > @@ -288,6 +288,7 @@ config MACH_NURI
> >   	select S5P_DEV_USB_EHCI
> >   	select S5P_SETUP_MIPIPHY
> >   	select EXYNOS4_DEV_DMA
> > +	select EXYNOS_DEV_SYSMMU
> >   	select EXYNOS4_SETUP_FIMC
> >   	select EXYNOS4_SETUP_FIMD0
> >   	select EXYNOS4_SETUP_I2C1
> > diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
> > index 29ae4df..fe459a3 100644
> > --- a/arch/arm/mach-exynos/clock-exynos4.c
> > +++ b/arch/arm/mach-exynos/clock-exynos4.c
> > @@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = {
> >
> >   static struct clk exynos4_init_clocks_off[] = {
> >   	{
> > -		.name		= "timers",
> > -		.parent		=&exynos4_clk_aclk_100.clk,
> > -		.enable		= exynos4_clk_ip_peril_ctrl,
> > -		.ctrlbit	= (1<<24),
> > -	}, {
> > -		.name		= "csis",
> > -		.devname	= "s5p-mipi-csis.0",
> > -		.enable		= exynos4_clk_ip_cam_ctrl,
> > -		.ctrlbit	= (1<<  4),
> > -		.parent		=&exynos4_clk_gate_cam,
> > -	}, {
> > -		.name		= "csis",
> > -		.devname	= "s5p-mipi-csis.1",
> > -		.enable		= exynos4_clk_ip_cam_ctrl,
> > -		.ctrlbit	= (1<<  5),
> > -		.parent		=&exynos4_clk_gate_cam,
> > -	}, {
> > -		.name		= "jpeg",
> > -		.id		= 0,
> > -		.enable		= exynos4_clk_ip_cam_ctrl,
> > -		.ctrlbit	= (1<<  6),
> > -		.parent		=&exynos4_clk_gate_cam,
> > -	}, {
> >   		.name		= "fimc",
> >   		.devname	= "exynos4-fimc.0",
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> > @@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.ctrlbit	= (1<<  3),
> >   		.parent		=&exynos4_clk_gate_cam,
> >   	}, {
> > +		.name		= "mfc",
> > +		.devname	= "s5p-mfc",
> > +		.enable		= exynos4_clk_ip_mfc_ctrl,
> > +		.ctrlbit	= (1<<  0),
> > +		.parent		=&exynos4_clk_gate_mfc,
> > +	}, {
> > +		.name		= "timers",
> > +		.parent		=&exynos4_clk_aclk_100.clk,
> > +		.enable		= exynos4_clk_ip_peril_ctrl,
> > +		.ctrlbit	= (1<<24),
> > +	}, {
> > +		.name		= "csis",
> > +		.devname	= "s5p-mipi-csis.0",
> > +		.enable		= exynos4_clk_ip_cam_ctrl,
> > +		.ctrlbit	= (1<<  4),
> > +		.parent		=&exynos4_clk_gate_cam,
> > +	}, {
> > +		.name		= "csis",
> > +		.devname	= "s5p-mipi-csis.1",
> > +		.enable		= exynos4_clk_ip_cam_ctrl,
> > +		.ctrlbit	= (1<<  5),
> > +		.parent		=&exynos4_clk_gate_cam,
> > +	}, {
> > +		.name		= "jpeg",
> > +		.id		= 0,
> > +		.enable		= exynos4_clk_ip_cam_ctrl,
> > +		.ctrlbit	= (1<<  6),
> > +		.parent		=&exynos4_clk_gate_cam,
> > +	}, {
> >   		.name		= "hsmmc",
> >   		.devname	= "exynos4-sdhci.0",
> >   		.parent		=&exynos4_clk_aclk_133.clk,
> > @@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.ctrlbit	= (1<<  0),
> >   		.parent		=&exynos4_clk_gate_lcd0,
> >   	}, {
> > -		.name		= "mfc",
> > -		.devname	= "s5p-mfc",
> > -		.enable		= exynos4_clk_ip_mfc_ctrl,
> > -		.ctrlbit	= (1<<  0),
> > -		.parent		=&exynos4_clk_gate_mfc,
> > -	}, {
> >   		.name		= "i2c",
> >   		.devname	= "s3c2440-i2c.0",
> >   		.parent		=&exynos4_clk_aclk_100.clk,
> > @@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
> >   		.enable		= exynos4_clk_ip_mfc_ctrl,
> >   		.ctrlbit	= (1<<  1),
> > +		.parent		=&exynos4_init_clocks_off[4],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
> >   		.enable		= exynos4_clk_ip_mfc_ctrl,
> >   		.ctrlbit	= (1<<  2),
> > +		.parent		=&exynos4_init_clocks_off[4],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(tv, 2),
> > @@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  7),
> > +		.parent		=&exynos4_init_clocks_off[0],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  8),
> > +		.parent		=&exynos4_init_clocks_off[1],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  9),
> > +		.parent		=&exynos4_init_clocks_off[2],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc3, 8),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  10),
> > +		.parent		=&exynos4_init_clocks_off[3],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimd0, 10),
> > diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
> > index 3544638..31f2d6ca 100644
> > --- a/arch/arm/mach-exynos/dev-sysmmu.c
> > +++ b/arch/arm/mach-exynos/dev-sysmmu.c
> > @@ -12,12 +12,15 @@
> >
> >   #include<linux/platform_device.h>
> >   #include<linux/dma-mapping.h>
> > +#include<linux/slab.h>
> >
> >   #include<plat/cpu.h>
> > +#include<plat/devs.h>
> >
> >   #include<mach/map.h>
> >   #include<mach/irqs.h>
> >   #include<mach/sysmmu.h>
> > +#include<asm/dma-iommu.h>
> >
> >   static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
> >
> > @@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void)
> >    * see pm_domain.c, which use arch_initcall()
> >    */
> >   core_initcall(init_sysmmu_platform_device);
> > +#ifdef CONFIG_ARM_DMA_USE_IOMMU
> > +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
> > +				    unsigned int size, int order)
> > +{
> > +	struct dma_iommu_mapping *mapping;
> > +	if (!client)
> > +		return 0;
> > +	mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
> > +	if (!mapping)
> > +		return -ENOMEM;
> > +	client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL);
> > +	dma_set_max_seg_size(client, 0xffffffffu);
> > +	arm_iommu_attach_device(client, mapping);
> > +	return 0;
> > +}
> > +
> > +/*
> > + * s5p_sysmmu_late_init
> > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > + * be called later, once SYSMMU driver gets registered and probed.
> > + */
> > +static int __init s5p_sysmmu_late_init(void)
> > +{
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > +
> > +	s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > +
> > +	return 0;
> > +}
> > +device_initcall(s5p_sysmmu_late_init);
> 
> Shouldn't these things be specific to a SoC? With this RFC, it happens
> that you will predefine the IOMMU attachment and mapping information for
> devices in common location (dev-sysmmu.c)? This may lead to problems
> because there are some IP's with SYSMMU support in exynos5, but not
> available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> to do above declaration in individual machine file, which I think was
> more meaningful.

Right, I simplified the code too much. Keeping these definitions inside machine 
files was a better idea. I completely forgot that Exynos sub-platform now covers
both Exynos4 and Exynos5 SoC families.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12  9:18       ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-12  9:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Subash,

On Thursday, April 12, 2012 11:06 AM Subash Patel wrote:

> On 04/11/2012 08:06 PM, Marek Szyprowski wrote:
> > This patch provides an provides setup code which assigns IOMMU controllers
> > to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them.
> > It has been tested on Samsung Exynos4 platform, NURI board.
> >
> > Most of the work is done in the s5p_sysmmu_late_init() function, which
> > first assigns SYSMMU controller to respective client device and then
> > creates IO address space mapping structures. In this example 128 MiB of
> > address space is created at 0x20000000 for most of the devices. IO address
> > allocation precision is set to 2^4 pages, so all small allocations will be
> > aligned to 64 pages. This reduces the size of the io address space bitmap
> > to 4 KiB.
> >
> > To solve the clock dependency issues, parent clocks have been added to each
> > SYSMMU controller bus clock. This models the true hardware behavior,
> > because client's device bus clock also gates the respective sysmmu bus
> > clock.
> >
> > Signed-off-by: Marek Szyprowski<m.szyprowski@samsung.com>
> > Acked-by: Kyungmin Park<kyungmin.park@samsung.com>
> > ---
> >   arch/arm/mach-exynos/Kconfig               |    1 +
> >   arch/arm/mach-exynos/clock-exynos4.c       |   64 +++++++++++++++-------------
> >   arch/arm/mach-exynos/dev-sysmmu.c          |   44 +++++++++++++++++++
> >   arch/arm/mach-exynos/include/mach/sysmmu.h |    3 +
> >   drivers/iommu/Kconfig                      |    1 +
> >   5 files changed, 84 insertions(+), 29 deletions(-)
> >
> > diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> > index 801c738..25b9ba5 100644
> > --- a/arch/arm/mach-exynos/Kconfig
> > +++ b/arch/arm/mach-exynos/Kconfig
> > @@ -288,6 +288,7 @@ config MACH_NURI
> >   	select S5P_DEV_USB_EHCI
> >   	select S5P_SETUP_MIPIPHY
> >   	select EXYNOS4_DEV_DMA
> > +	select EXYNOS_DEV_SYSMMU
> >   	select EXYNOS4_SETUP_FIMC
> >   	select EXYNOS4_SETUP_FIMD0
> >   	select EXYNOS4_SETUP_I2C1
> > diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
> > index 29ae4df..fe459a3 100644
> > --- a/arch/arm/mach-exynos/clock-exynos4.c
> > +++ b/arch/arm/mach-exynos/clock-exynos4.c
> > @@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = {
> >
> >   static struct clk exynos4_init_clocks_off[] = {
> >   	{
> > -		.name		= "timers",
> > -		.parent		=&exynos4_clk_aclk_100.clk,
> > -		.enable		= exynos4_clk_ip_peril_ctrl,
> > -		.ctrlbit	= (1<<24),
> > -	}, {
> > -		.name		= "csis",
> > -		.devname	= "s5p-mipi-csis.0",
> > -		.enable		= exynos4_clk_ip_cam_ctrl,
> > -		.ctrlbit	= (1<<  4),
> > -		.parent		=&exynos4_clk_gate_cam,
> > -	}, {
> > -		.name		= "csis",
> > -		.devname	= "s5p-mipi-csis.1",
> > -		.enable		= exynos4_clk_ip_cam_ctrl,
> > -		.ctrlbit	= (1<<  5),
> > -		.parent		=&exynos4_clk_gate_cam,
> > -	}, {
> > -		.name		= "jpeg",
> > -		.id		= 0,
> > -		.enable		= exynos4_clk_ip_cam_ctrl,
> > -		.ctrlbit	= (1<<  6),
> > -		.parent		=&exynos4_clk_gate_cam,
> > -	}, {
> >   		.name		= "fimc",
> >   		.devname	= "exynos4-fimc.0",
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> > @@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.ctrlbit	= (1<<  3),
> >   		.parent		=&exynos4_clk_gate_cam,
> >   	}, {
> > +		.name		= "mfc",
> > +		.devname	= "s5p-mfc",
> > +		.enable		= exynos4_clk_ip_mfc_ctrl,
> > +		.ctrlbit	= (1<<  0),
> > +		.parent		=&exynos4_clk_gate_mfc,
> > +	}, {
> > +		.name		= "timers",
> > +		.parent		=&exynos4_clk_aclk_100.clk,
> > +		.enable		= exynos4_clk_ip_peril_ctrl,
> > +		.ctrlbit	= (1<<24),
> > +	}, {
> > +		.name		= "csis",
> > +		.devname	= "s5p-mipi-csis.0",
> > +		.enable		= exynos4_clk_ip_cam_ctrl,
> > +		.ctrlbit	= (1<<  4),
> > +		.parent		=&exynos4_clk_gate_cam,
> > +	}, {
> > +		.name		= "csis",
> > +		.devname	= "s5p-mipi-csis.1",
> > +		.enable		= exynos4_clk_ip_cam_ctrl,
> > +		.ctrlbit	= (1<<  5),
> > +		.parent		=&exynos4_clk_gate_cam,
> > +	}, {
> > +		.name		= "jpeg",
> > +		.id		= 0,
> > +		.enable		= exynos4_clk_ip_cam_ctrl,
> > +		.ctrlbit	= (1<<  6),
> > +		.parent		=&exynos4_clk_gate_cam,
> > +	}, {
> >   		.name		= "hsmmc",
> >   		.devname	= "exynos4-sdhci.0",
> >   		.parent		=&exynos4_clk_aclk_133.clk,
> > @@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.ctrlbit	= (1<<  0),
> >   		.parent		=&exynos4_clk_gate_lcd0,
> >   	}, {
> > -		.name		= "mfc",
> > -		.devname	= "s5p-mfc",
> > -		.enable		= exynos4_clk_ip_mfc_ctrl,
> > -		.ctrlbit	= (1<<  0),
> > -		.parent		=&exynos4_clk_gate_mfc,
> > -	}, {
> >   		.name		= "i2c",
> >   		.devname	= "s3c2440-i2c.0",
> >   		.parent		=&exynos4_clk_aclk_100.clk,
> > @@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
> >   		.enable		= exynos4_clk_ip_mfc_ctrl,
> >   		.ctrlbit	= (1<<  1),
> > +		.parent		=&exynos4_init_clocks_off[4],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
> >   		.enable		= exynos4_clk_ip_mfc_ctrl,
> >   		.ctrlbit	= (1<<  2),
> > +		.parent		=&exynos4_init_clocks_off[4],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(tv, 2),
> > @@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = {
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  7),
> > +		.parent		=&exynos4_init_clocks_off[0],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  8),
> > +		.parent		=&exynos4_init_clocks_off[1],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  9),
> > +		.parent		=&exynos4_init_clocks_off[2],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimc3, 8),
> >   		.enable		= exynos4_clk_ip_cam_ctrl,
> >   		.ctrlbit	= (1<<  10),
> > +		.parent		=&exynos4_init_clocks_off[3],
> >   	}, {
> >   		.name		= SYSMMU_CLOCK_NAME,
> >   		.devname	= SYSMMU_CLOCK_DEVNAME(fimd0, 10),
> > diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
> > index 3544638..31f2d6ca 100644
> > --- a/arch/arm/mach-exynos/dev-sysmmu.c
> > +++ b/arch/arm/mach-exynos/dev-sysmmu.c
> > @@ -12,12 +12,15 @@
> >
> >   #include<linux/platform_device.h>
> >   #include<linux/dma-mapping.h>
> > +#include<linux/slab.h>
> >
> >   #include<plat/cpu.h>
> > +#include<plat/devs.h>
> >
> >   #include<mach/map.h>
> >   #include<mach/irqs.h>
> >   #include<mach/sysmmu.h>
> > +#include<asm/dma-iommu.h>
> >
> >   static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
> >
> > @@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void)
> >    * see pm_domain.c, which use arch_initcall()
> >    */
> >   core_initcall(init_sysmmu_platform_device);
> > +#ifdef CONFIG_ARM_DMA_USE_IOMMU
> > +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base,
> > +				    unsigned int size, int order)
> > +{
> > +	struct dma_iommu_mapping *mapping;
> > +	if (!client)
> > +		return 0;
> > +	mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
> > +	if (!mapping)
> > +		return -ENOMEM;
> > +	client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL);
> > +	dma_set_max_seg_size(client, 0xffffffffu);
> > +	arm_iommu_attach_device(client, mapping);
> > +	return 0;
> > +}
> > +
> > +/*
> > + * s5p_sysmmu_late_init
> > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > + * be called later, once SYSMMU driver gets registered and probed.
> > + */
> > +static int __init s5p_sysmmu_late_init(void)
> > +{
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > +	platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > +
> > +	s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > +	s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > +
> > +	return 0;
> > +}
> > +device_initcall(s5p_sysmmu_late_init);
> 
> Shouldn't these things be specific to a SoC? With this RFC, it happens
> that you will predefine the IOMMU attachment and mapping information for
> devices in common location (dev-sysmmu.c)? This may lead to problems
> because there are some IP's with SYSMMU support in exynos5, but not
> available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> to do above declaration in individual machine file, which I think was
> more meaningful.

Right, I simplified the code too much. Keeping these definitions inside machine 
files was a better idea. I completely forgot that Exynos sub-platform now covers
both Exynos4 and Exynos5 SoC families.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 11:09         ` Arnd Bergmann
  0 siblings, 0 replies; 24+ messages in thread
From: Arnd Bergmann @ 2012-04-12 11:09 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: 'Subash Patel',
	linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu,
	'Kyungmin Park', 'Joerg Roedel',
	'Russell King - ARM Linux', 'Chunsang Jeong',
	'Krishna Reddy', 'KyongHo Cho',
	Andrzej Pietrasiewicz, 'Benjamin Herrenschmidt',
	'Konrad Rzeszutek Wilk', 'Hiroshi Doyu'

On Thursday 12 April 2012, Marek Szyprowski wrote:
> +
> > > +/*
> > > + * s5p_sysmmu_late_init
> > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > + * be called later, once SYSMMU driver gets registered and probed.
> > > + */
> > > +static int __init s5p_sysmmu_late_init(void)
> > > +{
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > +
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > +
> > > +   return 0;
> > > +}
> > > +device_initcall(s5p_sysmmu_late_init);
> > 
> > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > that you will predefine the IOMMU attachment and mapping information for
> > devices in common location (dev-sysmmu.c)? This may lead to problems
> > because there are some IP's with SYSMMU support in exynos5, but not
> > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > to do above declaration in individual machine file, which I think was
> > more meaningful.
> 
> Right, I simplified the code too much. Keeping these definitions inside machine 
> files was a better idea. I completely forgot that Exynos sub-platform now covers
> both Exynos4 and Exynos5 SoC families.

Ideally the information about iommu attachment should come from the
device tree. We have the "dma-ranges" properties that define how a dma
address space is mapped. I am not entirely sure how that works when you
have multiple IOMMUs and if that requires defining addititional properties,
but I think we should make it so that we don't have to hardcode specific
devices in the source.

	Arnd

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 11:09         ` Arnd Bergmann
  0 siblings, 0 replies; 24+ messages in thread
From: Arnd Bergmann @ 2012-04-12 11:09 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: 'Subash Patel',
	linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu,
	'Kyungmin Park', 'Joerg Roedel',
	'Russell King - ARM Linux', 'Chunsang Jeong',
	'Krishna Reddy', 'KyongHo Cho',
	Andrzej Pietrasiewicz, 'Benjamin Herrenschmidt',
	'Konrad Rzeszutek Wilk', 'Hiroshi Doyu'

On Thursday 12 April 2012, Marek Szyprowski wrote:
> +
> > > +/*
> > > + * s5p_sysmmu_late_init
> > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > + * be called later, once SYSMMU driver gets registered and probed.
> > > + */
> > > +static int __init s5p_sysmmu_late_init(void)
> > > +{
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > +
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > +
> > > +   return 0;
> > > +}
> > > +device_initcall(s5p_sysmmu_late_init);
> > 
> > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > that you will predefine the IOMMU attachment and mapping information for
> > devices in common location (dev-sysmmu.c)? This may lead to problems
> > because there are some IP's with SYSMMU support in exynos5, but not
> > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > to do above declaration in individual machine file, which I think was
> > more meaningful.
> 
> Right, I simplified the code too much. Keeping these definitions inside machine 
> files was a better idea. I completely forgot that Exynos sub-platform now covers
> both Exynos4 and Exynos5 SoC families.

Ideally the information about iommu attachment should come from the
device tree. We have the "dma-ranges" properties that define how a dma
address space is mapped. I am not entirely sure how that works when you
have multiple IOMMUs and if that requires defining addititional properties,
but I think we should make it so that we don't have to hardcode specific
devices in the source.

	Arnd

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 11:09         ` Arnd Bergmann
  0 siblings, 0 replies; 24+ messages in thread
From: Arnd Bergmann @ 2012-04-12 11:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 12 April 2012, Marek Szyprowski wrote:
> +
> > > +/*
> > > + * s5p_sysmmu_late_init
> > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > + * be called later, once SYSMMU driver gets registered and probed.
> > > + */
> > > +static int __init s5p_sysmmu_late_init(void)
> > > +{
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > +
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > +
> > > +   return 0;
> > > +}
> > > +device_initcall(s5p_sysmmu_late_init);
> > 
> > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > that you will predefine the IOMMU attachment and mapping information for
> > devices in common location (dev-sysmmu.c)? This may lead to problems
> > because there are some IP's with SYSMMU support in exynos5, but not
> > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > to do above declaration in individual machine file, which I think was
> > more meaningful.
> 
> Right, I simplified the code too much. Keeping these definitions inside machine 
> files was a better idea. I completely forgot that Exynos sub-platform now covers
> both Exynos4 and Exynos5 SoC families.

Ideally the information about iommu attachment should come from the
device tree. We have the "dma-ranges" properties that define how a dma
address space is mapped. I am not entirely sure how that works when you
have multiple IOMMUs and if that requires defining addititional properties,
but I think we should make it so that we don't have to hardcode specific
devices in the source.

	Arnd

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 12:13             ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-12 12:13 UTC (permalink / raw)
  To: 'Arnd Bergmann'
  Cc: linux-arch-u79uwXL29TY76Z2rM5mHXA,
	'Russell King - ARM Linux',
	'Benjamin Herrenschmidt', 'Subash Patel',
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	'Krishna Reddy',
	Andrzej Pietrasiewicz, 'Kyungmin Park',
	'KyongHo Cho', 'Chunsang Jeong',
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r





> -----Original Message-----
> From: Arnd Bergmann [mailto:arnd-r2nGTMty4D4@public.gmane.org]
> Sent: Thursday, April 12, 2012 1:09 PM
> To: Marek Szyprowski
> Cc: 'Subash Patel'; linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org; linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw@public.gmane.org;
> linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org; linux-arch-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org; 'Kyungmin
> Park'; 'Joerg Roedel'; 'Russell King - ARM Linux'; 'Chunsang Jeong'; 'Krishna Reddy'; 'KyongHo
> Cho'; Andrzej Pietrasiewicz; 'Benjamin Herrenschmidt'; 'Konrad Rzeszutek Wilk'; 'Hiroshi Doyu'
> Subject: Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
> 
> On Thursday 12 April 2012, Marek Szyprowski wrote:
> > +
> > > > +/*
> > > > + * s5p_sysmmu_late_init
> > > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > > + * be called later, once SYSMMU driver gets registered and probed.
> > > > + */
> > > > +static int __init s5p_sysmmu_late_init(void)
> > > > +{
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > > +
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +device_initcall(s5p_sysmmu_late_init);
> > >
> > > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > > that you will predefine the IOMMU attachment and mapping information for
> > > devices in common location (dev-sysmmu.c)? This may lead to problems
> > > because there are some IP's with SYSMMU support in exynos5, but not
> > > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > > to do above declaration in individual machine file, which I think was
> > > more meaningful.
> >
> > Right, I simplified the code too much. Keeping these definitions inside machine
> > files was a better idea. I completely forgot that Exynos sub-platform now covers
> > both Exynos4 and Exynos5 SoC families.
> 
> Ideally the information about iommu attachment should come from the
> device tree. We have the "dma-ranges" properties that define how a dma
> address space is mapped. I am not entirely sure how that works when you
> have multiple IOMMUs and if that requires defining addititional properties,
> but I think we should make it so that we don't have to hardcode specific
> devices in the source.

Right, until that time machine/board files are imho ok.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 12:13             ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-12 12:13 UTC (permalink / raw)
  To: 'Arnd Bergmann'
  Cc: 'Subash Patel',
	linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu,
	'Kyungmin Park', 'Joerg Roedel',
	'Russell King - ARM Linux', 'Chunsang Jeong',
	'Krishna Reddy', 'KyongHo Cho',
	Andrzej Pietrasiewicz, 'Benjamin Herrenschmidt',
	'Konrad Rzeszutek Wilk', 'Hiroshi Doyu'





> -----Original Message-----
> From: Arnd Bergmann [mailto:arnd@arndb.de]
> Sent: Thursday, April 12, 2012 1:09 PM
> To: Marek Szyprowski
> Cc: 'Subash Patel'; linux-arm-kernel@lists.infradead.org; linaro-mm-sig@lists.linaro.org;
> linux-mm@kvack.org; linux-arch@vger.kernel.org; iommu@lists.linux-foundation.org; 'Kyungmin
> Park'; 'Joerg Roedel'; 'Russell King - ARM Linux'; 'Chunsang Jeong'; 'Krishna Reddy'; 'KyongHo
> Cho'; Andrzej Pietrasiewicz; 'Benjamin Herrenschmidt'; 'Konrad Rzeszutek Wilk'; 'Hiroshi Doyu'
> Subject: Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
> 
> On Thursday 12 April 2012, Marek Szyprowski wrote:
> > +
> > > > +/*
> > > > + * s5p_sysmmu_late_init
> > > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > > + * be called later, once SYSMMU driver gets registered and probed.
> > > > + */
> > > > +static int __init s5p_sysmmu_late_init(void)
> > > > +{
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > > +
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +device_initcall(s5p_sysmmu_late_init);
> > >
> > > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > > that you will predefine the IOMMU attachment and mapping information for
> > > devices in common location (dev-sysmmu.c)? This may lead to problems
> > > because there are some IP's with SYSMMU support in exynos5, but not
> > > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > > to do above declaration in individual machine file, which I think was
> > > more meaningful.
> >
> > Right, I simplified the code too much. Keeping these definitions inside machine
> > files was a better idea. I completely forgot that Exynos sub-platform now covers
> > both Exynos4 and Exynos5 SoC families.
> 
> Ideally the information about iommu attachment should come from the
> device tree. We have the "dma-ranges" properties that define how a dma
> address space is mapped. I am not entirely sure how that works when you
> have multiple IOMMUs and if that requires defining addititional properties,
> but I think we should make it so that we don't have to hardcode specific
> devices in the source.

Right, until that time machine/board files are imho ok.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center



^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 12:13             ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-12 12:13 UTC (permalink / raw)
  To: 'Arnd Bergmann'
  Cc: 'Subash Patel',
	linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch, iommu,
	'Kyungmin Park', 'Joerg Roedel',
	'Russell King - ARM Linux', 'Chunsang Jeong',
	'Krishna Reddy', 'KyongHo Cho',
	Andrzej Pietrasiewicz, 'Benjamin Herrenschmidt',
	'Konrad Rzeszutek Wilk', 'Hiroshi Doyu'





> -----Original Message-----
> From: Arnd Bergmann [mailto:arnd@arndb.de]
> Sent: Thursday, April 12, 2012 1:09 PM
> To: Marek Szyprowski
> Cc: 'Subash Patel'; linux-arm-kernel@lists.infradead.org; linaro-mm-sig@lists.linaro.org;
> linux-mm@kvack.org; linux-arch@vger.kernel.org; iommu@lists.linux-foundation.org; 'Kyungmin
> Park'; 'Joerg Roedel'; 'Russell King - ARM Linux'; 'Chunsang Jeong'; 'Krishna Reddy'; 'KyongHo
> Cho'; Andrzej Pietrasiewicz; 'Benjamin Herrenschmidt'; 'Konrad Rzeszutek Wilk'; 'Hiroshi Doyu'
> Subject: Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
> 
> On Thursday 12 April 2012, Marek Szyprowski wrote:
> > +
> > > > +/*
> > > > + * s5p_sysmmu_late_init
> > > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > > + * be called later, once SYSMMU driver gets registered and probed.
> > > > + */
> > > > +static int __init s5p_sysmmu_late_init(void)
> > > > +{
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > > +
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +device_initcall(s5p_sysmmu_late_init);
> > >
> > > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > > that you will predefine the IOMMU attachment and mapping information for
> > > devices in common location (dev-sysmmu.c)? This may lead to problems
> > > because there are some IP's with SYSMMU support in exynos5, but not
> > > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > > to do above declaration in individual machine file, which I think was
> > > more meaningful.
> >
> > Right, I simplified the code too much. Keeping these definitions inside machine
> > files was a better idea. I completely forgot that Exynos sub-platform now covers
> > both Exynos4 and Exynos5 SoC families.
> 
> Ideally the information about iommu attachment should come from the
> device tree. We have the "dma-ranges" properties that define how a dma
> address space is mapped. I am not entirely sure how that works when you
> have multiple IOMMUs and if that requires defining addititional properties,
> but I think we should make it so that we don't have to hardcode specific
> devices in the source.

Right, until that time machine/board files are imho ok.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 12:13             ` Marek Szyprowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Szyprowski @ 2012-04-12 12:13 UTC (permalink / raw)
  To: linux-arm-kernel





> -----Original Message-----
> From: Arnd Bergmann [mailto:arnd at arndb.de]
> Sent: Thursday, April 12, 2012 1:09 PM
> To: Marek Szyprowski
> Cc: 'Subash Patel'; linux-arm-kernel at lists.infradead.org; linaro-mm-sig at lists.linaro.org;
> linux-mm at kvack.org; linux-arch at vger.kernel.org; iommu at lists.linux-foundation.org; 'Kyungmin
> Park'; 'Joerg Roedel'; 'Russell King - ARM Linux'; 'Chunsang Jeong'; 'Krishna Reddy'; 'KyongHo
> Cho'; Andrzej Pietrasiewicz; 'Benjamin Herrenschmidt'; 'Konrad Rzeszutek Wilk'; 'Hiroshi Doyu'
> Subject: Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
> 
> On Thursday 12 April 2012, Marek Szyprowski wrote:
> > +
> > > > +/*
> > > > + * s5p_sysmmu_late_init
> > > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > > + * be called later, once SYSMMU driver gets registered and probed.
> > > > + */
> > > > +static int __init s5p_sysmmu_late_init(void)
> > > > +{
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > > +
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +device_initcall(s5p_sysmmu_late_init);
> > >
> > > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > > that you will predefine the IOMMU attachment and mapping information for
> > > devices in common location (dev-sysmmu.c)? This may lead to problems
> > > because there are some IP's with SYSMMU support in exynos5, but not
> > > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > > to do above declaration in individual machine file, which I think was
> > > more meaningful.
> >
> > Right, I simplified the code too much. Keeping these definitions inside machine
> > files was a better idea. I completely forgot that Exynos sub-platform now covers
> > both Exynos4 and Exynos5 SoC families.
> 
> Ideally the information about iommu attachment should come from the
> device tree. We have the "dma-ranges" properties that define how a dma
> address space is mapped. I am not entirely sure how that works when you
> have multiple IOMMUs and if that requires defining addititional properties,
> but I think we should make it so that we don't have to hardcode specific
> devices in the source.

Right, until that time machine/board files are imho ok.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 12:38                 ` Hiroshi Doyu
  0 siblings, 0 replies; 24+ messages in thread
From: Hiroshi Doyu @ 2012-04-12 12:38 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arch-u79uwXL29TY76Z2rM5mHXA, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	subashrp-Re5JQEeQqe8AvxtiuMwx3w,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Krishna Reddy,
	andrzej.p-Sze3O3UU22JBDgjK7y7TUQ,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	pullip.cho-Sze3O3UU22JBDgjK7y7TUQ,
	chunsang.jeong-QSEj5FYQhm4dnm+yROfE0A,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

From: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Subject: RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
Date: Thu, 12 Apr 2012 14:13:37 +0200
Message-ID: <028f01cd18a5$b0721770$11564650$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

>
>
>
>
> > -----Original Message-----
> > From: Arnd Bergmann [mailto:arnd-r2nGTMty4D4@public.gmane.org]
> > Sent: Thursday, April 12, 2012 1:09 PM
> > To: Marek Szyprowski
> > Cc: 'Subash Patel'; linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org; linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw@public.gmane.org;
> > linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org; linux-arch-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org; 'Kyungmin
> > Park'; 'Joerg Roedel'; 'Russell King - ARM Linux'; 'Chunsang Jeong'; 'Krishna Reddy'; 'KyongHo
> > Cho'; Andrzej Pietrasiewicz; 'Benjamin Herrenschmidt'; 'Konrad Rzeszutek Wilk'; 'Hiroshi Doyu'
> > Subject: Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
> >
> > On Thursday 12 April 2012, Marek Szyprowski wrote:
> > > +
> > > > > +/*
> > > > > + * s5p_sysmmu_late_init
> > > > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > > > + * be called later, once SYSMMU driver gets registered and probed.
> > > > > + */
> > > > > +static int __init s5p_sysmmu_late_init(void)
> > > > > +{
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > > > +
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > > > +
> > > > > +   return 0;
> > > > > +}
> > > > > +device_initcall(s5p_sysmmu_late_init);
> > > >
> > > > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > > > that you will predefine the IOMMU attachment and mapping information for
> > > > devices in common location (dev-sysmmu.c)? This may lead to problems
> > > > because there are some IP's with SYSMMU support in exynos5, but not
> > > > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > > > to do above declaration in individual machine file, which I think was
> > > > more meaningful.
> > >
> > > Right, I simplified the code too much. Keeping these definitions inside machine
> > > files was a better idea. I completely forgot that Exynos sub-platform now covers
> > > both Exynos4 and Exynos5 SoC families.
> >
> > Ideally the information about iommu attachment should come from the
> > device tree. We have the "dma-ranges" properties that define how a dma
> > address space is mapped. I am not entirely sure how that works when you
> > have multiple IOMMUs and if that requires defining addititional properties,
> > but I think we should make it so that we don't have to hardcode specific
> > devices in the source.
>
> Right, until that time machine/board files are imho ok.

In Tegra30, there are quite many IOMMU attachable (platform)devices,
and it's quite nice for us to configure them (un)attached with address
range and IOMMU device ID(ASID) in DT in advance rather than inserting
the code to attach those devices here and there.

Experimentally I added some hook in platform_device_add() as below,
but apparently this won't be accepted.

From cb34373ebbf025e42ec6d8fea2e19e74ba41231e Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Date: Thu, 22 Mar 2012 16:06:27 +0200
Subject: [PATCH 1/1] ARM: dma-mapping: All platform_device DMA API'able

Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/mach-tegra/board-cardhu.c |    7 ++++++-
 arch/arm/mm/dma-mapping.c          |    5 ++++-
 drivers/base/platform.c            |   11 +++++++++--
 include/linux/device.h             |    2 ++
 4 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index 339011e..38f5292 100644
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ca5544e..5e6dbe0 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -758,6 +758,9 @@ size_t arm_iommu_iova_avail(struct device *dev)
 	size_t size = 0;
 	unsigned long start = 0;

+	BUG_ON(!dev);
+	BUG_ON(!mapping);
+
 	spin_lock_irqsave(&mapping->lock, flags);
 	while (1) {
 		unsigned long end;
@@ -1513,7 +1516,7 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
 	mapping->domain = iommu_domain_alloc(bus);
 	if (!mapping->domain)
 		goto err3;
-
+	bus->map = mapping;
 	kref_init(&mapping->kref);
 	return mapping;
 err3:
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 99a5272..4af431c 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -21,6 +21,8 @@
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>

+#include <asm/dma-iommu.h>
+
 #include "base.h"

 #define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
@@ -305,8 +307,13 @@ int platform_device_add(struct platform_device *pdev)
 		 dev_name(&pdev->dev), dev_name(pdev->dev.parent));

 	ret = device_add(&pdev->dev);
-	if (ret == 0)
-		return ret;
+	if (ret)
+		goto failed;
+
+	if (platform_bus_type.map)
+		arm_iommu_attach_device(&pdev->dev, platform_bus_type.map);
+
+	return 0;

  failed:
 	while (--i >= 0) {
diff --git a/include/linux/device.h b/include/linux/device.h
index 28c35f8..732611f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -34,6 +34,7 @@ struct subsys_private;
 struct bus_type;
 struct device_node;
 struct iommu_ops;
+struct dma_iommu_mapping;

 struct bus_attribute {
 	struct attribute	attr;
@@ -101,6 +102,7 @@ struct bus_type {
 	const struct dev_pm_ops *pm;

 	struct iommu_ops *iommu_ops;
+	struct dma_iommu_mapping *map;

 	struct subsys_private *p;
 };
--
1.7.5.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 12:38                 ` Hiroshi Doyu
  0 siblings, 0 replies; 24+ messages in thread
From: Hiroshi Doyu @ 2012-04-12 12:38 UTC (permalink / raw)
  To: arnd, m.szyprowski, linux-tegra
  Cc: subashrp, linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch,
	iommu, kyungmin.park, joro, linux, chunsang.jeong, Krishna Reddy,
	pullip.cho, andrzej.p, benh, konrad.wilk

From: Marek Szyprowski <m.szyprowski@samsung.com>
Subject: RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
Date: Thu, 12 Apr 2012 14:13:37 +0200
Message-ID: <028f01cd18a5$b0721770$11564650$%szyprowski@samsung.com>

>
>
>
>
> > -----Original Message-----
> > From: Arnd Bergmann [mailto:arnd@arndb.de]
> > Sent: Thursday, April 12, 2012 1:09 PM
> > To: Marek Szyprowski
> > Cc: 'Subash Patel'; linux-arm-kernel@lists.infradead.org; linaro-mm-sig@lists.linaro.org;
> > linux-mm@kvack.org; linux-arch@vger.kernel.org; iommu@lists.linux-foundation.org; 'Kyungmin
> > Park'; 'Joerg Roedel'; 'Russell King - ARM Linux'; 'Chunsang Jeong'; 'Krishna Reddy'; 'KyongHo
> > Cho'; Andrzej Pietrasiewicz; 'Benjamin Herrenschmidt'; 'Konrad Rzeszutek Wilk'; 'Hiroshi Doyu'
> > Subject: Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
> >
> > On Thursday 12 April 2012, Marek Szyprowski wrote:
> > > +
> > > > > +/*
> > > > > + * s5p_sysmmu_late_init
> > > > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > > > + * be called later, once SYSMMU driver gets registered and probed.
> > > > > + */
> > > > > +static int __init s5p_sysmmu_late_init(void)
> > > > > +{
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > > > +
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > > > +
> > > > > +   return 0;
> > > > > +}
> > > > > +device_initcall(s5p_sysmmu_late_init);
> > > >
> > > > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > > > that you will predefine the IOMMU attachment and mapping information for
> > > > devices in common location (dev-sysmmu.c)? This may lead to problems
> > > > because there are some IP's with SYSMMU support in exynos5, but not
> > > > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > > > to do above declaration in individual machine file, which I think was
> > > > more meaningful.
> > >
> > > Right, I simplified the code too much. Keeping these definitions inside machine
> > > files was a better idea. I completely forgot that Exynos sub-platform now covers
> > > both Exynos4 and Exynos5 SoC families.
> >
> > Ideally the information about iommu attachment should come from the
> > device tree. We have the "dma-ranges" properties that define how a dma
> > address space is mapped. I am not entirely sure how that works when you
> > have multiple IOMMUs and if that requires defining addititional properties,
> > but I think we should make it so that we don't have to hardcode specific
> > devices in the source.
>
> Right, until that time machine/board files are imho ok.

In Tegra30, there are quite many IOMMU attachable (platform)devices,
and it's quite nice for us to configure them (un)attached with address
range and IOMMU device ID(ASID) in DT in advance rather than inserting
the code to attach those devices here and there.

Experimentally I added some hook in platform_device_add() as below,
but apparently this won't be accepted.

From cb34373ebbf025e42ec6d8fea2e19e74ba41231e Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <hdoyu@nvidia.com>
Date: Thu, 22 Mar 2012 16:06:27 +0200
Subject: [PATCH 1/1] ARM: dma-mapping: All platform_device DMA API'able

Signed-off-by: Hiroshi DOYU <hdoyu@nvidia.com>
---
 arch/arm/mach-tegra/board-cardhu.c |    7 ++++++-
 arch/arm/mm/dma-mapping.c          |    5 ++++-
 drivers/base/platform.c            |   11 +++++++++--
 include/linux/device.h             |    2 ++
 4 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index 339011e..38f5292 100644
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ca5544e..5e6dbe0 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -758,6 +758,9 @@ size_t arm_iommu_iova_avail(struct device *dev)
 	size_t size = 0;
 	unsigned long start = 0;

+	BUG_ON(!dev);
+	BUG_ON(!mapping);
+
 	spin_lock_irqsave(&mapping->lock, flags);
 	while (1) {
 		unsigned long end;
@@ -1513,7 +1516,7 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
 	mapping->domain = iommu_domain_alloc(bus);
 	if (!mapping->domain)
 		goto err3;
-
+	bus->map = mapping;
 	kref_init(&mapping->kref);
 	return mapping;
 err3:
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 99a5272..4af431c 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -21,6 +21,8 @@
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>

+#include <asm/dma-iommu.h>
+
 #include "base.h"

 #define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
@@ -305,8 +307,13 @@ int platform_device_add(struct platform_device *pdev)
 		 dev_name(&pdev->dev), dev_name(pdev->dev.parent));

 	ret = device_add(&pdev->dev);
-	if (ret == 0)
-		return ret;
+	if (ret)
+		goto failed;
+
+	if (platform_bus_type.map)
+		arm_iommu_attach_device(&pdev->dev, platform_bus_type.map);
+
+	return 0;

  failed:
 	while (--i >= 0) {
diff --git a/include/linux/device.h b/include/linux/device.h
index 28c35f8..732611f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -34,6 +34,7 @@ struct subsys_private;
 struct bus_type;
 struct device_node;
 struct iommu_ops;
+struct dma_iommu_mapping;

 struct bus_attribute {
 	struct attribute	attr;
@@ -101,6 +102,7 @@ struct bus_type {
 	const struct dev_pm_ops *pm;

 	struct iommu_ops *iommu_ops;
+	struct dma_iommu_mapping *map;

 	struct subsys_private *p;
 };
--
1.7.5.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 12:38                 ` Hiroshi Doyu
  0 siblings, 0 replies; 24+ messages in thread
From: Hiroshi Doyu @ 2012-04-12 12:38 UTC (permalink / raw)
  To: arnd, m.szyprowski, linux-tegra
  Cc: subashrp, linux-arm-kernel, linaro-mm-sig, linux-mm, linux-arch,
	iommu, kyungmin.park, joro, linux, chunsang.jeong, Krishna Reddy,
	pullip.cho, andrzej.p, benh, konrad.wilk

From: Marek Szyprowski <m.szyprowski@samsung.com>
Subject: RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
Date: Thu, 12 Apr 2012 14:13:37 +0200
Message-ID: <028f01cd18a5$b0721770$11564650$%szyprowski@samsung.com>

>
>
>
>
> > -----Original Message-----
> > From: Arnd Bergmann [mailto:arnd@arndb.de]
> > Sent: Thursday, April 12, 2012 1:09 PM
> > To: Marek Szyprowski
> > Cc: 'Subash Patel'; linux-arm-kernel@lists.infradead.org; linaro-mm-sig@lists.linaro.org;
> > linux-mm@kvack.org; linux-arch@vger.kernel.org; iommu@lists.linux-foundation.org; 'Kyungmin
> > Park'; 'Joerg Roedel'; 'Russell King - ARM Linux'; 'Chunsang Jeong'; 'Krishna Reddy'; 'KyongHo
> > Cho'; Andrzej Pietrasiewicz; 'Benjamin Herrenschmidt'; 'Konrad Rzeszutek Wilk'; 'Hiroshi Doyu'
> > Subject: Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
> >
> > On Thursday 12 April 2012, Marek Szyprowski wrote:
> > > +
> > > > > +/*
> > > > > + * s5p_sysmmu_late_init
> > > > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > > > + * be called later, once SYSMMU driver gets registered and probed.
> > > > > + */
> > > > > +static int __init s5p_sysmmu_late_init(void)
> > > > > +{
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > > > +
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > > > +
> > > > > +   return 0;
> > > > > +}
> > > > > +device_initcall(s5p_sysmmu_late_init);
> > > >
> > > > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > > > that you will predefine the IOMMU attachment and mapping information for
> > > > devices in common location (dev-sysmmu.c)? This may lead to problems
> > > > because there are some IP's with SYSMMU support in exynos5, but not
> > > > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > > > to do above declaration in individual machine file, which I think was
> > > > more meaningful.
> > >
> > > Right, I simplified the code too much. Keeping these definitions inside machine
> > > files was a better idea. I completely forgot that Exynos sub-platform now covers
> > > both Exynos4 and Exynos5 SoC families.
> >
> > Ideally the information about iommu attachment should come from the
> > device tree. We have the "dma-ranges" properties that define how a dma
> > address space is mapped. I am not entirely sure how that works when you
> > have multiple IOMMUs and if that requires defining addititional properties,
> > but I think we should make it so that we don't have to hardcode specific
> > devices in the source.
>
> Right, until that time machine/board files are imho ok.

In Tegra30, there are quite many IOMMU attachable (platform)devices,
and it's quite nice for us to configure them (un)attached with address
range and IOMMU device ID(ASID) in DT in advance rather than inserting
the code to attach those devices here and there.

Experimentally I added some hook in platform_device_add() as below,
but apparently this won't be accepted.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 12:38                 ` Hiroshi Doyu
  0 siblings, 0 replies; 24+ messages in thread
From: Hiroshi Doyu @ 2012-04-12 12:38 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arch-u79uwXL29TY76Z2rM5mHXA, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	subashrp-Re5JQEeQqe8AvxtiuMwx3w,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Krishna Reddy,
	andrzej.p-Sze3O3UU22JBDgjK7y7TUQ,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	pullip.cho-Sze3O3UU22JBDgjK7y7TUQ,
	chunsang.jeong-QSEj5FYQhm4dnm+yROfE0A,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

From: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Subject: RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
Date: Thu, 12 Apr 2012 14:13:37 +0200
Message-ID: <028f01cd18a5$b0721770$11564650$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

>
>
>
>
> > -----Original Message-----
> > From: Arnd Bergmann [mailto:arnd-r2nGTMty4D4@public.gmane.org]
> > Sent: Thursday, April 12, 2012 1:09 PM
> > To: Marek Szyprowski
> > Cc: 'Subash Patel'; linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org; linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw@public.gmane.org;
> > linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org; linux-arch-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org; 'Kyungmin
> > Park'; 'Joerg Roedel'; 'Russell King - ARM Linux'; 'Chunsang Jeong'; 'Krishna Reddy'; 'KyongHo
> > Cho'; Andrzej Pietrasiewicz; 'Benjamin Herrenschmidt'; 'Konrad Rzeszutek Wilk'; 'Hiroshi Doyu'
> > Subject: Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
> >
> > On Thursday 12 April 2012, Marek Szyprowski wrote:
> > > +
> > > > > +/*
> > > > > + * s5p_sysmmu_late_init
> > > > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > > > + * be called later, once SYSMMU driver gets registered and probed.
> > > > > + */
> > > > > +static int __init s5p_sysmmu_late_init(void)
> > > > > +{
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > > > +
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > > > +
> > > > > +   return 0;
> > > > > +}
> > > > > +device_initcall(s5p_sysmmu_late_init);
> > > >
> > > > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > > > that you will predefine the IOMMU attachment and mapping information for
> > > > devices in common location (dev-sysmmu.c)? This may lead to problems
> > > > because there are some IP's with SYSMMU support in exynos5, but not
> > > > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > > > to do above declaration in individual machine file, which I think was
> > > > more meaningful.
> > >
> > > Right, I simplified the code too much. Keeping these definitions inside machine
> > > files was a better idea. I completely forgot that Exynos sub-platform now covers
> > > both Exynos4 and Exynos5 SoC families.
> >
> > Ideally the information about iommu attachment should come from the
> > device tree. We have the "dma-ranges" properties that define how a dma
> > address space is mapped. I am not entirely sure how that works when you
> > have multiple IOMMUs and if that requires defining addititional properties,
> > but I think we should make it so that we don't have to hardcode specific
> > devices in the source.
>
> Right, until that time machine/board files are imho ok.

In Tegra30, there are quite many IOMMU attachable (platform)devices,
and it's quite nice for us to configure them (un)attached with address
range and IOMMU device ID(ASID) in DT in advance rather than inserting
the code to attach those devices here and there.

Experimentally I added some hook in platform_device_add() as below,
but apparently this won't be accepted.

>From cb34373ebbf025e42ec6d8fea2e19e74ba41231e Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Date: Thu, 22 Mar 2012 16:06:27 +0200
Subject: [PATCH 1/1] ARM: dma-mapping: All platform_device DMA API'able

Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/mach-tegra/board-cardhu.c |    7 ++++++-
 arch/arm/mm/dma-mapping.c          |    5 ++++-
 drivers/base/platform.c            |   11 +++++++++--
 include/linux/device.h             |    2 ++
 4 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index 339011e..38f5292 100644
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ca5544e..5e6dbe0 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -758,6 +758,9 @@ size_t arm_iommu_iova_avail(struct device *dev)
 	size_t size = 0;
 	unsigned long start = 0;

+	BUG_ON(!dev);
+	BUG_ON(!mapping);
+
 	spin_lock_irqsave(&mapping->lock, flags);
 	while (1) {
 		unsigned long end;
@@ -1513,7 +1516,7 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
 	mapping->domain = iommu_domain_alloc(bus);
 	if (!mapping->domain)
 		goto err3;
-
+	bus->map = mapping;
 	kref_init(&mapping->kref);
 	return mapping;
 err3:
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 99a5272..4af431c 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -21,6 +21,8 @@
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>

+#include <asm/dma-iommu.h>
+
 #include "base.h"

 #define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
@@ -305,8 +307,13 @@ int platform_device_add(struct platform_device *pdev)
 		 dev_name(&pdev->dev), dev_name(pdev->dev.parent));

 	ret = device_add(&pdev->dev);
-	if (ret == 0)
-		return ret;
+	if (ret)
+		goto failed;
+
+	if (platform_bus_type.map)
+		arm_iommu_attach_device(&pdev->dev, platform_bus_type.map);
+
+	return 0;

  failed:
 	while (--i >= 0) {
diff --git a/include/linux/device.h b/include/linux/device.h
index 28c35f8..732611f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -34,6 +34,7 @@ struct subsys_private;
 struct bus_type;
 struct device_node;
 struct iommu_ops;
+struct dma_iommu_mapping;

 struct bus_attribute {
 	struct attribute	attr;
@@ -101,6 +102,7 @@ struct bus_type {
 	const struct dev_pm_ops *pm;

 	struct iommu_ops *iommu_ops;
+	struct dma_iommu_mapping *map;

 	struct subsys_private *p;
 };
--
1.7.5.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
@ 2012-04-12 12:38                 ` Hiroshi Doyu
  0 siblings, 0 replies; 24+ messages in thread
From: Hiroshi Doyu @ 2012-04-12 12:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Marek Szyprowski <m.szyprowski@samsung.com>
Subject: RE: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
Date: Thu, 12 Apr 2012 14:13:37 +0200
Message-ID: <028f01cd18a5$b0721770$11564650$%szyprowski@samsung.com>

>
>
>
>
> > -----Original Message-----
> > From: Arnd Bergmann [mailto:arnd at arndb.de]
> > Sent: Thursday, April 12, 2012 1:09 PM
> > To: Marek Szyprowski
> > Cc: 'Subash Patel'; linux-arm-kernel at lists.infradead.org; linaro-mm-sig at lists.linaro.org;
> > linux-mm at kvack.org; linux-arch at vger.kernel.org; iommu at lists.linux-foundation.org; 'Kyungmin
> > Park'; 'Joerg Roedel'; 'Russell King - ARM Linux'; 'Chunsang Jeong'; 'Krishna Reddy'; 'KyongHo
> > Cho'; Andrzej Pietrasiewicz; 'Benjamin Herrenschmidt'; 'Konrad Rzeszutek Wilk'; 'Hiroshi Doyu'
> > Subject: Re: [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface
> >
> > On Thursday 12 April 2012, Marek Szyprowski wrote:
> > > +
> > > > > +/*
> > > > > + * s5p_sysmmu_late_init
> > > > > + * Create DMA-mapping IOMMU context for specified devices. This function must
> > > > > + * be called later, once SYSMMU driver gets registered and probed.
> > > > > + */
> > > > > +static int __init s5p_sysmmu_late_init(void)
> > > > > +{
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev,&s5p_device_fimc0.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev,&s5p_device_fimc1.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev,&s5p_device_fimc2.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev,&s5p_device_fimc3.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev,&s5p_device_mfc_l.dev);
> > > > > +   platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev,&s5p_device_mfc_r.dev);
> > > > > +
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4);
> > > > > +   s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4);
> > > > > +
> > > > > +   return 0;
> > > > > +}
> > > > > +device_initcall(s5p_sysmmu_late_init);
> > > >
> > > > Shouldn't these things be specific to a SoC? With this RFC, it happens
> > > > that you will predefine the IOMMU attachment and mapping information for
> > > > devices in common location (dev-sysmmu.c)? This may lead to problems
> > > > because there are some IP's with SYSMMU support in exynos5, but not
> > > > available in exynos4 (eg: GSC, FIMC-LITE, FIMC-ISP) Previously we used
> > > > to do above declaration in individual machine file, which I think was
> > > > more meaningful.
> > >
> > > Right, I simplified the code too much. Keeping these definitions inside machine
> > > files was a better idea. I completely forgot that Exynos sub-platform now covers
> > > both Exynos4 and Exynos5 SoC families.
> >
> > Ideally the information about iommu attachment should come from the
> > device tree. We have the "dma-ranges" properties that define how a dma
> > address space is mapped. I am not entirely sure how that works when you
> > have multiple IOMMUs and if that requires defining addititional properties,
> > but I think we should make it so that we don't have to hardcode specific
> > devices in the source.
>
> Right, until that time machine/board files are imho ok.

In Tegra30, there are quite many IOMMU attachable (platform)devices,
and it's quite nice for us to configure them (un)attached with address
range and IOMMU device ID(ASID) in DT in advance rather than inserting
the code to attach those devices here and there.

Experimentally I added some hook in platform_device_add() as below,
but apparently this won't be accepted.

>From cb34373ebbf025e42ec6d8fea2e19e74ba41231e Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <hdoyu@nvidia.com>
Date: Thu, 22 Mar 2012 16:06:27 +0200
Subject: [PATCH 1/1] ARM: dma-mapping: All platform_device DMA API'able

Signed-off-by: Hiroshi DOYU <hdoyu@nvidia.com>
---
 arch/arm/mach-tegra/board-cardhu.c |    7 ++++++-
 arch/arm/mm/dma-mapping.c          |    5 ++++-
 drivers/base/platform.c            |   11 +++++++++--
 include/linux/device.h             |    2 ++
 4 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index 339011e..38f5292 100644
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ca5544e..5e6dbe0 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -758,6 +758,9 @@ size_t arm_iommu_iova_avail(struct device *dev)
 	size_t size = 0;
 	unsigned long start = 0;

+	BUG_ON(!dev);
+	BUG_ON(!mapping);
+
 	spin_lock_irqsave(&mapping->lock, flags);
 	while (1) {
 		unsigned long end;
@@ -1513,7 +1516,7 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
 	mapping->domain = iommu_domain_alloc(bus);
 	if (!mapping->domain)
 		goto err3;
-
+	bus->map = mapping;
 	kref_init(&mapping->kref);
 	return mapping;
 err3:
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 99a5272..4af431c 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -21,6 +21,8 @@
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>

+#include <asm/dma-iommu.h>
+
 #include "base.h"

 #define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
@@ -305,8 +307,13 @@ int platform_device_add(struct platform_device *pdev)
 		 dev_name(&pdev->dev), dev_name(pdev->dev.parent));

 	ret = device_add(&pdev->dev);
-	if (ret == 0)
-		return ret;
+	if (ret)
+		goto failed;
+
+	if (platform_bus_type.map)
+		arm_iommu_attach_device(&pdev->dev, platform_bus_type.map);
+
+	return 0;

  failed:
 	while (--i >= 0) {
diff --git a/include/linux/device.h b/include/linux/device.h
index 28c35f8..732611f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -34,6 +34,7 @@ struct subsys_private;
 struct bus_type;
 struct device_node;
 struct iommu_ops;
+struct dma_iommu_mapping;

 struct bus_attribute {
 	struct attribute	attr;
@@ -101,6 +102,7 @@ struct bus_type {
 	const struct dev_pm_ops *pm;

 	struct iommu_ops *iommu_ops;
+	struct dma_iommu_mapping *map;

 	struct subsys_private *p;
 };
--
1.7.5.4

^ permalink raw reply related	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2012-04-12 12:39 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-11 14:36 [PATCH/RFC] ARM: Exynos4: Integrate IOMMU aware DMA-mapping Marek Szyprowski
2012-04-11 14:36 ` Marek Szyprowski
2012-04-11 14:36 ` Marek Szyprowski
2012-04-11 14:36 ` [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface Marek Szyprowski
2012-04-11 14:36   ` Marek Szyprowski
2012-04-11 14:36   ` Marek Szyprowski
2012-04-12  9:05   ` Subash Patel
2012-04-12  9:05     ` Subash Patel
2012-04-12  9:05     ` Subash Patel
2012-04-12  9:18     ` Marek Szyprowski
2012-04-12  9:18       ` Marek Szyprowski
2012-04-12  9:18       ` Marek Szyprowski
2012-04-12 11:09       ` Arnd Bergmann
2012-04-12 11:09         ` Arnd Bergmann
2012-04-12 11:09         ` Arnd Bergmann
     [not found]         ` <201204121109.28753.arnd-r2nGTMty4D4@public.gmane.org>
2012-04-12 12:13           ` Marek Szyprowski
2012-04-12 12:13             ` Marek Szyprowski
2012-04-12 12:13             ` Marek Szyprowski
2012-04-12 12:13             ` Marek Szyprowski
     [not found]             ` <028f01cd18a5$b0721770$11564650$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2012-04-12 12:38               ` Hiroshi Doyu
2012-04-12 12:38                 ` Hiroshi Doyu
2012-04-12 12:38                 ` Hiroshi Doyu
2012-04-12 12:38                 ` Hiroshi Doyu
2012-04-12 12:38                 ` Hiroshi Doyu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.