All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
@ 2015-05-04  8:15 ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

Hello Everyone,

This is yet another attempt to get Exynos SYSMMU driver with integrated
with IOMMU & DMA-mapping subsystems. The main change from previous
version is addition of the patches to define iommu-mapping, which need
to be created during system boot to avoid IOMMU fault by devices, which
has been left enabled by bootloader (i.e. framebuffer displaying slash
screen).

Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
more information:
http://www.spinics.net/lists/arm-kernel/msg414722.html).

All patches are also available in the following git repository:
https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
branch v4.1-exynos-iommu.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland


Changelog:

v6:
- rebased onto v4.1-rc2 with 'arm: dma-mapping: fix off-by-one check in
  arm_setup_iommu_dma_ops' patch
- added exynos 3250 and 4415 dts patches
- added support for devices, which have been left enabled by bootloader
  (i.e. framebuffer displaying slash screen)
- fixed freeze in fimd iommu initialization caused by lack of proper
  runtime pm management
- resolved issues with power domains by moving pd initialization to
  core_initcall

v5: https://lists.linaro.org/pipermail/linaro-mm-sig/2015-February/004442.html
- rebased onto 'Add HDMI support for Exynos5420 platform' patchset
- fixed 'const' issue in 'iommu: exynos: init from dt-specific callback
  instead of initcall' patch, thanks to Tobias Jakobi for reporting it
- fixed copy-paste typo in exynos5250 dts patch

v4: http://www.spinics.net/lists/linux-samsung-soc/msg41177.html
- rebased onto v3.19-rc4 and other Exynos DTS queued patches
- added DTS patch for Exynos 5250 & 5420/5422/5800

v3: http://www.spinics.net/lists/linux-samsung-soc/msg39168.html
- rebased onto "[RFC PATCH v4 0/8] Introduce automatic DMA
  configuration for IOMMU masters"
- added some minor fixes for iommu and dma-mapping frameworks

v2: http://thread.gmane.org/gmane.linux.kernel.iommu/6472/
- rebased onto "[RFC PATCH v3 0/7] Introduce automatic DMA
  configuration for IOMMU masters" patches:
  http://www.spinics.net/lists/arm-kernel/msg362076.html
- changed initialization from bus notifiers to DT related callbacks
- removed support for separate IO address spaces - this will be
  discussed separately after the basic support gets merged
- removed support for power domain notifier-based runtime power
  management - this also will be discussed separately later

v1: https://lkml.org/lkml/2014/8/5/183
- initial version, feature complete, completely rewrote integration
  approach


Patch summary:

Marek Szyprowski (25):
  arm: dma-mapping: add support for creating reserved mappings in iova
    space
  arm: exynos: pm_domains: register power domain driver from
    core_initcall
  drm/exynos: iommu: detach from default dma-mapping domain on init
  drm/exynos: fimd: ensure proper hw state in fimd_clear_channel()
  iommu: exynos: don't read version register on every tlb operation
  iommu: exynos: remove unused functions
  iommu: exynos: remove useless spinlock
  iommu: exynos: refactor function parameters to simplify code
  iommu: exynos: remove unused functions, part 2
  iommu: exynos: remove useless device_add/remove callbacks
  iommu: exynos: add support for binding more than one sysmmu to master
    device
  iommu: exynos: add support for runtime_pm
  iommu: exynos: rename variables to reflect their purpose
  iommu: exynos: use struct exynos_iommu_domain in internal structures
  iommu: exynos: document internal structures
  iommu: exynos: remove excessive includes and sort others
    alphabetically
  iommu: exynos: init from dt-specific callback instead of initcall
  iommu: exynos: add callback for initializing devices from device tree
  iommu: exynos: remove unneeded code
  ARM: dts: exynos4: add sysmmu nodes
  ARM: dts: exynos3250: add sysmmu nodes
  ARM: dts: exynos4415: add sysmmu nodes
  ARM: dts: exynos5250: add sysmmu nodes
  ARM: dts: exynos5420: add sysmmu nodes
  ARM: dts: exynos: add iommu reserved regions for bootloader's splash
    screen

 Documentation/devicetree/bindings/iommu/iommu.txt |  44 ++
 arch/arm/boot/dts/exynos3250-rinato.dts           |   1 +
 arch/arm/boot/dts/exynos3250.dtsi                 |  22 +
 arch/arm/boot/dts/exynos4.dtsi                    | 118 ++++++
 arch/arm/boot/dts/exynos4210-trats.dts            |   1 +
 arch/arm/boot/dts/exynos4210-universal_c210.dts   |   1 +
 arch/arm/boot/dts/exynos4210.dtsi                 |  23 +
 arch/arm/boot/dts/exynos4412-trats2.dts           |   1 +
 arch/arm/boot/dts/exynos4415.dtsi                 |  11 +
 arch/arm/boot/dts/exynos4x12.dtsi                 |  82 ++++
 arch/arm/boot/dts/exynos5250-snow.dts             |   1 +
 arch/arm/boot/dts/exynos5250-spring.dts           |   1 +
 arch/arm/boot/dts/exynos5250.dtsi                 | 250 +++++++++++
 arch/arm/boot/dts/exynos5420-peach-pit.dts        |   1 +
 arch/arm/boot/dts/exynos5420.dtsi                 | 181 ++++++++
 arch/arm/boot/dts/exynos5800-peach-pi.dts         |   1 +
 arch/arm/mach-exynos/pm_domains.c                 |  18 +-
 arch/arm/mm/dma-mapping.c                         | 112 +++++
 drivers/gpu/drm/exynos/exynos_drm_fimd.c          |  27 +-
 drivers/gpu/drm/exynos/exynos_drm_iommu.c         |   3 +
 drivers/iommu/exynos-iommu.c                      | 495 ++++++++++------------
 21 files changed, 1098 insertions(+), 296 deletions(-)

-- 
1.9.2

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

* [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
@ 2015-05-04  8:15 ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Everyone,

This is yet another attempt to get Exynos SYSMMU driver with integrated
with IOMMU & DMA-mapping subsystems. The main change from previous
version is addition of the patches to define iommu-mapping, which need
to be created during system boot to avoid IOMMU fault by devices, which
has been left enabled by bootloader (i.e. framebuffer displaying slash
screen).

Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
more information:
http://www.spinics.net/lists/arm-kernel/msg414722.html).

All patches are also available in the following git repository:
https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
branch v4.1-exynos-iommu.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland


Changelog:

v6:
- rebased onto v4.1-rc2 with 'arm: dma-mapping: fix off-by-one check in
  arm_setup_iommu_dma_ops' patch
- added exynos 3250 and 4415 dts patches
- added support for devices, which have been left enabled by bootloader
  (i.e. framebuffer displaying slash screen)
- fixed freeze in fimd iommu initialization caused by lack of proper
  runtime pm management
- resolved issues with power domains by moving pd initialization to
  core_initcall

v5: https://lists.linaro.org/pipermail/linaro-mm-sig/2015-February/004442.html
- rebased onto 'Add HDMI support for Exynos5420 platform' patchset
- fixed 'const' issue in 'iommu: exynos: init from dt-specific callback
  instead of initcall' patch, thanks to Tobias Jakobi for reporting it
- fixed copy-paste typo in exynos5250 dts patch

v4: http://www.spinics.net/lists/linux-samsung-soc/msg41177.html
- rebased onto v3.19-rc4 and other Exynos DTS queued patches
- added DTS patch for Exynos 5250 & 5420/5422/5800

v3: http://www.spinics.net/lists/linux-samsung-soc/msg39168.html
- rebased onto "[RFC PATCH v4 0/8] Introduce automatic DMA
  configuration for IOMMU masters"
- added some minor fixes for iommu and dma-mapping frameworks

v2: http://thread.gmane.org/gmane.linux.kernel.iommu/6472/
- rebased onto "[RFC PATCH v3 0/7] Introduce automatic DMA
  configuration for IOMMU masters" patches:
  http://www.spinics.net/lists/arm-kernel/msg362076.html
- changed initialization from bus notifiers to DT related callbacks
- removed support for separate IO address spaces - this will be
  discussed separately after the basic support gets merged
- removed support for power domain notifier-based runtime power
  management - this also will be discussed separately later

v1: https://lkml.org/lkml/2014/8/5/183
- initial version, feature complete, completely rewrote integration
  approach


Patch summary:

Marek Szyprowski (25):
  arm: dma-mapping: add support for creating reserved mappings in iova
    space
  arm: exynos: pm_domains: register power domain driver from
    core_initcall
  drm/exynos: iommu: detach from default dma-mapping domain on init
  drm/exynos: fimd: ensure proper hw state in fimd_clear_channel()
  iommu: exynos: don't read version register on every tlb operation
  iommu: exynos: remove unused functions
  iommu: exynos: remove useless spinlock
  iommu: exynos: refactor function parameters to simplify code
  iommu: exynos: remove unused functions, part 2
  iommu: exynos: remove useless device_add/remove callbacks
  iommu: exynos: add support for binding more than one sysmmu to master
    device
  iommu: exynos: add support for runtime_pm
  iommu: exynos: rename variables to reflect their purpose
  iommu: exynos: use struct exynos_iommu_domain in internal structures
  iommu: exynos: document internal structures
  iommu: exynos: remove excessive includes and sort others
    alphabetically
  iommu: exynos: init from dt-specific callback instead of initcall
  iommu: exynos: add callback for initializing devices from device tree
  iommu: exynos: remove unneeded code
  ARM: dts: exynos4: add sysmmu nodes
  ARM: dts: exynos3250: add sysmmu nodes
  ARM: dts: exynos4415: add sysmmu nodes
  ARM: dts: exynos5250: add sysmmu nodes
  ARM: dts: exynos5420: add sysmmu nodes
  ARM: dts: exynos: add iommu reserved regions for bootloader's splash
    screen

 Documentation/devicetree/bindings/iommu/iommu.txt |  44 ++
 arch/arm/boot/dts/exynos3250-rinato.dts           |   1 +
 arch/arm/boot/dts/exynos3250.dtsi                 |  22 +
 arch/arm/boot/dts/exynos4.dtsi                    | 118 ++++++
 arch/arm/boot/dts/exynos4210-trats.dts            |   1 +
 arch/arm/boot/dts/exynos4210-universal_c210.dts   |   1 +
 arch/arm/boot/dts/exynos4210.dtsi                 |  23 +
 arch/arm/boot/dts/exynos4412-trats2.dts           |   1 +
 arch/arm/boot/dts/exynos4415.dtsi                 |  11 +
 arch/arm/boot/dts/exynos4x12.dtsi                 |  82 ++++
 arch/arm/boot/dts/exynos5250-snow.dts             |   1 +
 arch/arm/boot/dts/exynos5250-spring.dts           |   1 +
 arch/arm/boot/dts/exynos5250.dtsi                 | 250 +++++++++++
 arch/arm/boot/dts/exynos5420-peach-pit.dts        |   1 +
 arch/arm/boot/dts/exynos5420.dtsi                 | 181 ++++++++
 arch/arm/boot/dts/exynos5800-peach-pi.dts         |   1 +
 arch/arm/mach-exynos/pm_domains.c                 |  18 +-
 arch/arm/mm/dma-mapping.c                         | 112 +++++
 drivers/gpu/drm/exynos/exynos_drm_fimd.c          |  27 +-
 drivers/gpu/drm/exynos/exynos_drm_iommu.c         |   3 +
 drivers/iommu/exynos-iommu.c                      | 495 ++++++++++------------
 21 files changed, 1098 insertions(+), 296 deletions(-)

-- 
1.9.2

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

* [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:15     ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Rob Herring, Thierry Reding, Shaik Ameer Basha, Joonyoung Shim,
	Arnd Bergmann, Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw, Kyungmin Park, Kukjin Kim,
	Laurent Pinchart, Javier Martinez Canillas, Cho KyongHo,
	David Wodhouse

Some devices (like frame buffers) are enabled by bootloader and configured
to perform DMA operations automatically (like displaying boot logo or splash
screen). Such devices operate and perform DMA operation usually until the
proper driver for them is loaded and probed. However before that happens,
system usually loads IOMMU drivers and configures dma parameters for each
device. When such initial configuration is created and enabled, it usually
contains empty translation rules betweem IO address space and physical
memory, because no buffers nor memory regions have been requested by the
respective driver.

This patch adds support for "iommu-reserved-mapping", which can be used
to provide definitions for mappings that need to be created on system
boot to let such devices (enabled by bootloader) to operate properly
until respective driver is probed.

Signed-off-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
 arch/arm/mm/dma-mapping.c                         | 112 ++++++++++++++++++++++
 2 files changed, 156 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/iommu.txt b/Documentation/devicetree/bindings/iommu/iommu.txt
index 5a8b4624defc..fd54e6b597f0 100644
--- a/Documentation/devicetree/bindings/iommu/iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/iommu.txt
@@ -86,6 +86,35 @@ have a means to turn off translation. But it is invalid in such cases to
 disable the IOMMU's device tree node in the first place because it would
 prevent any driver from properly setting up the translations.
 
+Optional properties:
+--------------------
+- iommu-reserved-mapping: A list of entries describing additional
+  reserved mapping, that will be inserted to the default IO address space
+  created for given master device. Each entry consist of IO address,
+  physical memory address and size of the region.
+
+Some devices (like frame buffers) are enabled by bootloader and configured
+to perform DMA operations automatically (like displaying boot logo or splash
+screen). Such devices operate and perform DMA operation usually until the
+proper driver for them is loaded and probed. However before that happens,
+system usually loads IOMMU drivers and configures dma parameters for each
+device. When such initial configuration is created and enabled, it usually
+contains empty translation rules betweem IO address space and physical
+memory, because no buffers nor memory regions have been requested by the
+respective driver.
+
+To avoid IOMMU page fault, one can provide "iommu-reserved-mapping"
+property, which defines all memory regions which must be mapped to IO
+address space to boot properly when device has been enabled by the
+bootloader. More than one region can be defined for given master device.
+Each region is defined by the following triplet: first entry is IO
+address (encoded in "address" cells), second is base physical memory
+address for this regions (also encoded in "address" cells) and the last
+is size of the region (encoded in "size" cells). To ensure that that
+given master device will not trigger page fault after enabling IOMMU,
+one should define identity mapping between physical memory and IO
+address space for the range of addresses accessed by the device.
+
 
 Notes:
 ======
@@ -113,6 +142,21 @@ Single-master IOMMU:
 		iommus = <&{/iommu}>;
 	};
 
+
+Single-master IOMMU, which has been left enabled by bootloader:
+---------------------------------------------------------------
+
+	iommu {
+		#iommu-cells = <0>;
+	};
+
+	master {
+		iommus = <&{/iommu}>;
+		/* bootloader configures framebuffer at 0x40000000 (32MiB)
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x2000000>;
+	};
+
+
 Multiple-master IOMMU with fixed associations:
 ----------------------------------------------
 
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7e7583ddd607..3b4a94695b68 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1019,6 +1019,50 @@ fs_initcall(dma_debug_do_init);
 
 static int extend_iommu_mapping(struct dma_iommu_mapping *mapping);
 
+static inline int __reserve_iova(struct dma_iommu_mapping *mapping,
+				 dma_addr_t iova, size_t size)
+{
+	unsigned long count, start;
+	unsigned long flags;
+	int i, sbitmap, ebitmap;
+
+	if (iova < mapping->base)
+		return -EINVAL;
+
+	start = (iova - mapping->base) >> PAGE_SHIFT;
+	count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+	sbitmap = start / mapping->bits;
+	ebitmap = (start + count) / mapping->bits;
+	start = start % mapping->bits;
+
+	if (ebitmap > mapping->extensions)
+		return -EINVAL;
+
+	spin_lock_irqsave(&mapping->lock, flags);
+
+	for (i = mapping->nr_bitmaps; i <= ebitmap; i++) {
+		if (extend_iommu_mapping(mapping)) {
+			spin_unlock_irqrestore(&mapping->lock, flags);
+			return -ENOMEM;
+		}
+	}
+
+	for (i = sbitmap; count && i < mapping->nr_bitmaps; i++) {
+		int bits = count;
+
+		if (bits + start > mapping->bits)
+			bits = mapping->bits - start;
+		bitmap_set(mapping->bitmaps[i], start, bits);
+		start = 0;
+		count -= bits;
+	}
+
+	spin_unlock_irqrestore(&mapping->lock, flags);
+
+	return 0;
+}
+
 static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
 				      size_t size)
 {
@@ -2048,6 +2092,66 @@ void arm_iommu_detach_device(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
+static int arm_iommu_add_reserved(struct device *dev,
+			struct dma_iommu_mapping *domain, phys_addr_t phys,
+			dma_addr_t dma, size_t size)
+{
+	int ret;
+
+	ret = __reserve_iova(domain, dma, size);
+	if (ret) {
+		dev_err(dev, "failed to reserve mapping\n");
+		return -EINVAL;
+	}
+
+	ret = iommu_map(domain->domain, dma, phys, size, IOMMU_READ);
+	if (ret != 0) {
+		dev_err(dev, "create IOMMU mapping\n");
+		return ret;
+	}
+
+	dev_info(dev, "created reserved DMA mapping (%pa -> %pad, %zu bytes)\n",
+		 &phys, &dma, size);
+
+	return 0;
+}
+
+static int arm_iommu_init_reserved(struct device *dev,
+				   struct dma_iommu_mapping *domain)
+{
+	const char *name = "iommu-reserved-mapping";
+	const __be32 *prop = NULL;
+	int len, naddr, nsize;
+	struct device_node *node = dev->of_node;
+	phys_addr_t phys;
+	dma_addr_t dma;
+	size_t size;
+
+	if (!node)
+		return 0;
+
+	naddr = of_n_addr_cells(node);
+	nsize = of_n_size_cells(node);
+
+	prop = of_get_property(node, name, &len);
+	if (!prop)
+		return 0;
+
+	len /= sizeof(u32);
+
+	if (len < 2 * naddr + nsize) {
+		dev_err(dev, "invalid length (%d cells) of %s property\n",
+			len, name);
+		return -EINVAL;
+	}
+
+	phys = of_read_number(prop, naddr);
+	dma = of_read_number(prop + naddr, naddr);
+	size = of_read_number(prop + 2*naddr, nsize);
+
+	return arm_iommu_add_reserved(dev, domain, phys, dma, size);
+}
+
 static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
 {
 	return coherent ? &iommu_coherent_ops : &iommu_ops;
@@ -2068,6 +2172,14 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		return false;
 	}
 
+	if (arm_iommu_init_reserved(dev, mapping) != 0) {
+		pr_warn("Failed to initialize reserved mapping for device %s\n",
+			dev_name(dev));
+		__arm_iommu_detach_device(dev);
+		arm_iommu_release_mapping(mapping);
+		return false;
+	}
+
 	if (__arm_iommu_attach_device(dev, mapping)) {
 		pr_warn("Failed to attached device %s to IOMMU_mapping\n",
 				dev_name(dev));
-- 
1.9.2

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

* [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
@ 2015-05-04  8:15     ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: linux-arm-kernel

Some devices (like frame buffers) are enabled by bootloader and configured
to perform DMA operations automatically (like displaying boot logo or splash
screen). Such devices operate and perform DMA operation usually until the
proper driver for them is loaded and probed. However before that happens,
system usually loads IOMMU drivers and configures dma parameters for each
device. When such initial configuration is created and enabled, it usually
contains empty translation rules betweem IO address space and physical
memory, because no buffers nor memory regions have been requested by the
respective driver.

This patch adds support for "iommu-reserved-mapping", which can be used
to provide definitions for mappings that need to be created on system
boot to let such devices (enabled by bootloader) to operate properly
until respective driver is probed.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
 arch/arm/mm/dma-mapping.c                         | 112 ++++++++++++++++++++++
 2 files changed, 156 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/iommu.txt b/Documentation/devicetree/bindings/iommu/iommu.txt
index 5a8b4624defc..fd54e6b597f0 100644
--- a/Documentation/devicetree/bindings/iommu/iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/iommu.txt
@@ -86,6 +86,35 @@ have a means to turn off translation. But it is invalid in such cases to
 disable the IOMMU's device tree node in the first place because it would
 prevent any driver from properly setting up the translations.
 
+Optional properties:
+--------------------
+- iommu-reserved-mapping: A list of entries describing additional
+  reserved mapping, that will be inserted to the default IO address space
+  created for given master device. Each entry consist of IO address,
+  physical memory address and size of the region.
+
+Some devices (like frame buffers) are enabled by bootloader and configured
+to perform DMA operations automatically (like displaying boot logo or splash
+screen). Such devices operate and perform DMA operation usually until the
+proper driver for them is loaded and probed. However before that happens,
+system usually loads IOMMU drivers and configures dma parameters for each
+device. When such initial configuration is created and enabled, it usually
+contains empty translation rules betweem IO address space and physical
+memory, because no buffers nor memory regions have been requested by the
+respective driver.
+
+To avoid IOMMU page fault, one can provide "iommu-reserved-mapping"
+property, which defines all memory regions which must be mapped to IO
+address space to boot properly when device has been enabled by the
+bootloader. More than one region can be defined for given master device.
+Each region is defined by the following triplet: first entry is IO
+address (encoded in "address" cells), second is base physical memory
+address for this regions (also encoded in "address" cells) and the last
+is size of the region (encoded in "size" cells). To ensure that that
+given master device will not trigger page fault after enabling IOMMU,
+one should define identity mapping between physical memory and IO
+address space for the range of addresses accessed by the device.
+
 
 Notes:
 ======
@@ -113,6 +142,21 @@ Single-master IOMMU:
 		iommus = <&{/iommu}>;
 	};
 
+
+Single-master IOMMU, which has been left enabled by bootloader:
+---------------------------------------------------------------
+
+	iommu {
+		#iommu-cells = <0>;
+	};
+
+	master {
+		iommus = <&{/iommu}>;
+		/* bootloader configures framebuffer at 0x40000000 (32MiB)
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x2000000>;
+	};
+
+
 Multiple-master IOMMU with fixed associations:
 ----------------------------------------------
 
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7e7583ddd607..3b4a94695b68 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1019,6 +1019,50 @@ fs_initcall(dma_debug_do_init);
 
 static int extend_iommu_mapping(struct dma_iommu_mapping *mapping);
 
+static inline int __reserve_iova(struct dma_iommu_mapping *mapping,
+				 dma_addr_t iova, size_t size)
+{
+	unsigned long count, start;
+	unsigned long flags;
+	int i, sbitmap, ebitmap;
+
+	if (iova < mapping->base)
+		return -EINVAL;
+
+	start = (iova - mapping->base) >> PAGE_SHIFT;
+	count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+	sbitmap = start / mapping->bits;
+	ebitmap = (start + count) / mapping->bits;
+	start = start % mapping->bits;
+
+	if (ebitmap > mapping->extensions)
+		return -EINVAL;
+
+	spin_lock_irqsave(&mapping->lock, flags);
+
+	for (i = mapping->nr_bitmaps; i <= ebitmap; i++) {
+		if (extend_iommu_mapping(mapping)) {
+			spin_unlock_irqrestore(&mapping->lock, flags);
+			return -ENOMEM;
+		}
+	}
+
+	for (i = sbitmap; count && i < mapping->nr_bitmaps; i++) {
+		int bits = count;
+
+		if (bits + start > mapping->bits)
+			bits = mapping->bits - start;
+		bitmap_set(mapping->bitmaps[i], start, bits);
+		start = 0;
+		count -= bits;
+	}
+
+	spin_unlock_irqrestore(&mapping->lock, flags);
+
+	return 0;
+}
+
 static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
 				      size_t size)
 {
@@ -2048,6 +2092,66 @@ void arm_iommu_detach_device(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
+static int arm_iommu_add_reserved(struct device *dev,
+			struct dma_iommu_mapping *domain, phys_addr_t phys,
+			dma_addr_t dma, size_t size)
+{
+	int ret;
+
+	ret = __reserve_iova(domain, dma, size);
+	if (ret) {
+		dev_err(dev, "failed to reserve mapping\n");
+		return -EINVAL;
+	}
+
+	ret = iommu_map(domain->domain, dma, phys, size, IOMMU_READ);
+	if (ret != 0) {
+		dev_err(dev, "create IOMMU mapping\n");
+		return ret;
+	}
+
+	dev_info(dev, "created reserved DMA mapping (%pa -> %pad, %zu bytes)\n",
+		 &phys, &dma, size);
+
+	return 0;
+}
+
+static int arm_iommu_init_reserved(struct device *dev,
+				   struct dma_iommu_mapping *domain)
+{
+	const char *name = "iommu-reserved-mapping";
+	const __be32 *prop = NULL;
+	int len, naddr, nsize;
+	struct device_node *node = dev->of_node;
+	phys_addr_t phys;
+	dma_addr_t dma;
+	size_t size;
+
+	if (!node)
+		return 0;
+
+	naddr = of_n_addr_cells(node);
+	nsize = of_n_size_cells(node);
+
+	prop = of_get_property(node, name, &len);
+	if (!prop)
+		return 0;
+
+	len /= sizeof(u32);
+
+	if (len < 2 * naddr + nsize) {
+		dev_err(dev, "invalid length (%d cells) of %s property\n",
+			len, name);
+		return -EINVAL;
+	}
+
+	phys = of_read_number(prop, naddr);
+	dma = of_read_number(prop + naddr, naddr);
+	size = of_read_number(prop + 2*naddr, nsize);
+
+	return arm_iommu_add_reserved(dev, domain, phys, dma, size);
+}
+
 static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
 {
 	return coherent ? &iommu_coherent_ops : &iommu_ops;
@@ -2068,6 +2172,14 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		return false;
 	}
 
+	if (arm_iommu_init_reserved(dev, mapping) != 0) {
+		pr_warn("Failed to initialize reserved mapping for device %s\n",
+			dev_name(dev));
+		__arm_iommu_detach_device(dev);
+		arm_iommu_release_mapping(mapping);
+		return false;
+	}
+
 	if (__arm_iommu_attach_device(dev, mapping)) {
 		pr_warn("Failed to attached device %s to IOMMU_mapping\n",
 				dev_name(dev));
-- 
1.9.2

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

* [PATCH v6 02/25] arm: exynos: pm_domains: register power domain driver from core_initcall
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:15   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

SYSMMU devices are registered very early in arch_initcall, so ensure
that they can get access to power domains by registering power domain
driver from earlier initcall. This change requires dropping usage of the
platform device associated with each power domain and replacing clock
calls with respective of_clk_* equivalents.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-exynos/pm_domains.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index cbe56b35aea0..708eb88aa677 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -117,16 +117,11 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)
 
 static __init int exynos4_pm_init_power_domain(void)
 {
-	struct platform_device *pdev;
 	struct device_node *np;
 
 	for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
 		struct exynos_pm_domain *pd;
 		int on, i;
-		struct device *dev;
-
-		pdev = of_find_device_by_node(np);
-		dev = &pdev->dev;
 
 		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 		if (!pd) {
@@ -135,7 +130,8 @@ static __init int exynos4_pm_init_power_domain(void)
 			return -ENOMEM;
 		}
 
-		pd->pd.name = kstrdup(dev_name(dev), GFP_KERNEL);
+		pd->pd.name = kstrdup_const(strrchr(np->full_name, '/') + 1,
+					    GFP_KERNEL);
 		pd->name = pd->pd.name;
 		pd->base = of_iomap(np, 0);
 		pd->pd.power_off = exynos_pd_power_off;
@@ -145,12 +141,12 @@ static __init int exynos4_pm_init_power_domain(void)
 			char clk_name[8];
 
 			snprintf(clk_name, sizeof(clk_name), "asb%d", i);
-			pd->asb_clk[i] = clk_get(dev, clk_name);
+			pd->asb_clk[i] = of_clk_get_by_name(np, clk_name);
 			if (IS_ERR(pd->asb_clk[i]))
 				break;
 		}
 
-		pd->oscclk = clk_get(dev, "oscclk");
+		pd->oscclk = of_clk_get_by_name(np, "oscclk");
 		if (IS_ERR(pd->oscclk))
 			goto no_clk;
 
@@ -158,11 +154,11 @@ static __init int exynos4_pm_init_power_domain(void)
 			char clk_name[8];
 
 			snprintf(clk_name, sizeof(clk_name), "clk%d", i);
-			pd->clk[i] = clk_get(dev, clk_name);
+			pd->clk[i] = of_clk_get_by_name(np, clk_name);
 			if (IS_ERR(pd->clk[i]))
 				break;
 			snprintf(clk_name, sizeof(clk_name), "pclk%d", i);
-			pd->pclk[i] = clk_get(dev, clk_name);
+			pd->pclk[i] = of_clk_get_by_name(np, clk_name);
 			if (IS_ERR(pd->pclk[i])) {
 				clk_put(pd->clk[i]);
 				pd->clk[i] = ERR_PTR(-EINVAL);
@@ -210,4 +206,4 @@ no_clk:
 
 	return 0;
 }
-arch_initcall(exynos4_pm_init_power_domain);
+core_initcall(exynos4_pm_init_power_domain);
-- 
1.9.2

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

* [PATCH v6 02/25] arm: exynos: pm_domains: register power domain driver from core_initcall
@ 2015-05-04  8:15   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: linux-arm-kernel

SYSMMU devices are registered very early in arch_initcall, so ensure
that they can get access to power domains by registering power domain
driver from earlier initcall. This change requires dropping usage of the
platform device associated with each power domain and replacing clock
calls with respective of_clk_* equivalents.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-exynos/pm_domains.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index cbe56b35aea0..708eb88aa677 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -117,16 +117,11 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)
 
 static __init int exynos4_pm_init_power_domain(void)
 {
-	struct platform_device *pdev;
 	struct device_node *np;
 
 	for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
 		struct exynos_pm_domain *pd;
 		int on, i;
-		struct device *dev;
-
-		pdev = of_find_device_by_node(np);
-		dev = &pdev->dev;
 
 		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 		if (!pd) {
@@ -135,7 +130,8 @@ static __init int exynos4_pm_init_power_domain(void)
 			return -ENOMEM;
 		}
 
-		pd->pd.name = kstrdup(dev_name(dev), GFP_KERNEL);
+		pd->pd.name = kstrdup_const(strrchr(np->full_name, '/') + 1,
+					    GFP_KERNEL);
 		pd->name = pd->pd.name;
 		pd->base = of_iomap(np, 0);
 		pd->pd.power_off = exynos_pd_power_off;
@@ -145,12 +141,12 @@ static __init int exynos4_pm_init_power_domain(void)
 			char clk_name[8];
 
 			snprintf(clk_name, sizeof(clk_name), "asb%d", i);
-			pd->asb_clk[i] = clk_get(dev, clk_name);
+			pd->asb_clk[i] = of_clk_get_by_name(np, clk_name);
 			if (IS_ERR(pd->asb_clk[i]))
 				break;
 		}
 
-		pd->oscclk = clk_get(dev, "oscclk");
+		pd->oscclk = of_clk_get_by_name(np, "oscclk");
 		if (IS_ERR(pd->oscclk))
 			goto no_clk;
 
@@ -158,11 +154,11 @@ static __init int exynos4_pm_init_power_domain(void)
 			char clk_name[8];
 
 			snprintf(clk_name, sizeof(clk_name), "clk%d", i);
-			pd->clk[i] = clk_get(dev, clk_name);
+			pd->clk[i] = of_clk_get_by_name(np, clk_name);
 			if (IS_ERR(pd->clk[i]))
 				break;
 			snprintf(clk_name, sizeof(clk_name), "pclk%d", i);
-			pd->pclk[i] = clk_get(dev, clk_name);
+			pd->pclk[i] = of_clk_get_by_name(np, clk_name);
 			if (IS_ERR(pd->pclk[i])) {
 				clk_put(pd->clk[i]);
 				pd->clk[i] = ERR_PTR(-EINVAL);
@@ -210,4 +206,4 @@ no_clk:
 
 	return 0;
 }
-arch_initcall(exynos4_pm_init_power_domain);
+core_initcall(exynos4_pm_init_power_domain);
-- 
1.9.2

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

* [PATCH v6 03/25] drm/exynos: iommu: detach from default dma-mapping domain on init
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:15   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch adds code, which detach sub-device nodes from default iommu
domain if such has been configured.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_iommu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index b32b291f88ff..323601a52a25 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -100,6 +100,9 @@ int drm_iommu_attach_device(struct drm_device *drm_dev,
 
 	dma_set_max_seg_size(subdrv_dev, 0xffffffffu);
 
+	if (subdrv_dev->archdata.mapping)
+		arm_iommu_detach_device(subdrv_dev);
+
 	ret = arm_iommu_attach_device(subdrv_dev, dev->archdata.mapping);
 	if (ret < 0) {
 		DRM_DEBUG_KMS("failed iommu attach.\n");
-- 
1.9.2

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

* [PATCH v6 03/25] drm/exynos: iommu: detach from default dma-mapping domain on init
@ 2015-05-04  8:15   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds code, which detach sub-device nodes from default iommu
domain if such has been configured.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_iommu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index b32b291f88ff..323601a52a25 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -100,6 +100,9 @@ int drm_iommu_attach_device(struct drm_device *drm_dev,
 
 	dma_set_max_seg_size(subdrv_dev, 0xffffffffu);
 
+	if (subdrv_dev->archdata.mapping)
+		arm_iommu_detach_device(subdrv_dev);
+
 	ret = arm_iommu_attach_device(subdrv_dev, dev->archdata.mapping);
 	if (ret < 0) {
 		DRM_DEBUG_KMS("failed iommu attach.\n");
-- 
1.9.2

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

* [PATCH v6 04/25] drm/exynos: fimd: ensure proper hw state in fimd_clear_channel()
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:15   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

One should not do any assumptions on the stare of the fimd hardware
during driver initialization, so to properly reset fimd before enabling
IOMMU, one should ensure that all power domains and clocks are really
enabled. This patch adds calls to power on/off in the
fimd_clear_channel() function to ensure that any access to fimd
registers will be performed with clocks and power domains enabled.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 9819fa6a9e2a..cf64550df59d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -242,12 +242,20 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
 	writel(val, ctx->regs + SHADOWCON);
 }
 
-static void fimd_clear_channel(struct fimd_context *ctx)
+static int fimd_poweron(struct fimd_context *ctx);
+static int fimd_poweroff(struct fimd_context *ctx);
+
+static int fimd_clear_channel(struct fimd_context *ctx)
 {
-	int win, ch_enabled = 0;
+	int ret, win, ch_enabled = 0;
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
+	/* Hardware is in unknown state, so ensure it get enabled properly */
+	ret = fimd_poweron(ctx);
+	if (ret)
+		return ret;
+
 	/* Check if any channel is enabled. */
 	for (win = 0; win < WINDOWS_NR; win++) {
 		u32 val = readl(ctx->regs + WINCON(win));
@@ -258,19 +266,15 @@ static void fimd_clear_channel(struct fimd_context *ctx)
 			if (ctx->driver_data->has_shadowcon)
 				fimd_enable_shadow_channel_path(ctx, win,
 								false);
-
 			ch_enabled = 1;
 		}
 	}
 
 	/* Wait for vsync, as disable channel takes effect at next vsync */
-	if (ch_enabled) {
-		unsigned int state = ctx->suspended;
-
-		ctx->suspended = 0;
+	if (ch_enabled)
 		fimd_wait_for_vblank(ctx->crtc);
-		ctx->suspended = state;
-	}
+
+	return fimd_poweroff(ctx);
 }
 
 static int fimd_iommu_attach_devices(struct fimd_context *ctx,
@@ -285,7 +289,10 @@ static int fimd_iommu_attach_devices(struct fimd_context *ctx,
 		 * If any channel is already active, iommu will throw
 		 * a PAGE FAULT when enabled. So clear any channel if enabled.
 		 */
-		fimd_clear_channel(ctx);
+		ret = fimd_clear_channel(ctx);
+		if (ret)
+			return ret;
+
 		ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
 		if (ret) {
 			DRM_ERROR("drm_iommu_attach failed.\n");
-- 
1.9.2

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

* [PATCH v6 04/25] drm/exynos: fimd: ensure proper hw state in fimd_clear_channel()
@ 2015-05-04  8:15   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:15 UTC (permalink / raw)
  To: linux-arm-kernel

One should not do any assumptions on the stare of the fimd hardware
during driver initialization, so to properly reset fimd before enabling
IOMMU, one should ensure that all power domains and clocks are really
enabled. This patch adds calls to power on/off in the
fimd_clear_channel() function to ensure that any access to fimd
registers will be performed with clocks and power domains enabled.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 9819fa6a9e2a..cf64550df59d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -242,12 +242,20 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
 	writel(val, ctx->regs + SHADOWCON);
 }
 
-static void fimd_clear_channel(struct fimd_context *ctx)
+static int fimd_poweron(struct fimd_context *ctx);
+static int fimd_poweroff(struct fimd_context *ctx);
+
+static int fimd_clear_channel(struct fimd_context *ctx)
 {
-	int win, ch_enabled = 0;
+	int ret, win, ch_enabled = 0;
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
+	/* Hardware is in unknown state, so ensure it get enabled properly */
+	ret = fimd_poweron(ctx);
+	if (ret)
+		return ret;
+
 	/* Check if any channel is enabled. */
 	for (win = 0; win < WINDOWS_NR; win++) {
 		u32 val = readl(ctx->regs + WINCON(win));
@@ -258,19 +266,15 @@ static void fimd_clear_channel(struct fimd_context *ctx)
 			if (ctx->driver_data->has_shadowcon)
 				fimd_enable_shadow_channel_path(ctx, win,
 								false);
-
 			ch_enabled = 1;
 		}
 	}
 
 	/* Wait for vsync, as disable channel takes effect at next vsync */
-	if (ch_enabled) {
-		unsigned int state = ctx->suspended;
-
-		ctx->suspended = 0;
+	if (ch_enabled)
 		fimd_wait_for_vblank(ctx->crtc);
-		ctx->suspended = state;
-	}
+
+	return fimd_poweroff(ctx);
 }
 
 static int fimd_iommu_attach_devices(struct fimd_context *ctx,
@@ -285,7 +289,10 @@ static int fimd_iommu_attach_devices(struct fimd_context *ctx,
 		 * If any channel is already active, iommu will throw
 		 * a PAGE FAULT when enabled. So clear any channel if enabled.
 		 */
-		fimd_clear_channel(ctx);
+		ret = fimd_clear_channel(ctx);
+		if (ret)
+			return ret;
+
 		ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
 		if (ret) {
 			DRM_ERROR("drm_iommu_attach failed.\n");
-- 
1.9.2

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

* [PATCH v6 05/25] iommu: exynos: don't read version register on every tlb operation
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch removes reading of REG_MMU_VERSION register on every tlb
operation and caches SYSMMU version in driver's internal data.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 3e898504a7c4..3861485f0689 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -213,6 +213,7 @@ struct sysmmu_drvdata {
 	spinlock_t lock;
 	struct iommu_domain *domain;
 	phys_addr_t pgtable;
+	int version;
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
@@ -244,11 +245,6 @@ static void sysmmu_unblock(void __iomem *sfrbase)
 	__raw_writel(CTRL_ENABLE, sfrbase + REG_MMU_CTRL);
 }
 
-static unsigned int __raw_sysmmu_version(struct sysmmu_drvdata *data)
-{
-	return MMU_RAW_VER(__raw_readl(data->sfrbase + REG_MMU_VERSION));
-}
-
 static bool sysmmu_block(void __iomem *sfrbase)
 {
 	int i = 120;
@@ -408,7 +404,7 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
 	unsigned int cfg = CFG_LRU | CFG_QOS(15);
 	unsigned int ver;
 
-	ver = __raw_sysmmu_version(data);
+	ver = MMU_RAW_VER(__raw_readl(data->sfrbase + REG_MMU_VERSION));
 	if (MMU_MAJ_VER(ver) == 3) {
 		if (MMU_MIN_VER(ver) >= 2) {
 			cfg |= CFG_FLPDCACHE;
@@ -422,6 +418,7 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
 	}
 
 	__raw_writel(cfg, data->sfrbase + REG_MMU_CFG);
+	data->version = ver;
 }
 
 static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
@@ -531,7 +528,7 @@ static bool exynos_sysmmu_disable(struct device *dev)
 static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
 					      sysmmu_iova_t iova)
 {
-	if (__raw_sysmmu_version(data) == MAKE_MMU_VER(3, 3))
+	if (data->version == MAKE_MMU_VER(3, 3))
 		__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
 }
 
@@ -580,7 +577,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
 		 * 1MB page can be cached in one of all sets.
 		 * 64KB page can be one of 16 consecutive sets.
 		 */
-		if (MMU_MAJ_VER(__raw_sysmmu_version(data)) == 2)
+		if (MMU_MAJ_VER(data->version) == 2)
 			num_inv = min_t(unsigned int, size / PAGE_SIZE, 64);
 
 		if (sysmmu_block(data->sfrbase)) {
-- 
1.9.2

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

* [PATCH v6 05/25] iommu: exynos: don't read version register on every tlb operation
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes reading of REG_MMU_VERSION register on every tlb
operation and caches SYSMMU version in driver's internal data.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 3e898504a7c4..3861485f0689 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -213,6 +213,7 @@ struct sysmmu_drvdata {
 	spinlock_t lock;
 	struct iommu_domain *domain;
 	phys_addr_t pgtable;
+	int version;
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
@@ -244,11 +245,6 @@ static void sysmmu_unblock(void __iomem *sfrbase)
 	__raw_writel(CTRL_ENABLE, sfrbase + REG_MMU_CTRL);
 }
 
-static unsigned int __raw_sysmmu_version(struct sysmmu_drvdata *data)
-{
-	return MMU_RAW_VER(__raw_readl(data->sfrbase + REG_MMU_VERSION));
-}
-
 static bool sysmmu_block(void __iomem *sfrbase)
 {
 	int i = 120;
@@ -408,7 +404,7 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
 	unsigned int cfg = CFG_LRU | CFG_QOS(15);
 	unsigned int ver;
 
-	ver = __raw_sysmmu_version(data);
+	ver = MMU_RAW_VER(__raw_readl(data->sfrbase + REG_MMU_VERSION));
 	if (MMU_MAJ_VER(ver) == 3) {
 		if (MMU_MIN_VER(ver) >= 2) {
 			cfg |= CFG_FLPDCACHE;
@@ -422,6 +418,7 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
 	}
 
 	__raw_writel(cfg, data->sfrbase + REG_MMU_CFG);
+	data->version = ver;
 }
 
 static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
@@ -531,7 +528,7 @@ static bool exynos_sysmmu_disable(struct device *dev)
 static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
 					      sysmmu_iova_t iova)
 {
-	if (__raw_sysmmu_version(data) == MAKE_MMU_VER(3, 3))
+	if (data->version == MAKE_MMU_VER(3, 3))
 		__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
 }
 
@@ -580,7 +577,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
 		 * 1MB page can be cached in one of all sets.
 		 * 64KB page can be one of 16 consecutive sets.
 		 */
-		if (MMU_MAJ_VER(__raw_sysmmu_version(data)) == 2)
+		if (MMU_MAJ_VER(data->version) == 2)
 			num_inv = min_t(unsigned int, size / PAGE_SIZE, 64);
 
 		if (sysmmu_block(data->sfrbase)) {
-- 
1.9.2

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

* [PATCH v6 06/25] iommu: exynos: remove unused functions
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16     ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Rob Herring, Thierry Reding, Shaik Ameer Basha, Joonyoung Shim,
	Arnd Bergmann, Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw, Kyungmin Park, Kukjin Kim,
	Laurent Pinchart, Javier Martinez Canillas, Cho KyongHo,
	David Wodhouse

This patch removes two unneeded functions, which are not a part of
generic IOMMU API and were never used by any other driver.

Signed-off-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 drivers/iommu/exynos-iommu.c | 31 -------------------------------
 1 file changed, 31 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 3861485f0689..98aa7e9c2507 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -496,13 +496,6 @@ static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
 	return ret;
 }
 
-int exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable)
-{
-	BUG_ON(!memblock_is_memory(pgtable));
-
-	return __exynos_sysmmu_enable(dev, pgtable, NULL);
-}
-
 static bool exynos_sysmmu_disable(struct device *dev)
 {
 	unsigned long flags;
@@ -594,30 +587,6 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
 	spin_unlock_irqrestore(&data->lock, flags);
 }
 
-void exynos_sysmmu_tlb_invalidate(struct device *dev)
-{
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	unsigned long flags;
-	struct sysmmu_drvdata *data;
-
-	data = dev_get_drvdata(owner->sysmmu);
-
-	spin_lock_irqsave(&data->lock, flags);
-	if (is_sysmmu_active(data)) {
-		if (!IS_ERR(data->clk_master))
-			clk_enable(data->clk_master);
-		if (sysmmu_block(data->sfrbase)) {
-			__sysmmu_tlb_invalidate(data->sfrbase);
-			sysmmu_unblock(data->sfrbase);
-		}
-		if (!IS_ERR(data->clk_master))
-			clk_disable(data->clk_master);
-	} else {
-		dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
-	}
-	spin_unlock_irqrestore(&data->lock, flags);
-}
-
 static int __init exynos_sysmmu_probe(struct platform_device *pdev)
 {
 	int irq, ret;
-- 
1.9.2

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

* [PATCH v6 06/25] iommu: exynos: remove unused functions
@ 2015-05-04  8:16     ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes two unneeded functions, which are not a part of
generic IOMMU API and were never used by any other driver.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 31 -------------------------------
 1 file changed, 31 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 3861485f0689..98aa7e9c2507 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -496,13 +496,6 @@ static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
 	return ret;
 }
 
-int exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable)
-{
-	BUG_ON(!memblock_is_memory(pgtable));
-
-	return __exynos_sysmmu_enable(dev, pgtable, NULL);
-}
-
 static bool exynos_sysmmu_disable(struct device *dev)
 {
 	unsigned long flags;
@@ -594,30 +587,6 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
 	spin_unlock_irqrestore(&data->lock, flags);
 }
 
-void exynos_sysmmu_tlb_invalidate(struct device *dev)
-{
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	unsigned long flags;
-	struct sysmmu_drvdata *data;
-
-	data = dev_get_drvdata(owner->sysmmu);
-
-	spin_lock_irqsave(&data->lock, flags);
-	if (is_sysmmu_active(data)) {
-		if (!IS_ERR(data->clk_master))
-			clk_enable(data->clk_master);
-		if (sysmmu_block(data->sfrbase)) {
-			__sysmmu_tlb_invalidate(data->sfrbase);
-			sysmmu_unblock(data->sfrbase);
-		}
-		if (!IS_ERR(data->clk_master))
-			clk_disable(data->clk_master);
-	} else {
-		dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
-	}
-	spin_unlock_irqrestore(&data->lock, flags);
-}
-
 static int __init exynos_sysmmu_probe(struct platform_device *pdev)
 {
 	int irq, ret;
-- 
1.9.2

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

* [PATCH v6 07/25] iommu: exynos: remove useless spinlock
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch removes useless spinlocks and other unused members from
struct exynos_iommu_owner. There is no point is protecting this
structure by spinlock because content of this structure doesn't change
and other structures have their own spinlocks.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 98aa7e9c2507..c307c400613c 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -189,9 +189,6 @@ struct exynos_iommu_owner {
 	struct list_head client; /* entry of exynos_iommu_domain.clients */
 	struct device *dev;
 	struct device *sysmmu;
-	struct iommu_domain *domain;
-	void *vmm_data;         /* IO virtual memory manager's data */
-	spinlock_t lock;        /* Lock to preserve consistency of System MMU */
 };
 
 struct exynos_iommu_domain {
@@ -483,16 +480,12 @@ static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
 
 	BUG_ON(!has_sysmmu(dev));
 
-	spin_lock_irqsave(&owner->lock, flags);
-
 	data = dev_get_drvdata(owner->sysmmu);
 
 	ret = __sysmmu_enable(data, pgtable, domain);
 	if (ret >= 0)
 		data->master = dev;
 
-	spin_unlock_irqrestore(&owner->lock, flags);
-
 	return ret;
 }
 
@@ -505,16 +498,12 @@ static bool exynos_sysmmu_disable(struct device *dev)
 
 	BUG_ON(!has_sysmmu(dev));
 
-	spin_lock_irqsave(&owner->lock, flags);
-
 	data = dev_get_drvdata(owner->sysmmu);
 
 	disabled = __sysmmu_disable(data);
 	if (disabled)
 		data->master = NULL;
 
-	spin_unlock_irqrestore(&owner->lock, flags);
-
 	return disabled;
 }
 
-- 
1.9.2

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

* [PATCH v6 07/25] iommu: exynos: remove useless spinlock
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes useless spinlocks and other unused members from
struct exynos_iommu_owner. There is no point is protecting this
structure by spinlock because content of this structure doesn't change
and other structures have their own spinlocks.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 98aa7e9c2507..c307c400613c 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -189,9 +189,6 @@ struct exynos_iommu_owner {
 	struct list_head client; /* entry of exynos_iommu_domain.clients */
 	struct device *dev;
 	struct device *sysmmu;
-	struct iommu_domain *domain;
-	void *vmm_data;         /* IO virtual memory manager's data */
-	spinlock_t lock;        /* Lock to preserve consistency of System MMU */
 };
 
 struct exynos_iommu_domain {
@@ -483,16 +480,12 @@ static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
 
 	BUG_ON(!has_sysmmu(dev));
 
-	spin_lock_irqsave(&owner->lock, flags);
-
 	data = dev_get_drvdata(owner->sysmmu);
 
 	ret = __sysmmu_enable(data, pgtable, domain);
 	if (ret >= 0)
 		data->master = dev;
 
-	spin_unlock_irqrestore(&owner->lock, flags);
-
 	return ret;
 }
 
@@ -505,16 +498,12 @@ static bool exynos_sysmmu_disable(struct device *dev)
 
 	BUG_ON(!has_sysmmu(dev));
 
-	spin_lock_irqsave(&owner->lock, flags);
-
 	data = dev_get_drvdata(owner->sysmmu);
 
 	disabled = __sysmmu_disable(data);
 	if (disabled)
 		data->master = NULL;
 
-	spin_unlock_irqrestore(&owner->lock, flags);
-
 	return disabled;
 }
 
-- 
1.9.2

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

* [PATCH v6 08/25] iommu: exynos: refactor function parameters to simplify code
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch simplifies the code by:
- refactoring function parameters from struct device pointer to direct
  pointer to struct sysmmu drvdata
- moving list_head enteries from struct exynos_iommu_owner directly to
  struct sysmmu_drvdata

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 93 ++++++++++++++++++++++----------------------
 1 file changed, 46 insertions(+), 47 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index c307c400613c..0c23b69022cd 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -186,8 +186,6 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
 
 /* attached to dev.archdata.iommu of the master device */
 struct exynos_iommu_owner {
-	struct list_head client; /* entry of exynos_iommu_domain.clients */
-	struct device *dev;
 	struct device *sysmmu;
 };
 
@@ -209,6 +207,7 @@ struct sysmmu_drvdata {
 	int activations;
 	spinlock_t lock;
 	struct iommu_domain *domain;
+	struct list_head domain_node;
 	phys_addr_t pgtable;
 	int version;
 };
@@ -514,12 +513,10 @@ static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
 		__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
 }
 
-static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
+static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
 					    sysmmu_iova_t iova)
 {
 	unsigned long flags;
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	struct sysmmu_drvdata *data = dev_get_drvdata(owner->sysmmu);
 
 	if (!IS_ERR(data->clk_master))
 		clk_enable(data->clk_master);
@@ -533,14 +530,10 @@ static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
 		clk_disable(data->clk_master);
 }
 
-static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
-					size_t size)
+static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
+					sysmmu_iova_t iova, size_t size)
 {
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
 	unsigned long flags;
-	struct sysmmu_drvdata *data;
-
-	data = dev_get_drvdata(owner->sysmmu);
 
 	spin_lock_irqsave(&data->lock, flags);
 	if (is_sysmmu_active(data)) {
@@ -570,8 +563,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
 		if (!IS_ERR(data->clk_master))
 			clk_disable(data->clk_master);
 	} else {
-		dev_dbg(dev, "disabled. Skipping TLB invalidation @ %#x\n",
-			iova);
+		dev_dbg(data->master,
+			"disabled. Skipping TLB invalidation @ %#x\n", iova);
 	}
 	spin_unlock_irqrestore(&data->lock, flags);
 }
@@ -711,7 +704,7 @@ err_pgtable:
 static void exynos_iommu_domain_free(struct iommu_domain *domain)
 {
 	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
-	struct exynos_iommu_owner *owner;
+	struct sysmmu_drvdata *data;
 	unsigned long flags;
 	int i;
 
@@ -719,14 +712,12 @@ static void exynos_iommu_domain_free(struct iommu_domain *domain)
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	list_for_each_entry(owner, &priv->clients, client) {
-		while (!exynos_sysmmu_disable(owner->dev))
-			; /* until System MMU is actually disabled */
+	list_for_each_entry(data, &priv->clients, domain_node) {
+		if (__sysmmu_disable(data))
+			data->master = NULL;
+		list_del_init(&data->domain_node);
 	}
 
-	while (!list_empty(&priv->clients))
-		list_del_init(priv->clients.next);
-
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	for (i = 0; i < NUM_LV1ENTRIES; i++)
@@ -744,20 +735,26 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 {
 	struct exynos_iommu_owner *owner = dev->archdata.iommu;
 	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct sysmmu_drvdata *data;
 	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
 	unsigned long flags;
-	int ret;
+	int ret = -ENODEV;
 
-	spin_lock_irqsave(&priv->lock, flags);
+	if (!has_sysmmu(dev))
+		return -ENODEV;
 
-	ret = __exynos_sysmmu_enable(dev, pagetable, domain);
-	if (ret == 0) {
-		list_add_tail(&owner->client, &priv->clients);
-		owner->domain = domain;
+	data = dev_get_drvdata(owner->sysmmu);
+	if (data) {
+		ret = __sysmmu_enable(data, pagetable, domain);
+		if (ret >= 0) {
+			data->master = dev;
+
+			spin_lock_irqsave(&priv->lock, flags);
+			list_add_tail(&data->domain_node, &priv->clients);
+			spin_unlock_irqrestore(&priv->lock, flags);
+		}
 	}
 
-	spin_unlock_irqrestore(&priv->lock, flags);
-
 	if (ret < 0) {
 		dev_err(dev, "%s: Failed to attach IOMMU with pgtable %pa\n",
 					__func__, &pagetable);
@@ -773,26 +770,29 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 static void exynos_iommu_detach_device(struct iommu_domain *domain,
 				    struct device *dev)
 {
-	struct exynos_iommu_owner *owner;
 	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
+	struct sysmmu_drvdata *data;
 	unsigned long flags;
+	bool found = false;
 
-	spin_lock_irqsave(&priv->lock, flags);
+	if (!has_sysmmu(dev))
+		return;
 
-	list_for_each_entry(owner, &priv->clients, client) {
-		if (owner == dev->archdata.iommu) {
-			if (exynos_sysmmu_disable(dev)) {
-				list_del_init(&owner->client);
-				owner->domain = NULL;
+	spin_lock_irqsave(&priv->lock, flags);
+	list_for_each_entry(data, &priv->clients, domain_node) {
+		if (data->master == dev) {
+			if (__sysmmu_disable(data)) {
+				data->master = NULL;
+				list_del_init(&data->domain_node);
 			}
+			found = true;
 			break;
 		}
 	}
-
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	if (owner == dev->archdata.iommu)
+	if (found)
 		dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
 					__func__, &pagetable);
 	else
@@ -839,12 +839,11 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
 		 * not currently mapped.
 		 */
 		if (need_flush_flpd_cache) {
-			struct exynos_iommu_owner *owner;
+			struct sysmmu_drvdata *data;
 
 			spin_lock(&priv->lock);
-			list_for_each_entry(owner, &priv->clients, client)
-				sysmmu_tlb_invalidate_flpdcache(
-							owner->dev, iova);
+			list_for_each_entry(data, &priv->clients, domain_node)
+				sysmmu_tlb_invalidate_flpdcache(data, iova);
 			spin_unlock(&priv->lock);
 		}
 	}
@@ -879,13 +878,13 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
 
 	spin_lock(&priv->lock);
 	if (lv1ent_page_zero(sent)) {
-		struct exynos_iommu_owner *owner;
+		struct sysmmu_drvdata *data;
 		/*
 		 * Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
 		 * entry by speculative prefetch of SLPD which has no mapping.
 		 */
-		list_for_each_entry(owner, &priv->clients, client)
-			sysmmu_tlb_invalidate_flpdcache(owner->dev, iova);
+		list_for_each_entry(data, &priv->clients, domain_node)
+			sysmmu_tlb_invalidate_flpdcache(data, iova);
 	}
 	spin_unlock(&priv->lock);
 
@@ -990,13 +989,13 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
 static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
 						sysmmu_iova_t iova, size_t size)
 {
-	struct exynos_iommu_owner *owner;
+	struct sysmmu_drvdata *data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	list_for_each_entry(owner, &priv->clients, client)
-		sysmmu_tlb_invalidate_entry(owner->dev, iova, size);
+	list_for_each_entry(data, &priv->clients, domain_node)
+		sysmmu_tlb_invalidate_entry(data, iova, size);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
-- 
1.9.2

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

* [PATCH v6 08/25] iommu: exynos: refactor function parameters to simplify code
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch simplifies the code by:
- refactoring function parameters from struct device pointer to direct
  pointer to struct sysmmu drvdata
- moving list_head enteries from struct exynos_iommu_owner directly to
  struct sysmmu_drvdata

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 93 ++++++++++++++++++++++----------------------
 1 file changed, 46 insertions(+), 47 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index c307c400613c..0c23b69022cd 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -186,8 +186,6 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
 
 /* attached to dev.archdata.iommu of the master device */
 struct exynos_iommu_owner {
-	struct list_head client; /* entry of exynos_iommu_domain.clients */
-	struct device *dev;
 	struct device *sysmmu;
 };
 
@@ -209,6 +207,7 @@ struct sysmmu_drvdata {
 	int activations;
 	spinlock_t lock;
 	struct iommu_domain *domain;
+	struct list_head domain_node;
 	phys_addr_t pgtable;
 	int version;
 };
@@ -514,12 +513,10 @@ static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
 		__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
 }
 
-static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
+static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
 					    sysmmu_iova_t iova)
 {
 	unsigned long flags;
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	struct sysmmu_drvdata *data = dev_get_drvdata(owner->sysmmu);
 
 	if (!IS_ERR(data->clk_master))
 		clk_enable(data->clk_master);
@@ -533,14 +530,10 @@ static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
 		clk_disable(data->clk_master);
 }
 
-static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
-					size_t size)
+static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
+					sysmmu_iova_t iova, size_t size)
 {
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
 	unsigned long flags;
-	struct sysmmu_drvdata *data;
-
-	data = dev_get_drvdata(owner->sysmmu);
 
 	spin_lock_irqsave(&data->lock, flags);
 	if (is_sysmmu_active(data)) {
@@ -570,8 +563,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
 		if (!IS_ERR(data->clk_master))
 			clk_disable(data->clk_master);
 	} else {
-		dev_dbg(dev, "disabled. Skipping TLB invalidation @ %#x\n",
-			iova);
+		dev_dbg(data->master,
+			"disabled. Skipping TLB invalidation @ %#x\n", iova);
 	}
 	spin_unlock_irqrestore(&data->lock, flags);
 }
@@ -711,7 +704,7 @@ err_pgtable:
 static void exynos_iommu_domain_free(struct iommu_domain *domain)
 {
 	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
-	struct exynos_iommu_owner *owner;
+	struct sysmmu_drvdata *data;
 	unsigned long flags;
 	int i;
 
@@ -719,14 +712,12 @@ static void exynos_iommu_domain_free(struct iommu_domain *domain)
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	list_for_each_entry(owner, &priv->clients, client) {
-		while (!exynos_sysmmu_disable(owner->dev))
-			; /* until System MMU is actually disabled */
+	list_for_each_entry(data, &priv->clients, domain_node) {
+		if (__sysmmu_disable(data))
+			data->master = NULL;
+		list_del_init(&data->domain_node);
 	}
 
-	while (!list_empty(&priv->clients))
-		list_del_init(priv->clients.next);
-
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	for (i = 0; i < NUM_LV1ENTRIES; i++)
@@ -744,20 +735,26 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 {
 	struct exynos_iommu_owner *owner = dev->archdata.iommu;
 	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct sysmmu_drvdata *data;
 	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
 	unsigned long flags;
-	int ret;
+	int ret = -ENODEV;
 
-	spin_lock_irqsave(&priv->lock, flags);
+	if (!has_sysmmu(dev))
+		return -ENODEV;
 
-	ret = __exynos_sysmmu_enable(dev, pagetable, domain);
-	if (ret == 0) {
-		list_add_tail(&owner->client, &priv->clients);
-		owner->domain = domain;
+	data = dev_get_drvdata(owner->sysmmu);
+	if (data) {
+		ret = __sysmmu_enable(data, pagetable, domain);
+		if (ret >= 0) {
+			data->master = dev;
+
+			spin_lock_irqsave(&priv->lock, flags);
+			list_add_tail(&data->domain_node, &priv->clients);
+			spin_unlock_irqrestore(&priv->lock, flags);
+		}
 	}
 
-	spin_unlock_irqrestore(&priv->lock, flags);
-
 	if (ret < 0) {
 		dev_err(dev, "%s: Failed to attach IOMMU with pgtable %pa\n",
 					__func__, &pagetable);
@@ -773,26 +770,29 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 static void exynos_iommu_detach_device(struct iommu_domain *domain,
 				    struct device *dev)
 {
-	struct exynos_iommu_owner *owner;
 	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
+	struct sysmmu_drvdata *data;
 	unsigned long flags;
+	bool found = false;
 
-	spin_lock_irqsave(&priv->lock, flags);
+	if (!has_sysmmu(dev))
+		return;
 
-	list_for_each_entry(owner, &priv->clients, client) {
-		if (owner == dev->archdata.iommu) {
-			if (exynos_sysmmu_disable(dev)) {
-				list_del_init(&owner->client);
-				owner->domain = NULL;
+	spin_lock_irqsave(&priv->lock, flags);
+	list_for_each_entry(data, &priv->clients, domain_node) {
+		if (data->master == dev) {
+			if (__sysmmu_disable(data)) {
+				data->master = NULL;
+				list_del_init(&data->domain_node);
 			}
+			found = true;
 			break;
 		}
 	}
-
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	if (owner == dev->archdata.iommu)
+	if (found)
 		dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
 					__func__, &pagetable);
 	else
@@ -839,12 +839,11 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
 		 * not currently mapped.
 		 */
 		if (need_flush_flpd_cache) {
-			struct exynos_iommu_owner *owner;
+			struct sysmmu_drvdata *data;
 
 			spin_lock(&priv->lock);
-			list_for_each_entry(owner, &priv->clients, client)
-				sysmmu_tlb_invalidate_flpdcache(
-							owner->dev, iova);
+			list_for_each_entry(data, &priv->clients, domain_node)
+				sysmmu_tlb_invalidate_flpdcache(data, iova);
 			spin_unlock(&priv->lock);
 		}
 	}
@@ -879,13 +878,13 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
 
 	spin_lock(&priv->lock);
 	if (lv1ent_page_zero(sent)) {
-		struct exynos_iommu_owner *owner;
+		struct sysmmu_drvdata *data;
 		/*
 		 * Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
 		 * entry by speculative prefetch of SLPD which has no mapping.
 		 */
-		list_for_each_entry(owner, &priv->clients, client)
-			sysmmu_tlb_invalidate_flpdcache(owner->dev, iova);
+		list_for_each_entry(data, &priv->clients, domain_node)
+			sysmmu_tlb_invalidate_flpdcache(data, iova);
 	}
 	spin_unlock(&priv->lock);
 
@@ -990,13 +989,13 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
 static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
 						sysmmu_iova_t iova, size_t size)
 {
-	struct exynos_iommu_owner *owner;
+	struct sysmmu_drvdata *data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	list_for_each_entry(owner, &priv->clients, client)
-		sysmmu_tlb_invalidate_entry(owner->dev, iova, size);
+	list_for_each_entry(data, &priv->clients, domain_node)
+		sysmmu_tlb_invalidate_entry(data, iova, size);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
-- 
1.9.2

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

* [PATCH v6 09/25] iommu: exynos: remove unused functions, part 2
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

After refactoring functions to use pointer to struct sysmmu_drvdata
directly, some functions became useless and thus never used, so remove
them completely.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 43 -------------------------------------------
 1 file changed, 43 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 0c23b69022cd..7d62715ab51e 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -463,49 +463,6 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
 	return ret;
 }
 
-/* __exynos_sysmmu_enable: Enables System MMU
- *
- * returns -error if an error occurred and System MMU is not enabled,
- * 0 if the System MMU has been just enabled and 1 if System MMU was already
- * enabled before.
- */
-static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
-				  struct iommu_domain *domain)
-{
-	int ret = 0;
-	unsigned long flags;
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	struct sysmmu_drvdata *data;
-
-	BUG_ON(!has_sysmmu(dev));
-
-	data = dev_get_drvdata(owner->sysmmu);
-
-	ret = __sysmmu_enable(data, pgtable, domain);
-	if (ret >= 0)
-		data->master = dev;
-
-	return ret;
-}
-
-static bool exynos_sysmmu_disable(struct device *dev)
-{
-	unsigned long flags;
-	bool disabled = true;
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	struct sysmmu_drvdata *data;
-
-	BUG_ON(!has_sysmmu(dev));
-
-	data = dev_get_drvdata(owner->sysmmu);
-
-	disabled = __sysmmu_disable(data);
-	if (disabled)
-		data->master = NULL;
-
-	return disabled;
-}
-
 static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
 					      sysmmu_iova_t iova)
 {
-- 
1.9.2

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

* [PATCH v6 09/25] iommu: exynos: remove unused functions, part 2
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

After refactoring functions to use pointer to struct sysmmu_drvdata
directly, some functions became useless and thus never used, so remove
them completely.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 43 -------------------------------------------
 1 file changed, 43 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 0c23b69022cd..7d62715ab51e 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -463,49 +463,6 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
 	return ret;
 }
 
-/* __exynos_sysmmu_enable: Enables System MMU
- *
- * returns -error if an error occurred and System MMU is not enabled,
- * 0 if the System MMU has been just enabled and 1 if System MMU was already
- * enabled before.
- */
-static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
-				  struct iommu_domain *domain)
-{
-	int ret = 0;
-	unsigned long flags;
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	struct sysmmu_drvdata *data;
-
-	BUG_ON(!has_sysmmu(dev));
-
-	data = dev_get_drvdata(owner->sysmmu);
-
-	ret = __sysmmu_enable(data, pgtable, domain);
-	if (ret >= 0)
-		data->master = dev;
-
-	return ret;
-}
-
-static bool exynos_sysmmu_disable(struct device *dev)
-{
-	unsigned long flags;
-	bool disabled = true;
-	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	struct sysmmu_drvdata *data;
-
-	BUG_ON(!has_sysmmu(dev));
-
-	data = dev_get_drvdata(owner->sysmmu);
-
-	disabled = __sysmmu_disable(data);
-	if (disabled)
-		data->master = NULL;
-
-	return disabled;
-}
-
 static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
 					      sysmmu_iova_t iova)
 {
-- 
1.9.2

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

* [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

The driver doesn't need to do anything important in device add/remove
callbacks, because initialization will be done from device-tree specific
callbacks added later. IOMMU groups created by current code were never
used.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 28 ----------------------------
 1 file changed, 28 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 7d62715ab51e..f2eceb6605c5 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1062,32 +1062,6 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
 	return phys;
 }
 
-static int exynos_iommu_add_device(struct device *dev)
-{
-	struct iommu_group *group;
-	int ret;
-
-	group = iommu_group_get(dev);
-
-	if (!group) {
-		group = iommu_group_alloc();
-		if (IS_ERR(group)) {
-			dev_err(dev, "Failed to allocate IOMMU group\n");
-			return PTR_ERR(group);
-		}
-	}
-
-	ret = iommu_group_add_device(group, dev);
-	iommu_group_put(group);
-
-	return ret;
-}
-
-static void exynos_iommu_remove_device(struct device *dev)
-{
-	iommu_group_remove_device(dev);
-}
-
 static const struct iommu_ops exynos_iommu_ops = {
 	.domain_alloc = exynos_iommu_domain_alloc,
 	.domain_free = exynos_iommu_domain_free,
@@ -1097,8 +1071,6 @@ static const struct iommu_ops exynos_iommu_ops = {
 	.unmap = exynos_iommu_unmap,
 	.map_sg = default_iommu_map_sg,
 	.iova_to_phys = exynos_iommu_iova_to_phys,
-	.add_device = exynos_iommu_add_device,
-	.remove_device = exynos_iommu_remove_device,
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 };
 
-- 
1.9.2

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

* [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

The driver doesn't need to do anything important in device add/remove
callbacks, because initialization will be done from device-tree specific
callbacks added later. IOMMU groups created by current code were never
used.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 28 ----------------------------
 1 file changed, 28 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 7d62715ab51e..f2eceb6605c5 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1062,32 +1062,6 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
 	return phys;
 }
 
-static int exynos_iommu_add_device(struct device *dev)
-{
-	struct iommu_group *group;
-	int ret;
-
-	group = iommu_group_get(dev);
-
-	if (!group) {
-		group = iommu_group_alloc();
-		if (IS_ERR(group)) {
-			dev_err(dev, "Failed to allocate IOMMU group\n");
-			return PTR_ERR(group);
-		}
-	}
-
-	ret = iommu_group_add_device(group, dev);
-	iommu_group_put(group);
-
-	return ret;
-}
-
-static void exynos_iommu_remove_device(struct device *dev)
-{
-	iommu_group_remove_device(dev);
-}
-
 static const struct iommu_ops exynos_iommu_ops = {
 	.domain_alloc = exynos_iommu_domain_alloc,
 	.domain_free = exynos_iommu_domain_free,
@@ -1097,8 +1071,6 @@ static const struct iommu_ops exynos_iommu_ops = {
 	.unmap = exynos_iommu_unmap,
 	.map_sg = default_iommu_map_sg,
 	.iova_to_phys = exynos_iommu_iova_to_phys,
-	.add_device = exynos_iommu_add_device,
-	.remove_device = exynos_iommu_remove_device,
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 };
 
-- 
1.9.2

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

* [PATCH v6 11/25] iommu: exynos: add support for binding more than one sysmmu to master device
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch adds support for assigning more than one SYSMMU controller to
the master device. This has been achieved simply by chaning the struct
device pointer in struct exynos_iommu_owner into the list of struct
sysmmu_drvdata of all controllers assigned to the given master device.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index f2eceb6605c5..598660c87410 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -186,7 +186,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
 
 /* attached to dev.archdata.iommu of the master device */
 struct exynos_iommu_owner {
-	struct device *sysmmu;
+	struct list_head clients;
 };
 
 struct exynos_iommu_domain {
@@ -208,6 +208,7 @@ struct sysmmu_drvdata {
 	spinlock_t lock;
 	struct iommu_domain *domain;
 	struct list_head domain_node;
+	struct list_head owner_node;
 	phys_addr_t pgtable;
 	int version;
 };
@@ -700,8 +701,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 	if (!has_sysmmu(dev))
 		return -ENODEV;
 
-	data = dev_get_drvdata(owner->sysmmu);
-	if (data) {
+	list_for_each_entry(data, &owner->clients, owner_node) {
 		ret = __sysmmu_enable(data, pagetable, domain);
 		if (ret >= 0) {
 			data->master = dev;
@@ -729,7 +729,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 {
 	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
-	struct sysmmu_drvdata *data;
+	struct sysmmu_drvdata *data, *next;
 	unsigned long flags;
 	bool found = false;
 
@@ -737,14 +737,13 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 		return;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	list_for_each_entry(data, &priv->clients, domain_node) {
+	list_for_each_entry_safe(data, next, &priv->clients, domain_node) {
 		if (data->master == dev) {
 			if (__sysmmu_disable(data)) {
 				data->master = NULL;
 				list_del_init(&data->domain_node);
 			}
 			found = true;
-			break;
 		}
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
-- 
1.9.2

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

* [PATCH v6 11/25] iommu: exynos: add support for binding more than one sysmmu to master device
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for assigning more than one SYSMMU controller to
the master device. This has been achieved simply by chaning the struct
device pointer in struct exynos_iommu_owner into the list of struct
sysmmu_drvdata of all controllers assigned to the given master device.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index f2eceb6605c5..598660c87410 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -186,7 +186,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
 
 /* attached to dev.archdata.iommu of the master device */
 struct exynos_iommu_owner {
-	struct device *sysmmu;
+	struct list_head clients;
 };
 
 struct exynos_iommu_domain {
@@ -208,6 +208,7 @@ struct sysmmu_drvdata {
 	spinlock_t lock;
 	struct iommu_domain *domain;
 	struct list_head domain_node;
+	struct list_head owner_node;
 	phys_addr_t pgtable;
 	int version;
 };
@@ -700,8 +701,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 	if (!has_sysmmu(dev))
 		return -ENODEV;
 
-	data = dev_get_drvdata(owner->sysmmu);
-	if (data) {
+	list_for_each_entry(data, &owner->clients, owner_node) {
 		ret = __sysmmu_enable(data, pagetable, domain);
 		if (ret >= 0) {
 			data->master = dev;
@@ -729,7 +729,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 {
 	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
 	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
-	struct sysmmu_drvdata *data;
+	struct sysmmu_drvdata *data, *next;
 	unsigned long flags;
 	bool found = false;
 
@@ -737,14 +737,13 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 		return;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	list_for_each_entry(data, &priv->clients, domain_node) {
+	list_for_each_entry_safe(data, next, &priv->clients, domain_node) {
 		if (data->master == dev) {
 			if (__sysmmu_disable(data)) {
 				data->master = NULL;
 				list_del_init(&data->domain_node);
 			}
 			found = true;
-			break;
 		}
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
-- 
1.9.2

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

* [PATCH v6 12/25] iommu: exynos: add support for runtime_pm
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch fixes support for runtime power management for SYSMMU
controllers, so they are enabled when master device is attached.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 598660c87410..734107ec78fa 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -702,6 +702,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 		return -ENODEV;
 
 	list_for_each_entry(data, &owner->clients, owner_node) {
+		pm_runtime_get_sync(data->sysmmu);
 		ret = __sysmmu_enable(data, pagetable, domain);
 		if (ret >= 0) {
 			data->master = dev;
@@ -743,6 +744,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 				data->master = NULL;
 				list_del_init(&data->domain_node);
 			}
+			pm_runtime_put(data->sysmmu);
 			found = true;
 		}
 	}
-- 
1.9.2

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

* [PATCH v6 12/25] iommu: exynos: add support for runtime_pm
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch fixes support for runtime power management for SYSMMU
controllers, so they are enabled when master device is attached.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 598660c87410..734107ec78fa 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -702,6 +702,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 		return -ENODEV;
 
 	list_for_each_entry(data, &owner->clients, owner_node) {
+		pm_runtime_get_sync(data->sysmmu);
 		ret = __sysmmu_enable(data, pagetable, domain);
 		if (ret >= 0) {
 			data->master = dev;
@@ -743,6 +744,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 				data->master = NULL;
 				list_del_init(&data->domain_node);
 			}
+			pm_runtime_put(data->sysmmu);
 			found = true;
 		}
 	}
-- 
1.9.2

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

* [PATCH v6 13/25] iommu: exynos: rename variables to reflect their purpose
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch renames some variables to make the code easier to understand.
'domain' is replaced by 'iommu_domain' (more generic entity) and really
meaningless 'priv' by 'domain' to reflect its purpose.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 187 ++++++++++++++++++++++---------------------
 1 file changed, 94 insertions(+), 93 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 734107ec78fa..a58f4a4c91d0 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -436,8 +436,8 @@ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
 		clk_disable(data->clk_master);
 }
 
-static int __sysmmu_enable(struct sysmmu_drvdata *data,
-			phys_addr_t pgtable, struct iommu_domain *domain)
+static int __sysmmu_enable(struct sysmmu_drvdata *data, phys_addr_t pgtable,
+			   struct iommu_domain *iommu_domain)
 {
 	int ret = 0;
 	unsigned long flags;
@@ -445,7 +445,7 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
 	spin_lock_irqsave(&data->lock, flags);
 	if (set_sysmmu_active(data)) {
 		data->pgtable = pgtable;
-		data->domain = domain;
+		data->domain = iommu_domain;
 
 		__sysmmu_enable_nocount(data);
 
@@ -610,91 +610,91 @@ static inline void pgtable_flush(void *vastart, void *vaend)
 
 static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
 {
-	struct exynos_iommu_domain *exynos_domain;
+	struct exynos_iommu_domain *domain;
 	int i;
 
 	if (type != IOMMU_DOMAIN_UNMANAGED)
 		return NULL;
 
-	exynos_domain = kzalloc(sizeof(*exynos_domain), GFP_KERNEL);
-	if (!exynos_domain)
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (!domain)
 		return NULL;
 
-	exynos_domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
-	if (!exynos_domain->pgtable)
+	domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
+	if (!domain->pgtable)
 		goto err_pgtable;
 
-	exynos_domain->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
-	if (!exynos_domain->lv2entcnt)
+	domain->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
+	if (!domain->lv2entcnt)
 		goto err_counter;
 
 	/* Workaround for System MMU v3.3 to prevent caching 1MiB mapping */
 	for (i = 0; i < NUM_LV1ENTRIES; i += 8) {
-		exynos_domain->pgtable[i + 0] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 1] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 2] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 3] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 4] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 5] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 6] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 7] = ZERO_LV2LINK;
+		domain->pgtable[i + 0] = ZERO_LV2LINK;
+		domain->pgtable[i + 1] = ZERO_LV2LINK;
+		domain->pgtable[i + 2] = ZERO_LV2LINK;
+		domain->pgtable[i + 3] = ZERO_LV2LINK;
+		domain->pgtable[i + 4] = ZERO_LV2LINK;
+		domain->pgtable[i + 5] = ZERO_LV2LINK;
+		domain->pgtable[i + 6] = ZERO_LV2LINK;
+		domain->pgtable[i + 7] = ZERO_LV2LINK;
 	}
 
-	pgtable_flush(exynos_domain->pgtable, exynos_domain->pgtable + NUM_LV1ENTRIES);
+	pgtable_flush(domain->pgtable, domain->pgtable + NUM_LV1ENTRIES);
 
-	spin_lock_init(&exynos_domain->lock);
-	spin_lock_init(&exynos_domain->pgtablelock);
-	INIT_LIST_HEAD(&exynos_domain->clients);
+	spin_lock_init(&domain->lock);
+	spin_lock_init(&domain->pgtablelock);
+	INIT_LIST_HEAD(&domain->clients);
 
-	exynos_domain->domain.geometry.aperture_start = 0;
-	exynos_domain->domain.geometry.aperture_end   = ~0UL;
-	exynos_domain->domain.geometry.force_aperture = true;
+	domain->domain.geometry.aperture_start = 0;
+	domain->domain.geometry.aperture_end   = ~0UL;
+	domain->domain.geometry.force_aperture = true;
 
-	return &exynos_domain->domain;
+	return &domain->domain;
 
 err_counter:
-	free_pages((unsigned long)exynos_domain->pgtable, 2);
+	free_pages((unsigned long)domain->pgtable, 2);
 err_pgtable:
-	kfree(exynos_domain);
+	kfree(domain);
 	return NULL;
 }
 
-static void exynos_iommu_domain_free(struct iommu_domain *domain)
+static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	struct sysmmu_drvdata *data;
 	unsigned long flags;
 	int i;
 
-	WARN_ON(!list_empty(&priv->clients));
+	WARN_ON(!list_empty(&domain->clients));
 
-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&domain->lock, flags);
 
-	list_for_each_entry(data, &priv->clients, domain_node) {
+	list_for_each_entry(data, &domain->clients, domain_node) {
 		if (__sysmmu_disable(data))
 			data->master = NULL;
 		list_del_init(&data->domain_node);
 	}
 
-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&domain->lock, flags);
 
 	for (i = 0; i < NUM_LV1ENTRIES; i++)
-		if (lv1ent_page(priv->pgtable + i))
+		if (lv1ent_page(domain->pgtable + i))
 			kmem_cache_free(lv2table_kmem_cache,
-				phys_to_virt(lv2table_base(priv->pgtable + i)));
+				phys_to_virt(lv2table_base(domain->pgtable + i)));
 
-	free_pages((unsigned long)priv->pgtable, 2);
-	free_pages((unsigned long)priv->lv2entcnt, 1);
-	kfree(priv);
+	free_pages((unsigned long)domain->pgtable, 2);
+	free_pages((unsigned long)domain->lv2entcnt, 1);
+	kfree(domain);
 }
 
-static int exynos_iommu_attach_device(struct iommu_domain *domain,
+static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
 				   struct device *dev)
 {
 	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	struct sysmmu_drvdata *data;
-	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
+	phys_addr_t pagetable = virt_to_phys(domain->pgtable);
 	unsigned long flags;
 	int ret = -ENODEV;
 
@@ -703,13 +703,13 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 
 	list_for_each_entry(data, &owner->clients, owner_node) {
 		pm_runtime_get_sync(data->sysmmu);
-		ret = __sysmmu_enable(data, pagetable, domain);
+		ret = __sysmmu_enable(data, pagetable, iommu_domain);
 		if (ret >= 0) {
 			data->master = dev;
 
-			spin_lock_irqsave(&priv->lock, flags);
-			list_add_tail(&data->domain_node, &priv->clients);
-			spin_unlock_irqrestore(&priv->lock, flags);
+			spin_lock_irqsave(&domain->lock, flags);
+			list_add_tail(&data->domain_node, &domain->clients);
+			spin_unlock_irqrestore(&domain->lock, flags);
 		}
 	}
 
@@ -725,11 +725,11 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 	return ret;
 }
 
-static void exynos_iommu_detach_device(struct iommu_domain *domain,
+static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
 				    struct device *dev)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
-	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
+	phys_addr_t pagetable = virt_to_phys(domain->pgtable);
 	struct sysmmu_drvdata *data, *next;
 	unsigned long flags;
 	bool found = false;
@@ -737,8 +737,8 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 	if (!has_sysmmu(dev))
 		return;
 
-	spin_lock_irqsave(&priv->lock, flags);
-	list_for_each_entry_safe(data, next, &priv->clients, domain_node) {
+	spin_lock_irqsave(&domain->lock, flags);
+	list_for_each_entry_safe(data, next, &domain->clients, domain_node) {
 		if (data->master == dev) {
 			if (__sysmmu_disable(data)) {
 				data->master = NULL;
@@ -748,7 +748,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 			found = true;
 		}
 	}
-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&domain->lock, flags);
 
 	if (found)
 		dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
@@ -757,7 +757,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 		dev_err(dev, "%s: No IOMMU is attached\n", __func__);
 }
 
-static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
+static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *domain,
 		sysmmu_pte_t *sent, sysmmu_iova_t iova, short *pgcounter)
 {
 	if (lv1ent_section(sent)) {
@@ -799,17 +799,17 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
 		if (need_flush_flpd_cache) {
 			struct sysmmu_drvdata *data;
 
-			spin_lock(&priv->lock);
-			list_for_each_entry(data, &priv->clients, domain_node)
+			spin_lock(&domain->lock);
+			list_for_each_entry(data, &domain->clients, domain_node)
 				sysmmu_tlb_invalidate_flpdcache(data, iova);
-			spin_unlock(&priv->lock);
+			spin_unlock(&domain->lock);
 		}
 	}
 
 	return page_entry(sent, iova);
 }
 
-static int lv1set_section(struct exynos_iommu_domain *priv,
+static int lv1set_section(struct exynos_iommu_domain *domain,
 			  sysmmu_pte_t *sent, sysmmu_iova_t iova,
 			  phys_addr_t paddr, short *pgcnt)
 {
@@ -834,17 +834,17 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
 
 	pgtable_flush(sent, sent + 1);
 
-	spin_lock(&priv->lock);
+	spin_lock(&domain->lock);
 	if (lv1ent_page_zero(sent)) {
 		struct sysmmu_drvdata *data;
 		/*
 		 * Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
 		 * entry by speculative prefetch of SLPD which has no mapping.
 		 */
-		list_for_each_entry(data, &priv->clients, domain_node)
+		list_for_each_entry(data, &domain->clients, domain_node)
 			sysmmu_tlb_invalidate_flpdcache(data, iova);
 	}
-	spin_unlock(&priv->lock);
+	spin_unlock(&domain->lock);
 
 	return 0;
 }
@@ -904,74 +904,75 @@ static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr, size_t size,
  *   than or equal to 128KiB.
  * - Start address of an I/O virtual region must be aligned by 128KiB.
  */
-static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
-			 phys_addr_t paddr, size_t size, int prot)
+static int exynos_iommu_map(struct iommu_domain *iommu_domain,
+			    unsigned long l_iova, phys_addr_t paddr, size_t size,
+			    int prot)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	sysmmu_pte_t *entry;
 	sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
 	unsigned long flags;
 	int ret = -ENOMEM;
 
-	BUG_ON(priv->pgtable == NULL);
+	BUG_ON(domain->pgtable == NULL);
 
-	spin_lock_irqsave(&priv->pgtablelock, flags);
+	spin_lock_irqsave(&domain->pgtablelock, flags);
 
-	entry = section_entry(priv->pgtable, iova);
+	entry = section_entry(domain->pgtable, iova);
 
 	if (size == SECT_SIZE) {
-		ret = lv1set_section(priv, entry, iova, paddr,
-					&priv->lv2entcnt[lv1ent_offset(iova)]);
+		ret = lv1set_section(domain, entry, iova, paddr,
+				     &domain->lv2entcnt[lv1ent_offset(iova)]);
 	} else {
 		sysmmu_pte_t *pent;
 
-		pent = alloc_lv2entry(priv, entry, iova,
-					&priv->lv2entcnt[lv1ent_offset(iova)]);
+		pent = alloc_lv2entry(domain, entry, iova,
+				      &domain->lv2entcnt[lv1ent_offset(iova)]);
 
 		if (IS_ERR(pent))
 			ret = PTR_ERR(pent);
 		else
 			ret = lv2set_page(pent, paddr, size,
-					&priv->lv2entcnt[lv1ent_offset(iova)]);
+				       &domain->lv2entcnt[lv1ent_offset(iova)]);
 	}
 
 	if (ret)
 		pr_err("%s: Failed(%d) to map %#zx bytes @ %#x\n",
 			__func__, ret, size, iova);
 
-	spin_unlock_irqrestore(&priv->pgtablelock, flags);
+	spin_unlock_irqrestore(&domain->pgtablelock, flags);
 
 	return ret;
 }
 
-static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
-						sysmmu_iova_t iova, size_t size)
+static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *domain,
+					      sysmmu_iova_t iova, size_t size)
 {
 	struct sysmmu_drvdata *data;
 	unsigned long flags;
 
-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&domain->lock, flags);
 
-	list_for_each_entry(data, &priv->clients, domain_node)
+	list_for_each_entry(data, &domain->clients, domain_node)
 		sysmmu_tlb_invalidate_entry(data, iova, size);
 
-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&domain->lock, flags);
 }
 
-static size_t exynos_iommu_unmap(struct iommu_domain *domain,
-					unsigned long l_iova, size_t size)
+static size_t exynos_iommu_unmap(struct iommu_domain *iommu_domain,
+				 unsigned long l_iova, size_t size)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
 	sysmmu_pte_t *ent;
 	size_t err_pgsize;
 	unsigned long flags;
 
-	BUG_ON(priv->pgtable == NULL);
+	BUG_ON(domain->pgtable == NULL);
 
-	spin_lock_irqsave(&priv->pgtablelock, flags);
+	spin_lock_irqsave(&domain->pgtablelock, flags);
 
-	ent = section_entry(priv->pgtable, iova);
+	ent = section_entry(domain->pgtable, iova);
 
 	if (lv1ent_section(ent)) {
 		if (WARN_ON(size < SECT_SIZE)) {
@@ -1005,7 +1006,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
 		*ent = 0;
 		size = SPAGE_SIZE;
 		pgtable_flush(ent, ent + 1);
-		priv->lv2entcnt[lv1ent_offset(iova)] += 1;
+		domain->lv2entcnt[lv1ent_offset(iova)] += 1;
 		goto done;
 	}
 
@@ -1019,15 +1020,15 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
 	pgtable_flush(ent, ent + SPAGES_PER_LPAGE);
 
 	size = LPAGE_SIZE;
-	priv->lv2entcnt[lv1ent_offset(iova)] += SPAGES_PER_LPAGE;
+	domain->lv2entcnt[lv1ent_offset(iova)] += SPAGES_PER_LPAGE;
 done:
-	spin_unlock_irqrestore(&priv->pgtablelock, flags);
+	spin_unlock_irqrestore(&domain->pgtablelock, flags);
 
-	exynos_iommu_tlb_invalidate_entry(priv, iova, size);
+	exynos_iommu_tlb_invalidate_entry(domain, iova, size);
 
 	return size;
 err:
-	spin_unlock_irqrestore(&priv->pgtablelock, flags);
+	spin_unlock_irqrestore(&domain->pgtablelock, flags);
 
 	pr_err("%s: Failed: size(%#zx) @ %#x is smaller than page size %#zx\n",
 		__func__, size, iova, err_pgsize);
@@ -1035,17 +1036,17 @@ err:
 	return 0;
 }
 
-static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
+static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
 					  dma_addr_t iova)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	sysmmu_pte_t *entry;
 	unsigned long flags;
 	phys_addr_t phys = 0;
 
-	spin_lock_irqsave(&priv->pgtablelock, flags);
+	spin_lock_irqsave(&domain->pgtablelock, flags);
 
-	entry = section_entry(priv->pgtable, iova);
+	entry = section_entry(domain->pgtable, iova);
 
 	if (lv1ent_section(entry)) {
 		phys = section_phys(entry) + section_offs(iova);
@@ -1058,7 +1059,7 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
 			phys = spage_phys(entry) + spage_offs(iova);
 	}
 
-	spin_unlock_irqrestore(&priv->pgtablelock, flags);
+	spin_unlock_irqrestore(&domain->pgtablelock, flags);
 
 	return phys;
 }
-- 
1.9.2

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

* [PATCH v6 13/25] iommu: exynos: rename variables to reflect their purpose
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch renames some variables to make the code easier to understand.
'domain' is replaced by 'iommu_domain' (more generic entity) and really
meaningless 'priv' by 'domain' to reflect its purpose.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 187 ++++++++++++++++++++++---------------------
 1 file changed, 94 insertions(+), 93 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 734107ec78fa..a58f4a4c91d0 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -436,8 +436,8 @@ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
 		clk_disable(data->clk_master);
 }
 
-static int __sysmmu_enable(struct sysmmu_drvdata *data,
-			phys_addr_t pgtable, struct iommu_domain *domain)
+static int __sysmmu_enable(struct sysmmu_drvdata *data, phys_addr_t pgtable,
+			   struct iommu_domain *iommu_domain)
 {
 	int ret = 0;
 	unsigned long flags;
@@ -445,7 +445,7 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
 	spin_lock_irqsave(&data->lock, flags);
 	if (set_sysmmu_active(data)) {
 		data->pgtable = pgtable;
-		data->domain = domain;
+		data->domain = iommu_domain;
 
 		__sysmmu_enable_nocount(data);
 
@@ -610,91 +610,91 @@ static inline void pgtable_flush(void *vastart, void *vaend)
 
 static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
 {
-	struct exynos_iommu_domain *exynos_domain;
+	struct exynos_iommu_domain *domain;
 	int i;
 
 	if (type != IOMMU_DOMAIN_UNMANAGED)
 		return NULL;
 
-	exynos_domain = kzalloc(sizeof(*exynos_domain), GFP_KERNEL);
-	if (!exynos_domain)
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (!domain)
 		return NULL;
 
-	exynos_domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
-	if (!exynos_domain->pgtable)
+	domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
+	if (!domain->pgtable)
 		goto err_pgtable;
 
-	exynos_domain->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
-	if (!exynos_domain->lv2entcnt)
+	domain->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
+	if (!domain->lv2entcnt)
 		goto err_counter;
 
 	/* Workaround for System MMU v3.3 to prevent caching 1MiB mapping */
 	for (i = 0; i < NUM_LV1ENTRIES; i += 8) {
-		exynos_domain->pgtable[i + 0] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 1] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 2] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 3] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 4] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 5] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 6] = ZERO_LV2LINK;
-		exynos_domain->pgtable[i + 7] = ZERO_LV2LINK;
+		domain->pgtable[i + 0] = ZERO_LV2LINK;
+		domain->pgtable[i + 1] = ZERO_LV2LINK;
+		domain->pgtable[i + 2] = ZERO_LV2LINK;
+		domain->pgtable[i + 3] = ZERO_LV2LINK;
+		domain->pgtable[i + 4] = ZERO_LV2LINK;
+		domain->pgtable[i + 5] = ZERO_LV2LINK;
+		domain->pgtable[i + 6] = ZERO_LV2LINK;
+		domain->pgtable[i + 7] = ZERO_LV2LINK;
 	}
 
-	pgtable_flush(exynos_domain->pgtable, exynos_domain->pgtable + NUM_LV1ENTRIES);
+	pgtable_flush(domain->pgtable, domain->pgtable + NUM_LV1ENTRIES);
 
-	spin_lock_init(&exynos_domain->lock);
-	spin_lock_init(&exynos_domain->pgtablelock);
-	INIT_LIST_HEAD(&exynos_domain->clients);
+	spin_lock_init(&domain->lock);
+	spin_lock_init(&domain->pgtablelock);
+	INIT_LIST_HEAD(&domain->clients);
 
-	exynos_domain->domain.geometry.aperture_start = 0;
-	exynos_domain->domain.geometry.aperture_end   = ~0UL;
-	exynos_domain->domain.geometry.force_aperture = true;
+	domain->domain.geometry.aperture_start = 0;
+	domain->domain.geometry.aperture_end   = ~0UL;
+	domain->domain.geometry.force_aperture = true;
 
-	return &exynos_domain->domain;
+	return &domain->domain;
 
 err_counter:
-	free_pages((unsigned long)exynos_domain->pgtable, 2);
+	free_pages((unsigned long)domain->pgtable, 2);
 err_pgtable:
-	kfree(exynos_domain);
+	kfree(domain);
 	return NULL;
 }
 
-static void exynos_iommu_domain_free(struct iommu_domain *domain)
+static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	struct sysmmu_drvdata *data;
 	unsigned long flags;
 	int i;
 
-	WARN_ON(!list_empty(&priv->clients));
+	WARN_ON(!list_empty(&domain->clients));
 
-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&domain->lock, flags);
 
-	list_for_each_entry(data, &priv->clients, domain_node) {
+	list_for_each_entry(data, &domain->clients, domain_node) {
 		if (__sysmmu_disable(data))
 			data->master = NULL;
 		list_del_init(&data->domain_node);
 	}
 
-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&domain->lock, flags);
 
 	for (i = 0; i < NUM_LV1ENTRIES; i++)
-		if (lv1ent_page(priv->pgtable + i))
+		if (lv1ent_page(domain->pgtable + i))
 			kmem_cache_free(lv2table_kmem_cache,
-				phys_to_virt(lv2table_base(priv->pgtable + i)));
+				phys_to_virt(lv2table_base(domain->pgtable + i)));
 
-	free_pages((unsigned long)priv->pgtable, 2);
-	free_pages((unsigned long)priv->lv2entcnt, 1);
-	kfree(priv);
+	free_pages((unsigned long)domain->pgtable, 2);
+	free_pages((unsigned long)domain->lv2entcnt, 1);
+	kfree(domain);
 }
 
-static int exynos_iommu_attach_device(struct iommu_domain *domain,
+static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
 				   struct device *dev)
 {
 	struct exynos_iommu_owner *owner = dev->archdata.iommu;
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	struct sysmmu_drvdata *data;
-	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
+	phys_addr_t pagetable = virt_to_phys(domain->pgtable);
 	unsigned long flags;
 	int ret = -ENODEV;
 
@@ -703,13 +703,13 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 
 	list_for_each_entry(data, &owner->clients, owner_node) {
 		pm_runtime_get_sync(data->sysmmu);
-		ret = __sysmmu_enable(data, pagetable, domain);
+		ret = __sysmmu_enable(data, pagetable, iommu_domain);
 		if (ret >= 0) {
 			data->master = dev;
 
-			spin_lock_irqsave(&priv->lock, flags);
-			list_add_tail(&data->domain_node, &priv->clients);
-			spin_unlock_irqrestore(&priv->lock, flags);
+			spin_lock_irqsave(&domain->lock, flags);
+			list_add_tail(&data->domain_node, &domain->clients);
+			spin_unlock_irqrestore(&domain->lock, flags);
 		}
 	}
 
@@ -725,11 +725,11 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 	return ret;
 }
 
-static void exynos_iommu_detach_device(struct iommu_domain *domain,
+static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
 				    struct device *dev)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
-	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
+	phys_addr_t pagetable = virt_to_phys(domain->pgtable);
 	struct sysmmu_drvdata *data, *next;
 	unsigned long flags;
 	bool found = false;
@@ -737,8 +737,8 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 	if (!has_sysmmu(dev))
 		return;
 
-	spin_lock_irqsave(&priv->lock, flags);
-	list_for_each_entry_safe(data, next, &priv->clients, domain_node) {
+	spin_lock_irqsave(&domain->lock, flags);
+	list_for_each_entry_safe(data, next, &domain->clients, domain_node) {
 		if (data->master == dev) {
 			if (__sysmmu_disable(data)) {
 				data->master = NULL;
@@ -748,7 +748,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 			found = true;
 		}
 	}
-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&domain->lock, flags);
 
 	if (found)
 		dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
@@ -757,7 +757,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 		dev_err(dev, "%s: No IOMMU is attached\n", __func__);
 }
 
-static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
+static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *domain,
 		sysmmu_pte_t *sent, sysmmu_iova_t iova, short *pgcounter)
 {
 	if (lv1ent_section(sent)) {
@@ -799,17 +799,17 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
 		if (need_flush_flpd_cache) {
 			struct sysmmu_drvdata *data;
 
-			spin_lock(&priv->lock);
-			list_for_each_entry(data, &priv->clients, domain_node)
+			spin_lock(&domain->lock);
+			list_for_each_entry(data, &domain->clients, domain_node)
 				sysmmu_tlb_invalidate_flpdcache(data, iova);
-			spin_unlock(&priv->lock);
+			spin_unlock(&domain->lock);
 		}
 	}
 
 	return page_entry(sent, iova);
 }
 
-static int lv1set_section(struct exynos_iommu_domain *priv,
+static int lv1set_section(struct exynos_iommu_domain *domain,
 			  sysmmu_pte_t *sent, sysmmu_iova_t iova,
 			  phys_addr_t paddr, short *pgcnt)
 {
@@ -834,17 +834,17 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
 
 	pgtable_flush(sent, sent + 1);
 
-	spin_lock(&priv->lock);
+	spin_lock(&domain->lock);
 	if (lv1ent_page_zero(sent)) {
 		struct sysmmu_drvdata *data;
 		/*
 		 * Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
 		 * entry by speculative prefetch of SLPD which has no mapping.
 		 */
-		list_for_each_entry(data, &priv->clients, domain_node)
+		list_for_each_entry(data, &domain->clients, domain_node)
 			sysmmu_tlb_invalidate_flpdcache(data, iova);
 	}
-	spin_unlock(&priv->lock);
+	spin_unlock(&domain->lock);
 
 	return 0;
 }
@@ -904,74 +904,75 @@ static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr, size_t size,
  *   than or equal to 128KiB.
  * - Start address of an I/O virtual region must be aligned by 128KiB.
  */
-static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
-			 phys_addr_t paddr, size_t size, int prot)
+static int exynos_iommu_map(struct iommu_domain *iommu_domain,
+			    unsigned long l_iova, phys_addr_t paddr, size_t size,
+			    int prot)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	sysmmu_pte_t *entry;
 	sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
 	unsigned long flags;
 	int ret = -ENOMEM;
 
-	BUG_ON(priv->pgtable == NULL);
+	BUG_ON(domain->pgtable == NULL);
 
-	spin_lock_irqsave(&priv->pgtablelock, flags);
+	spin_lock_irqsave(&domain->pgtablelock, flags);
 
-	entry = section_entry(priv->pgtable, iova);
+	entry = section_entry(domain->pgtable, iova);
 
 	if (size == SECT_SIZE) {
-		ret = lv1set_section(priv, entry, iova, paddr,
-					&priv->lv2entcnt[lv1ent_offset(iova)]);
+		ret = lv1set_section(domain, entry, iova, paddr,
+				     &domain->lv2entcnt[lv1ent_offset(iova)]);
 	} else {
 		sysmmu_pte_t *pent;
 
-		pent = alloc_lv2entry(priv, entry, iova,
-					&priv->lv2entcnt[lv1ent_offset(iova)]);
+		pent = alloc_lv2entry(domain, entry, iova,
+				      &domain->lv2entcnt[lv1ent_offset(iova)]);
 
 		if (IS_ERR(pent))
 			ret = PTR_ERR(pent);
 		else
 			ret = lv2set_page(pent, paddr, size,
-					&priv->lv2entcnt[lv1ent_offset(iova)]);
+				       &domain->lv2entcnt[lv1ent_offset(iova)]);
 	}
 
 	if (ret)
 		pr_err("%s: Failed(%d) to map %#zx bytes @ %#x\n",
 			__func__, ret, size, iova);
 
-	spin_unlock_irqrestore(&priv->pgtablelock, flags);
+	spin_unlock_irqrestore(&domain->pgtablelock, flags);
 
 	return ret;
 }
 
-static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
-						sysmmu_iova_t iova, size_t size)
+static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *domain,
+					      sysmmu_iova_t iova, size_t size)
 {
 	struct sysmmu_drvdata *data;
 	unsigned long flags;
 
-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&domain->lock, flags);
 
-	list_for_each_entry(data, &priv->clients, domain_node)
+	list_for_each_entry(data, &domain->clients, domain_node)
 		sysmmu_tlb_invalidate_entry(data, iova, size);
 
-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&domain->lock, flags);
 }
 
-static size_t exynos_iommu_unmap(struct iommu_domain *domain,
-					unsigned long l_iova, size_t size)
+static size_t exynos_iommu_unmap(struct iommu_domain *iommu_domain,
+				 unsigned long l_iova, size_t size)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
 	sysmmu_pte_t *ent;
 	size_t err_pgsize;
 	unsigned long flags;
 
-	BUG_ON(priv->pgtable == NULL);
+	BUG_ON(domain->pgtable == NULL);
 
-	spin_lock_irqsave(&priv->pgtablelock, flags);
+	spin_lock_irqsave(&domain->pgtablelock, flags);
 
-	ent = section_entry(priv->pgtable, iova);
+	ent = section_entry(domain->pgtable, iova);
 
 	if (lv1ent_section(ent)) {
 		if (WARN_ON(size < SECT_SIZE)) {
@@ -1005,7 +1006,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
 		*ent = 0;
 		size = SPAGE_SIZE;
 		pgtable_flush(ent, ent + 1);
-		priv->lv2entcnt[lv1ent_offset(iova)] += 1;
+		domain->lv2entcnt[lv1ent_offset(iova)] += 1;
 		goto done;
 	}
 
@@ -1019,15 +1020,15 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
 	pgtable_flush(ent, ent + SPAGES_PER_LPAGE);
 
 	size = LPAGE_SIZE;
-	priv->lv2entcnt[lv1ent_offset(iova)] += SPAGES_PER_LPAGE;
+	domain->lv2entcnt[lv1ent_offset(iova)] += SPAGES_PER_LPAGE;
 done:
-	spin_unlock_irqrestore(&priv->pgtablelock, flags);
+	spin_unlock_irqrestore(&domain->pgtablelock, flags);
 
-	exynos_iommu_tlb_invalidate_entry(priv, iova, size);
+	exynos_iommu_tlb_invalidate_entry(domain, iova, size);
 
 	return size;
 err:
-	spin_unlock_irqrestore(&priv->pgtablelock, flags);
+	spin_unlock_irqrestore(&domain->pgtablelock, flags);
 
 	pr_err("%s: Failed: size(%#zx) @ %#x is smaller than page size %#zx\n",
 		__func__, size, iova, err_pgsize);
@@ -1035,17 +1036,17 @@ err:
 	return 0;
 }
 
-static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
+static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
 					  dma_addr_t iova)
 {
-	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
+	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	sysmmu_pte_t *entry;
 	unsigned long flags;
 	phys_addr_t phys = 0;
 
-	spin_lock_irqsave(&priv->pgtablelock, flags);
+	spin_lock_irqsave(&domain->pgtablelock, flags);
 
-	entry = section_entry(priv->pgtable, iova);
+	entry = section_entry(domain->pgtable, iova);
 
 	if (lv1ent_section(entry)) {
 		phys = section_phys(entry) + section_offs(iova);
@@ -1058,7 +1059,7 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
 			phys = spage_phys(entry) + spage_offs(iova);
 	}
 
-	spin_unlock_irqrestore(&priv->pgtablelock, flags);
+	spin_unlock_irqrestore(&domain->pgtablelock, flags);
 
 	return phys;
 }
-- 
1.9.2

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

* [PATCH v6 14/25] iommu: exynos: use struct exynos_iommu_domain in internal structures
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

Replace all remaining usage of struct iommu_domain with struct
exynos_iommu_domain in all internal structures and functions.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index a58f4a4c91d0..67e0633b8080 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -206,7 +206,7 @@ struct sysmmu_drvdata {
 	struct clk *clk_master;
 	int activations;
 	spinlock_t lock;
-	struct iommu_domain *domain;
+	struct exynos_iommu_domain *domain;
 	struct list_head domain_node;
 	struct list_head owner_node;
 	phys_addr_t pgtable;
@@ -338,7 +338,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
 		show_fault_information(dev_name(data->sysmmu),
 					itype, base, addr);
 		if (data->domain)
-			ret = report_iommu_fault(data->domain,
+			ret = report_iommu_fault(&data->domain->domain,
 					data->master, addr, itype);
 	}
 
@@ -437,7 +437,7 @@ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
 }
 
 static int __sysmmu_enable(struct sysmmu_drvdata *data, phys_addr_t pgtable,
-			   struct iommu_domain *iommu_domain)
+			   struct exynos_iommu_domain *domain)
 {
 	int ret = 0;
 	unsigned long flags;
@@ -445,7 +445,7 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data, phys_addr_t pgtable,
 	spin_lock_irqsave(&data->lock, flags);
 	if (set_sysmmu_active(data)) {
 		data->pgtable = pgtable;
-		data->domain = iommu_domain;
+		data->domain = domain;
 
 		__sysmmu_enable_nocount(data);
 
@@ -703,7 +703,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
 
 	list_for_each_entry(data, &owner->clients, owner_node) {
 		pm_runtime_get_sync(data->sysmmu);
-		ret = __sysmmu_enable(data, pagetable, iommu_domain);
+		ret = __sysmmu_enable(data, pagetable, domain);
 		if (ret >= 0) {
 			data->master = dev;
 
-- 
1.9.2

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

* [PATCH v6 14/25] iommu: exynos: use struct exynos_iommu_domain in internal structures
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

Replace all remaining usage of struct iommu_domain with struct
exynos_iommu_domain in all internal structures and functions.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index a58f4a4c91d0..67e0633b8080 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -206,7 +206,7 @@ struct sysmmu_drvdata {
 	struct clk *clk_master;
 	int activations;
 	spinlock_t lock;
-	struct iommu_domain *domain;
+	struct exynos_iommu_domain *domain;
 	struct list_head domain_node;
 	struct list_head owner_node;
 	phys_addr_t pgtable;
@@ -338,7 +338,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
 		show_fault_information(dev_name(data->sysmmu),
 					itype, base, addr);
 		if (data->domain)
-			ret = report_iommu_fault(data->domain,
+			ret = report_iommu_fault(&data->domain->domain,
 					data->master, addr, itype);
 	}
 
@@ -437,7 +437,7 @@ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
 }
 
 static int __sysmmu_enable(struct sysmmu_drvdata *data, phys_addr_t pgtable,
-			   struct iommu_domain *iommu_domain)
+			   struct exynos_iommu_domain *domain)
 {
 	int ret = 0;
 	unsigned long flags;
@@ -445,7 +445,7 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data, phys_addr_t pgtable,
 	spin_lock_irqsave(&data->lock, flags);
 	if (set_sysmmu_active(data)) {
 		data->pgtable = pgtable;
-		data->domain = iommu_domain;
+		data->domain = domain;
 
 		__sysmmu_enable_nocount(data);
 
@@ -703,7 +703,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
 
 	list_for_each_entry(data, &owner->clients, owner_node) {
 		pm_runtime_get_sync(data->sysmmu);
-		ret = __sysmmu_enable(data, pagetable, iommu_domain);
+		ret = __sysmmu_enable(data, pagetable, domain);
 		if (ret >= 0) {
 			data->master = dev;
 
-- 
1.9.2

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

* [PATCH v6 15/25] iommu: exynos: document internal structures
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

Add a few words of comment to all internal structures used by the driver.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 49 +++++++++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 67e0633b8080..6a0199570b00 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -184,33 +184,50 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
 	"UNKNOWN FAULT"
 };
 
-/* attached to dev.archdata.iommu of the master device */
+/*
+ * This structure is attached to dev.archdata.iommu of the master device
+ * on device add, contains a list of SYSMMU controllers defined by device tree,
+ * which are bound to given master device. It is usually referenced by 'owner'
+ * pointer.
+*/
 struct exynos_iommu_owner {
-	struct list_head clients;
+	struct list_head clients; /* list of sysmmu_drvdata.owner_node */
 };
 
+/*
+ * This structure exynos specific generalization of struct iommu_domain.
+ * It contains list of SYSMMU controllers from all master devices, which has
+ * been attached to this domain and page tables of IO address space defined by
+ * it. It is usually referenced by 'domain' pointer.
+ */
 struct exynos_iommu_domain {
-	struct list_head clients; /* list of sysmmu_drvdata.node */
+	struct list_head clients; /* list of sysmmu_drvdata.domain_node */
 	sysmmu_pte_t *pgtable; /* lv1 page table, 16KB */
 	short *lv2entcnt; /* free lv2 entry counter for each section */
-	spinlock_t lock; /* lock for this structure */
+	spinlock_t lock; /* lock for modyfying list of clients */
 	spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
 	struct iommu_domain domain; /* generic domain data structure */
 };
 
+/*
+ * This structure hold all data of a single SYSMMU controller, this includes
+ * hw resources like registers and clocks, pointers and list nodes to connect
+ * it to all other structures, internal state and parameters read from device
+ * tree. It is usually referenced by 'data' pointer.
+ */
 struct sysmmu_drvdata {
-	struct device *sysmmu;	/* System MMU's device descriptor */
-	struct device *master;	/* Owner of system MMU */
-	void __iomem *sfrbase;
-	struct clk *clk;
-	struct clk *clk_master;
-	int activations;
-	spinlock_t lock;
-	struct exynos_iommu_domain *domain;
-	struct list_head domain_node;
-	struct list_head owner_node;
-	phys_addr_t pgtable;
-	int version;
+	struct device *sysmmu; /* SYSMMU controller device */
+	struct device *master; /* master device (owner of given SYSMMU) */
+	void __iomem *sfrbase; /* our registers */
+	struct clk *clk; /* SYSMMU's clock */
+	struct clk *clk_master; /* master's device clock */
+	int activations; /* number of calls to sysmmu_enable */
+	spinlock_t lock; /* lock for modyfying enable/disable state */
+	struct exynos_iommu_domain *domain; /* domain we belong to */
+	struct list_head domain_node; /* node for domain clients list */
+	struct list_head owner_node; /* node for owner clients list */
+	phys_addr_t pgtable; /* assigned page table structure */
+	int version; /* our version */
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
-- 
1.9.2

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

* [PATCH v6 15/25] iommu: exynos: document internal structures
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

Add a few words of comment to all internal structures used by the driver.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 49 +++++++++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 67e0633b8080..6a0199570b00 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -184,33 +184,50 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
 	"UNKNOWN FAULT"
 };
 
-/* attached to dev.archdata.iommu of the master device */
+/*
+ * This structure is attached to dev.archdata.iommu of the master device
+ * on device add, contains a list of SYSMMU controllers defined by device tree,
+ * which are bound to given master device. It is usually referenced by 'owner'
+ * pointer.
+*/
 struct exynos_iommu_owner {
-	struct list_head clients;
+	struct list_head clients; /* list of sysmmu_drvdata.owner_node */
 };
 
+/*
+ * This structure exynos specific generalization of struct iommu_domain.
+ * It contains list of SYSMMU controllers from all master devices, which has
+ * been attached to this domain and page tables of IO address space defined by
+ * it. It is usually referenced by 'domain' pointer.
+ */
 struct exynos_iommu_domain {
-	struct list_head clients; /* list of sysmmu_drvdata.node */
+	struct list_head clients; /* list of sysmmu_drvdata.domain_node */
 	sysmmu_pte_t *pgtable; /* lv1 page table, 16KB */
 	short *lv2entcnt; /* free lv2 entry counter for each section */
-	spinlock_t lock; /* lock for this structure */
+	spinlock_t lock; /* lock for modyfying list of clients */
 	spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
 	struct iommu_domain domain; /* generic domain data structure */
 };
 
+/*
+ * This structure hold all data of a single SYSMMU controller, this includes
+ * hw resources like registers and clocks, pointers and list nodes to connect
+ * it to all other structures, internal state and parameters read from device
+ * tree. It is usually referenced by 'data' pointer.
+ */
 struct sysmmu_drvdata {
-	struct device *sysmmu;	/* System MMU's device descriptor */
-	struct device *master;	/* Owner of system MMU */
-	void __iomem *sfrbase;
-	struct clk *clk;
-	struct clk *clk_master;
-	int activations;
-	spinlock_t lock;
-	struct exynos_iommu_domain *domain;
-	struct list_head domain_node;
-	struct list_head owner_node;
-	phys_addr_t pgtable;
-	int version;
+	struct device *sysmmu; /* SYSMMU controller device */
+	struct device *master; /* master device (owner of given SYSMMU) */
+	void __iomem *sfrbase; /* our registers */
+	struct clk *clk; /* SYSMMU's clock */
+	struct clk *clk_master; /* master's device clock */
+	int activations; /* number of calls to sysmmu_enable */
+	spinlock_t lock; /* lock for modyfying enable/disable state */
+	struct exynos_iommu_domain *domain; /* domain we belong to */
+	struct list_head domain_node; /* node for domain clients list */
+	struct list_head owner_node; /* node for owner clients list */
+	phys_addr_t pgtable; /* assigned page table structure */
+	int version; /* our version */
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
-- 
1.9.2

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

* [PATCH v6 16/25] iommu: exynos: remove excessive includes and sort others alphabetically
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

Removed following unused includes: <linux/mm.h>, <linux/errno.h>,
<linux/memblock.h> and <linux/export.h>.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 6a0199570b00..5429e75b120c 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -12,19 +12,15 @@
 #define DEBUG
 #endif
 
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/err.h>
-#include <linux/mm.h>
+#include <linux/io.h>
 #include <linux/iommu.h>
-#include <linux/errno.h>
+#include <linux/interrupt.h>
 #include <linux/list.h>
-#include <linux/memblock.h>
-#include <linux/export.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
 
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
-- 
1.9.2

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

* [PATCH v6 16/25] iommu: exynos: remove excessive includes and sort others alphabetically
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

Removed following unused includes: <linux/mm.h>, <linux/errno.h>,
<linux/memblock.h> and <linux/export.h>.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 6a0199570b00..5429e75b120c 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -12,19 +12,15 @@
 #define DEBUG
 #endif
 
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/err.h>
-#include <linux/mm.h>
+#include <linux/io.h>
 #include <linux/iommu.h>
-#include <linux/errno.h>
+#include <linux/interrupt.h>
 #include <linux/list.h>
-#include <linux/memblock.h>
-#include <linux/export.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
 
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
-- 
1.9.2

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

* [PATCH v6 17/25] iommu: exynos: init from dt-specific callback instead of initcall
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch introduces IOMMU_OF_DECLARE-based initialization to the
driver, which replaces subsys_initcall-based procedure.
exynos_iommu_of_setup ensures that each sysmmu controller is probed
before its master device.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 5429e75b120c..94fbd870ede6 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -13,16 +13,21 @@
 #endif
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/iommu.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/of.h>
+#include <linux/of_iommu.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include <asm/cacheflush.h>
+#include <asm/dma-iommu.h>
 #include <asm/pgtable.h>
 
 typedef u32 sysmmu_iova_t;
@@ -1077,7 +1082,7 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
 	return phys;
 }
 
-static const struct iommu_ops exynos_iommu_ops = {
+static struct iommu_ops exynos_iommu_ops = {
 	.domain_alloc = exynos_iommu_domain_alloc,
 	.domain_free = exynos_iommu_domain_free,
 	.attach_dev = exynos_iommu_attach_device,
@@ -1089,6 +1094,8 @@ static const struct iommu_ops exynos_iommu_ops = {
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 };
 
+static bool init_done;
+
 static int __init exynos_iommu_init(void)
 {
 	struct device_node *np;
@@ -1128,6 +1135,8 @@ static int __init exynos_iommu_init(void)
 		goto err_set_iommu;
 	}
 
+	init_done = true;
+
 	return 0;
 err_set_iommu:
 	kmem_cache_free(lv2table_kmem_cache, zero_lv2_table);
@@ -1137,4 +1146,21 @@ err_reg_driver:
 	kmem_cache_destroy(lv2table_kmem_cache);
 	return ret;
 }
-subsys_initcall(exynos_iommu_init);
+
+static int __init exynos_iommu_of_setup(struct device_node *np)
+{
+	struct platform_device *pdev;
+
+	if (!init_done)
+		exynos_iommu_init();
+
+	pdev = of_platform_device_create(np, NULL, platform_bus_type.dev_root);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	of_iommu_set_ops(np, &exynos_iommu_ops);
+	return 0;
+}
+
+IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu",
+		 exynos_iommu_of_setup);
-- 
1.9.2

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

* [PATCH v6 17/25] iommu: exynos: init from dt-specific callback instead of initcall
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch introduces IOMMU_OF_DECLARE-based initialization to the
driver, which replaces subsys_initcall-based procedure.
exynos_iommu_of_setup ensures that each sysmmu controller is probed
before its master device.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 5429e75b120c..94fbd870ede6 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -13,16 +13,21 @@
 #endif
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/iommu.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/of.h>
+#include <linux/of_iommu.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include <asm/cacheflush.h>
+#include <asm/dma-iommu.h>
 #include <asm/pgtable.h>
 
 typedef u32 sysmmu_iova_t;
@@ -1077,7 +1082,7 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
 	return phys;
 }
 
-static const struct iommu_ops exynos_iommu_ops = {
+static struct iommu_ops exynos_iommu_ops = {
 	.domain_alloc = exynos_iommu_domain_alloc,
 	.domain_free = exynos_iommu_domain_free,
 	.attach_dev = exynos_iommu_attach_device,
@@ -1089,6 +1094,8 @@ static const struct iommu_ops exynos_iommu_ops = {
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 };
 
+static bool init_done;
+
 static int __init exynos_iommu_init(void)
 {
 	struct device_node *np;
@@ -1128,6 +1135,8 @@ static int __init exynos_iommu_init(void)
 		goto err_set_iommu;
 	}
 
+	init_done = true;
+
 	return 0;
 err_set_iommu:
 	kmem_cache_free(lv2table_kmem_cache, zero_lv2_table);
@@ -1137,4 +1146,21 @@ err_reg_driver:
 	kmem_cache_destroy(lv2table_kmem_cache);
 	return ret;
 }
-subsys_initcall(exynos_iommu_init);
+
+static int __init exynos_iommu_of_setup(struct device_node *np)
+{
+	struct platform_device *pdev;
+
+	if (!init_done)
+		exynos_iommu_init();
+
+	pdev = of_platform_device_create(np, NULL, platform_bus_type.dev_root);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	of_iommu_set_ops(np, &exynos_iommu_ops);
+	return 0;
+}
+
+IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu",
+		 exynos_iommu_of_setup);
-- 
1.9.2

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

* [PATCH v6 18/25] iommu: exynos: add callback for initializing devices from device tree
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch adds implementation of of_xlate callback, which prepares
masters device for attaching to IOMMU. This callback is called during
creating devices from device tree.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 94fbd870ede6..6e6b502ee2c9 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1082,6 +1082,33 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
 	return phys;
 }
 
+static int exynos_iommu_of_xlate(struct device *dev,
+				 struct of_phandle_args *spec)
+{
+	struct exynos_iommu_owner *owner = dev->archdata.iommu;
+	struct platform_device *sysmmu = of_find_device_by_node(spec->np);
+	struct sysmmu_drvdata *data;
+
+	if (!sysmmu)
+		return -ENODEV;
+
+	data = platform_get_drvdata(sysmmu);
+	if (!data)
+		return -ENODEV;
+
+	if (!owner) {
+		owner = kzalloc(sizeof(*owner), GFP_KERNEL);
+		if (!owner)
+			return -ENOMEM;
+
+		INIT_LIST_HEAD(&owner->clients);
+		dev->archdata.iommu = owner;
+	}
+
+	list_add_tail(&data->owner_node, &owner->clients);
+	return 0;
+}
+
 static struct iommu_ops exynos_iommu_ops = {
 	.domain_alloc = exynos_iommu_domain_alloc,
 	.domain_free = exynos_iommu_domain_free,
@@ -1092,6 +1119,7 @@ static struct iommu_ops exynos_iommu_ops = {
 	.map_sg = default_iommu_map_sg,
 	.iova_to_phys = exynos_iommu_iova_to_phys,
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
+	.of_xlate = exynos_iommu_of_xlate,
 };
 
 static bool init_done;
-- 
1.9.2

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

* [PATCH v6 18/25] iommu: exynos: add callback for initializing devices from device tree
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds implementation of of_xlate callback, which prepares
masters device for attaching to IOMMU. This callback is called during
creating devices from device tree.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 94fbd870ede6..6e6b502ee2c9 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1082,6 +1082,33 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
 	return phys;
 }
 
+static int exynos_iommu_of_xlate(struct device *dev,
+				 struct of_phandle_args *spec)
+{
+	struct exynos_iommu_owner *owner = dev->archdata.iommu;
+	struct platform_device *sysmmu = of_find_device_by_node(spec->np);
+	struct sysmmu_drvdata *data;
+
+	if (!sysmmu)
+		return -ENODEV;
+
+	data = platform_get_drvdata(sysmmu);
+	if (!data)
+		return -ENODEV;
+
+	if (!owner) {
+		owner = kzalloc(sizeof(*owner), GFP_KERNEL);
+		if (!owner)
+			return -ENOMEM;
+
+		INIT_LIST_HEAD(&owner->clients);
+		dev->archdata.iommu = owner;
+	}
+
+	list_add_tail(&data->owner_node, &owner->clients);
+	return 0;
+}
+
 static struct iommu_ops exynos_iommu_ops = {
 	.domain_alloc = exynos_iommu_domain_alloc,
 	.domain_free = exynos_iommu_domain_free,
@@ -1092,6 +1119,7 @@ static struct iommu_ops exynos_iommu_ops = {
 	.map_sg = default_iommu_map_sg,
 	.iova_to_phys = exynos_iommu_iova_to_phys,
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
+	.of_xlate = exynos_iommu_of_xlate,
 };
 
 static bool init_done;
-- 
1.9.2

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

* [PATCH v6 19/25] iommu: exynos: remove unneeded code
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

Once driver initialization has been moved from initcall to of_xlate()
callback, this patch is no longer needed.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 6e6b502ee2c9..821797328c52 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1126,15 +1126,8 @@ static bool init_done;
 
 static int __init exynos_iommu_init(void)
 {
-	struct device_node *np;
 	int ret;
 
-	np = of_find_matching_node(NULL, sysmmu_of_match);
-	if (!np)
-		return 0;
-
-	of_node_put(np);
-
 	lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
 				LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
 	if (!lv2table_kmem_cache) {
-- 
1.9.2

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

* [PATCH v6 19/25] iommu: exynos: remove unneeded code
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

Once driver initialization has been moved from initcall to of_xlate()
callback, this patch is no longer needed.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/iommu/exynos-iommu.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 6e6b502ee2c9..821797328c52 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1126,15 +1126,8 @@ static bool init_done;
 
 static int __init exynos_iommu_init(void)
 {
-	struct device_node *np;
 	int ret;
 
-	np = of_find_matching_node(NULL, sysmmu_of_match);
-	if (!np)
-		return 0;
-
-	of_node_put(np);
-
 	lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
 				LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
 	if (!lv2table_kmem_cache) {
-- 
1.9.2

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

* [PATCH v6 20/25] ARM: dts: exynos4: add sysmmu nodes
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch adds System MMU nodes that are specific to Exynos4210/4x12 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos4.dtsi    | 118 ++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/exynos4210.dtsi |  23 ++++++++
 arch/arm/boot/dts/exynos4x12.dtsi |  82 ++++++++++++++++++++++++++
 3 files changed, 223 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index e20cdc24c3bb..32593a8ac7c2 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -190,6 +190,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc0>;
 			status = "disabled";
 		};
 
@@ -201,6 +202,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc1>;
 			status = "disabled";
 		};
 
@@ -212,6 +214,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc2>;
 			status = "disabled";
 		};
 
@@ -223,6 +226,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc3>;
 			status = "disabled";
 		};
 
@@ -418,6 +422,8 @@
 		clocks = <&clock CLK_MFC>, <&clock CLK_SCLK_MFC>;
 		clock-names = "mfc", "sclk_mfc";
 		status = "disabled";
+		iommus = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+		iommu-names = "left", "right";
 	};
 
 	serial_0: serial@13800000 {
@@ -683,6 +689,7 @@
 		power-domains = <&pd_lcd0>;
 		samsung,sysreg = <&sys_reg>;
 		status = "disabled";
+		iommus = <&sysmmu_fimd0>;
 	};
 
 	tmu: tmu@100C0000 {
@@ -709,6 +716,7 @@
 		interrupts = <0 91 0>;
 		reg = <0x12C10000 0x2100>, <0x12c00000 0x300>;
 		power-domains = <&pd_tv>;
+		iommus = <&sysmmu_tv>;
 		status = "disabled";
 	};
 
@@ -819,4 +827,114 @@
 		clock-names = "ppmu";
 		status = "disabled";
 	};
+
+	sysmmu_mfc_l: sysmmu@13620000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13620000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
+		power-domains = <&pd_mfc>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_r: sysmmu@13630000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13630000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 6>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
+		power-domains = <&pd_mfc>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_tv: sysmmu@12E20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12E20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 4>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_TV>, <&clock CLK_MIXER>;
+		power-domains = <&pd_tv>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc0: sysmmu@11A20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC0>, <&clock CLK_FIMC0>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc1: sysmmu@11A30000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A30000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 3>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC1>, <&clock CLK_FIMC1>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc2: sysmmu@11A40000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 4>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC2>, <&clock CLK_FIMC2>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc3: sysmmu@11A50000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A50000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC3>, <&clock CLK_FIMC3>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_jpeg: sysmmu@11A60000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A60000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 6>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_JPEG>, <&clock CLK_JPEG>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_rotator: sysmmu@12A30000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12A30000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
+		power-domains = <&pd_lcd0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd0: sysmmu@11E20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11E20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD0>, <&clock CLK_FIMD0>;
+		power-domains = <&pd_lcd0>;
+		#iommu-cells = <0>;
+	};
 };
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index be89f83f70e7..19a8e711e616 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -195,6 +195,7 @@
 		interrupts = <0 89 0>;
 		clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
 		clock-names = "sclk_fimg2d", "fimg2d";
+		iommus = <&sysmmu_g2d>;
 		status = "disabled";
 	};
 
@@ -244,4 +245,26 @@
 		clock-names = "ppmu";
 		status = "disabled";
 	};
+
+	sysmmu_g2d: sysmmu@12A20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12A20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 7>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+		power-domains = <&pd_lcd0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd1: sysmmu@12220000 {
+		compatible = "samsung,exynos-sysmmu";
+		interrupt-parent = <&combiner>;
+		reg = <0x12220000 0x1000>;
+		interrupts = <5 3>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD1>, <&clock CLK_FIMD1>;
+		power-domains = <&pd_lcd1>;
+		#iommu-cells = <0>;
+	};
 };
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 6a6abe14fd9b..6c664bae0d9f 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -165,6 +165,7 @@
 		interrupts = <0 89 0>;
 		clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
 		clock-names = "sclk_fimg2d", "fimg2d";
+		iommus = <&sysmmu_g2d>;
 		status = "disabled";
 	};
 
@@ -214,6 +215,7 @@
 			power-domains = <&pd_isp>;
 			clocks = <&clock CLK_FIMC_LITE0>;
 			clock-names = "flite";
+			iommus = <&sysmmu_fimc_lite0>;
 			status = "disabled";
 		};
 
@@ -224,6 +226,7 @@
 			power-domains = <&pd_isp>;
 			clocks = <&clock CLK_FIMC_LITE1>;
 			clock-names = "flite";
+			iommus = <&sysmmu_fimc_lite1>;
 			status = "disabled";
 		};
 
@@ -252,6 +255,9 @@
 				      "mcuispdiv1", "uart", "aclk200",
 				      "div_aclk200", "aclk400mcuisp",
 				      "div_aclk400mcuisp";
+			iommus = <&sysmmu_fimc_isp>, <&sysmmu_fimc_drc>,
+				 <&sysmmu_fimc_fd>, <&sysmmu_fimc_mcuctl>;
+			iommu-names = "isp", "drc", "fd", "mcuctl";
 			#address-cells = <1>;
 			#size-cells = <1>;
 			ranges;
@@ -309,4 +315,80 @@
 		clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
 			 <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>;
 	};
+
+	sysmmu_g2d: sysmmu@10A40000{
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x10A40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 7>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_isp: sysmmu@12260000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12260000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 2>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_ISP>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_drc: sysmmu@12270000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12270000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 3>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_DRC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_fd: sysmmu@122A0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x122A0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 4>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FD>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_mcuctl: sysmmu@122B0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x122B0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 5>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_ISPCX>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_lite0: sysmmu@123B0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x123B0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 0>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_LITE0>, <&clock CLK_FIMC_LITE0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_lite1: sysmmu@123C0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x123C0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 1>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_LITE1>, <&clock CLK_FIMC_LITE1>;
+		#iommu-cells = <0>;
+	};
 };
-- 
1.9.2

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

* [PATCH v6 20/25] ARM: dts: exynos4: add sysmmu nodes
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds System MMU nodes that are specific to Exynos4210/4x12 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos4.dtsi    | 118 ++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/exynos4210.dtsi |  23 ++++++++
 arch/arm/boot/dts/exynos4x12.dtsi |  82 ++++++++++++++++++++++++++
 3 files changed, 223 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index e20cdc24c3bb..32593a8ac7c2 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -190,6 +190,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc0>;
 			status = "disabled";
 		};
 
@@ -201,6 +202,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc1>;
 			status = "disabled";
 		};
 
@@ -212,6 +214,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc2>;
 			status = "disabled";
 		};
 
@@ -223,6 +226,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc3>;
 			status = "disabled";
 		};
 
@@ -418,6 +422,8 @@
 		clocks = <&clock CLK_MFC>, <&clock CLK_SCLK_MFC>;
 		clock-names = "mfc", "sclk_mfc";
 		status = "disabled";
+		iommus = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+		iommu-names = "left", "right";
 	};
 
 	serial_0: serial at 13800000 {
@@ -683,6 +689,7 @@
 		power-domains = <&pd_lcd0>;
 		samsung,sysreg = <&sys_reg>;
 		status = "disabled";
+		iommus = <&sysmmu_fimd0>;
 	};
 
 	tmu: tmu at 100C0000 {
@@ -709,6 +716,7 @@
 		interrupts = <0 91 0>;
 		reg = <0x12C10000 0x2100>, <0x12c00000 0x300>;
 		power-domains = <&pd_tv>;
+		iommus = <&sysmmu_tv>;
 		status = "disabled";
 	};
 
@@ -819,4 +827,114 @@
 		clock-names = "ppmu";
 		status = "disabled";
 	};
+
+	sysmmu_mfc_l: sysmmu at 13620000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13620000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
+		power-domains = <&pd_mfc>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_r: sysmmu at 13630000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13630000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 6>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
+		power-domains = <&pd_mfc>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_tv: sysmmu at 12E20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12E20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 4>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_TV>, <&clock CLK_MIXER>;
+		power-domains = <&pd_tv>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc0: sysmmu at 11A20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC0>, <&clock CLK_FIMC0>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc1: sysmmu at 11A30000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A30000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 3>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC1>, <&clock CLK_FIMC1>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc2: sysmmu at 11A40000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 4>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC2>, <&clock CLK_FIMC2>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc3: sysmmu at 11A50000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A50000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC3>, <&clock CLK_FIMC3>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_jpeg: sysmmu at 11A60000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11A60000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 6>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_JPEG>, <&clock CLK_JPEG>;
+		power-domains = <&pd_cam>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_rotator: sysmmu at 12A30000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12A30000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
+		power-domains = <&pd_lcd0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd0: sysmmu at 11E20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11E20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD0>, <&clock CLK_FIMD0>;
+		power-domains = <&pd_lcd0>;
+		#iommu-cells = <0>;
+	};
 };
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index be89f83f70e7..19a8e711e616 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -195,6 +195,7 @@
 		interrupts = <0 89 0>;
 		clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
 		clock-names = "sclk_fimg2d", "fimg2d";
+		iommus = <&sysmmu_g2d>;
 		status = "disabled";
 	};
 
@@ -244,4 +245,26 @@
 		clock-names = "ppmu";
 		status = "disabled";
 	};
+
+	sysmmu_g2d: sysmmu at 12A20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12A20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 7>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+		power-domains = <&pd_lcd0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd1: sysmmu at 12220000 {
+		compatible = "samsung,exynos-sysmmu";
+		interrupt-parent = <&combiner>;
+		reg = <0x12220000 0x1000>;
+		interrupts = <5 3>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD1>, <&clock CLK_FIMD1>;
+		power-domains = <&pd_lcd1>;
+		#iommu-cells = <0>;
+	};
 };
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 6a6abe14fd9b..6c664bae0d9f 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -165,6 +165,7 @@
 		interrupts = <0 89 0>;
 		clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
 		clock-names = "sclk_fimg2d", "fimg2d";
+		iommus = <&sysmmu_g2d>;
 		status = "disabled";
 	};
 
@@ -214,6 +215,7 @@
 			power-domains = <&pd_isp>;
 			clocks = <&clock CLK_FIMC_LITE0>;
 			clock-names = "flite";
+			iommus = <&sysmmu_fimc_lite0>;
 			status = "disabled";
 		};
 
@@ -224,6 +226,7 @@
 			power-domains = <&pd_isp>;
 			clocks = <&clock CLK_FIMC_LITE1>;
 			clock-names = "flite";
+			iommus = <&sysmmu_fimc_lite1>;
 			status = "disabled";
 		};
 
@@ -252,6 +255,9 @@
 				      "mcuispdiv1", "uart", "aclk200",
 				      "div_aclk200", "aclk400mcuisp",
 				      "div_aclk400mcuisp";
+			iommus = <&sysmmu_fimc_isp>, <&sysmmu_fimc_drc>,
+				 <&sysmmu_fimc_fd>, <&sysmmu_fimc_mcuctl>;
+			iommu-names = "isp", "drc", "fd", "mcuctl";
 			#address-cells = <1>;
 			#size-cells = <1>;
 			ranges;
@@ -309,4 +315,80 @@
 		clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
 			 <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>;
 	};
+
+	sysmmu_g2d: sysmmu at 10A40000{
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x10A40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 7>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_isp: sysmmu at 12260000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12260000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 2>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_ISP>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_drc: sysmmu at 12270000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12270000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 3>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_DRC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_fd: sysmmu at 122A0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x122A0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 4>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FD>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_mcuctl: sysmmu at 122B0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x122B0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 5>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_ISPCX>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_lite0: sysmmu at 123B0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x123B0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 0>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_LITE0>, <&clock CLK_FIMC_LITE0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_lite1: sysmmu at 123C0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x123C0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <16 1>;
+		power-domains = <&pd_isp>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_LITE1>, <&clock CLK_FIMC_LITE1>;
+		#iommu-cells = <0>;
+	};
 };
-- 
1.9.2

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

* [PATCH v6 21/25] ARM: dts: exynos3250: add sysmmu nodes
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch adds System MMU nodes to the devices that are specific to
Exynos3250 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos3250.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index e3bfb11c6ef8..36361e0cb802 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -251,6 +251,7 @@
 			clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
 			clock-names = "sclk_fimd", "fimd";
 			power-domains = <&pd_lcd0>;
+			iommus = <&sysmmu_fimd0>;
 			samsung,sysreg = <&sys_reg>;
 			status = "disabled";
 		};
@@ -270,6 +271,16 @@
 			status = "disabled";
 		};
 
+		sysmmu_fimd0: sysmmu@11E20000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11e20000 0x1000>;
+			interrupts = <0 80 0>, <0 81 0>;
+			clock-names = "sysmmu", "master";
+			clocks = <&cmu CLK_SMMUFIMD0>, <&cmu CLK_FIMD0>;
+			samsung,power-domain = <&pd_lcd0>;
+			#iommu-cells = <0>;
+		};
+
 		hsotg: hsotg@12480000 {
 			compatible = "snps,dwc2";
 			reg = <0x12480000 0x20000>;
@@ -364,9 +375,20 @@
 			clock-names = "mfc", "sclk_mfc";
 			clocks = <&cmu CLK_MFC>, <&cmu CLK_SCLK_MFC>;
 			power-domains = <&pd_mfc>;
+			iommus = <&sysmmu_mfc>;
 			status = "disabled";
 		};
 
+		sysmmu_mfc: sysmmu@13620000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x13620000 0x1000>;
+			interrupts = <0 96 0>, <0 98 0>;
+			clock-names = "sysmmu", "master";
+			clocks = <&cmu CLK_SMMUMFC_L>, <&cmu CLK_MFC>;
+			samsung,power-domain = <&pd_mfc>;
+			#iommu-cells = <0>;
+		};
+
 		serial_0: serial@13800000 {
 			compatible = "samsung,exynos4210-uart";
 			reg = <0x13800000 0x100>;
-- 
1.9.2

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

* [PATCH v6 21/25] ARM: dts: exynos3250: add sysmmu nodes
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds System MMU nodes to the devices that are specific to
Exynos3250 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos3250.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index e3bfb11c6ef8..36361e0cb802 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -251,6 +251,7 @@
 			clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
 			clock-names = "sclk_fimd", "fimd";
 			power-domains = <&pd_lcd0>;
+			iommus = <&sysmmu_fimd0>;
 			samsung,sysreg = <&sys_reg>;
 			status = "disabled";
 		};
@@ -270,6 +271,16 @@
 			status = "disabled";
 		};
 
+		sysmmu_fimd0: sysmmu at 11E20000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11e20000 0x1000>;
+			interrupts = <0 80 0>, <0 81 0>;
+			clock-names = "sysmmu", "master";
+			clocks = <&cmu CLK_SMMUFIMD0>, <&cmu CLK_FIMD0>;
+			samsung,power-domain = <&pd_lcd0>;
+			#iommu-cells = <0>;
+		};
+
 		hsotg: hsotg at 12480000 {
 			compatible = "snps,dwc2";
 			reg = <0x12480000 0x20000>;
@@ -364,9 +375,20 @@
 			clock-names = "mfc", "sclk_mfc";
 			clocks = <&cmu CLK_MFC>, <&cmu CLK_SCLK_MFC>;
 			power-domains = <&pd_mfc>;
+			iommus = <&sysmmu_mfc>;
 			status = "disabled";
 		};
 
+		sysmmu_mfc: sysmmu at 13620000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x13620000 0x1000>;
+			interrupts = <0 96 0>, <0 98 0>;
+			clock-names = "sysmmu", "master";
+			clocks = <&cmu CLK_SMMUMFC_L>, <&cmu CLK_MFC>;
+			samsung,power-domain = <&pd_mfc>;
+			#iommu-cells = <0>;
+		};
+
 		serial_0: serial at 13800000 {
 			compatible = "samsung,exynos4210-uart";
 			reg = <0x13800000 0x100>;
-- 
1.9.2

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

* [PATCH v6 22/25] ARM: dts: exynos4415: add sysmmu nodes
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch adds System MMU nodes to all defined devices that are specific
to Exynos4415 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos4415.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4415.dtsi b/arch/arm/boot/dts/exynos4415.dtsi
index 5caea996e090..7c4e44cfe75d 100644
--- a/arch/arm/boot/dts/exynos4415.dtsi
+++ b/arch/arm/boot/dts/exynos4415.dtsi
@@ -249,6 +249,7 @@
 			clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
 			clock-names = "sclk_fimd", "fimd";
 			samsung,power-domain = <&pd_lcd0>;
+			iommus = <&sysmmu_fimd0>;
 			samsung,sysreg = <&sysreg_system_controller>;
 			status = "disabled";
 		};
@@ -268,6 +269,16 @@
 			status = "disabled";
 		};
 
+		sysmmu_fimd0: sysmmu@11E20000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11e20000 0x1000>;
+			interrupts = <0 80 0>, <0 81 0>;
+			clock-names = "sysmmu", "master";
+			clocks = <&cmu CLK_SMMUFIMD0>, <&cmu CLK_FIMD0>;
+			samsung,power-domain = <&pd_lcd0>;
+			#iommu-cells = <0>;
+		};
+
 		hsotg: hsotg@12480000 {
 			compatible = "samsung,s3c6400-hsotg";
 			reg = <0x12480000 0x20000>;
-- 
1.9.2

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

* [PATCH v6 22/25] ARM: dts: exynos4415: add sysmmu nodes
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds System MMU nodes to all defined devices that are specific
to Exynos4415 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos4415.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4415.dtsi b/arch/arm/boot/dts/exynos4415.dtsi
index 5caea996e090..7c4e44cfe75d 100644
--- a/arch/arm/boot/dts/exynos4415.dtsi
+++ b/arch/arm/boot/dts/exynos4415.dtsi
@@ -249,6 +249,7 @@
 			clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
 			clock-names = "sclk_fimd", "fimd";
 			samsung,power-domain = <&pd_lcd0>;
+			iommus = <&sysmmu_fimd0>;
 			samsung,sysreg = <&sysreg_system_controller>;
 			status = "disabled";
 		};
@@ -268,6 +269,16 @@
 			status = "disabled";
 		};
 
+		sysmmu_fimd0: sysmmu at 11E20000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11e20000 0x1000>;
+			interrupts = <0 80 0>, <0 81 0>;
+			clock-names = "sysmmu", "master";
+			clocks = <&cmu CLK_SMMUFIMD0>, <&cmu CLK_FIMD0>;
+			samsung,power-domain = <&pd_lcd0>;
+			#iommu-cells = <0>;
+		};
+
 		hsotg: hsotg at 12480000 {
 			compatible = "samsung,s3c6400-hsotg";
 			reg = <0x12480000 0x20000>;
-- 
1.9.2

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

* [PATCH v6 23/25] ARM: dts: exynos5250: add sysmmu nodes
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch adds System MMU nodes to all defined devices that are specific
to Exynos5250 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 250 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 250 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 257e2f10525d..96471eabeb24 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -230,6 +230,7 @@
 		interrupts = <0 91 0>;
 		clocks = <&clock CLK_G2D>;
 		clock-names = "fimg2d";
+		iommus = <&sysmmu_g2d>;
 	};
 
 	mfc: codec@11000000 {
@@ -239,6 +240,8 @@
 		power-domains = <&pd_mfc>;
 		clocks = <&clock CLK_MFC>;
 		clock-names = "mfc";
+		iommus = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+		iommu-names = "left", "right";
 	};
 
 	rtc: rtc@101E0000 {
@@ -720,6 +723,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL0>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc1>;
 	};
 
 	gsc_1:  gsc@13e10000 {
@@ -729,6 +733,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL1>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc1>;
 	};
 
 	gsc_2:  gsc@13e20000 {
@@ -738,6 +743,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL2>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc2>;
 	};
 
 	gsc_3:  gsc@13e30000 {
@@ -747,6 +753,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL3>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc3>;
 	};
 
 	hdmi: hdmi {
@@ -770,6 +777,7 @@
 		clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
 			 <&clock CLK_SCLK_HDMI>;
 		clock-names = "mixer", "hdmi", "sclk_hdmi";
+		iommus = <&sysmmu_tv>;
 	};
 
 	dp_phy: video-phy@10040720 {
@@ -790,6 +798,7 @@
 		power-domains = <&pd_disp1>;
 		clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
 		clock-names = "sclk_fimd", "fimd";
+		iommus = <&sysmmu_fimd1>;
 	};
 
 	adc: adc@12D10000 {
@@ -811,4 +820,245 @@
 		clocks = <&clock CLK_SSS>;
 		clock-names = "secss";
 	};
+
+	sysmmu_gsc0: sysmmu@13E80000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13E80000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 0>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL0>, <&clock CLK_GSCL0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gsc1: sysmmu@13E90000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13E90000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 2>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL1>, <&clock CLK_GSCL1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gsc2: sysmmu@13EA0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13EA0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 4>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL2>, <&clock CLK_GSCL2>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gsc3: sysmmu@13EB0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13EB0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 6>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL3>, <&clock CLK_GSCL3>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_r: sysmmu@11200000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11200000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <6 2>;
+		power-domains = <&pd_mfc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_l: sysmmu@11210000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11210000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <8 5>;
+		power-domains = <&pd_mfc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_tv: sysmmu@14650000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14650000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <7 4>;
+		power-domains = <&pd_disp1>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_TV>, <&clock CLK_MIXER>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd1: sysmmu@14640000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14640000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 2>;
+		power-domains = <&pd_disp1>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD1>, <&clock CLK_FIMD1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_g2d: sysmmu@10A60000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x10A60000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <24 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_2D>, <&clock CLK_G2D>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_rotator: sysmmu@11D40000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11D40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_jpeg: sysmmu@11F20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11F20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 2>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_JPEG>, <&clock CLK_JPEG>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_isp: sysmmu@13260000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13260000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <10 6>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_ISP>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_drc: sysmmu@13270000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13270000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <11 6>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_DRC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_fd: sysmmu@132A0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132A0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 0>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_FD>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_scc: sysmmu@13280000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13280000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 2>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_SCC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_scp: sysmmu@13290000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13290000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 6>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_SCP>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_mcuctl: sysmmu@132B0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132B0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 4>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_MCU>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_odc: sysmmu@132C0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132C0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <11 0>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_ODC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_dis0: sysmmu@132D0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132D0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <10 4>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_DIS0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_dis1: sysmmu@132E0000{
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132E0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <9 4>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_DIS1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_3dnr: sysmmu@132F0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132F0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 6>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_3DNR>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_lite0: sysmmu@13C40000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13C40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 4>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC_LITE0>, <&clock CLK_CAMIF_TOP>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_lite1: sysmmu@13C50000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13C50000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <24 1>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC_LITE1>, <&clock CLK_CAMIF_TOP>;
+		#iommu-cells = <0>;
+	};
 };
-- 
1.9.2

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

* [PATCH v6 23/25] ARM: dts: exynos5250: add sysmmu nodes
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds System MMU nodes to all defined devices that are specific
to Exynos5250 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 250 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 250 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 257e2f10525d..96471eabeb24 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -230,6 +230,7 @@
 		interrupts = <0 91 0>;
 		clocks = <&clock CLK_G2D>;
 		clock-names = "fimg2d";
+		iommus = <&sysmmu_g2d>;
 	};
 
 	mfc: codec at 11000000 {
@@ -239,6 +240,8 @@
 		power-domains = <&pd_mfc>;
 		clocks = <&clock CLK_MFC>;
 		clock-names = "mfc";
+		iommus = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+		iommu-names = "left", "right";
 	};
 
 	rtc: rtc at 101E0000 {
@@ -720,6 +723,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL0>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc1>;
 	};
 
 	gsc_1:  gsc at 13e10000 {
@@ -729,6 +733,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL1>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc1>;
 	};
 
 	gsc_2:  gsc at 13e20000 {
@@ -738,6 +743,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL2>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc2>;
 	};
 
 	gsc_3:  gsc at 13e30000 {
@@ -747,6 +753,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL3>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc3>;
 	};
 
 	hdmi: hdmi {
@@ -770,6 +777,7 @@
 		clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
 			 <&clock CLK_SCLK_HDMI>;
 		clock-names = "mixer", "hdmi", "sclk_hdmi";
+		iommus = <&sysmmu_tv>;
 	};
 
 	dp_phy: video-phy at 10040720 {
@@ -790,6 +798,7 @@
 		power-domains = <&pd_disp1>;
 		clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
 		clock-names = "sclk_fimd", "fimd";
+		iommus = <&sysmmu_fimd1>;
 	};
 
 	adc: adc at 12D10000 {
@@ -811,4 +820,245 @@
 		clocks = <&clock CLK_SSS>;
 		clock-names = "secss";
 	};
+
+	sysmmu_gsc0: sysmmu at 13E80000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13E80000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 0>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL0>, <&clock CLK_GSCL0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gsc1: sysmmu at 13E90000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13E90000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 2>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL1>, <&clock CLK_GSCL1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gsc2: sysmmu at 13EA0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13EA0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 4>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL2>, <&clock CLK_GSCL2>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gsc3: sysmmu at 13EB0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13EB0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 6>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL3>, <&clock CLK_GSCL3>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_r: sysmmu at 11200000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11200000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <6 2>;
+		power-domains = <&pd_mfc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_l: sysmmu at 11210000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11210000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <8 5>;
+		power-domains = <&pd_mfc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_tv: sysmmu at 14650000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14650000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <7 4>;
+		power-domains = <&pd_disp1>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_TV>, <&clock CLK_MIXER>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd1: sysmmu at 14640000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14640000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 2>;
+		power-domains = <&pd_disp1>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD1>, <&clock CLK_FIMD1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_g2d: sysmmu at 10A60000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x10A60000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <24 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_2D>, <&clock CLK_G2D>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_rotator: sysmmu at 11D40000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11D40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_jpeg: sysmmu at 11F20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11F20000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 2>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_JPEG>, <&clock CLK_JPEG>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_isp: sysmmu at 13260000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13260000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <10 6>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_ISP>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_drc: sysmmu at 13270000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13270000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <11 6>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_DRC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_fd: sysmmu at 132A0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132A0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 0>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_FD>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_scc: sysmmu at 13280000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13280000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 2>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_SCC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_scp: sysmmu at 13290000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13290000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 6>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_SCP>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_mcuctl: sysmmu at 132B0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132B0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 4>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_MCU>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_odc: sysmmu at 132C0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132C0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <11 0>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_ODC>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_dis0: sysmmu at 132D0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132D0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <10 4>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_DIS0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_dis1: sysmmu at 132E0000{
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132E0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <9 4>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_DIS1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_3dnr: sysmmu at 132F0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x132F0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <5 6>;
+		clock-names = "sysmmu";
+		clocks = <&clock CLK_SMMU_FIMC_3DNR>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_lite0: sysmmu at 13C40000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13C40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 4>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC_LITE0>, <&clock CLK_CAMIF_TOP>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimc_lite1: sysmmu at 13C50000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13C50000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <24 1>;
+		power-domains = <&pd_gsc>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMC_LITE1>, <&clock CLK_CAMIF_TOP>;
+		#iommu-cells = <0>;
+	};
 };
-- 
1.9.2

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

* [PATCH v6 24/25] ARM: dts: exynos5420: add sysmmu nodes
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

This patch adds System MMU nodes to all defined devices that are specific
to Exynos5420/5800/5422 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos5420.dtsi | 181 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 181 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index f67b23f303c3..7fdab914703f 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -179,6 +179,8 @@
 		clocks = <&clock CLK_MFC>;
 		clock-names = "mfc";
 		power-domains = <&mfc_pd>;
+		iommus = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+		iommu-names = "left", "right";
 	};
 
 	mmc_0: mmc@12200000 {
@@ -561,6 +563,8 @@
 		clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
 		clock-names = "sclk_fimd", "fimd";
 		power-domains = <&disp_pd>;
+		iommus = <&sysmmu_fimd1_0>, <&sysmmu_fimd1_1>;
+		iommu-names = "m0", "m1";
 	};
 
 	adc: adc@12D10000 {
@@ -748,6 +752,7 @@
 		clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
 			 <&clock CLK_SCLK_HDMI>;
 		clock-names = "mixer", "hdmi", "sclk_hdmi";
+		iommus = <&sysmmu_tv>;
 		power-domains = <&disp_pd>;
 	};
 
@@ -758,6 +763,7 @@
 		clocks = <&clock CLK_GSCL0>;
 		clock-names = "gscl";
 		power-domains = <&gsc_pd>;
+		iommus = <&sysmmu_gscl0>;
 	};
 
 	gsc_1: video-scaler@13e10000 {
@@ -767,6 +773,7 @@
 		clocks = <&clock CLK_GSCL1>;
 		clock-names = "gscl";
 		power-domains = <&gsc_pd>;
+		iommus = <&sysmmu_gscl1>;
 	};
 
 	pmu_system_controller: system-controller@10040000 {
@@ -961,4 +968,178 @@
 		samsung,sysreg-phandle = <&sysreg_system_controller>;
 		samsung,pmureg-phandle = <&pmu_system_controller>;
 	};
+
+	sysmmu_g2dr: sysmmu@0x10A60000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x10A60000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <24 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_g2dw: sysmmu@0x10A70000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x10A70000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <22 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_tv: sysmmu@0x14650000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14650000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <7 4>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MIXER>, <&clock CLK_MIXER>;
+		samsung,power-domain = <&disp_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gscl0: sysmmu@0x13E80000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13E80000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL0>, <&clock CLK_GSCL0>;
+		power-domains = <&gsc_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gscl1: sysmmu@0x13E90000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13E90000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL1>, <&clock CLK_GSCL1>;
+		power-domains = <&gsc_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler0r: sysmmu@0x12880000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12880000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <22 4>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL0>, <&clock CLK_MSCL0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler1r: sysmmu@0x12890000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12890000 0x1000>;
+		interrupts = <0 186 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL1>, <&clock CLK_MSCL1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler2r: sysmmu@0x128A0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x128A0000 0x1000>;
+		interrupts = <0 188 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL2>, <&clock CLK_MSCL2>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler0w: sysmmu@0x128C0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x128C0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <27 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL0>, <&clock CLK_MSCL0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler1w: sysmmu@0x128D0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x128D0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <22 6>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL1>, <&clock CLK_MSCL1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler2w: sysmmu@0x128E0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x128E0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <19 6>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL2>, <&clock CLK_MSCL2>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_jpeg: sysmmu@0x11F10000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11F10000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_JPEG>, <&clock CLK_JPEG>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_jpeg2: sysmmu@0x11F20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11F20000 0x1000>;
+		interrupts = <0 169 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_JPEG2>, <&clock CLK_JPEG2>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_l: sysmmu@0x11200000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11200000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <6 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
+		power-domains = <&mfc_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_r: sysmmu@0x11210000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11210000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <8 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
+		power-domains = <&mfc_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd1_0: sysmmu@0x14640000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14640000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD1M0>, <&clock CLK_FIMD1>;
+		samsung,power-domain = <&disp_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd1_1: sysmmu@0x14680000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14680000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD1M0>, <&clock CLK_FIMD1>;
+		samsung,power-domain = <&disp_pd>;
+		#iommu-cells = <0>;
+	};
 };
-- 
1.9.2

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

* [PATCH v6 24/25] ARM: dts: exynos5420: add sysmmu nodes
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds System MMU nodes to all defined devices that are specific
to Exynos5420/5800/5422 series.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos5420.dtsi | 181 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 181 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index f67b23f303c3..7fdab914703f 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -179,6 +179,8 @@
 		clocks = <&clock CLK_MFC>;
 		clock-names = "mfc";
 		power-domains = <&mfc_pd>;
+		iommus = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+		iommu-names = "left", "right";
 	};
 
 	mmc_0: mmc at 12200000 {
@@ -561,6 +563,8 @@
 		clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
 		clock-names = "sclk_fimd", "fimd";
 		power-domains = <&disp_pd>;
+		iommus = <&sysmmu_fimd1_0>, <&sysmmu_fimd1_1>;
+		iommu-names = "m0", "m1";
 	};
 
 	adc: adc at 12D10000 {
@@ -748,6 +752,7 @@
 		clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
 			 <&clock CLK_SCLK_HDMI>;
 		clock-names = "mixer", "hdmi", "sclk_hdmi";
+		iommus = <&sysmmu_tv>;
 		power-domains = <&disp_pd>;
 	};
 
@@ -758,6 +763,7 @@
 		clocks = <&clock CLK_GSCL0>;
 		clock-names = "gscl";
 		power-domains = <&gsc_pd>;
+		iommus = <&sysmmu_gscl0>;
 	};
 
 	gsc_1: video-scaler at 13e10000 {
@@ -767,6 +773,7 @@
 		clocks = <&clock CLK_GSCL1>;
 		clock-names = "gscl";
 		power-domains = <&gsc_pd>;
+		iommus = <&sysmmu_gscl1>;
 	};
 
 	pmu_system_controller: system-controller at 10040000 {
@@ -961,4 +968,178 @@
 		samsung,sysreg-phandle = <&sysreg_system_controller>;
 		samsung,pmureg-phandle = <&pmu_system_controller>;
 	};
+
+	sysmmu_g2dr: sysmmu at 0x10A60000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x10A60000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <24 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_g2dw: sysmmu at 0x10A70000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x10A70000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <22 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_tv: sysmmu at 0x14650000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14650000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <7 4>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MIXER>, <&clock CLK_MIXER>;
+		samsung,power-domain = <&disp_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gscl0: sysmmu at 0x13E80000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13E80000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL0>, <&clock CLK_GSCL0>;
+		power-domains = <&gsc_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_gscl1: sysmmu at 0x13E90000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x13E90000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <2 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_GSCL1>, <&clock CLK_GSCL1>;
+		power-domains = <&gsc_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler0r: sysmmu at 0x12880000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12880000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <22 4>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL0>, <&clock CLK_MSCL0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler1r: sysmmu at 0x12890000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x12890000 0x1000>;
+		interrupts = <0 186 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL1>, <&clock CLK_MSCL1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler2r: sysmmu at 0x128A0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x128A0000 0x1000>;
+		interrupts = <0 188 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL2>, <&clock CLK_MSCL2>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler0w: sysmmu at 0x128C0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x128C0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <27 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL0>, <&clock CLK_MSCL0>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler1w: sysmmu at 0x128D0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x128D0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <22 6>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL1>, <&clock CLK_MSCL1>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_scaler2w: sysmmu at 0x128E0000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x128E0000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <19 6>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MSCL2>, <&clock CLK_MSCL2>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_jpeg: sysmmu at 0x11F10000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11F10000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_JPEG>, <&clock CLK_JPEG>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_jpeg2: sysmmu at 0x11F20000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11F20000 0x1000>;
+		interrupts = <0 169 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_JPEG2>, <&clock CLK_JPEG2>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_l: sysmmu at 0x11200000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11200000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <6 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
+		power-domains = <&mfc_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_mfc_r: sysmmu at 0x11210000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11210000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <8 5>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
+		power-domains = <&mfc_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd1_0: sysmmu at 0x14640000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14640000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 2>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD1M0>, <&clock CLK_FIMD1>;
+		samsung,power-domain = <&disp_pd>;
+		#iommu-cells = <0>;
+	};
+
+	sysmmu_fimd1_1: sysmmu at 0x14680000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x14680000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <3 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_FIMD1M0>, <&clock CLK_FIMD1>;
+		samsung,power-domain = <&disp_pd>;
+		#iommu-cells = <0>;
+	};
 };
-- 
1.9.2

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

* [PATCH v6 25/25] ARM: dts: exynos: add iommu reserved regions for bootloader's splash screen
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04  8:16   ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Shaik Ameer Basha, Cho KyongHo, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

Some bootloaders enable FIMD module and configure it as a simple
framebuffer to display boot logo or splash screen before booting the
kernel. Such framebuffer stays enabled until proper kernel driver gets
probbed. Usually it is configured in such a way, that it performs DMA
from the buffer located in system memory. To avoid IOMMU access fault
during system boot, additional identity mapping between system memory
and IO virtual address space must be created when IOMMU driver gets
enabled.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos3250-rinato.dts         | 1 +
 arch/arm/boot/dts/exynos4210-trats.dts          | 1 +
 arch/arm/boot/dts/exynos4210-universal_c210.dts | 1 +
 arch/arm/boot/dts/exynos4412-trats2.dts         | 1 +
 arch/arm/boot/dts/exynos5250-snow.dts           | 1 +
 arch/arm/boot/dts/exynos5250-spring.dts         | 1 +
 arch/arm/boot/dts/exynos5420-peach-pit.dts      | 1 +
 arch/arm/boot/dts/exynos5800-peach-pi.dts       | 1 +
 8 files changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 0b9906880c0c..71641f47f6bb 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -203,6 +203,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x40000000 0x40000000 0x1ff00000>;
 
 	i80-if-timings {
 		cs-setup = <0>;
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 32c5fd8f6269..becc84b881a6 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -424,6 +424,7 @@
 
 	fimd@11c00000 {
 		status = "okay";
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x40000000>;
 	};
 
 	tmu@100C0000 {
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index d4f2b11319dd..ecc95263ff4c 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -450,6 +450,7 @@
 		pinctrl-0 = <&lcd_clk>, <&lcd_data24>;
 		pinctrl-names = "default";
 		status = "okay";
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x20000000>;
 		samsung,invert-vden;
 		samsung,invert-vclk;
 		#address-cells = <1>;
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 173ffa479ad3..78532629f396 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -758,6 +758,7 @@
 
 	fimd@11c00000 {
 		status = "okay";
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x40000000>;
 	};
 
 	camera: camera {
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index 2657e842e5a5..9f2e992cb396 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -286,6 +286,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x40000000 0x40000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
index d03f9b8d376d..334d98925d4b 100644
--- a/arch/arm/boot/dts/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -84,6 +84,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x40000000 0x40000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 0788d08fb43e..edc3976665d0 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -166,6 +166,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x20000000 0x20000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 412f41d62686..ac5a67a3ce48 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -153,6 +153,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x20000000 0x20000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
-- 
1.9.2

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

* [PATCH v6 25/25] ARM: dts: exynos: add iommu reserved regions for bootloader's splash screen
@ 2015-05-04  8:16   ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

Some bootloaders enable FIMD module and configure it as a simple
framebuffer to display boot logo or splash screen before booting the
kernel. Such framebuffer stays enabled until proper kernel driver gets
probbed. Usually it is configured in such a way, that it performs DMA
from the buffer located in system memory. To avoid IOMMU access fault
during system boot, additional identity mapping between system memory
and IO virtual address space must be created when IOMMU driver gets
enabled.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos3250-rinato.dts         | 1 +
 arch/arm/boot/dts/exynos4210-trats.dts          | 1 +
 arch/arm/boot/dts/exynos4210-universal_c210.dts | 1 +
 arch/arm/boot/dts/exynos4412-trats2.dts         | 1 +
 arch/arm/boot/dts/exynos5250-snow.dts           | 1 +
 arch/arm/boot/dts/exynos5250-spring.dts         | 1 +
 arch/arm/boot/dts/exynos5420-peach-pit.dts      | 1 +
 arch/arm/boot/dts/exynos5800-peach-pi.dts       | 1 +
 8 files changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 0b9906880c0c..71641f47f6bb 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -203,6 +203,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x40000000 0x40000000 0x1ff00000>;
 
 	i80-if-timings {
 		cs-setup = <0>;
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 32c5fd8f6269..becc84b881a6 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -424,6 +424,7 @@
 
 	fimd at 11c00000 {
 		status = "okay";
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x40000000>;
 	};
 
 	tmu at 100C0000 {
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index d4f2b11319dd..ecc95263ff4c 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -450,6 +450,7 @@
 		pinctrl-0 = <&lcd_clk>, <&lcd_data24>;
 		pinctrl-names = "default";
 		status = "okay";
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x20000000>;
 		samsung,invert-vden;
 		samsung,invert-vclk;
 		#address-cells = <1>;
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 173ffa479ad3..78532629f396 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -758,6 +758,7 @@
 
 	fimd at 11c00000 {
 		status = "okay";
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x40000000>;
 	};
 
 	camera: camera {
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index 2657e842e5a5..9f2e992cb396 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -286,6 +286,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x40000000 0x40000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
index d03f9b8d376d..334d98925d4b 100644
--- a/arch/arm/boot/dts/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -84,6 +84,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x40000000 0x40000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 0788d08fb43e..edc3976665d0 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -166,6 +166,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x20000000 0x20000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 412f41d62686..ac5a67a3ce48 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -153,6 +153,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x20000000 0x20000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
-- 
1.9.2

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

* [PATCH v6 27/26] iommu: exynos: add system suspend/resume support
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-04 10:30     ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04 10:30 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Rob Herring, Thierry Reding, Shaik Ameer Basha, Joonyoung Shim,
	Arnd Bergmann, Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw, Kyungmin Park, Kukjin Kim,
	Laurent Pinchart, Javier Martinez Canillas, Cho KyongHo,
	David Wodhouse

When system goes into suspend state, iommu should save it's state and
restore after system resume. This is handled by 'late' pm ops to ensure
that sysmmu will be suspended after its master devices and restored
before them.

Signed-off-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Hello,

This patch got lost in the rebase, I'm really sorry. Please process it
together with other iommu patches from "[PATCH v6 00/25] Exynos SYSMMU
(IOMMU) integration with DT and DMA-mapping subsystem" patchset.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland
---
 drivers/iommu/exynos-iommu.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 821797328c52..074e6cb05cc8 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -606,6 +606,36 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int exynos_sysmmu_suspend(struct device *dev)
+{
+	struct sysmmu_drvdata *data = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "suspend\n");
+	if (is_sysmmu_active(data)) {
+		__sysmmu_disable_nocount(data);
+		pm_runtime_put(dev);
+	}
+	return 0;
+}
+
+static int exynos_sysmmu_resume(struct device *dev)
+{
+	struct sysmmu_drvdata *data = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "resume\n");
+	if (is_sysmmu_active(data)) {
+		pm_runtime_get_sync(dev);
+		__sysmmu_enable_nocount(data);
+	}
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops sysmmu_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(exynos_sysmmu_suspend, exynos_sysmmu_resume)
+};
+
 static const struct of_device_id sysmmu_of_match[] __initconst = {
 	{ .compatible	= "samsung,exynos-sysmmu", },
 	{ },
@@ -616,6 +646,7 @@ static struct platform_driver exynos_sysmmu_driver __refdata = {
 	.driver	= {
 		.name		= "exynos-sysmmu",
 		.of_match_table	= sysmmu_of_match,
+		.pm		= &sysmmu_pm_ops,
 	}
 };
 
-- 
1.9.2

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

* [PATCH v6 27/26] iommu: exynos: add system suspend/resume support
@ 2015-05-04 10:30     ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-04 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

When system goes into suspend state, iommu should save it's state and
restore after system resume. This is handled by 'late' pm ops to ensure
that sysmmu will be suspended after its master devices and restored
before them.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
Hello,

This patch got lost in the rebase, I'm really sorry. Please process it
together with other iommu patches from "[PATCH v6 00/25] Exynos SYSMMU
(IOMMU) integration with DT and DMA-mapping subsystem" patchset.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland
---
 drivers/iommu/exynos-iommu.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 821797328c52..074e6cb05cc8 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -606,6 +606,36 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int exynos_sysmmu_suspend(struct device *dev)
+{
+	struct sysmmu_drvdata *data = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "suspend\n");
+	if (is_sysmmu_active(data)) {
+		__sysmmu_disable_nocount(data);
+		pm_runtime_put(dev);
+	}
+	return 0;
+}
+
+static int exynos_sysmmu_resume(struct device *dev)
+{
+	struct sysmmu_drvdata *data = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "resume\n");
+	if (is_sysmmu_active(data)) {
+		pm_runtime_get_sync(dev);
+		__sysmmu_enable_nocount(data);
+	}
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops sysmmu_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(exynos_sysmmu_suspend, exynos_sysmmu_resume)
+};
+
 static const struct of_device_id sysmmu_of_match[] __initconst = {
 	{ .compatible	= "samsung,exynos-sysmmu", },
 	{ },
@@ -616,6 +646,7 @@ static struct platform_driver exynos_sysmmu_driver __refdata = {
 	.driver	= {
 		.name		= "exynos-sysmmu",
 		.of_match_table	= sysmmu_of_match,
+		.pm		= &sysmmu_pm_ops,
 	}
 };
 
-- 
1.9.2

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

* Re: [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
  2015-05-04  8:15     ` Marek Szyprowski
@ 2015-05-04 22:12       ` Rob Herring
  -1 siblings, 0 replies; 116+ messages in thread
From: Rob Herring @ 2015-05-04 22:12 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Linux IOMMU, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Joerg Roedel,
	Thierry Reding, Olof Johansson, Laurent Pinchart, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

On Mon, May 4, 2015 at 3:15 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Some devices (like frame buffers) are enabled by bootloader and configured
> to perform DMA operations automatically (like displaying boot logo or splash
> screen). Such devices operate and perform DMA operation usually until the
> proper driver for them is loaded and probed. However before that happens,
> system usually loads IOMMU drivers and configures dma parameters for each
> device. When such initial configuration is created and enabled, it usually
> contains empty translation rules betweem IO address space and physical
> memory, because no buffers nor memory regions have been requested by the
> respective driver.
>
> This patch adds support for "iommu-reserved-mapping", which can be used
> to provide definitions for mappings that need to be created on system
> boot to let such devices (enabled by bootloader) to operate properly
> until respective driver is probed.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
>  arch/arm/mm/dma-mapping.c                         | 112 ++++++++++++++++++++++
>  2 files changed, 156 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/iommu/iommu.txt b/Documentation/devicetree/bindings/iommu/iommu.txt
> index 5a8b4624defc..fd54e6b597f0 100644
> --- a/Documentation/devicetree/bindings/iommu/iommu.txt
> +++ b/Documentation/devicetree/bindings/iommu/iommu.txt
> @@ -86,6 +86,35 @@ have a means to turn off translation. But it is invalid in such cases to
>  disable the IOMMU's device tree node in the first place because it would
>  prevent any driver from properly setting up the translations.
>
> +Optional properties:
> +--------------------
> +- iommu-reserved-mapping: A list of entries describing additional
> +  reserved mapping, that will be inserted to the default IO address space
> +  created for given master device. Each entry consist of IO address,
> +  physical memory address and size of the region.
> +
> +Some devices (like frame buffers) are enabled by bootloader and configured
> +to perform DMA operations automatically (like displaying boot logo or splash
> +screen). Such devices operate and perform DMA operation usually until the
> +proper driver for them is loaded and probed. However before that happens,
> +system usually loads IOMMU drivers and configures dma parameters for each

s/dma/DMA/

> +device. When such initial configuration is created and enabled, it usually
> +contains empty translation rules betweem IO address space and physical

s/betweem/between/

> +memory, because no buffers nor memory regions have been requested by the
> +respective driver.
> +
> +To avoid IOMMU page fault, one can provide "iommu-reserved-mapping"
> +property, which defines all memory regions which must be mapped to IO
> +address space to boot properly when device has been enabled by the
> +bootloader. More than one region can be defined for given master device.
> +Each region is defined by the following triplet: first entry is IO
> +address (encoded in "address" cells), second is base physical memory
> +address for this regions (also encoded in "address" cells) and the last
> +is size of the region (encoded in "size" cells). To ensure that that
> +given master device will not trigger page fault after enabling IOMMU,
> +one should define identity mapping between physical memory and IO
> +address space for the range of addresses accessed by the device.
> +
>
>  Notes:
>  ======
> @@ -113,6 +142,21 @@ Single-master IOMMU:
>                 iommus = <&{/iommu}>;
>         };
>
> +
> +Single-master IOMMU, which has been left enabled by bootloader:
> +---------------------------------------------------------------
> +
> +       iommu {
> +               #iommu-cells = <0>;
> +       };
> +
> +       master {
> +               iommus = <&{/iommu}>;
> +               /* bootloader configures framebuffer at 0x40000000 (32MiB)
> +               iommu-reserved-mapping = <0x40000000 0x40000000 0x2000000>;

Is there not an ordering problem if kernel initializes the IOMMU
before parsing this for each master? I would think the IOMMU driver
needs to find all of these mappings and cleanly switch the page tables
with the new reserved mapping.

Rob

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

* [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
@ 2015-05-04 22:12       ` Rob Herring
  0 siblings, 0 replies; 116+ messages in thread
From: Rob Herring @ 2015-05-04 22:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 4, 2015 at 3:15 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Some devices (like frame buffers) are enabled by bootloader and configured
> to perform DMA operations automatically (like displaying boot logo or splash
> screen). Such devices operate and perform DMA operation usually until the
> proper driver for them is loaded and probed. However before that happens,
> system usually loads IOMMU drivers and configures dma parameters for each
> device. When such initial configuration is created and enabled, it usually
> contains empty translation rules betweem IO address space and physical
> memory, because no buffers nor memory regions have been requested by the
> respective driver.
>
> This patch adds support for "iommu-reserved-mapping", which can be used
> to provide definitions for mappings that need to be created on system
> boot to let such devices (enabled by bootloader) to operate properly
> until respective driver is probed.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
>  arch/arm/mm/dma-mapping.c                         | 112 ++++++++++++++++++++++
>  2 files changed, 156 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/iommu/iommu.txt b/Documentation/devicetree/bindings/iommu/iommu.txt
> index 5a8b4624defc..fd54e6b597f0 100644
> --- a/Documentation/devicetree/bindings/iommu/iommu.txt
> +++ b/Documentation/devicetree/bindings/iommu/iommu.txt
> @@ -86,6 +86,35 @@ have a means to turn off translation. But it is invalid in such cases to
>  disable the IOMMU's device tree node in the first place because it would
>  prevent any driver from properly setting up the translations.
>
> +Optional properties:
> +--------------------
> +- iommu-reserved-mapping: A list of entries describing additional
> +  reserved mapping, that will be inserted to the default IO address space
> +  created for given master device. Each entry consist of IO address,
> +  physical memory address and size of the region.
> +
> +Some devices (like frame buffers) are enabled by bootloader and configured
> +to perform DMA operations automatically (like displaying boot logo or splash
> +screen). Such devices operate and perform DMA operation usually until the
> +proper driver for them is loaded and probed. However before that happens,
> +system usually loads IOMMU drivers and configures dma parameters for each

s/dma/DMA/

> +device. When such initial configuration is created and enabled, it usually
> +contains empty translation rules betweem IO address space and physical

s/betweem/between/

> +memory, because no buffers nor memory regions have been requested by the
> +respective driver.
> +
> +To avoid IOMMU page fault, one can provide "iommu-reserved-mapping"
> +property, which defines all memory regions which must be mapped to IO
> +address space to boot properly when device has been enabled by the
> +bootloader. More than one region can be defined for given master device.
> +Each region is defined by the following triplet: first entry is IO
> +address (encoded in "address" cells), second is base physical memory
> +address for this regions (also encoded in "address" cells) and the last
> +is size of the region (encoded in "size" cells). To ensure that that
> +given master device will not trigger page fault after enabling IOMMU,
> +one should define identity mapping between physical memory and IO
> +address space for the range of addresses accessed by the device.
> +
>
>  Notes:
>  ======
> @@ -113,6 +142,21 @@ Single-master IOMMU:
>                 iommus = <&{/iommu}>;
>         };
>
> +
> +Single-master IOMMU, which has been left enabled by bootloader:
> +---------------------------------------------------------------
> +
> +       iommu {
> +               #iommu-cells = <0>;
> +       };
> +
> +       master {
> +               iommus = <&{/iommu}>;
> +               /* bootloader configures framebuffer at 0x40000000 (32MiB)
> +               iommu-reserved-mapping = <0x40000000 0x40000000 0x2000000>;

Is there not an ordering problem if kernel initializes the IOMMU
before parsing this for each master? I would think the IOMMU driver
needs to find all of these mappings and cleanly switch the page tables
with the new reserved mapping.

Rob

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

* Re: [PATCH v6 23/25] ARM: dts: exynos5250: add sysmmu nodes
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05  4:04     ` Krzysztof Kozłowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:04 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Joerg Roedel,
	Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
	Will Deacon, David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa,
	Kyungmin Park, Joonyoung Shim, Seung-Woo Kim,
	Javier Martinez Canillas

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes to all defined devices that are specific
> to Exynos5250 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* [PATCH v6 23/25] ARM: dts: exynos5250: add sysmmu nodes
@ 2015-05-05  4:04     ` Krzysztof Kozłowski
  0 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:04 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes to all defined devices that are specific
> to Exynos5250 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* Re: [PATCH v6 20/25] ARM: dts: exynos4: add sysmmu nodes
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05  4:08     ` Krzysztof Kozłowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:08 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Joerg Roedel,
	Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
	Will Deacon, David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa,
	Kyungmin Park, Joonyoung Shim, Seung-Woo Kim,
	Javier Martinez Canillas

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes that are specific to Exynos4210/4x12 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* [PATCH v6 20/25] ARM: dts: exynos4: add sysmmu nodes
@ 2015-05-05  4:08     ` Krzysztof Kozłowski
  0 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:08 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes that are specific to Exynos4210/4x12 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* Re: [PATCH v6 22/25] ARM: dts: exynos4415: add sysmmu nodes
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05  4:09     ` Krzysztof Kozłowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:09 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Joerg Roedel,
	Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
	Will Deacon, David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa,
	Kyungmin Park, Joonyoung Shim, Seung-Woo Kim,
	Javier Martinez Canillas

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes to all defined devices that are specific
> to Exynos4415 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* [PATCH v6 22/25] ARM: dts: exynos4415: add sysmmu nodes
@ 2015-05-05  4:09     ` Krzysztof Kozłowski
  0 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:09 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes to all defined devices that are specific
> to Exynos4415 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* Re: [PATCH v6 21/25] ARM: dts: exynos3250: add sysmmu nodes
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05  4:10     ` Krzysztof Kozłowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:10 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Joerg Roedel,
	Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
	Will Deacon, David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa,
	Kyungmin Park, Joonyoung Shim, Seung-Woo Kim,
	Javier Martinez Canillas

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes to the devices that are specific to
> Exynos3250 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* [PATCH v6 21/25] ARM: dts: exynos3250: add sysmmu nodes
@ 2015-05-05  4:10     ` Krzysztof Kozłowski
  0 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:10 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes to the devices that are specific to
> Exynos3250 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* Re: [PATCH v6 24/25] ARM: dts: exynos5420: add sysmmu nodes
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05  4:10     ` Krzysztof Kozłowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:10 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Joerg Roedel,
	Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
	Will Deacon, David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa,
	Kyungmin Park, Joonyoung Shim, Seung-Woo Kim,
	Javier Martinez Canillas

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes to all defined devices that are specific
> to Exynos5420/5800/5422 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* [PATCH v6 24/25] ARM: dts: exynos5420: add sysmmu nodes
@ 2015-05-05  4:10     ` Krzysztof Kozłowski
  0 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  4:10 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> This patch adds System MMU nodes to all defined devices that are specific
> to Exynos5420/5800/5422 series.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* Re: [PATCH v6 25/25] ARM: dts: exynos: add iommu reserved regions for bootloader's splash screen
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05  5:50       ` Krzysztof Kozłowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  5:50 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Rob Herring,
	Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Cho KyongHo, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
> Some bootloaders enable FIMD module and configure it as a simple
> framebuffer to display boot logo or splash screen before booting the
> kernel. Such framebuffer stays enabled until proper kernel driver gets
> probbed. Usually it is configured in such a way, that it performs DMA
> from the buffer located in system memory. To avoid IOMMU access fault
> during system boot, additional identity mapping between system memory
> and IO virtual address space must be created when IOMMU driver gets
> enabled.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

Acked-by: Krzysztof Kozlowski <k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

Best regards,
Krzysztof

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

* [PATCH v6 25/25] ARM: dts: exynos: add iommu reserved regions for bootloader's splash screen
@ 2015-05-05  5:50       ` Krzysztof Kozłowski
  0 siblings, 0 replies; 116+ messages in thread
From: Krzysztof Kozłowski @ 2015-05-05  5:50 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-04 17:16 GMT+09:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> Some bootloaders enable FIMD module and configure it as a simple
> framebuffer to display boot logo or splash screen before booting the
> kernel. Such framebuffer stays enabled until proper kernel driver gets
> probbed. Usually it is configured in such a way, that it performs DMA
> from the buffer located in system memory. To avoid IOMMU access fault
> during system boot, additional identity mapping between system memory
> and IO virtual address space must be created when IOMMU driver gets
> enabled.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

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

* Re: [PATCH v6 08/25] iommu: exynos: refactor function parameters to simplify code
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05 14:52       ` Joerg Roedel
  -1 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 14:52 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Rob Herring,
	Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Cho KyongHo, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Mon, May 04, 2015 at 10:16:03AM +0200, Marek Szyprowski wrote:
> @@ -719,14 +712,12 @@ static void exynos_iommu_domain_free(struct iommu_domain *domain)
>  
>  	spin_lock_irqsave(&priv->lock, flags);
>  
> -	list_for_each_entry(owner, &priv->clients, client) {
> -		while (!exynos_sysmmu_disable(owner->dev))
> -			; /* until System MMU is actually disabled */
> +	list_for_each_entry(data, &priv->clients, domain_node) {
> +		if (__sysmmu_disable(data))
> +			data->master = NULL;
> +		list_del_init(&data->domain_node);
>  	}

This needs list_for_each_entry_safe.

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

* [PATCH v6 08/25] iommu: exynos: refactor function parameters to simplify code
@ 2015-05-05 14:52       ` Joerg Roedel
  0 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 14:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 04, 2015 at 10:16:03AM +0200, Marek Szyprowski wrote:
> @@ -719,14 +712,12 @@ static void exynos_iommu_domain_free(struct iommu_domain *domain)
>  
>  	spin_lock_irqsave(&priv->lock, flags);
>  
> -	list_for_each_entry(owner, &priv->clients, client) {
> -		while (!exynos_sysmmu_disable(owner->dev))
> -			; /* until System MMU is actually disabled */
> +	list_for_each_entry(data, &priv->clients, domain_node) {
> +		if (__sysmmu_disable(data))
> +			data->master = NULL;
> +		list_del_init(&data->domain_node);
>  	}

This needs list_for_each_entry_safe.

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

* Re: [PATCH v6 09/25] iommu: exynos: remove unused functions, part 2
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05 14:53       ` Joerg Roedel
  -1 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 14:53 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Rob Herring,
	Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Cho KyongHo, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Mon, May 04, 2015 at 10:16:04AM +0200, Marek Szyprowski wrote:
> After refactoring functions to use pointer to struct sysmmu_drvdata
> directly, some functions became useless and thus never used, so remove
> them completely.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/iommu/exynos-iommu.c | 43 -------------------------------------------
>  1 file changed, 43 deletions(-)

Can you fold this patch into the previous one? Then the simplifications
become directly visible in the diffstat.

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

* [PATCH v6 09/25] iommu: exynos: remove unused functions, part 2
@ 2015-05-05 14:53       ` Joerg Roedel
  0 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 14:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 04, 2015 at 10:16:04AM +0200, Marek Szyprowski wrote:
> After refactoring functions to use pointer to struct sysmmu_drvdata
> directly, some functions became useless and thus never used, so remove
> them completely.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 43 -------------------------------------------
>  1 file changed, 43 deletions(-)

Can you fold this patch into the previous one? Then the simplifications
become directly visible in the diffstat.

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

* Re: [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05 14:55       ` Joerg Roedel
  -1 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 14:55 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Rob Herring,
	Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Cho KyongHo, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Mon, May 04, 2015 at 10:16:05AM +0200, Marek Szyprowski wrote:
> The driver doesn't need to do anything important in device add/remove
> callbacks, because initialization will be done from device-tree specific
> callbacks added later. IOMMU groups created by current code were never
> used.

Hmm, will this remove support for iommu-groups in the exynos driver? I
am still working on the default-domain patch-set which makes iommu-group
support mandatory for iommu-drivers.


	Joerg

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

* [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
@ 2015-05-05 14:55       ` Joerg Roedel
  0 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 14:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 04, 2015 at 10:16:05AM +0200, Marek Szyprowski wrote:
> The driver doesn't need to do anything important in device add/remove
> callbacks, because initialization will be done from device-tree specific
> callbacks added later. IOMMU groups created by current code were never
> used.

Hmm, will this remove support for iommu-groups in the exynos driver? I
am still working on the default-domain patch-set which makes iommu-group
support mandatory for iommu-drivers.


	Joerg

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

* Re: [PATCH v6 15/25] iommu: exynos: document internal structures
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-05 15:00       ` Joerg Roedel
  -1 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 15:00 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Rob Herring,
	Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Cho KyongHo, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Mon, May 04, 2015 at 10:16:10AM +0200, Marek Szyprowski wrote:
>  struct exynos_iommu_domain {
> -	struct list_head clients; /* list of sysmmu_drvdata.node */
> +	struct list_head clients; /* list of sysmmu_drvdata.domain_node */
>  	sysmmu_pte_t *pgtable; /* lv1 page table, 16KB */
>  	short *lv2entcnt; /* free lv2 entry counter for each section */
> -	spinlock_t lock; /* lock for this structure */
> +	spinlock_t lock; /* lock for modyfying list of clients */
>  	spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
>  	struct iommu_domain domain; /* generic domain data structure */
>  };
>  
> +/*
> + * This structure hold all data of a single SYSMMU controller, this includes
> + * hw resources like registers and clocks, pointers and list nodes to connect
> + * it to all other structures, internal state and parameters read from device
> + * tree. It is usually referenced by 'data' pointer.
> + */
>  struct sysmmu_drvdata {
> -	struct device *sysmmu;	/* System MMU's device descriptor */
> -	struct device *master;	/* Owner of system MMU */
> -	void __iomem *sfrbase;
> -	struct clk *clk;
> -	struct clk *clk_master;
> -	int activations;
> -	spinlock_t lock;
> -	struct exynos_iommu_domain *domain;
> -	struct list_head domain_node;
> -	struct list_head owner_node;
> -	phys_addr_t pgtable;
> -	int version;
> +	struct device *sysmmu; /* SYSMMU controller device */
> +	struct device *master; /* master device (owner of given SYSMMU) */
> +	void __iomem *sfrbase; /* our registers */
> +	struct clk *clk; /* SYSMMU's clock */
> +	struct clk *clk_master; /* master's device clock */
> +	int activations; /* number of calls to sysmmu_enable */
> +	spinlock_t lock; /* lock for modyfying enable/disable state */
> +	struct exynos_iommu_domain *domain; /* domain we belong to */
> +	struct list_head domain_node; /* node for domain clients list */
> +	struct list_head owner_node; /* node for owner clients list */
> +	phys_addr_t pgtable; /* assigned page table structure */
> +	int version; /* our version */
>  };

Please align the comments for the struct members to the same column for
better readability.

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

* [PATCH v6 15/25] iommu: exynos: document internal structures
@ 2015-05-05 15:00       ` Joerg Roedel
  0 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 15:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 04, 2015 at 10:16:10AM +0200, Marek Szyprowski wrote:
>  struct exynos_iommu_domain {
> -	struct list_head clients; /* list of sysmmu_drvdata.node */
> +	struct list_head clients; /* list of sysmmu_drvdata.domain_node */
>  	sysmmu_pte_t *pgtable; /* lv1 page table, 16KB */
>  	short *lv2entcnt; /* free lv2 entry counter for each section */
> -	spinlock_t lock; /* lock for this structure */
> +	spinlock_t lock; /* lock for modyfying list of clients */
>  	spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
>  	struct iommu_domain domain; /* generic domain data structure */
>  };
>  
> +/*
> + * This structure hold all data of a single SYSMMU controller, this includes
> + * hw resources like registers and clocks, pointers and list nodes to connect
> + * it to all other structures, internal state and parameters read from device
> + * tree. It is usually referenced by 'data' pointer.
> + */
>  struct sysmmu_drvdata {
> -	struct device *sysmmu;	/* System MMU's device descriptor */
> -	struct device *master;	/* Owner of system MMU */
> -	void __iomem *sfrbase;
> -	struct clk *clk;
> -	struct clk *clk_master;
> -	int activations;
> -	spinlock_t lock;
> -	struct exynos_iommu_domain *domain;
> -	struct list_head domain_node;
> -	struct list_head owner_node;
> -	phys_addr_t pgtable;
> -	int version;
> +	struct device *sysmmu; /* SYSMMU controller device */
> +	struct device *master; /* master device (owner of given SYSMMU) */
> +	void __iomem *sfrbase; /* our registers */
> +	struct clk *clk; /* SYSMMU's clock */
> +	struct clk *clk_master; /* master's device clock */
> +	int activations; /* number of calls to sysmmu_enable */
> +	spinlock_t lock; /* lock for modyfying enable/disable state */
> +	struct exynos_iommu_domain *domain; /* domain we belong to */
> +	struct list_head domain_node; /* node for domain clients list */
> +	struct list_head owner_node; /* node for owner clients list */
> +	phys_addr_t pgtable; /* assigned page table structure */
> +	int version; /* our version */
>  };

Please align the comments for the struct members to the same column for
better readability.

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

* Re: [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-05 15:05     ` Joerg Roedel
  -1 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 15:05 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Rob Herring,
	Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Cho KyongHo, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Marek,

On Mon, May 04, 2015 at 10:15:55AM +0200, Marek Szyprowski wrote:
>   iommu: exynos: don't read version register on every tlb operation

Please use 'iommu/exynos:' as prefix for the iommu patches and start
the remaining subject with a capital letter, like this:

	iommu/exynos: Don't read version register on every tlb operation

>  Documentation/devicetree/bindings/iommu/iommu.txt |  44 ++
>  arch/arm/boot/dts/exynos3250-rinato.dts           |   1 +
>  arch/arm/boot/dts/exynos3250.dtsi                 |  22 +
>  arch/arm/boot/dts/exynos4.dtsi                    | 118 ++++++
>  arch/arm/boot/dts/exynos4210-trats.dts            |   1 +
>  arch/arm/boot/dts/exynos4210-universal_c210.dts   |   1 +
>  arch/arm/boot/dts/exynos4210.dtsi                 |  23 +
>  arch/arm/boot/dts/exynos4412-trats2.dts           |   1 +
>  arch/arm/boot/dts/exynos4415.dtsi                 |  11 +
>  arch/arm/boot/dts/exynos4x12.dtsi                 |  82 ++++
>  arch/arm/boot/dts/exynos5250-snow.dts             |   1 +
>  arch/arm/boot/dts/exynos5250-spring.dts           |   1 +
>  arch/arm/boot/dts/exynos5250.dtsi                 | 250 +++++++++++
>  arch/arm/boot/dts/exynos5420-peach-pit.dts        |   1 +
>  arch/arm/boot/dts/exynos5420.dtsi                 | 181 ++++++++
>  arch/arm/boot/dts/exynos5800-peach-pi.dts         |   1 +
>  arch/arm/mach-exynos/pm_domains.c                 |  18 +-
>  arch/arm/mm/dma-mapping.c                         | 112 +++++
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c          |  27 +-
>  drivers/gpu/drm/exynos/exynos_drm_iommu.c         |   3 +
>  drivers/iommu/exynos-iommu.c                      | 495 ++++++++++------------
>  21 files changed, 1098 insertions(+), 296 deletions(-)

What is the plan for merging this, should it go through the iommu tree
or some other path?


	Joerg

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

* [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
@ 2015-05-05 15:05     ` Joerg Roedel
  0 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-05 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marek,

On Mon, May 04, 2015 at 10:15:55AM +0200, Marek Szyprowski wrote:
>   iommu: exynos: don't read version register on every tlb operation

Please use 'iommu/exynos:' as prefix for the iommu patches and start
the remaining subject with a capital letter, like this:

	iommu/exynos: Don't read version register on every tlb operation

>  Documentation/devicetree/bindings/iommu/iommu.txt |  44 ++
>  arch/arm/boot/dts/exynos3250-rinato.dts           |   1 +
>  arch/arm/boot/dts/exynos3250.dtsi                 |  22 +
>  arch/arm/boot/dts/exynos4.dtsi                    | 118 ++++++
>  arch/arm/boot/dts/exynos4210-trats.dts            |   1 +
>  arch/arm/boot/dts/exynos4210-universal_c210.dts   |   1 +
>  arch/arm/boot/dts/exynos4210.dtsi                 |  23 +
>  arch/arm/boot/dts/exynos4412-trats2.dts           |   1 +
>  arch/arm/boot/dts/exynos4415.dtsi                 |  11 +
>  arch/arm/boot/dts/exynos4x12.dtsi                 |  82 ++++
>  arch/arm/boot/dts/exynos5250-snow.dts             |   1 +
>  arch/arm/boot/dts/exynos5250-spring.dts           |   1 +
>  arch/arm/boot/dts/exynos5250.dtsi                 | 250 +++++++++++
>  arch/arm/boot/dts/exynos5420-peach-pit.dts        |   1 +
>  arch/arm/boot/dts/exynos5420.dtsi                 | 181 ++++++++
>  arch/arm/boot/dts/exynos5800-peach-pi.dts         |   1 +
>  arch/arm/mach-exynos/pm_domains.c                 |  18 +-
>  arch/arm/mm/dma-mapping.c                         | 112 +++++
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c          |  27 +-
>  drivers/gpu/drm/exynos/exynos_drm_iommu.c         |   3 +
>  drivers/iommu/exynos-iommu.c                      | 495 ++++++++++------------
>  21 files changed, 1098 insertions(+), 296 deletions(-)

What is the plan for merging this, should it go through the iommu tree
or some other path?


	Joerg

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

* Re: [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
  2015-05-04  8:15     ` Marek Szyprowski
@ 2015-05-06 14:01       ` Robin Murphy
  -1 siblings, 0 replies; 116+ messages in thread
From: Robin Murphy @ 2015-05-06 14:01 UTC (permalink / raw)
  To: Marek Szyprowski, iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Rob Herring, Thierry Reding, Shaik Ameer Basha, Joonyoung Shim,
	Arnd Bergmann, Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig, Kyungmin Park, Kukjin Kim, Laurent Pinchart,
	Javier Martinez Canillas, Cho KyongHo, David Wodhouse

Hi Marek,

On 04/05/15 09:15, Marek Szyprowski wrote:
> Some devices (like frame buffers) are enabled by bootloader and configured
> to perform DMA operations automatically (like displaying boot logo or splash
> screen). Such devices operate and perform DMA operation usually until the
> proper driver for them is loaded and probed. However before that happens,
> system usually loads IOMMU drivers and configures dma parameters for each
> device. When such initial configuration is created and enabled, it usually
> contains empty translation rules betweem IO address space and physical
> memory, because no buffers nor memory regions have been requested by the
> respective driver.
>
> This patch adds support for "iommu-reserved-mapping", which can be used
> to provide definitions for mappings that need to be created on system
> boot to let such devices (enabled by bootloader) to operate properly
> until respective driver is probed.

This appears to only work if you assume the driver is going to tear down 
the existing domain entirely; what about drivers that don't manage 
IOMMUs explicitly, or if there are multiple active devices behind the 
same IOMMU which (in future) start out in the same default domain? If 
any device is happy to remain in the default domain then it would be 
nice to clear the reservations once they are no longer needed.

Could we not address the issue in a more robust way, like fleshing out 
an implementation of the nascent IOMMU_DOMAIN_IDENTITY type, then just 
flagging such devices to stipulate that their boot-time default domain 
must be an identity-mapped one?

> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>   Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
>   arch/arm/mm/dma-mapping.c                         | 112 ++++++++++++++++++++++
>   2 files changed, 156 insertions(+)
>
[...]
> @@ -2048,6 +2092,66 @@ void arm_iommu_detach_device(struct device *dev)
>   }
>   EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
>
> +static int arm_iommu_add_reserved(struct device *dev,
> +                       struct dma_iommu_mapping *domain, phys_addr_t phys,
> +                       dma_addr_t dma, size_t size)
> +{
> +       int ret;
> +
> +       ret = __reserve_iova(domain, dma, size);
> +       if (ret) {
> +               dev_err(dev, "failed to reserve mapping\n");
> +               return -EINVAL;
> +       }
> +
> +       ret = iommu_map(domain->domain, dma, phys, size, IOMMU_READ);
> +       if (ret != 0) {
> +               dev_err(dev, "create IOMMU mapping\n");
> +               return ret;
> +       }
> +
> +       dev_info(dev, "created reserved DMA mapping (%pa -> %pad, %zu bytes)\n",
> +                &phys, &dma, size);
> +
> +       return 0;
> +}
> +
> +static int arm_iommu_init_reserved(struct device *dev,
> +                                  struct dma_iommu_mapping *domain)
> +{
> +       const char *name = "iommu-reserved-mapping";
> +       const __be32 *prop = NULL;
> +       int len, naddr, nsize;
> +       struct device_node *node = dev->of_node;
> +       phys_addr_t phys;
> +       dma_addr_t dma;
> +       size_t size;
> +
> +       if (!node)
> +               return 0;
> +
> +       naddr = of_n_addr_cells(node);
> +       nsize = of_n_size_cells(node);
> +
> +       prop = of_get_property(node, name, &len);
> +       if (!prop)
> +               return 0;
> +
> +       len /= sizeof(u32);
> +
> +       if (len < 2 * naddr + nsize) {
> +               dev_err(dev, "invalid length (%d cells) of %s property\n",
> +                       len, name);
> +               return -EINVAL;
> +       }
> +
> +       phys = of_read_number(prop, naddr);
> +       dma = of_read_number(prop + naddr, naddr);
> +       size = of_read_number(prop + 2*naddr, nsize);
> +
> +       return arm_iommu_add_reserved(dev, domain, phys, dma, size);
 > +}

I may be missing something, but I don't see how this can handle multiple 
ranges for the same device as the binding says.

>   static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
>   {
>          return coherent ? &iommu_coherent_ops : &iommu_ops;
> @@ -2068,6 +2172,14 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
>                  return false;
>          }
>
> +       if (arm_iommu_init_reserved(dev, mapping) != 0) {
> +               pr_warn("Failed to initialize reserved mapping for device %s\n",
> +                       dev_name(dev));
> +               __arm_iommu_detach_device(dev);
> +               arm_iommu_release_mapping(mapping);
> +               return false;
> +       }
> +
>          if (__arm_iommu_attach_device(dev, mapping)) {
>                  pr_warn("Failed to attached device %s to IOMMU_mapping\n",
>                                  dev_name(dev));

I'm hoping Joerg is still working on his default domain series, because 
the domain creation in arch_setup_dma_ops turns out to be horrible on a 
number of levels (like everything happening in the wrong order for 
platform devices). If that doesn't negate this issue entirely, it's 
going to significantly break this way of hooking up the solution 
(depending on what the drivers do) - worth some consideration, at least.

Robin.

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

* [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
@ 2015-05-06 14:01       ` Robin Murphy
  0 siblings, 0 replies; 116+ messages in thread
From: Robin Murphy @ 2015-05-06 14:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marek,

On 04/05/15 09:15, Marek Szyprowski wrote:
> Some devices (like frame buffers) are enabled by bootloader and configured
> to perform DMA operations automatically (like displaying boot logo or splash
> screen). Such devices operate and perform DMA operation usually until the
> proper driver for them is loaded and probed. However before that happens,
> system usually loads IOMMU drivers and configures dma parameters for each
> device. When such initial configuration is created and enabled, it usually
> contains empty translation rules betweem IO address space and physical
> memory, because no buffers nor memory regions have been requested by the
> respective driver.
>
> This patch adds support for "iommu-reserved-mapping", which can be used
> to provide definitions for mappings that need to be created on system
> boot to let such devices (enabled by bootloader) to operate properly
> until respective driver is probed.

This appears to only work if you assume the driver is going to tear down 
the existing domain entirely; what about drivers that don't manage 
IOMMUs explicitly, or if there are multiple active devices behind the 
same IOMMU which (in future) start out in the same default domain? If 
any device is happy to remain in the default domain then it would be 
nice to clear the reservations once they are no longer needed.

Could we not address the issue in a more robust way, like fleshing out 
an implementation of the nascent IOMMU_DOMAIN_IDENTITY type, then just 
flagging such devices to stipulate that their boot-time default domain 
must be an identity-mapped one?

> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>   Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
>   arch/arm/mm/dma-mapping.c                         | 112 ++++++++++++++++++++++
>   2 files changed, 156 insertions(+)
>
[...]
> @@ -2048,6 +2092,66 @@ void arm_iommu_detach_device(struct device *dev)
>   }
>   EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
>
> +static int arm_iommu_add_reserved(struct device *dev,
> +                       struct dma_iommu_mapping *domain, phys_addr_t phys,
> +                       dma_addr_t dma, size_t size)
> +{
> +       int ret;
> +
> +       ret = __reserve_iova(domain, dma, size);
> +       if (ret) {
> +               dev_err(dev, "failed to reserve mapping\n");
> +               return -EINVAL;
> +       }
> +
> +       ret = iommu_map(domain->domain, dma, phys, size, IOMMU_READ);
> +       if (ret != 0) {
> +               dev_err(dev, "create IOMMU mapping\n");
> +               return ret;
> +       }
> +
> +       dev_info(dev, "created reserved DMA mapping (%pa -> %pad, %zu bytes)\n",
> +                &phys, &dma, size);
> +
> +       return 0;
> +}
> +
> +static int arm_iommu_init_reserved(struct device *dev,
> +                                  struct dma_iommu_mapping *domain)
> +{
> +       const char *name = "iommu-reserved-mapping";
> +       const __be32 *prop = NULL;
> +       int len, naddr, nsize;
> +       struct device_node *node = dev->of_node;
> +       phys_addr_t phys;
> +       dma_addr_t dma;
> +       size_t size;
> +
> +       if (!node)
> +               return 0;
> +
> +       naddr = of_n_addr_cells(node);
> +       nsize = of_n_size_cells(node);
> +
> +       prop = of_get_property(node, name, &len);
> +       if (!prop)
> +               return 0;
> +
> +       len /= sizeof(u32);
> +
> +       if (len < 2 * naddr + nsize) {
> +               dev_err(dev, "invalid length (%d cells) of %s property\n",
> +                       len, name);
> +               return -EINVAL;
> +       }
> +
> +       phys = of_read_number(prop, naddr);
> +       dma = of_read_number(prop + naddr, naddr);
> +       size = of_read_number(prop + 2*naddr, nsize);
> +
> +       return arm_iommu_add_reserved(dev, domain, phys, dma, size);
 > +}

I may be missing something, but I don't see how this can handle multiple 
ranges for the same device as the binding says.

>   static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
>   {
>          return coherent ? &iommu_coherent_ops : &iommu_ops;
> @@ -2068,6 +2172,14 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
>                  return false;
>          }
>
> +       if (arm_iommu_init_reserved(dev, mapping) != 0) {
> +               pr_warn("Failed to initialize reserved mapping for device %s\n",
> +                       dev_name(dev));
> +               __arm_iommu_detach_device(dev);
> +               arm_iommu_release_mapping(mapping);
> +               return false;
> +       }
> +
>          if (__arm_iommu_attach_device(dev, mapping)) {
>                  pr_warn("Failed to attached device %s to IOMMU_mapping\n",
>                                  dev_name(dev));

I'm hoping Joerg is still working on his default domain series, because 
the domain creation in arch_setup_dma_ops turns out to be horrible on a 
number of levels (like everything happening in the wrong order for 
platform devices). If that doesn't negate this issue entirely, it's 
going to significantly break this way of hooking up the solution 
(depending on what the drivers do) - worth some consideration, at least.

Robin.

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

* Re: [PATCH v6 05/25] iommu: exynos: don't read version register on every tlb operation
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-10 12:59     ` Cho KyongHo
  -1 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 12:59 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

On Mon, 04 May 2015 10:16:00 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> This patch removes reading of REG_MMU_VERSION register on every tlb
> operation and caches SYSMMU version in driver's internal data.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 3e898504a7c4..3861485f0689 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -213,6 +213,7 @@ struct sysmmu_drvdata {
>  	spinlock_t lock;
>  	struct iommu_domain *domain;
>  	phys_addr_t pgtable;
> +	int version;

Why don't you define its type as unsigned int or u32?

Regards,

KyongHo

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

* [PATCH v6 05/25] iommu: exynos: don't read version register on every tlb operation
@ 2015-05-10 12:59     ` Cho KyongHo
  0 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 04 May 2015 10:16:00 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> This patch removes reading of REG_MMU_VERSION register on every tlb
> operation and caches SYSMMU version in driver's internal data.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 3e898504a7c4..3861485f0689 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -213,6 +213,7 @@ struct sysmmu_drvdata {
>  	spinlock_t lock;
>  	struct iommu_domain *domain;
>  	phys_addr_t pgtable;
> +	int version;

Why don't you define its type as unsigned int or u32?

Regards,

KyongHo

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

* Re: [PATCH v6 06/25] iommu: exynos: remove unused functions
  2015-05-04  8:16     ` Marek Szyprowski
@ 2015-05-10 13:01       ` Cho KyongHo
  -1 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 13:01 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

On Mon, 04 May 2015 10:16:01 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> This patch removes two unneeded functions, which are not a part of
> generic IOMMU API and were never used by any other driver.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 31 -------------------------------
>  1 file changed, 31 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 3861485f0689..98aa7e9c2507 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -496,13 +496,6 @@ static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
>  	return ret;
>  }
>  
> -int exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable)
> -{
> -	BUG_ON(!memblock_is_memory(pgtable));
> -
> -	return __exynos_sysmmu_enable(dev, pgtable, NULL);
> -}
> -
>  static bool exynos_sysmmu_disable(struct device *dev)
>  {
>  	unsigned long flags;
> @@ -594,30 +587,6 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
>  	spin_unlock_irqrestore(&data->lock, flags);
>  }
>  
> -void exynos_sysmmu_tlb_invalidate(struct device *dev)
> -{
> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
> -	unsigned long flags;
> -	struct sysmmu_drvdata *data;
> -
> -	data = dev_get_drvdata(owner->sysmmu);
> -
> -	spin_lock_irqsave(&data->lock, flags);
> -	if (is_sysmmu_active(data)) {
> -		if (!IS_ERR(data->clk_master))
> -			clk_enable(data->clk_master);
> -		if (sysmmu_block(data->sfrbase)) {
> -			__sysmmu_tlb_invalidate(data->sfrbase);
> -			sysmmu_unblock(data->sfrbase);
> -		}
> -		if (!IS_ERR(data->clk_master))
> -			clk_disable(data->clk_master);
> -	} else {
> -		dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
> -	}
> -	spin_unlock_irqrestore(&data->lock, flags);
> -}
> -
>  static int __init exynos_sysmmu_probe(struct platform_device *pdev)
>  {
>  	int irq, ret;


Actually they are for some drivers that are not upstreamed.
But I agree removing them.

Regards,

KyongHo

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

* [PATCH v6 06/25] iommu: exynos: remove unused functions
@ 2015-05-10 13:01       ` Cho KyongHo
  0 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 13:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 04 May 2015 10:16:01 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> This patch removes two unneeded functions, which are not a part of
> generic IOMMU API and were never used by any other driver.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 31 -------------------------------
>  1 file changed, 31 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 3861485f0689..98aa7e9c2507 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -496,13 +496,6 @@ static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
>  	return ret;
>  }
>  
> -int exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable)
> -{
> -	BUG_ON(!memblock_is_memory(pgtable));
> -
> -	return __exynos_sysmmu_enable(dev, pgtable, NULL);
> -}
> -
>  static bool exynos_sysmmu_disable(struct device *dev)
>  {
>  	unsigned long flags;
> @@ -594,30 +587,6 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
>  	spin_unlock_irqrestore(&data->lock, flags);
>  }
>  
> -void exynos_sysmmu_tlb_invalidate(struct device *dev)
> -{
> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
> -	unsigned long flags;
> -	struct sysmmu_drvdata *data;
> -
> -	data = dev_get_drvdata(owner->sysmmu);
> -
> -	spin_lock_irqsave(&data->lock, flags);
> -	if (is_sysmmu_active(data)) {
> -		if (!IS_ERR(data->clk_master))
> -			clk_enable(data->clk_master);
> -		if (sysmmu_block(data->sfrbase)) {
> -			__sysmmu_tlb_invalidate(data->sfrbase);
> -			sysmmu_unblock(data->sfrbase);
> -		}
> -		if (!IS_ERR(data->clk_master))
> -			clk_disable(data->clk_master);
> -	} else {
> -		dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
> -	}
> -	spin_unlock_irqrestore(&data->lock, flags);
> -}
> -
>  static int __init exynos_sysmmu_probe(struct platform_device *pdev)
>  {
>  	int irq, ret;


Actually they are for some drivers that are not upstreamed.
But I agree removing them.

Regards,

KyongHo

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

* Re: [PATCH v6 08/25] iommu: exynos: refactor function parameters to simplify code
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-10 13:27       ` Cho KyongHo
  -1 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 13:27 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Rob Herring, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Inki Dae,
	Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Thierry Reding, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Mon, 04 May 2015 10:16:03 +0200 Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:

> This patch simplifies the code by:
> - refactoring function parameters from struct device pointer to direct
>   pointer to struct sysmmu drvdata
> - moving list_head enteries from struct exynos_iommu_owner directly to
>   struct sysmmu_drvdata
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/iommu/exynos-iommu.c | 93 ++++++++++++++++++++++----------------------
>  1 file changed, 46 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index c307c400613c..0c23b69022cd 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -186,8 +186,6 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
>  
>  /* attached to dev.archdata.iommu of the master device */
>  struct exynos_iommu_owner {
> -	struct list_head client; /* entry of exynos_iommu_domain.clients */
> -	struct device *dev;
>  	struct device *sysmmu;
>  };
>  
> @@ -209,6 +207,7 @@ struct sysmmu_drvdata {
>  	int activations;
>  	spinlock_t lock;
>  	struct iommu_domain *domain;
> +	struct list_head domain_node;
>  	phys_addr_t pgtable;
>  	int version;
>  };
> @@ -514,12 +513,10 @@ static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
>  		__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
>  }
>  
> -static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
> +static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
>  					    sysmmu_iova_t iova)
>  {
>  	unsigned long flags;
> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
> -	struct sysmmu_drvdata *data = dev_get_drvdata(owner->sysmmu);
>  
>  	if (!IS_ERR(data->clk_master))
>  		clk_enable(data->clk_master);
> @@ -533,14 +530,10 @@ static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
>  		clk_disable(data->clk_master);
>  }
>  
> -static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
> -					size_t size)
> +static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
> +					sysmmu_iova_t iova, size_t size)
>  {
> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>  	unsigned long flags;
> -	struct sysmmu_drvdata *data;
> -
> -	data = dev_get_drvdata(owner->sysmmu);
>  
>  	spin_lock_irqsave(&data->lock, flags);
>  	if (is_sysmmu_active(data)) {
> @@ -570,8 +563,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
>  		if (!IS_ERR(data->clk_master))
>  			clk_disable(data->clk_master);
>  	} else {
> -		dev_dbg(dev, "disabled. Skipping TLB invalidation @ %#x\n",
> -			iova);
> +		dev_dbg(data->master,
> +			"disabled. Skipping TLB invalidation @ %#x\n", iova);
>  	}
>  	spin_unlock_irqrestore(&data->lock, flags);
>  }
> @@ -711,7 +704,7 @@ err_pgtable:
>  static void exynos_iommu_domain_free(struct iommu_domain *domain)
>  {
>  	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
> -	struct exynos_iommu_owner *owner;
> +	struct sysmmu_drvdata *data;
>  	unsigned long flags;
>  	int i;
>  
> @@ -719,14 +712,12 @@ static void exynos_iommu_domain_free(struct iommu_domain *domain)
>  
>  	spin_lock_irqsave(&priv->lock, flags);
>  
> -	list_for_each_entry(owner, &priv->clients, client) {
> -		while (!exynos_sysmmu_disable(owner->dev))
> -			; /* until System MMU is actually disabled */
> +	list_for_each_entry(data, &priv->clients, domain_node) {

Use list_for_each_entry_safe() or you will get panic.

> +		if (__sysmmu_disable(data))
> +			data->master = NULL;
> +		list_del_init(&data->domain_node);
>  	}
>  
> -	while (!list_empty(&priv->clients))
> -		list_del_init(priv->clients.next);
> -
>  	spin_unlock_irqrestore(&priv->lock, flags);
>  
>  	for (i = 0; i < NUM_LV1ENTRIES; i++)
> @@ -744,20 +735,26 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>  {
>  	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>  	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
> +	struct sysmmu_drvdata *data;
>  	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
>  	unsigned long flags;
> -	int ret;
> +	int ret = -ENODEV;
>  
> -	spin_lock_irqsave(&priv->lock, flags);
> +	if (!has_sysmmu(dev))
> +		return -ENODEV;
>  
> -	ret = __exynos_sysmmu_enable(dev, pagetable, domain);
> -	if (ret == 0) {
> -		list_add_tail(&owner->client, &priv->clients);
> -		owner->domain = domain;
> +	data = dev_get_drvdata(owner->sysmmu);
> +	if (data) {

Is there a case that a probed System MMU without driver data?

> +		ret = __sysmmu_enable(data, pagetable, domain);
> +		if (ret >= 0) {
> +			data->master = dev;
> +
> +			spin_lock_irqsave(&priv->lock, flags);
> +			list_add_tail(&data->domain_node, &priv->clients);
> +			spin_unlock_irqrestore(&priv->lock, flags);
> +		}
>  	}
>  
> -	spin_unlock_irqrestore(&priv->lock, flags);
> -
>  	if (ret < 0) {
>  		dev_err(dev, "%s: Failed to attach IOMMU with pgtable %pa\n",
>  					__func__, &pagetable);
> @@ -773,26 +770,29 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>  static void exynos_iommu_detach_device(struct iommu_domain *domain,
>  				    struct device *dev)
>  {
> -	struct exynos_iommu_owner *owner;
>  	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
>  	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
> +	struct sysmmu_drvdata *data;
>  	unsigned long flags;
> +	bool found = false;
>  
> -	spin_lock_irqsave(&priv->lock, flags);
> +	if (!has_sysmmu(dev))
> +		return;
>  
> -	list_for_each_entry(owner, &priv->clients, client) {
> -		if (owner == dev->archdata.iommu) {
> -			if (exynos_sysmmu_disable(dev)) {
> -				list_del_init(&owner->client);
> -				owner->domain = NULL;
> +	spin_lock_irqsave(&priv->lock, flags);
> +	list_for_each_entry(data, &priv->clients, domain_node) {
> +		if (data->master == dev) {
> +			if (__sysmmu_disable(data)) {
> +				data->master = NULL;
> +				list_del_init(&data->domain_node);
>  			}
> +			found = true;
>  			break;
>  		}
>  	}
> -
>  	spin_unlock_irqrestore(&priv->lock, flags);
>  
> -	if (owner == dev->archdata.iommu)
> +	if (found)
>  		dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
>  					__func__, &pagetable);
>  	else
> @@ -839,12 +839,11 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
>  		 * not currently mapped.
>  		 */
>  		if (need_flush_flpd_cache) {
> -			struct exynos_iommu_owner *owner;
> +			struct sysmmu_drvdata *data;
>  
>  			spin_lock(&priv->lock);
> -			list_for_each_entry(owner, &priv->clients, client)
> -				sysmmu_tlb_invalidate_flpdcache(
> -							owner->dev, iova);
> +			list_for_each_entry(data, &priv->clients, domain_node)
> +				sysmmu_tlb_invalidate_flpdcache(data, iova);
>  			spin_unlock(&priv->lock);
>  		}
>  	}
> @@ -879,13 +878,13 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
>  
>  	spin_lock(&priv->lock);
>  	if (lv1ent_page_zero(sent)) {
> -		struct exynos_iommu_owner *owner;
> +		struct sysmmu_drvdata *data;
>  		/*
>  		 * Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
>  		 * entry by speculative prefetch of SLPD which has no mapping.
>  		 */
> -		list_for_each_entry(owner, &priv->clients, client)
> -			sysmmu_tlb_invalidate_flpdcache(owner->dev, iova);
> +		list_for_each_entry(data, &priv->clients, domain_node)
> +			sysmmu_tlb_invalidate_flpdcache(data, iova);
>  	}
>  	spin_unlock(&priv->lock);
>  
> @@ -990,13 +989,13 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
>  static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
>  						sysmmu_iova_t iova, size_t size)
>  {
> -	struct exynos_iommu_owner *owner;
> +	struct sysmmu_drvdata *data;
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&priv->lock, flags);
>  
> -	list_for_each_entry(owner, &priv->clients, client)
> -		sysmmu_tlb_invalidate_entry(owner->dev, iova, size);
> +	list_for_each_entry(data, &priv->clients, domain_node)
> +		sysmmu_tlb_invalidate_entry(data, iova, size);
>  
>  	spin_unlock_irqrestore(&priv->lock, flags);
>  }
> -- 
> 1.9.2
> 


-- 
samsung.com <pullip.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

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

* [PATCH v6 08/25] iommu: exynos: refactor function parameters to simplify code
@ 2015-05-10 13:27       ` Cho KyongHo
  0 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 13:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 04 May 2015 10:16:03 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> This patch simplifies the code by:
> - refactoring function parameters from struct device pointer to direct
>   pointer to struct sysmmu drvdata
> - moving list_head enteries from struct exynos_iommu_owner directly to
>   struct sysmmu_drvdata
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 93 ++++++++++++++++++++++----------------------
>  1 file changed, 46 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index c307c400613c..0c23b69022cd 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -186,8 +186,6 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
>  
>  /* attached to dev.archdata.iommu of the master device */
>  struct exynos_iommu_owner {
> -	struct list_head client; /* entry of exynos_iommu_domain.clients */
> -	struct device *dev;
>  	struct device *sysmmu;
>  };
>  
> @@ -209,6 +207,7 @@ struct sysmmu_drvdata {
>  	int activations;
>  	spinlock_t lock;
>  	struct iommu_domain *domain;
> +	struct list_head domain_node;
>  	phys_addr_t pgtable;
>  	int version;
>  };
> @@ -514,12 +513,10 @@ static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
>  		__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
>  }
>  
> -static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
> +static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
>  					    sysmmu_iova_t iova)
>  {
>  	unsigned long flags;
> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
> -	struct sysmmu_drvdata *data = dev_get_drvdata(owner->sysmmu);
>  
>  	if (!IS_ERR(data->clk_master))
>  		clk_enable(data->clk_master);
> @@ -533,14 +530,10 @@ static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
>  		clk_disable(data->clk_master);
>  }
>  
> -static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
> -					size_t size)
> +static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
> +					sysmmu_iova_t iova, size_t size)
>  {
> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>  	unsigned long flags;
> -	struct sysmmu_drvdata *data;
> -
> -	data = dev_get_drvdata(owner->sysmmu);
>  
>  	spin_lock_irqsave(&data->lock, flags);
>  	if (is_sysmmu_active(data)) {
> @@ -570,8 +563,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
>  		if (!IS_ERR(data->clk_master))
>  			clk_disable(data->clk_master);
>  	} else {
> -		dev_dbg(dev, "disabled. Skipping TLB invalidation @ %#x\n",
> -			iova);
> +		dev_dbg(data->master,
> +			"disabled. Skipping TLB invalidation @ %#x\n", iova);
>  	}
>  	spin_unlock_irqrestore(&data->lock, flags);
>  }
> @@ -711,7 +704,7 @@ err_pgtable:
>  static void exynos_iommu_domain_free(struct iommu_domain *domain)
>  {
>  	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
> -	struct exynos_iommu_owner *owner;
> +	struct sysmmu_drvdata *data;
>  	unsigned long flags;
>  	int i;
>  
> @@ -719,14 +712,12 @@ static void exynos_iommu_domain_free(struct iommu_domain *domain)
>  
>  	spin_lock_irqsave(&priv->lock, flags);
>  
> -	list_for_each_entry(owner, &priv->clients, client) {
> -		while (!exynos_sysmmu_disable(owner->dev))
> -			; /* until System MMU is actually disabled */
> +	list_for_each_entry(data, &priv->clients, domain_node) {

Use list_for_each_entry_safe() or you will get panic.

> +		if (__sysmmu_disable(data))
> +			data->master = NULL;
> +		list_del_init(&data->domain_node);
>  	}
>  
> -	while (!list_empty(&priv->clients))
> -		list_del_init(priv->clients.next);
> -
>  	spin_unlock_irqrestore(&priv->lock, flags);
>  
>  	for (i = 0; i < NUM_LV1ENTRIES; i++)
> @@ -744,20 +735,26 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>  {
>  	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>  	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
> +	struct sysmmu_drvdata *data;
>  	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
>  	unsigned long flags;
> -	int ret;
> +	int ret = -ENODEV;
>  
> -	spin_lock_irqsave(&priv->lock, flags);
> +	if (!has_sysmmu(dev))
> +		return -ENODEV;
>  
> -	ret = __exynos_sysmmu_enable(dev, pagetable, domain);
> -	if (ret == 0) {
> -		list_add_tail(&owner->client, &priv->clients);
> -		owner->domain = domain;
> +	data = dev_get_drvdata(owner->sysmmu);
> +	if (data) {

Is there a case that a probed System MMU without driver data?

> +		ret = __sysmmu_enable(data, pagetable, domain);
> +		if (ret >= 0) {
> +			data->master = dev;
> +
> +			spin_lock_irqsave(&priv->lock, flags);
> +			list_add_tail(&data->domain_node, &priv->clients);
> +			spin_unlock_irqrestore(&priv->lock, flags);
> +		}
>  	}
>  
> -	spin_unlock_irqrestore(&priv->lock, flags);
> -
>  	if (ret < 0) {
>  		dev_err(dev, "%s: Failed to attach IOMMU with pgtable %pa\n",
>  					__func__, &pagetable);
> @@ -773,26 +770,29 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>  static void exynos_iommu_detach_device(struct iommu_domain *domain,
>  				    struct device *dev)
>  {
> -	struct exynos_iommu_owner *owner;
>  	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
>  	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
> +	struct sysmmu_drvdata *data;
>  	unsigned long flags;
> +	bool found = false;
>  
> -	spin_lock_irqsave(&priv->lock, flags);
> +	if (!has_sysmmu(dev))
> +		return;
>  
> -	list_for_each_entry(owner, &priv->clients, client) {
> -		if (owner == dev->archdata.iommu) {
> -			if (exynos_sysmmu_disable(dev)) {
> -				list_del_init(&owner->client);
> -				owner->domain = NULL;
> +	spin_lock_irqsave(&priv->lock, flags);
> +	list_for_each_entry(data, &priv->clients, domain_node) {
> +		if (data->master == dev) {
> +			if (__sysmmu_disable(data)) {
> +				data->master = NULL;
> +				list_del_init(&data->domain_node);
>  			}
> +			found = true;
>  			break;
>  		}
>  	}
> -
>  	spin_unlock_irqrestore(&priv->lock, flags);
>  
> -	if (owner == dev->archdata.iommu)
> +	if (found)
>  		dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
>  					__func__, &pagetable);
>  	else
> @@ -839,12 +839,11 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
>  		 * not currently mapped.
>  		 */
>  		if (need_flush_flpd_cache) {
> -			struct exynos_iommu_owner *owner;
> +			struct sysmmu_drvdata *data;
>  
>  			spin_lock(&priv->lock);
> -			list_for_each_entry(owner, &priv->clients, client)
> -				sysmmu_tlb_invalidate_flpdcache(
> -							owner->dev, iova);
> +			list_for_each_entry(data, &priv->clients, domain_node)
> +				sysmmu_tlb_invalidate_flpdcache(data, iova);
>  			spin_unlock(&priv->lock);
>  		}
>  	}
> @@ -879,13 +878,13 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
>  
>  	spin_lock(&priv->lock);
>  	if (lv1ent_page_zero(sent)) {
> -		struct exynos_iommu_owner *owner;
> +		struct sysmmu_drvdata *data;
>  		/*
>  		 * Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
>  		 * entry by speculative prefetch of SLPD which has no mapping.
>  		 */
> -		list_for_each_entry(owner, &priv->clients, client)
> -			sysmmu_tlb_invalidate_flpdcache(owner->dev, iova);
> +		list_for_each_entry(data, &priv->clients, domain_node)
> +			sysmmu_tlb_invalidate_flpdcache(data, iova);
>  	}
>  	spin_unlock(&priv->lock);
>  
> @@ -990,13 +989,13 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
>  static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
>  						sysmmu_iova_t iova, size_t size)
>  {
> -	struct exynos_iommu_owner *owner;
> +	struct sysmmu_drvdata *data;
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&priv->lock, flags);
>  
> -	list_for_each_entry(owner, &priv->clients, client)
> -		sysmmu_tlb_invalidate_entry(owner->dev, iova, size);
> +	list_for_each_entry(data, &priv->clients, domain_node)
> +		sysmmu_tlb_invalidate_entry(data, iova, size);
>  
>  	spin_unlock_irqrestore(&priv->lock, flags);
>  }
> -- 
> 1.9.2
> 


-- 
samsung.com <pullip.cho@samsung.com>

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

* Re: [PATCH v6 11/25] iommu: exynos: add support for binding more than one sysmmu to master device
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-10 13:34     ` Cho KyongHo
  -1 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 13:34 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

On Mon, 04 May 2015 10:16:06 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> This patch adds support for assigning more than one SYSMMU controller to
> the master device. This has been achieved simply by chaning the struct
> device pointer in struct exynos_iommu_owner into the list of struct
> sysmmu_drvdata of all controllers assigned to the given master device.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index f2eceb6605c5..598660c87410 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -186,7 +186,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
>  
>  /* attached to dev.archdata.iommu of the master device */
>  struct exynos_iommu_owner {
> -	struct device *sysmmu;
> +	struct list_head clients;

'clients' is the list of System MMUs that are assigned to the same iommu
domain. I don't think clients is not a good list name for exynos_iommu_owner
even though the elements are the same because they are used in different
contexts.

-- 
samsung.com <pullip.cho@samsung.com>

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

* [PATCH v6 11/25] iommu: exynos: add support for binding more than one sysmmu to master device
@ 2015-05-10 13:34     ` Cho KyongHo
  0 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 13:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 04 May 2015 10:16:06 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> This patch adds support for assigning more than one SYSMMU controller to
> the master device. This has been achieved simply by chaning the struct
> device pointer in struct exynos_iommu_owner into the list of struct
> sysmmu_drvdata of all controllers assigned to the given master device.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index f2eceb6605c5..598660c87410 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -186,7 +186,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
>  
>  /* attached to dev.archdata.iommu of the master device */
>  struct exynos_iommu_owner {
> -	struct device *sysmmu;
> +	struct list_head clients;

'clients' is the list of System MMUs that are assigned to the same iommu
domain. I don't think clients is not a good list name for exynos_iommu_owner
even though the elements are the same because they are used in different
contexts.

-- 
samsung.com <pullip.cho@samsung.com>

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

* Re: [PATCH v6 12/25] iommu: exynos: add support for runtime_pm
  2015-05-04  8:16   ` Marek Szyprowski
@ 2015-05-10 13:38     ` Cho KyongHo
  -1 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 13:38 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

On Mon, 04 May 2015 10:16:07 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> This patch fixes support for runtime power management for SYSMMU
> controllers, so they are enabled when master device is attached.
> 

You should later think that this style of runtime PM support
will increase the leakage current because some devices may
enable System MMUs during they are not working.
If a device driver of a master device attaches its iommu domain
in probe, its local power will be never gated.

> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 598660c87410..734107ec78fa 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -702,6 +702,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>  		return -ENODEV;
>  
>  	list_for_each_entry(data, &owner->clients, owner_node) {
> +		pm_runtime_get_sync(data->sysmmu);
>  		ret = __sysmmu_enable(data, pagetable, domain);
>  		if (ret >= 0) {
>  			data->master = dev;
> @@ -743,6 +744,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
>  				data->master = NULL;
>  				list_del_init(&data->domain_node);
>  			}
> +			pm_runtime_put(data->sysmmu);
>  			found = true;
>  		}
>  	}
> -- 
> 1.9.2
> 


-- 
samsung.com <pullip.cho@samsung.com>

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

* [PATCH v6 12/25] iommu: exynos: add support for runtime_pm
@ 2015-05-10 13:38     ` Cho KyongHo
  0 siblings, 0 replies; 116+ messages in thread
From: Cho KyongHo @ 2015-05-10 13:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 04 May 2015 10:16:07 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> This patch fixes support for runtime power management for SYSMMU
> controllers, so they are enabled when master device is attached.
> 

You should later think that this style of runtime PM support
will increase the leakage current because some devices may
enable System MMUs during they are not working.
If a device driver of a master device attaches its iommu domain
in probe, its local power will be never gated.

> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/iommu/exynos-iommu.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 598660c87410..734107ec78fa 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -702,6 +702,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>  		return -ENODEV;
>  
>  	list_for_each_entry(data, &owner->clients, owner_node) {
> +		pm_runtime_get_sync(data->sysmmu);
>  		ret = __sysmmu_enable(data, pagetable, domain);
>  		if (ret >= 0) {
>  			data->master = dev;
> @@ -743,6 +744,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
>  				data->master = NULL;
>  				list_del_init(&data->domain_node);
>  			}
> +			pm_runtime_put(data->sysmmu);
>  			found = true;
>  		}
>  	}
> -- 
> 1.9.2
> 


-- 
samsung.com <pullip.cho@samsung.com>

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

* Re: [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
  2015-05-04  8:15 ` Marek Szyprowski
@ 2015-05-11 16:00   ` Javier Martinez Canillas
  -1 siblings, 0 replies; 116+ messages in thread
From: Javier Martinez Canillas @ 2015-05-11 16:00 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Joerg Roedel,
	Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
	Will Deacon, David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa,
	Kyungmin Park, Joonyoung Shim, Seung-Woo Kim

Hello Marek,

On Mon, May 4, 2015 at 10:15 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Hello Everyone,
>
> This is yet another attempt to get Exynos SYSMMU driver with integrated
> with IOMMU & DMA-mapping subsystems. The main change from previous
> version is addition of the patches to define iommu-mapping, which need
> to be created during system boot to avoid IOMMU fault by devices, which
> has been left enabled by bootloader (i.e. framebuffer displaying slash
> screen).
>
> Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
> off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
> 1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
> git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
> more information:
> http://www.spinics.net/lists/arm-kernel/msg414722.html).
>
> All patches are also available in the following git repository:
> https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
> branch v4.1-exynos-iommu.
>

Thanks for the new series, this time I didn't get a system hang when I
enabled both CONFIG_DRM_EXYNOS_FIMD and CONFIG_DRM_EXYNOS_DP on my
Exynos5420 Peach Pit Chromebook.

The system finished booting and I have both a console on the HDMI and
eDP/LVDS displays. But if I try to start X or weston, I again have a
completele system hang with no output on the serial console. This
works correctly without your IOMMU series.

And again disabling CONFIG_DRM_EXYNOS_DP or CONFIG_DRM_EXYNOS_FIMD
avoids the system to hang. If I only have CONFIG_DRM_EXYNOS_HDMI
enabled, then I can start X with out issues and is displayed correctly
in the HDMI output.

So it seems your workaround for the boot-loader leaving the FIMD dma
engine enabled is not enough? I'm not a graphics person so I can think
of the top of my head what could trigger the system hang when X or
weston are executed so I wondered if you have any ideas.

> Best regards
> Marek Szyprowski
> Samsung R&D Institute Poland
>

Best regards,
Javier

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

* [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
@ 2015-05-11 16:00   ` Javier Martinez Canillas
  0 siblings, 0 replies; 116+ messages in thread
From: Javier Martinez Canillas @ 2015-05-11 16:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Marek,

On Mon, May 4, 2015 at 10:15 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Hello Everyone,
>
> This is yet another attempt to get Exynos SYSMMU driver with integrated
> with IOMMU & DMA-mapping subsystems. The main change from previous
> version is addition of the patches to define iommu-mapping, which need
> to be created during system boot to avoid IOMMU fault by devices, which
> has been left enabled by bootloader (i.e. framebuffer displaying slash
> screen).
>
> Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
> off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
> 1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
> git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
> more information:
> http://www.spinics.net/lists/arm-kernel/msg414722.html).
>
> All patches are also available in the following git repository:
> https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
> branch v4.1-exynos-iommu.
>

Thanks for the new series, this time I didn't get a system hang when I
enabled both CONFIG_DRM_EXYNOS_FIMD and CONFIG_DRM_EXYNOS_DP on my
Exynos5420 Peach Pit Chromebook.

The system finished booting and I have both a console on the HDMI and
eDP/LVDS displays. But if I try to start X or weston, I again have a
completele system hang with no output on the serial console. This
works correctly without your IOMMU series.

And again disabling CONFIG_DRM_EXYNOS_DP or CONFIG_DRM_EXYNOS_FIMD
avoids the system to hang. If I only have CONFIG_DRM_EXYNOS_HDMI
enabled, then I can start X with out issues and is displayed correctly
in the HDMI output.

So it seems your workaround for the boot-loader leaving the FIMD dma
engine enabled is not enough? I'm not a graphics person so I can think
of the top of my head what could trigger the system hang when X or
weston are executed so I wondered if you have any ideas.

> Best regards
> Marek Szyprowski
> Samsung R&D Institute Poland
>

Best regards,
Javier

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

* Re: [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
  2015-05-11 16:00   ` Javier Martinez Canillas
@ 2015-05-12 15:35     ` Javier Martinez Canillas
  -1 siblings, 0 replies; 116+ messages in thread
From: Javier Martinez Canillas @ 2015-05-12 15:35 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Joerg Roedel,
	Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
	Will Deacon, David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa,
	Kyungmin Park, Joonyoung Shim, Seung-Woo Kim

On Mon, May 11, 2015 at 6:00 PM, Javier Martinez Canillas
<javier@dowhile0.org> wrote:
> Hello Marek,
>
> On Mon, May 4, 2015 at 10:15 AM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
>> Hello Everyone,
>>
>> This is yet another attempt to get Exynos SYSMMU driver with integrated
>> with IOMMU & DMA-mapping subsystems. The main change from previous
>> version is addition of the patches to define iommu-mapping, which need
>> to be created during system boot to avoid IOMMU fault by devices, which
>> has been left enabled by bootloader (i.e. framebuffer displaying slash
>> screen).
>>
>> Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
>> off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
>> 1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
>> git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
>> more information:
>> http://www.spinics.net/lists/arm-kernel/msg414722.html).
>>
>> All patches are also available in the following git repository:
>> https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
>> branch v4.1-exynos-iommu.
>>
>
> Thanks for the new series, this time I didn't get a system hang when I
> enabled both CONFIG_DRM_EXYNOS_FIMD and CONFIG_DRM_EXYNOS_DP on my
> Exynos5420 Peach Pit Chromebook.
>
> The system finished booting and I have both a console on the HDMI and
> eDP/LVDS displays. But if I try to start X or weston, I again have a
> completele system hang with no output on the serial console. This
> works correctly without your IOMMU series.
>
> And again disabling CONFIG_DRM_EXYNOS_DP or CONFIG_DRM_EXYNOS_FIMD
> avoids the system to hang. If I only have CONFIG_DRM_EXYNOS_HDMI
> enabled, then I can start X with out issues and is displayed correctly
> in the HDMI output.
>
> So it seems your workaround for the boot-loader leaving the FIMD dma
> engine enabled is not enough? I'm not a graphics person so I can think
> of the top of my head what could trigger the system hang when X or
> weston are executed so I wondered if you have any ideas.
>

I looked a a bit more on this issue today and found that the system
hang when dma_alloc_attrs() is called from lowlevel_buffer_allocate()
in drivers/gpu/drm/exynos/exynos_drm_buf.c [0].

The call chain is:

exynos_drm_gem_create_ioctl() -> exynos_drm_gem_create() ->
exynos_drm_alloc_buf() -> lowlevel_buffer_allocate() ->
dma_alloc_attrs().

An interesting data point is that the allocation succeeds when a GEM
buffer is created for fbdev but it causes a system hang when is
created from the DRM ioctl API. For fbdev the call chain is:

exynos_drm_fbdev_init() -> exynos_drm_fbdev_init() ->
exynos_drm_fbdev_create() -> exynos_drm_gem_create() ->
exynos_drm_alloc_buf() -> lowlevel_buffer_allocated() ->
dma_alloc_attrs().

Although for fbdev, the EXYNOS_BO_CONTIG flag is passed to
exynos_drm_gem_create() so the DMA_ATTR_FORCE_CONTIGUOUS attribute is
set before calling  dma_alloc_attrs(). So I don't know if is only
working because the allocated memory is physically contiguous so the
IOMMU mapping is less of an issue here?

I also don't know if is relevant but I noticed that both for HDMI and
DP, the address of the allocated a DMA buffer is always 0x20000000.
Which is the start of the iommu-reserved-mapping region for the
exynos5420 peach pit.

While the address of the allocated DMA buffer for the GEM buffer
allocated with EXYNOS_GEM_CREATE is always != 0x20000000 (i.e
0x2184c000).

So in summary, Exynos HDMI DRM can allocate GEM buffers correctly
fbdev and DRM while EXYNOS DRM DP/FIMD can only allocate a GEM buffer
for fbdev, trying to allocate with the EXYNOS_GEM_CREATE ioctl hangs
the system. Both fbdev and DRM works correctly with Exynos IOMMU
disabled.

I included some DRM debug log [2] (drm.debug=0xff) for DP/FIMD fbdev
and DRM GEM buffer creation.

Thanks a lot and best regards,
Javier

[0]: http://lxr.free-electrons.com/source/drivers/gpu/drm/exynos/exynos_drm_buf.c#L84
[1]: http://lxr.free-electrons.com/source/drivers/gpu/drm/exynos/exynos_drm_fbdev.c#L153
[2]:

DP fbdev:

[    4.181241] [drm:drm_enable_connectors] connector 31 enabled? yes
[    4.181248] [drm:drm_target_preferred] looking for cmdline mode on
connector 25
[    4.181254] [drm:drm_target_preferred] looking for preferred mode
on connector 25 0
[    4.181259] [drm:drm_target_preferred] found mode 1366x768
[    4.181265] [drm:drm_target_preferred] looking for cmdline mode on
connector 31
[    4.181270] [drm:drm_target_preferred] looking for preferred mode
on connector 31 0
[    4.181276] [drm:drm_target_preferred] found mode 1920x1080
[    4.181281] [drm:drm_setup_crtcs] picking CRTCs for 4096x4096 config
[    4.181290] [drm:drm_setup_crtcs] desired mode 1366x768 set on crtc 23 (0,0)
[    4.181298] [drm:drm_setup_crtcs] desired mode 1920x1080 set on crtc 29 (0,0)
[    4.181307] [drm:exynos_drm_fbdev_create] surface width(1920),
height(1080) and bpp(32
[    4.181314] [drm:exynos_drm_init_buf] desired size = 0x7e9000
[    4.181327] [drm:exynos_drm_gem_init] created file object = 0xedc68300
[    4.187406] [drm:lowlevel_buffer_allocate] ccu
dma_addr(0x20000000), size(0x7e9000)
[    4.187418] [drm:exynos_drm_fb_buffer] dma_addr = 0x20000000

DP DRM:

[  206.210769] [drm:drm_mode_getconnector] [CONNECTOR:31:?]
[  206.216074] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPERTY
[  206.223798] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPERTY
[  206.231538] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPBLOB
[  206.239240] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPBLOB
[  206.246965] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPERTY
[  206.254680] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPERTY
[  206.275736] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1, EXYNOS_GEM_CREATE
[  206.281287] [drm:exynos_drm_init_buf] desired size = 0x408000
[  206.286989] [drm:exynos_drm_gem_init] created file object = 0xed0d6400

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

* [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
@ 2015-05-12 15:35     ` Javier Martinez Canillas
  0 siblings, 0 replies; 116+ messages in thread
From: Javier Martinez Canillas @ 2015-05-12 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 11, 2015 at 6:00 PM, Javier Martinez Canillas
<javier@dowhile0.org> wrote:
> Hello Marek,
>
> On Mon, May 4, 2015 at 10:15 AM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
>> Hello Everyone,
>>
>> This is yet another attempt to get Exynos SYSMMU driver with integrated
>> with IOMMU & DMA-mapping subsystems. The main change from previous
>> version is addition of the patches to define iommu-mapping, which need
>> to be created during system boot to avoid IOMMU fault by devices, which
>> has been left enabled by bootloader (i.e. framebuffer displaying slash
>> screen).
>>
>> Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
>> off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
>> 1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
>> git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
>> more information:
>> http://www.spinics.net/lists/arm-kernel/msg414722.html).
>>
>> All patches are also available in the following git repository:
>> https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
>> branch v4.1-exynos-iommu.
>>
>
> Thanks for the new series, this time I didn't get a system hang when I
> enabled both CONFIG_DRM_EXYNOS_FIMD and CONFIG_DRM_EXYNOS_DP on my
> Exynos5420 Peach Pit Chromebook.
>
> The system finished booting and I have both a console on the HDMI and
> eDP/LVDS displays. But if I try to start X or weston, I again have a
> completele system hang with no output on the serial console. This
> works correctly without your IOMMU series.
>
> And again disabling CONFIG_DRM_EXYNOS_DP or CONFIG_DRM_EXYNOS_FIMD
> avoids the system to hang. If I only have CONFIG_DRM_EXYNOS_HDMI
> enabled, then I can start X with out issues and is displayed correctly
> in the HDMI output.
>
> So it seems your workaround for the boot-loader leaving the FIMD dma
> engine enabled is not enough? I'm not a graphics person so I can think
> of the top of my head what could trigger the system hang when X or
> weston are executed so I wondered if you have any ideas.
>

I looked a a bit more on this issue today and found that the system
hang when dma_alloc_attrs() is called from lowlevel_buffer_allocate()
in drivers/gpu/drm/exynos/exynos_drm_buf.c [0].

The call chain is:

exynos_drm_gem_create_ioctl() -> exynos_drm_gem_create() ->
exynos_drm_alloc_buf() -> lowlevel_buffer_allocate() ->
dma_alloc_attrs().

An interesting data point is that the allocation succeeds when a GEM
buffer is created for fbdev but it causes a system hang when is
created from the DRM ioctl API. For fbdev the call chain is:

exynos_drm_fbdev_init() -> exynos_drm_fbdev_init() ->
exynos_drm_fbdev_create() -> exynos_drm_gem_create() ->
exynos_drm_alloc_buf() -> lowlevel_buffer_allocated() ->
dma_alloc_attrs().

Although for fbdev, the EXYNOS_BO_CONTIG flag is passed to
exynos_drm_gem_create() so the DMA_ATTR_FORCE_CONTIGUOUS attribute is
set before calling  dma_alloc_attrs(). So I don't know if is only
working because the allocated memory is physically contiguous so the
IOMMU mapping is less of an issue here?

I also don't know if is relevant but I noticed that both for HDMI and
DP, the address of the allocated a DMA buffer is always 0x20000000.
Which is the start of the iommu-reserved-mapping region for the
exynos5420 peach pit.

While the address of the allocated DMA buffer for the GEM buffer
allocated with EXYNOS_GEM_CREATE is always != 0x20000000 (i.e
0x2184c000).

So in summary, Exynos HDMI DRM can allocate GEM buffers correctly
fbdev and DRM while EXYNOS DRM DP/FIMD can only allocate a GEM buffer
for fbdev, trying to allocate with the EXYNOS_GEM_CREATE ioctl hangs
the system. Both fbdev and DRM works correctly with Exynos IOMMU
disabled.

I included some DRM debug log [2] (drm.debug=0xff) for DP/FIMD fbdev
and DRM GEM buffer creation.

Thanks a lot and best regards,
Javier

[0]: http://lxr.free-electrons.com/source/drivers/gpu/drm/exynos/exynos_drm_buf.c#L84
[1]: http://lxr.free-electrons.com/source/drivers/gpu/drm/exynos/exynos_drm_fbdev.c#L153
[2]:

DP fbdev:

[    4.181241] [drm:drm_enable_connectors] connector 31 enabled? yes
[    4.181248] [drm:drm_target_preferred] looking for cmdline mode on
connector 25
[    4.181254] [drm:drm_target_preferred] looking for preferred mode
on connector 25 0
[    4.181259] [drm:drm_target_preferred] found mode 1366x768
[    4.181265] [drm:drm_target_preferred] looking for cmdline mode on
connector 31
[    4.181270] [drm:drm_target_preferred] looking for preferred mode
on connector 31 0
[    4.181276] [drm:drm_target_preferred] found mode 1920x1080
[    4.181281] [drm:drm_setup_crtcs] picking CRTCs for 4096x4096 config
[    4.181290] [drm:drm_setup_crtcs] desired mode 1366x768 set on crtc 23 (0,0)
[    4.181298] [drm:drm_setup_crtcs] desired mode 1920x1080 set on crtc 29 (0,0)
[    4.181307] [drm:exynos_drm_fbdev_create] surface width(1920),
height(1080) and bpp(32
[    4.181314] [drm:exynos_drm_init_buf] desired size = 0x7e9000
[    4.181327] [drm:exynos_drm_gem_init] created file object = 0xedc68300
[    4.187406] [drm:lowlevel_buffer_allocate] ccu
dma_addr(0x20000000), size(0x7e9000)
[    4.187418] [drm:exynos_drm_fb_buffer] dma_addr = 0x20000000

DP DRM:

[  206.210769] [drm:drm_mode_getconnector] [CONNECTOR:31:?]
[  206.216074] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPERTY
[  206.223798] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPERTY
[  206.231538] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPBLOB
[  206.239240] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPBLOB
[  206.246965] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPERTY
[  206.254680] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1,
DRM_IOCTL_MODE_GETPROPERTY
[  206.275736] [drm:drm_ioctl] pid=3458, dev=0xe200, auth=1, EXYNOS_GEM_CREATE
[  206.281287] [drm:exynos_drm_init_buf] desired size = 0x408000
[  206.286989] [drm:exynos_drm_gem_init] created file object = 0xed0d6400

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

* Re: [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
  2015-05-04 22:12       ` Rob Herring
@ 2015-05-18 12:09           ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Inki Dae,
	Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw, Linux IOMMU, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Cho KyongHo, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hello,

On 2015-05-05 00:12, Rob Herring wrote:
> On Mon, May 4, 2015 at 3:15 AM, Marek Szyprowski
> <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
>> Some devices (like frame buffers) are enabled by bootloader and configured
>> to perform DMA operations automatically (like displaying boot logo or splash
>> screen). Such devices operate and perform DMA operation usually until the
>> proper driver for them is loaded and probed. However before that happens,
>> system usually loads IOMMU drivers and configures dma parameters for each
>> device. When such initial configuration is created and enabled, it usually
>> contains empty translation rules betweem IO address space and physical
>> memory, because no buffers nor memory regions have been requested by the
>> respective driver.
>>
>> This patch adds support for "iommu-reserved-mapping", which can be used
>> to provide definitions for mappings that need to be created on system
>> boot to let such devices (enabled by bootloader) to operate properly
>> until respective driver is probed.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>> ---
>>   Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
>>   arch/arm/mm/dma-mapping.c                         | 112 ++++++++++++++++++++++
>>   2 files changed, 156 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/iommu/iommu.txt b/Documentation/devicetree/bindings/iommu/iommu.txt
>> index 5a8b4624defc..fd54e6b597f0 100644
>> --- a/Documentation/devicetree/bindings/iommu/iommu.txt
>> +++ b/Documentation/devicetree/bindings/iommu/iommu.txt
>> @@ -86,6 +86,35 @@ have a means to turn off translation. But it is invalid in such cases to
>>   disable the IOMMU's device tree node in the first place because it would
>>   prevent any driver from properly setting up the translations.
>>
>> +Optional properties:
>> +--------------------
>> +- iommu-reserved-mapping: A list of entries describing additional
>> +  reserved mapping, that will be inserted to the default IO address space
>> +  created for given master device. Each entry consist of IO address,
>> +  physical memory address and size of the region.
>> +
>> +Some devices (like frame buffers) are enabled by bootloader and configured
>> +to perform DMA operations automatically (like displaying boot logo or splash
>> +screen). Such devices operate and perform DMA operation usually until the
>> +proper driver for them is loaded and probed. However before that happens,
>> +system usually loads IOMMU drivers and configures dma parameters for each
> s/dma/DMA/
>
>> +device. When such initial configuration is created and enabled, it usually
>> +contains empty translation rules betweem IO address space and physical
> s/betweem/between/
>
>> +memory, because no buffers nor memory regions have been requested by the
>> +respective driver.
>> +
>> +To avoid IOMMU page fault, one can provide "iommu-reserved-mapping"
>> +property, which defines all memory regions which must be mapped to IO
>> +address space to boot properly when device has been enabled by the
>> +bootloader. More than one region can be defined for given master device.
>> +Each region is defined by the following triplet: first entry is IO
>> +address (encoded in "address" cells), second is base physical memory
>> +address for this regions (also encoded in "address" cells) and the last
>> +is size of the region (encoded in "size" cells). To ensure that that
>> +given master device will not trigger page fault after enabling IOMMU,
>> +one should define identity mapping between physical memory and IO
>> +address space for the range of addresses accessed by the device.
>> +
>>
>>   Notes:
>>   ======
>> @@ -113,6 +142,21 @@ Single-master IOMMU:
>>                  iommus = <&{/iommu}>;
>>          };
>>
>> +
>> +Single-master IOMMU, which has been left enabled by bootloader:
>> +---------------------------------------------------------------
>> +
>> +       iommu {
>> +               #iommu-cells = <0>;
>> +       };
>> +
>> +       master {
>> +               iommus = <&{/iommu}>;
>> +               /* bootloader configures framebuffer at 0x40000000 (32MiB)
>> +               iommu-reserved-mapping = <0x40000000 0x40000000 0x2000000>;
> Is there not an ordering problem if kernel initializes the IOMMU
> before parsing this for each master? I would think the IOMMU driver
> needs to find all of these mappings and cleanly switch the page tables
> with the new reserved mapping.

The proper ordering is guaranteed by arm_get_iommu_dma_map_ops function, 
which first
created iommu domain for given master device, then scans for reserved 
regions and
adds them to the given domains. Only then it attaches such domain to the 
iommu
driver.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
@ 2015-05-18 12:09           ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2015-05-05 00:12, Rob Herring wrote:
> On Mon, May 4, 2015 at 3:15 AM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
>> Some devices (like frame buffers) are enabled by bootloader and configured
>> to perform DMA operations automatically (like displaying boot logo or splash
>> screen). Such devices operate and perform DMA operation usually until the
>> proper driver for them is loaded and probed. However before that happens,
>> system usually loads IOMMU drivers and configures dma parameters for each
>> device. When such initial configuration is created and enabled, it usually
>> contains empty translation rules betweem IO address space and physical
>> memory, because no buffers nor memory regions have been requested by the
>> respective driver.
>>
>> This patch adds support for "iommu-reserved-mapping", which can be used
>> to provide definitions for mappings that need to be created on system
>> boot to let such devices (enabled by bootloader) to operate properly
>> until respective driver is probed.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
>>   arch/arm/mm/dma-mapping.c                         | 112 ++++++++++++++++++++++
>>   2 files changed, 156 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/iommu/iommu.txt b/Documentation/devicetree/bindings/iommu/iommu.txt
>> index 5a8b4624defc..fd54e6b597f0 100644
>> --- a/Documentation/devicetree/bindings/iommu/iommu.txt
>> +++ b/Documentation/devicetree/bindings/iommu/iommu.txt
>> @@ -86,6 +86,35 @@ have a means to turn off translation. But it is invalid in such cases to
>>   disable the IOMMU's device tree node in the first place because it would
>>   prevent any driver from properly setting up the translations.
>>
>> +Optional properties:
>> +--------------------
>> +- iommu-reserved-mapping: A list of entries describing additional
>> +  reserved mapping, that will be inserted to the default IO address space
>> +  created for given master device. Each entry consist of IO address,
>> +  physical memory address and size of the region.
>> +
>> +Some devices (like frame buffers) are enabled by bootloader and configured
>> +to perform DMA operations automatically (like displaying boot logo or splash
>> +screen). Such devices operate and perform DMA operation usually until the
>> +proper driver for them is loaded and probed. However before that happens,
>> +system usually loads IOMMU drivers and configures dma parameters for each
> s/dma/DMA/
>
>> +device. When such initial configuration is created and enabled, it usually
>> +contains empty translation rules betweem IO address space and physical
> s/betweem/between/
>
>> +memory, because no buffers nor memory regions have been requested by the
>> +respective driver.
>> +
>> +To avoid IOMMU page fault, one can provide "iommu-reserved-mapping"
>> +property, which defines all memory regions which must be mapped to IO
>> +address space to boot properly when device has been enabled by the
>> +bootloader. More than one region can be defined for given master device.
>> +Each region is defined by the following triplet: first entry is IO
>> +address (encoded in "address" cells), second is base physical memory
>> +address for this regions (also encoded in "address" cells) and the last
>> +is size of the region (encoded in "size" cells). To ensure that that
>> +given master device will not trigger page fault after enabling IOMMU,
>> +one should define identity mapping between physical memory and IO
>> +address space for the range of addresses accessed by the device.
>> +
>>
>>   Notes:
>>   ======
>> @@ -113,6 +142,21 @@ Single-master IOMMU:
>>                  iommus = <&{/iommu}>;
>>          };
>>
>> +
>> +Single-master IOMMU, which has been left enabled by bootloader:
>> +---------------------------------------------------------------
>> +
>> +       iommu {
>> +               #iommu-cells = <0>;
>> +       };
>> +
>> +       master {
>> +               iommus = <&{/iommu}>;
>> +               /* bootloader configures framebuffer at 0x40000000 (32MiB)
>> +               iommu-reserved-mapping = <0x40000000 0x40000000 0x2000000>;
> Is there not an ordering problem if kernel initializes the IOMMU
> before parsing this for each master? I would think the IOMMU driver
> needs to find all of these mappings and cleanly switch the page tables
> with the new reserved mapping.

The proper ordering is guaranteed by arm_get_iommu_dma_map_ops function, 
which first
created iommu domain for given master device, then scans for reserved 
regions and
adds them to the given domains. Only then it attaches such domain to the 
iommu
driver.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
  2015-05-05 14:55       ` Joerg Roedel
@ 2015-05-18 12:09           ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:09 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Rob Herring,
	Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Cho KyongHo, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hello,

On 2015-05-05 16:55, Joerg Roedel wrote:
> On Mon, May 04, 2015 at 10:16:05AM +0200, Marek Szyprowski wrote:
>> The driver doesn't need to do anything important in device add/remove
>> callbacks, because initialization will be done from device-tree specific
>> callbacks added later. IOMMU groups created by current code were never
>> used.
> Hmm, will this remove support for iommu-groups in the exynos driver? I
> am still working on the default-domain patch-set which makes iommu-group
> support mandatory for iommu-drivers.

I you wish, I can leave this code. iommu-groups were not used at all on 
Exynos,
so I thought that there is no point keeping useless code.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
@ 2015-05-18 12:09           ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2015-05-05 16:55, Joerg Roedel wrote:
> On Mon, May 04, 2015 at 10:16:05AM +0200, Marek Szyprowski wrote:
>> The driver doesn't need to do anything important in device add/remove
>> callbacks, because initialization will be done from device-tree specific
>> callbacks added later. IOMMU groups created by current code were never
>> used.
> Hmm, will this remove support for iommu-groups in the exynos driver? I
> am still working on the default-domain patch-set which makes iommu-group
> support mandatory for iommu-drivers.

I you wish, I can leave this code. iommu-groups were not used at all on 
Exynos,
so I thought that there is no point keeping useless code.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
  2015-05-05 15:05     ` Joerg Roedel
@ 2015-05-18 12:16       ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:16 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas,
	Krzysztof Kozłowski

Hello,

On 2015-05-05 17:05, Joerg Roedel wrote:
> Hi Marek,
>
> On Mon, May 04, 2015 at 10:15:55AM +0200, Marek Szyprowski wrote:
>>    iommu: exynos: don't read version register on every tlb operation
> Please use 'iommu/exynos:' as prefix for the iommu patches and start
> the remaining subject with a capital letter, like this:
>
> 	iommu/exynos: Don't read version register on every tlb operation

Okay, I will post an updated version soon

>>   Documentation/devicetree/bindings/iommu/iommu.txt |  44 ++
>>   arch/arm/boot/dts/exynos3250-rinato.dts           |   1 +
>>   arch/arm/boot/dts/exynos3250.dtsi                 |  22 +
>>   arch/arm/boot/dts/exynos4.dtsi                    | 118 ++++++
>>   arch/arm/boot/dts/exynos4210-trats.dts            |   1 +
>>   arch/arm/boot/dts/exynos4210-universal_c210.dts   |   1 +
>>   arch/arm/boot/dts/exynos4210.dtsi                 |  23 +
>>   arch/arm/boot/dts/exynos4412-trats2.dts           |   1 +
>>   arch/arm/boot/dts/exynos4415.dtsi                 |  11 +
>>   arch/arm/boot/dts/exynos4x12.dtsi                 |  82 ++++
>>   arch/arm/boot/dts/exynos5250-snow.dts             |   1 +
>>   arch/arm/boot/dts/exynos5250-spring.dts           |   1 +
>>   arch/arm/boot/dts/exynos5250.dtsi                 | 250 +++++++++++
>>   arch/arm/boot/dts/exynos5420-peach-pit.dts        |   1 +
>>   arch/arm/boot/dts/exynos5420.dtsi                 | 181 ++++++++
>>   arch/arm/boot/dts/exynos5800-peach-pi.dts         |   1 +
>>   arch/arm/mach-exynos/pm_domains.c                 |  18 +-
>>   arch/arm/mm/dma-mapping.c                         | 112 +++++
>>   drivers/gpu/drm/exynos/exynos_drm_fimd.c          |  27 +-
>>   drivers/gpu/drm/exynos/exynos_drm_iommu.c         |   3 +
>>   drivers/iommu/exynos-iommu.c                      | 495 ++++++++++------------
>>   21 files changed, 1098 insertions(+), 296 deletions(-)
> What is the plan for merging this, should it go through the iommu tree
> or some other path?

I would prefer to split those patches into 3 trees and merge as follows:
- DTS changes and power domain changes via Samsung tree to avoid 
conflicts with
   other DTS patches
- all exynos-iommu patches and dma-mapping/reserved iommu region via 
IOMMU tree,
- all Exynos DRM patches via DRM/Exynos tree.

There are no build cross-subsystem dependencies and IOMMU on Exynos is 
already
nonfunctional (and disabled in defconfig) till now, so merging patches 
in parts
doesn't break anything.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
@ 2015-05-18 12:16       ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2015-05-05 17:05, Joerg Roedel wrote:
> Hi Marek,
>
> On Mon, May 04, 2015 at 10:15:55AM +0200, Marek Szyprowski wrote:
>>    iommu: exynos: don't read version register on every tlb operation
> Please use 'iommu/exynos:' as prefix for the iommu patches and start
> the remaining subject with a capital letter, like this:
>
> 	iommu/exynos: Don't read version register on every tlb operation

Okay, I will post an updated version soon

>>   Documentation/devicetree/bindings/iommu/iommu.txt |  44 ++
>>   arch/arm/boot/dts/exynos3250-rinato.dts           |   1 +
>>   arch/arm/boot/dts/exynos3250.dtsi                 |  22 +
>>   arch/arm/boot/dts/exynos4.dtsi                    | 118 ++++++
>>   arch/arm/boot/dts/exynos4210-trats.dts            |   1 +
>>   arch/arm/boot/dts/exynos4210-universal_c210.dts   |   1 +
>>   arch/arm/boot/dts/exynos4210.dtsi                 |  23 +
>>   arch/arm/boot/dts/exynos4412-trats2.dts           |   1 +
>>   arch/arm/boot/dts/exynos4415.dtsi                 |  11 +
>>   arch/arm/boot/dts/exynos4x12.dtsi                 |  82 ++++
>>   arch/arm/boot/dts/exynos5250-snow.dts             |   1 +
>>   arch/arm/boot/dts/exynos5250-spring.dts           |   1 +
>>   arch/arm/boot/dts/exynos5250.dtsi                 | 250 +++++++++++
>>   arch/arm/boot/dts/exynos5420-peach-pit.dts        |   1 +
>>   arch/arm/boot/dts/exynos5420.dtsi                 | 181 ++++++++
>>   arch/arm/boot/dts/exynos5800-peach-pi.dts         |   1 +
>>   arch/arm/mach-exynos/pm_domains.c                 |  18 +-
>>   arch/arm/mm/dma-mapping.c                         | 112 +++++
>>   drivers/gpu/drm/exynos/exynos_drm_fimd.c          |  27 +-
>>   drivers/gpu/drm/exynos/exynos_drm_iommu.c         |   3 +
>>   drivers/iommu/exynos-iommu.c                      | 495 ++++++++++------------
>>   21 files changed, 1098 insertions(+), 296 deletions(-)
> What is the plan for merging this, should it go through the iommu tree
> or some other path?

I would prefer to split those patches into 3 trees and merge as follows:
- DTS changes and power domain changes via Samsung tree to avoid 
conflicts with
   other DTS patches
- all exynos-iommu patches and dma-mapping/reserved iommu region via 
IOMMU tree,
- all Exynos DRM patches via DRM/Exynos tree.

There are no build cross-subsystem dependencies and IOMMU on Exynos is 
already
nonfunctional (and disabled in defconfig) till now, so merging patches 
in parts
doesn't break anything.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v6 12/25] iommu: exynos: add support for runtime_pm
  2015-05-10 13:38     ` Cho KyongHo
@ 2015-05-18 12:25       ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:25 UTC (permalink / raw)
  To: Cho KyongHo
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Joerg Roedel, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

Hello,

On 2015-05-10 15:38, Cho KyongHo wrote:
> On Mon, 04 May 2015 10:16:07 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>
>> This patch fixes support for runtime power management for SYSMMU
>> controllers, so they are enabled when master device is attached.
>>
> You should later think that this style of runtime PM support
> will increase the leakage current because some devices may
> enable System MMUs during they are not working.
> If a device driver of a master device attaches its iommu domain
> in probe, its local power will be never gated.

Yes, true, but let's merge something that WORKS first and add more 
fine-grained
runtime-pm later as a separate patch. Some time ago I've posted a 
fully-blown
patchset for Exynos IOMMU will all features 
(https://lkml.org/lkml/2014/8/5/183)
- but it turned out that it will be to hard to agree on all needed 
features and
dependencies, so I simplified the code as much as possible. All 
remaining features
(like fine-grained power management and access for more than one iommu 
controller
per device) will be posted separately.

>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   drivers/iommu/exynos-iommu.c | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>> index 598660c87410..734107ec78fa 100644
>> --- a/drivers/iommu/exynos-iommu.c
>> +++ b/drivers/iommu/exynos-iommu.c
>> @@ -702,6 +702,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>>   		return -ENODEV;
>>   
>>   	list_for_each_entry(data, &owner->clients, owner_node) {
>> +		pm_runtime_get_sync(data->sysmmu);
>>   		ret = __sysmmu_enable(data, pagetable, domain);
>>   		if (ret >= 0) {
>>   			data->master = dev;
>> @@ -743,6 +744,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
>>   				data->master = NULL;
>>   				list_del_init(&data->domain_node);
>>   			}
>> +			pm_runtime_put(data->sysmmu);
>>   			found = true;
>>   		}
>>   	}
>> -- 
>> 1.9.2

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* [PATCH v6 12/25] iommu: exynos: add support for runtime_pm
@ 2015-05-18 12:25       ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2015-05-10 15:38, Cho KyongHo wrote:
> On Mon, 04 May 2015 10:16:07 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>
>> This patch fixes support for runtime power management for SYSMMU
>> controllers, so they are enabled when master device is attached.
>>
> You should later think that this style of runtime PM support
> will increase the leakage current because some devices may
> enable System MMUs during they are not working.
> If a device driver of a master device attaches its iommu domain
> in probe, its local power will be never gated.

Yes, true, but let's merge something that WORKS first and add more 
fine-grained
runtime-pm later as a separate patch. Some time ago I've posted a 
fully-blown
patchset for Exynos IOMMU will all features 
(https://lkml.org/lkml/2014/8/5/183)
- but it turned out that it will be to hard to agree on all needed 
features and
dependencies, so I simplified the code as much as possible. All 
remaining features
(like fine-grained power management and access for more than one iommu 
controller
per device) will be posted separately.

>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   drivers/iommu/exynos-iommu.c | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>> index 598660c87410..734107ec78fa 100644
>> --- a/drivers/iommu/exynos-iommu.c
>> +++ b/drivers/iommu/exynos-iommu.c
>> @@ -702,6 +702,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>>   		return -ENODEV;
>>   
>>   	list_for_each_entry(data, &owner->clients, owner_node) {
>> +		pm_runtime_get_sync(data->sysmmu);
>>   		ret = __sysmmu_enable(data, pagetable, domain);
>>   		if (ret >= 0) {
>>   			data->master = dev;
>> @@ -743,6 +744,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
>>   				data->master = NULL;
>>   				list_del_init(&data->domain_node);
>>   			}
>> +			pm_runtime_put(data->sysmmu);
>>   			found = true;
>>   		}
>>   	}
>> -- 
>> 1.9.2

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v6 08/25] iommu: exynos: refactor function parameters to simplify code
  2015-05-10 13:27       ` Cho KyongHo
@ 2015-05-18 12:58           ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:58 UTC (permalink / raw)
  To: Cho KyongHo
  Cc: Rob Herring, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Inki Dae,
	Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Thierry Reding, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hello,

On 2015-05-10 15:27, Cho KyongHo wrote:
> On Mon, 04 May 2015 10:16:03 +0200 Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
>
>> This patch simplifies the code by:
>> - refactoring function parameters from struct device pointer to direct
>>    pointer to struct sysmmu drvdata
>> - moving list_head enteries from struct exynos_iommu_owner directly to
>>    struct sysmmu_drvdata
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>> ---
>>   drivers/iommu/exynos-iommu.c | 93 ++++++++++++++++++++++----------------------
>>   1 file changed, 46 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>> index c307c400613c..0c23b69022cd 100644
>> --- a/drivers/iommu/exynos-iommu.c
>> +++ b/drivers/iommu/exynos-iommu.c
>> @@ -186,8 +186,6 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
>>   
>>   /* attached to dev.archdata.iommu of the master device */
>>   struct exynos_iommu_owner {
>> -	struct list_head client; /* entry of exynos_iommu_domain.clients */
>> -	struct device *dev;
>>   	struct device *sysmmu;
>>   };
>>   
>> @@ -209,6 +207,7 @@ struct sysmmu_drvdata {
>>   	int activations;
>>   	spinlock_t lock;
>>   	struct iommu_domain *domain;
>> +	struct list_head domain_node;
>>   	phys_addr_t pgtable;
>>   	int version;
>>   };
>> @@ -514,12 +513,10 @@ static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
>>   		__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
>>   }
>>   
>> -static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
>> +static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
>>   					    sysmmu_iova_t iova)
>>   {
>>   	unsigned long flags;
>> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>> -	struct sysmmu_drvdata *data = dev_get_drvdata(owner->sysmmu);
>>   
>>   	if (!IS_ERR(data->clk_master))
>>   		clk_enable(data->clk_master);
>> @@ -533,14 +530,10 @@ static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
>>   		clk_disable(data->clk_master);
>>   }
>>   
>> -static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
>> -					size_t size)
>> +static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
>> +					sysmmu_iova_t iova, size_t size)
>>   {
>> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>>   	unsigned long flags;
>> -	struct sysmmu_drvdata *data;
>> -
>> -	data = dev_get_drvdata(owner->sysmmu);
>>   
>>   	spin_lock_irqsave(&data->lock, flags);
>>   	if (is_sysmmu_active(data)) {
>> @@ -570,8 +563,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
>>   		if (!IS_ERR(data->clk_master))
>>   			clk_disable(data->clk_master);
>>   	} else {
>> -		dev_dbg(dev, "disabled. Skipping TLB invalidation @ %#x\n",
>> -			iova);
>> +		dev_dbg(data->master,
>> +			"disabled. Skipping TLB invalidation @ %#x\n", iova);
>>   	}
>>   	spin_unlock_irqrestore(&data->lock, flags);
>>   }
>> @@ -711,7 +704,7 @@ err_pgtable:
>>   static void exynos_iommu_domain_free(struct iommu_domain *domain)
>>   {
>>   	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
>> -	struct exynos_iommu_owner *owner;
>> +	struct sysmmu_drvdata *data;
>>   	unsigned long flags;
>>   	int i;
>>   
>> @@ -719,14 +712,12 @@ static void exynos_iommu_domain_free(struct iommu_domain *domain)
>>   
>>   	spin_lock_irqsave(&priv->lock, flags);
>>   
>> -	list_for_each_entry(owner, &priv->clients, client) {
>> -		while (!exynos_sysmmu_disable(owner->dev))
>> -			; /* until System MMU is actually disabled */
>> +	list_for_each_entry(data, &priv->clients, domain_node) {
> Use list_for_each_entry_safe() or you will get panic.

Right.

>
>> +		if (__sysmmu_disable(data))
>> +			data->master = NULL;
>> +		list_del_init(&data->domain_node);
>>   	}
>>   
>> -	while (!list_empty(&priv->clients))
>> -		list_del_init(priv->clients.next);
>> -
>>   	spin_unlock_irqrestore(&priv->lock, flags);
>>   
>>   	for (i = 0; i < NUM_LV1ENTRIES; i++)
>> @@ -744,20 +735,26 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>>   {
>>   	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>>   	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
>> +	struct sysmmu_drvdata *data;
>>   	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
>>   	unsigned long flags;
>> -	int ret;
>> +	int ret = -ENODEV;
>>   
>> -	spin_lock_irqsave(&priv->lock, flags);
>> +	if (!has_sysmmu(dev))
>> +		return -ENODEV;
>>   
>> -	ret = __exynos_sysmmu_enable(dev, pagetable, domain);
>> -	if (ret == 0) {
>> -		list_add_tail(&owner->client, &priv->clients);
>> -		owner->domain = domain;
>> +	data = dev_get_drvdata(owner->sysmmu);
>> +	if (data) {
> Is there a case that a probed System MMU without driver data?

It is better to have one more safety check than to debug strange issues 
later in
the future.

>
>> +		ret = __sysmmu_enable(data, pagetable, domain);
>> +		if (ret >= 0) {
>> +			data->master = dev;
>> +
>> +			spin_lock_irqsave(&priv->lock, flags);
>> +			list_add_tail(&data->domain_node, &priv->clients);
>> +			spin_unlock_irqrestore(&priv->lock, flags);
>> +		}
>>   	}
>>   
>> -	spin_unlock_irqrestore(&priv->lock, flags);
>> -
>>   	if (ret < 0) {
>>   		dev_err(dev, "%s: Failed to attach IOMMU with pgtable %pa\n",
>>   					__func__, &pagetable);
>> @@ -773,26 +770,29 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>>   static void exynos_iommu_detach_device(struct iommu_domain *domain,
>>   				    struct device *dev)
>>   {
>> -	struct exynos_iommu_owner *owner;
>>   	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
>>   	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
>> +	struct sysmmu_drvdata *data;
>>   	unsigned long flags;
>> +	bool found = false;
>>   
>> -	spin_lock_irqsave(&priv->lock, flags);
>> +	if (!has_sysmmu(dev))
>> +		return;
>>   
>> -	list_for_each_entry(owner, &priv->clients, client) {
>> -		if (owner == dev->archdata.iommu) {
>> -			if (exynos_sysmmu_disable(dev)) {
>> -				list_del_init(&owner->client);
>> -				owner->domain = NULL;
>> +	spin_lock_irqsave(&priv->lock, flags);
>> +	list_for_each_entry(data, &priv->clients, domain_node) {
>> +		if (data->master == dev) {
>> +			if (__sysmmu_disable(data)) {
>> +				data->master = NULL;
>> +				list_del_init(&data->domain_node);
>>   			}
>> +			found = true;
>>   			break;
>>   		}
>>   	}
>> -
>>   	spin_unlock_irqrestore(&priv->lock, flags);
>>   
>> -	if (owner == dev->archdata.iommu)
>> +	if (found)
>>   		dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
>>   					__func__, &pagetable);
>>   	else
>> @@ -839,12 +839,11 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
>>   		 * not currently mapped.
>>   		 */
>>   		if (need_flush_flpd_cache) {
>> -			struct exynos_iommu_owner *owner;
>> +			struct sysmmu_drvdata *data;
>>   
>>   			spin_lock(&priv->lock);
>> -			list_for_each_entry(owner, &priv->clients, client)
>> -				sysmmu_tlb_invalidate_flpdcache(
>> -							owner->dev, iova);
>> +			list_for_each_entry(data, &priv->clients, domain_node)
>> +				sysmmu_tlb_invalidate_flpdcache(data, iova);
>>   			spin_unlock(&priv->lock);
>>   		}
>>   	}
>> @@ -879,13 +878,13 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
>>   
>>   	spin_lock(&priv->lock);
>>   	if (lv1ent_page_zero(sent)) {
>> -		struct exynos_iommu_owner *owner;
>> +		struct sysmmu_drvdata *data;
>>   		/*
>>   		 * Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
>>   		 * entry by speculative prefetch of SLPD which has no mapping.
>>   		 */
>> -		list_for_each_entry(owner, &priv->clients, client)
>> -			sysmmu_tlb_invalidate_flpdcache(owner->dev, iova);
>> +		list_for_each_entry(data, &priv->clients, domain_node)
>> +			sysmmu_tlb_invalidate_flpdcache(data, iova);
>>   	}
>>   	spin_unlock(&priv->lock);
>>   
>> @@ -990,13 +989,13 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
>>   static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
>>   						sysmmu_iova_t iova, size_t size)
>>   {
>> -	struct exynos_iommu_owner *owner;
>> +	struct sysmmu_drvdata *data;
>>   	unsigned long flags;
>>   
>>   	spin_lock_irqsave(&priv->lock, flags);
>>   
>> -	list_for_each_entry(owner, &priv->clients, client)
>> -		sysmmu_tlb_invalidate_entry(owner->dev, iova, size);
>> +	list_for_each_entry(data, &priv->clients, domain_node)
>> +		sysmmu_tlb_invalidate_entry(data, iova, size);
>>   
>>   	spin_unlock_irqrestore(&priv->lock, flags);
>>   }
>> -- 
>> 1.9.2
>>
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* [PATCH v6 08/25] iommu: exynos: refactor function parameters to simplify code
@ 2015-05-18 12:58           ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 12:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2015-05-10 15:27, Cho KyongHo wrote:
> On Mon, 04 May 2015 10:16:03 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>
>> This patch simplifies the code by:
>> - refactoring function parameters from struct device pointer to direct
>>    pointer to struct sysmmu drvdata
>> - moving list_head enteries from struct exynos_iommu_owner directly to
>>    struct sysmmu_drvdata
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   drivers/iommu/exynos-iommu.c | 93 ++++++++++++++++++++++----------------------
>>   1 file changed, 46 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>> index c307c400613c..0c23b69022cd 100644
>> --- a/drivers/iommu/exynos-iommu.c
>> +++ b/drivers/iommu/exynos-iommu.c
>> @@ -186,8 +186,6 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
>>   
>>   /* attached to dev.archdata.iommu of the master device */
>>   struct exynos_iommu_owner {
>> -	struct list_head client; /* entry of exynos_iommu_domain.clients */
>> -	struct device *dev;
>>   	struct device *sysmmu;
>>   };
>>   
>> @@ -209,6 +207,7 @@ struct sysmmu_drvdata {
>>   	int activations;
>>   	spinlock_t lock;
>>   	struct iommu_domain *domain;
>> +	struct list_head domain_node;
>>   	phys_addr_t pgtable;
>>   	int version;
>>   };
>> @@ -514,12 +513,10 @@ static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
>>   		__raw_writel(iova | 0x1, data->sfrbase + REG_MMU_FLUSH_ENTRY);
>>   }
>>   
>> -static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
>> +static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
>>   					    sysmmu_iova_t iova)
>>   {
>>   	unsigned long flags;
>> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>> -	struct sysmmu_drvdata *data = dev_get_drvdata(owner->sysmmu);
>>   
>>   	if (!IS_ERR(data->clk_master))
>>   		clk_enable(data->clk_master);
>> @@ -533,14 +530,10 @@ static void sysmmu_tlb_invalidate_flpdcache(struct device *dev,
>>   		clk_disable(data->clk_master);
>>   }
>>   
>> -static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
>> -					size_t size)
>> +static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
>> +					sysmmu_iova_t iova, size_t size)
>>   {
>> -	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>>   	unsigned long flags;
>> -	struct sysmmu_drvdata *data;
>> -
>> -	data = dev_get_drvdata(owner->sysmmu);
>>   
>>   	spin_lock_irqsave(&data->lock, flags);
>>   	if (is_sysmmu_active(data)) {
>> @@ -570,8 +563,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova,
>>   		if (!IS_ERR(data->clk_master))
>>   			clk_disable(data->clk_master);
>>   	} else {
>> -		dev_dbg(dev, "disabled. Skipping TLB invalidation @ %#x\n",
>> -			iova);
>> +		dev_dbg(data->master,
>> +			"disabled. Skipping TLB invalidation @ %#x\n", iova);
>>   	}
>>   	spin_unlock_irqrestore(&data->lock, flags);
>>   }
>> @@ -711,7 +704,7 @@ err_pgtable:
>>   static void exynos_iommu_domain_free(struct iommu_domain *domain)
>>   {
>>   	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
>> -	struct exynos_iommu_owner *owner;
>> +	struct sysmmu_drvdata *data;
>>   	unsigned long flags;
>>   	int i;
>>   
>> @@ -719,14 +712,12 @@ static void exynos_iommu_domain_free(struct iommu_domain *domain)
>>   
>>   	spin_lock_irqsave(&priv->lock, flags);
>>   
>> -	list_for_each_entry(owner, &priv->clients, client) {
>> -		while (!exynos_sysmmu_disable(owner->dev))
>> -			; /* until System MMU is actually disabled */
>> +	list_for_each_entry(data, &priv->clients, domain_node) {
> Use list_for_each_entry_safe() or you will get panic.

Right.

>
>> +		if (__sysmmu_disable(data))
>> +			data->master = NULL;
>> +		list_del_init(&data->domain_node);
>>   	}
>>   
>> -	while (!list_empty(&priv->clients))
>> -		list_del_init(priv->clients.next);
>> -
>>   	spin_unlock_irqrestore(&priv->lock, flags);
>>   
>>   	for (i = 0; i < NUM_LV1ENTRIES; i++)
>> @@ -744,20 +735,26 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>>   {
>>   	struct exynos_iommu_owner *owner = dev->archdata.iommu;
>>   	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
>> +	struct sysmmu_drvdata *data;
>>   	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
>>   	unsigned long flags;
>> -	int ret;
>> +	int ret = -ENODEV;
>>   
>> -	spin_lock_irqsave(&priv->lock, flags);
>> +	if (!has_sysmmu(dev))
>> +		return -ENODEV;
>>   
>> -	ret = __exynos_sysmmu_enable(dev, pagetable, domain);
>> -	if (ret == 0) {
>> -		list_add_tail(&owner->client, &priv->clients);
>> -		owner->domain = domain;
>> +	data = dev_get_drvdata(owner->sysmmu);
>> +	if (data) {
> Is there a case that a probed System MMU without driver data?

It is better to have one more safety check than to debug strange issues 
later in
the future.

>
>> +		ret = __sysmmu_enable(data, pagetable, domain);
>> +		if (ret >= 0) {
>> +			data->master = dev;
>> +
>> +			spin_lock_irqsave(&priv->lock, flags);
>> +			list_add_tail(&data->domain_node, &priv->clients);
>> +			spin_unlock_irqrestore(&priv->lock, flags);
>> +		}
>>   	}
>>   
>> -	spin_unlock_irqrestore(&priv->lock, flags);
>> -
>>   	if (ret < 0) {
>>   		dev_err(dev, "%s: Failed to attach IOMMU with pgtable %pa\n",
>>   					__func__, &pagetable);
>> @@ -773,26 +770,29 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
>>   static void exynos_iommu_detach_device(struct iommu_domain *domain,
>>   				    struct device *dev)
>>   {
>> -	struct exynos_iommu_owner *owner;
>>   	struct exynos_iommu_domain *priv = to_exynos_domain(domain);
>>   	phys_addr_t pagetable = virt_to_phys(priv->pgtable);
>> +	struct sysmmu_drvdata *data;
>>   	unsigned long flags;
>> +	bool found = false;
>>   
>> -	spin_lock_irqsave(&priv->lock, flags);
>> +	if (!has_sysmmu(dev))
>> +		return;
>>   
>> -	list_for_each_entry(owner, &priv->clients, client) {
>> -		if (owner == dev->archdata.iommu) {
>> -			if (exynos_sysmmu_disable(dev)) {
>> -				list_del_init(&owner->client);
>> -				owner->domain = NULL;
>> +	spin_lock_irqsave(&priv->lock, flags);
>> +	list_for_each_entry(data, &priv->clients, domain_node) {
>> +		if (data->master == dev) {
>> +			if (__sysmmu_disable(data)) {
>> +				data->master = NULL;
>> +				list_del_init(&data->domain_node);
>>   			}
>> +			found = true;
>>   			break;
>>   		}
>>   	}
>> -
>>   	spin_unlock_irqrestore(&priv->lock, flags);
>>   
>> -	if (owner == dev->archdata.iommu)
>> +	if (found)
>>   		dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
>>   					__func__, &pagetable);
>>   	else
>> @@ -839,12 +839,11 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv,
>>   		 * not currently mapped.
>>   		 */
>>   		if (need_flush_flpd_cache) {
>> -			struct exynos_iommu_owner *owner;
>> +			struct sysmmu_drvdata *data;
>>   
>>   			spin_lock(&priv->lock);
>> -			list_for_each_entry(owner, &priv->clients, client)
>> -				sysmmu_tlb_invalidate_flpdcache(
>> -							owner->dev, iova);
>> +			list_for_each_entry(data, &priv->clients, domain_node)
>> +				sysmmu_tlb_invalidate_flpdcache(data, iova);
>>   			spin_unlock(&priv->lock);
>>   		}
>>   	}
>> @@ -879,13 +878,13 @@ static int lv1set_section(struct exynos_iommu_domain *priv,
>>   
>>   	spin_lock(&priv->lock);
>>   	if (lv1ent_page_zero(sent)) {
>> -		struct exynos_iommu_owner *owner;
>> +		struct sysmmu_drvdata *data;
>>   		/*
>>   		 * Flushing FLPD cache in System MMU v3.3 that may cache a FLPD
>>   		 * entry by speculative prefetch of SLPD which has no mapping.
>>   		 */
>> -		list_for_each_entry(owner, &priv->clients, client)
>> -			sysmmu_tlb_invalidate_flpdcache(owner->dev, iova);
>> +		list_for_each_entry(data, &priv->clients, domain_node)
>> +			sysmmu_tlb_invalidate_flpdcache(data, iova);
>>   	}
>>   	spin_unlock(&priv->lock);
>>   
>> @@ -990,13 +989,13 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova,
>>   static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *priv,
>>   						sysmmu_iova_t iova, size_t size)
>>   {
>> -	struct exynos_iommu_owner *owner;
>> +	struct sysmmu_drvdata *data;
>>   	unsigned long flags;
>>   
>>   	spin_lock_irqsave(&priv->lock, flags);
>>   
>> -	list_for_each_entry(owner, &priv->clients, client)
>> -		sysmmu_tlb_invalidate_entry(owner->dev, iova, size);
>> +	list_for_each_entry(data, &priv->clients, domain_node)
>> +		sysmmu_tlb_invalidate_entry(data, iova, size);
>>   
>>   	spin_unlock_irqrestore(&priv->lock, flags);
>>   }
>> -- 
>> 1.9.2
>>
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v6 11/25] iommu: exynos: add support for binding more than one sysmmu to master device
  2015-05-10 13:34     ` Cho KyongHo
@ 2015-05-18 13:03         ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 13:03 UTC (permalink / raw)
  To: Cho KyongHo
  Cc: Rob Herring, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Inki Dae,
	Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Javier Martinez Canillas,
	Thierry Reding, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hello,

On 2015-05-10 15:34, Cho KyongHo wrote:
> On Mon, 04 May 2015 10:16:06 +0200 Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
>
>> This patch adds support for assigning more than one SYSMMU controller to
>> the master device. This has been achieved simply by chaning the struct
>> device pointer in struct exynos_iommu_owner into the list of struct
>> sysmmu_drvdata of all controllers assigned to the given master device.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>> ---
>>   drivers/iommu/exynos-iommu.c | 11 +++++------
>>   1 file changed, 5 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>> index f2eceb6605c5..598660c87410 100644
>> --- a/drivers/iommu/exynos-iommu.c
>> +++ b/drivers/iommu/exynos-iommu.c
>> @@ -186,7 +186,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
>>   
>>   /* attached to dev.archdata.iommu of the master device */
>>   struct exynos_iommu_owner {
>> -	struct device *sysmmu;
>> +	struct list_head clients;
> 'clients' is the list of System MMUs that are assigned to the same iommu
> domain. I don't think clients is not a good list name for exynos_iommu_owner
> even though the elements are the same because they are used in different
> contexts.

Okay, I will rename it to 'controllers' then.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* [PATCH v6 11/25] iommu: exynos: add support for binding more than one sysmmu to master device
@ 2015-05-18 13:03         ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 13:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2015-05-10 15:34, Cho KyongHo wrote:
> On Mon, 04 May 2015 10:16:06 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>
>> This patch adds support for assigning more than one SYSMMU controller to
>> the master device. This has been achieved simply by chaning the struct
>> device pointer in struct exynos_iommu_owner into the list of struct
>> sysmmu_drvdata of all controllers assigned to the given master device.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   drivers/iommu/exynos-iommu.c | 11 +++++------
>>   1 file changed, 5 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>> index f2eceb6605c5..598660c87410 100644
>> --- a/drivers/iommu/exynos-iommu.c
>> +++ b/drivers/iommu/exynos-iommu.c
>> @@ -186,7 +186,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
>>   
>>   /* attached to dev.archdata.iommu of the master device */
>>   struct exynos_iommu_owner {
>> -	struct device *sysmmu;
>> +	struct list_head clients;
> 'clients' is the list of System MMUs that are assigned to the same iommu
> domain. I don't think clients is not a good list name for exynos_iommu_owner
> even though the elements are the same because they are used in different
> contexts.

Okay, I will rename it to 'controllers' then.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
  2015-05-11 16:00   ` Javier Martinez Canillas
@ 2015-05-18 13:26     ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 13:26 UTC (permalink / raw)
  To: Javier Martinez Canillas
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Joerg Roedel,
	Thierry Reding, Olof Johansson, Laurent Pinchart, Rob Herring,
	Will Deacon, David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa,
	Kyungmin Park, Joonyoung Shim, Seung-Woo Kim

Hello,

On 2015-05-11 18:00, Javier Martinez Canillas wrote:
> Hello Marek,
>
> On Mon, May 4, 2015 at 10:15 AM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
>> Hello Everyone,
>>
>> This is yet another attempt to get Exynos SYSMMU driver with integrated
>> with IOMMU & DMA-mapping subsystems. The main change from previous
>> version is addition of the patches to define iommu-mapping, which need
>> to be created during system boot to avoid IOMMU fault by devices, which
>> has been left enabled by bootloader (i.e. framebuffer displaying slash
>> screen).
>>
>> Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
>> off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
>> 1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
>> git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
>> more information:
>> http://www.spinics.net/lists/arm-kernel/msg414722.html).
>>
>> All patches are also available in the following git repository:
>> https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
>> branch v4.1-exynos-iommu.
>>
> Thanks for the new series, this time I didn't get a system hang when I
> enabled both CONFIG_DRM_EXYNOS_FIMD and CONFIG_DRM_EXYNOS_DP on my
> Exynos5420 Peach Pit Chromebook.
>
> The system finished booting and I have both a console on the HDMI and
> eDP/LVDS displays. But if I try to start X or weston, I again have a
> completele system hang with no output on the serial console. This
> works correctly without your IOMMU series.
>
> And again disabling CONFIG_DRM_EXYNOS_DP or CONFIG_DRM_EXYNOS_FIMD
> avoids the system to hang. If I only have CONFIG_DRM_EXYNOS_HDMI
> enabled, then I can start X with out issues and is displayed correctly
> in the HDMI output.
>
> So it seems your workaround for the boot-loader leaving the FIMD dma
> engine enabled is not enough? I'm not a graphics person so I can think
> of the top of my head what could trigger the system hang when X or
> weston are executed so I wondered if you have any ideas.

This means that there are more bugs in Exynos DRM driver. Once Exynos DRM
driver is probed, the initial iommu domain with identity mapping is 
destroyed
and Exynos DRM manages it's own iommu domain, so it has nothing to my
mentioned patch.

I will try to check this issue.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
@ 2015-05-18 13:26     ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-18 13:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2015-05-11 18:00, Javier Martinez Canillas wrote:
> Hello Marek,
>
> On Mon, May 4, 2015 at 10:15 AM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
>> Hello Everyone,
>>
>> This is yet another attempt to get Exynos SYSMMU driver with integrated
>> with IOMMU & DMA-mapping subsystems. The main change from previous
>> version is addition of the patches to define iommu-mapping, which need
>> to be created during system boot to avoid IOMMU fault by devices, which
>> has been left enabled by bootloader (i.e. framebuffer displaying slash
>> screen).
>>
>> Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
>> off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
>> 1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
>> git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
>> more information:
>> http://www.spinics.net/lists/arm-kernel/msg414722.html).
>>
>> All patches are also available in the following git repository:
>> https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
>> branch v4.1-exynos-iommu.
>>
> Thanks for the new series, this time I didn't get a system hang when I
> enabled both CONFIG_DRM_EXYNOS_FIMD and CONFIG_DRM_EXYNOS_DP on my
> Exynos5420 Peach Pit Chromebook.
>
> The system finished booting and I have both a console on the HDMI and
> eDP/LVDS displays. But if I try to start X or weston, I again have a
> completele system hang with no output on the serial console. This
> works correctly without your IOMMU series.
>
> And again disabling CONFIG_DRM_EXYNOS_DP or CONFIG_DRM_EXYNOS_FIMD
> avoids the system to hang. If I only have CONFIG_DRM_EXYNOS_HDMI
> enabled, then I can start X with out issues and is displayed correctly
> in the HDMI output.
>
> So it seems your workaround for the boot-loader leaving the FIMD dma
> engine enabled is not enough? I'm not a graphics person so I can think
> of the top of my head what could trigger the system hang when X or
> weston are executed so I wondered if you have any ideas.

This means that there are more bugs in Exynos DRM driver. Once Exynos DRM
driver is probed, the initial iommu domain with identity mapping is 
destroyed
and Exynos DRM manages it's own iommu domain, so it has nothing to my
mentioned patch.

I will try to check this issue.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
  2015-05-18 13:26     ` Marek Szyprowski
@ 2015-05-18 13:32         ` Javier Martinez Canillas
  -1 siblings, 0 replies; 116+ messages in thread
From: Javier Martinez Canillas @ 2015-05-18 13:32 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Rob Herring,
	Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Laurent Pinchart, Kyungmin Park, Cho KyongHo, David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hello Marek,

On Mon, May 18, 2015 at 3:26 PM, Marek Szyprowski
<m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> Hello,
>
>
> On 2015-05-11 18:00, Javier Martinez Canillas wrote:
>>
>> Hello Marek,
>>
>> On Mon, May 4, 2015 at 10:15 AM, Marek Szyprowski
>> <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
>>>
>>> Hello Everyone,
>>>
>>> This is yet another attempt to get Exynos SYSMMU driver with integrated
>>> with IOMMU & DMA-mapping subsystems. The main change from previous
>>> version is addition of the patches to define iommu-mapping, which need
>>> to be created during system boot to avoid IOMMU fault by devices, which
>>> has been left enabled by bootloader (i.e. framebuffer displaying slash
>>> screen).
>>>
>>> Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
>>> off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
>>> 1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
>>> git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
>>> more information:
>>> http://www.spinics.net/lists/arm-kernel/msg414722.html).
>>>
>>> All patches are also available in the following git repository:
>>> https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
>>> branch v4.1-exynos-iommu.
>>>
>> Thanks for the new series, this time I didn't get a system hang when I
>> enabled both CONFIG_DRM_EXYNOS_FIMD and CONFIG_DRM_EXYNOS_DP on my
>> Exynos5420 Peach Pit Chromebook.
>>
>> The system finished booting and I have both a console on the HDMI and
>> eDP/LVDS displays. But if I try to start X or weston, I again have a
>> completele system hang with no output on the serial console. This
>> works correctly without your IOMMU series.
>>
>> And again disabling CONFIG_DRM_EXYNOS_DP or CONFIG_DRM_EXYNOS_FIMD
>> avoids the system to hang. If I only have CONFIG_DRM_EXYNOS_HDMI
>> enabled, then I can start X with out issues and is displayed correctly
>> in the HDMI output.
>>
>> So it seems your workaround for the boot-loader leaving the FIMD dma
>> engine enabled is not enough? I'm not a graphics person so I can think
>> of the top of my head what could trigger the system hang when X or
>> weston are executed so I wondered if you have any ideas.
>
>
> This means that there are more bugs in Exynos DRM driver. Once Exynos DRM
> driver is probed, the initial iommu domain with identity mapping is
> destroyed
> and Exynos DRM manages it's own iommu domain, so it has nothing to my
> mentioned patch.
>

I see, thanks for the explanation.

> I will try to check this issue.
>

Great, thanks a lot for taking a look.

>
> Best regards
> --
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
>

Best regards,
Javier

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

* [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem
@ 2015-05-18 13:32         ` Javier Martinez Canillas
  0 siblings, 0 replies; 116+ messages in thread
From: Javier Martinez Canillas @ 2015-05-18 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Marek,

On Mon, May 18, 2015 at 3:26 PM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Hello,
>
>
> On 2015-05-11 18:00, Javier Martinez Canillas wrote:
>>
>> Hello Marek,
>>
>> On Mon, May 4, 2015 at 10:15 AM, Marek Szyprowski
>> <m.szyprowski@samsung.com> wrote:
>>>
>>> Hello Everyone,
>>>
>>> This is yet another attempt to get Exynos SYSMMU driver with integrated
>>> with IOMMU & DMA-mapping subsystems. The main change from previous
>>> version is addition of the patches to define iommu-mapping, which need
>>> to be created during system boot to avoid IOMMU fault by devices, which
>>> has been left enabled by bootloader (i.e. framebuffer displaying slash
>>> screen).
>>>
>>> Patches has been also rebased onto v4.1-rc2 with 'arm: dma-mapping: fix
>>> off-by-one check in arm_setup_iommu_dma_ops' patch applied (see commit
>>> 1424532b2163bf1580f4b1091a5801e12310fac5 on fixes branch in
>>> git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git,
>>> more information:
>>> http://www.spinics.net/lists/arm-kernel/msg414722.html).
>>>
>>> All patches are also available in the following git repository:
>>> https://git.linaro.org/people/marek.szyprowski/linux-srpol.git
>>> branch v4.1-exynos-iommu.
>>>
>> Thanks for the new series, this time I didn't get a system hang when I
>> enabled both CONFIG_DRM_EXYNOS_FIMD and CONFIG_DRM_EXYNOS_DP on my
>> Exynos5420 Peach Pit Chromebook.
>>
>> The system finished booting and I have both a console on the HDMI and
>> eDP/LVDS displays. But if I try to start X or weston, I again have a
>> completele system hang with no output on the serial console. This
>> works correctly without your IOMMU series.
>>
>> And again disabling CONFIG_DRM_EXYNOS_DP or CONFIG_DRM_EXYNOS_FIMD
>> avoids the system to hang. If I only have CONFIG_DRM_EXYNOS_HDMI
>> enabled, then I can start X with out issues and is displayed correctly
>> in the HDMI output.
>>
>> So it seems your workaround for the boot-loader leaving the FIMD dma
>> engine enabled is not enough? I'm not a graphics person so I can think
>> of the top of my head what could trigger the system hang when X or
>> weston are executed so I wondered if you have any ideas.
>
>
> This means that there are more bugs in Exynos DRM driver. Once Exynos DRM
> driver is probed, the initial iommu domain with identity mapping is
> destroyed
> and Exynos DRM manages it's own iommu domain, so it has nothing to my
> mentioned patch.
>

I see, thanks for the explanation.

> I will try to check this issue.
>

Great, thanks a lot for taking a look.

>
> Best regards
> --
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
>

Best regards,
Javier

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

* Re: [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
  2015-05-18 12:09           ` Marek Szyprowski
@ 2015-05-18 17:04             ` Joerg Roedel
  -1 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-18 17:04 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: iommu, linux-samsung-soc, linux-arm-kernel, linaro-mm-sig,
	Arnd Bergmann, Shaik Ameer Basha, Cho KyongHo, Thierry Reding,
	Olof Johansson, Laurent Pinchart, Rob Herring, Will Deacon,
	David Wodhouse, Inki Dae, Kukjin Kim, Tomasz Figa, Kyungmin Park,
	Joonyoung Shim, Seung-Woo Kim, Javier Martinez Canillas

Hi Marek,

On Mon, May 18, 2015 at 02:09:14PM +0200, Marek Szyprowski wrote:
> >Hmm, will this remove support for iommu-groups in the exynos driver? I
> >am still working on the default-domain patch-set which makes iommu-group
> >support mandatory for iommu-drivers.
> 
> I you wish, I can leave this code. iommu-groups were not used at all
> on Exynos,
> so I thought that there is no point keeping useless code.

Yes, please keep the iommu-goups support, it will be required at some
point.


	Joerg

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

* [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
@ 2015-05-18 17:04             ` Joerg Roedel
  0 siblings, 0 replies; 116+ messages in thread
From: Joerg Roedel @ 2015-05-18 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marek,

On Mon, May 18, 2015 at 02:09:14PM +0200, Marek Szyprowski wrote:
> >Hmm, will this remove support for iommu-groups in the exynos driver? I
> >am still working on the default-domain patch-set which makes iommu-group
> >support mandatory for iommu-drivers.
> 
> I you wish, I can leave this code. iommu-groups were not used at all
> on Exynos,
> so I thought that there is no point keeping useless code.

Yes, please keep the iommu-goups support, it will be required at some
point.


	Joerg

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

* Re: [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
  2015-05-18 17:04             ` Joerg Roedel
@ 2015-05-18 19:37                 ` Laurent Pinchart
  -1 siblings, 0 replies; 116+ messages in thread
From: Laurent Pinchart @ 2015-05-18 19:37 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: Thierry Reding, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Shaik Ameer Basha, Joonyoung Shim, Arnd Bergmann, Rob Herring,
	Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Kukjin Kim,
	Kyungmin Park, Javier Martinez Canillas, Cho KyongHo,
	David Wodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Joerg,

On Monday 18 May 2015 19:04:30 Joerg Roedel wrote:
> On Mon, May 18, 2015 at 02:09:14PM +0200, Marek Szyprowski wrote:
> > > Hmm, will this remove support for iommu-groups in the exynos driver? I
> > > am still working on the default-domain patch-set which makes iommu-group
> > > support mandatory for iommu-drivers.
> > 
> > I you wish, I can leave this code. iommu-groups were not used at all
> > on Exynos, so I thought that there is no point keeping useless code.
> 
> Yes, please keep the iommu-goups support, it will be required at some
> point.

I think the concept of iommu groups isn't very well understood, hence the 
little love it receives from developers who conclude it's useless. I can't 
blame anyone, I don't do any better. Could I convince you to include 
documentation in your next patch series that touches iommu groups ?

Could you please have a look at my "[RFC/PATCH 0/9] IOMMU probe deferral 
support" patch series in the context of iommu groups ? The series pretty much 
drops groups support from the ipmmu-vmsa driver, not because of a real desire 
to do so, but because I wasn't sure how to keep them. Tips would be 
appreciated.

-- 
Regards,

Laurent Pinchart

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

* [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks
@ 2015-05-18 19:37                 ` Laurent Pinchart
  0 siblings, 0 replies; 116+ messages in thread
From: Laurent Pinchart @ 2015-05-18 19:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Joerg,

On Monday 18 May 2015 19:04:30 Joerg Roedel wrote:
> On Mon, May 18, 2015 at 02:09:14PM +0200, Marek Szyprowski wrote:
> > > Hmm, will this remove support for iommu-groups in the exynos driver? I
> > > am still working on the default-domain patch-set which makes iommu-group
> > > support mandatory for iommu-drivers.
> > 
> > I you wish, I can leave this code. iommu-groups were not used at all
> > on Exynos, so I thought that there is no point keeping useless code.
> 
> Yes, please keep the iommu-goups support, it will be required at some
> point.

I think the concept of iommu groups isn't very well understood, hence the 
little love it receives from developers who conclude it's useless. I can't 
blame anyone, I don't do any better. Could I convince you to include 
documentation in your next patch series that touches iommu groups ?

Could you please have a look at my "[RFC/PATCH 0/9] IOMMU probe deferral 
support" patch series in the context of iommu groups ? The series pretty much 
drops groups support from the ipmmu-vmsa driver, not because of a real desire 
to do so, but because I wasn't sure how to keep them. Tips would be 
appreciated.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
  2015-05-06 14:01       ` Robin Murphy
@ 2015-05-19 10:49         ` Marek Szyprowski
  -1 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-19 10:49 UTC (permalink / raw)
  To: Robin Murphy, iommu, linux-samsung-soc, linux-arm-kernel
  Cc: Rob Herring, Thierry Reding, Shaik Ameer Basha, Joonyoung Shim,
	Arnd Bergmann, Inki Dae, Seung-Woo Kim, Will Deacon, Tomasz Figa,
	linaro-mm-sig, Kyungmin Park, Kukjin Kim, Laurent Pinchart,
	Javier Martinez Canillas, Cho KyongHo, David Wodhouse

Hello,

On 2015-05-06 16:01, Robin Murphy wrote:
> Hi Marek,
>
> On 04/05/15 09:15, Marek Szyprowski wrote:
>> Some devices (like frame buffers) are enabled by bootloader and 
>> configured
>> to perform DMA operations automatically (like displaying boot logo or 
>> splash
>> screen). Such devices operate and perform DMA operation usually until 
>> the
>> proper driver for them is loaded and probed. However before that 
>> happens,
>> system usually loads IOMMU drivers and configures dma parameters for 
>> each
>> device. When such initial configuration is created and enabled, it 
>> usually
>> contains empty translation rules betweem IO address space and physical
>> memory, because no buffers nor memory regions have been requested by the
>> respective driver.
>>
>> This patch adds support for "iommu-reserved-mapping", which can be used
>> to provide definitions for mappings that need to be created on system
>> boot to let such devices (enabled by bootloader) to operate properly
>> until respective driver is probed.
>
> This appears to only work if you assume the driver is going to tear 
> down the existing domain entirely; what about drivers that don't 
> manage IOMMUs explicitly, or if there are multiple active devices 
> behind the same IOMMU which (in future) start out in the same default 
> domain? If any device is happy to remain in the default domain then it 
> would be nice to clear the reservations once they are no longer needed.

Right, this need to be somehow worked out, but frankly right now I don't 
have
good idea which code should do it. The only idea that comes to my mind 
is using
a BUS_NOTIFY_BOUND_DRIVER notifier, but I don't like this approach.

> Could we not address the issue in a more robust way, like fleshing out 
> an implementation of the nascent IOMMU_DOMAIN_IDENTITY type, then just 
> flagging such devices to stipulate that their boot-time default domain 
> must be an identity-mapped one?

I'm open for any solution that will cover this case. Maybe my idea of iommu
reserved regions is a bit over-engineered? Maybe instead of defining 
reserved
ranges it will be enough to add something like 
'iommu-on-boot-identity-mapping'
property? This way one can later use it for IOMMU_DOMAIN_IDENTITY 
approach or
something else what will be agreed?

>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
>>   arch/arm/mm/dma-mapping.c                         | 112 
>> ++++++++++++++++++++++
>>   2 files changed, 156 insertions(+)
>>
> [...]
>> @@ -2048,6 +2092,66 @@ void arm_iommu_detach_device(struct device *dev)
>>   }
>>   EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
>>
>> +static int arm_iommu_add_reserved(struct device *dev,
>> +                       struct dma_iommu_mapping *domain, phys_addr_t 
>> phys,
>> +                       dma_addr_t dma, size_t size)
>> +{
>> +       int ret;
>> +
>> +       ret = __reserve_iova(domain, dma, size);
>> +       if (ret) {
>> +               dev_err(dev, "failed to reserve mapping\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       ret = iommu_map(domain->domain, dma, phys, size, IOMMU_READ);
>> +       if (ret != 0) {
>> +               dev_err(dev, "create IOMMU mapping\n");
>> +               return ret;
>> +       }
>> +
>> +       dev_info(dev, "created reserved DMA mapping (%pa -> %pad, %zu 
>> bytes)\n",
>> +                &phys, &dma, size);
>> +
>> +       return 0;
>> +}
>> +
>> +static int arm_iommu_init_reserved(struct device *dev,
>> +                                  struct dma_iommu_mapping *domain)
>> +{
>> +       const char *name = "iommu-reserved-mapping";
>> +       const __be32 *prop = NULL;
>> +       int len, naddr, nsize;
>> +       struct device_node *node = dev->of_node;
>> +       phys_addr_t phys;
>> +       dma_addr_t dma;
>> +       size_t size;
>> +
>> +       if (!node)
>> +               return 0;
>> +
>> +       naddr = of_n_addr_cells(node);
>> +       nsize = of_n_size_cells(node);
>> +
>> +       prop = of_get_property(node, name, &len);
>> +       if (!prop)
>> +               return 0;
>> +
>> +       len /= sizeof(u32);
>> +
>> +       if (len < 2 * naddr + nsize) {
>> +               dev_err(dev, "invalid length (%d cells) of %s 
>> property\n",
>> +                       len, name);
>> +               return -EINVAL;
>> +       }
>> +
>> +       phys = of_read_number(prop, naddr);
>> +       dma = of_read_number(prop + naddr, naddr);
>> +       size = of_read_number(prop + 2*naddr, nsize);
>> +
>> +       return arm_iommu_add_reserved(dev, domain, phys, dma, size);
> > +}
>
> I may be missing something, but I don't see how this can handle 
> multiple ranges for the same device as the binding says.
>

Right, loop is missing in the above calls.

>>   static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
>>   {
>>          return coherent ? &iommu_coherent_ops : &iommu_ops;
>> @@ -2068,6 +2172,14 @@ static bool arm_setup_iommu_dma_ops(struct 
>> device *dev, u64 dma_base, u64 size,
>>                  return false;
>>          }
>>
>> +       if (arm_iommu_init_reserved(dev, mapping) != 0) {
>> +               pr_warn("Failed to initialize reserved mapping for 
>> device %s\n",
>> +                       dev_name(dev));
>> +               __arm_iommu_detach_device(dev);
>> +               arm_iommu_release_mapping(mapping);
>> +               return false;
>> +       }
>> +
>>          if (__arm_iommu_attach_device(dev, mapping)) {
>>                  pr_warn("Failed to attached device %s to 
>> IOMMU_mapping\n",
>>                                  dev_name(dev));
>
> I'm hoping Joerg is still working on his default domain series, 
> because the domain creation in arch_setup_dma_ops turns out to be 
> horrible on a number of levels (like everything happening in the wrong 
> order for platform devices). If that doesn't negate this issue 
> entirely, it's going to significantly break this way of hooking up the 
> solution (depending on what the drivers do) - worth some 
> consideration, at least.

I would really like to have something working soon, it's been a lot of 
discussion but still
very little of code that actually implements anything...

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space
@ 2015-05-19 10:49         ` Marek Szyprowski
  0 siblings, 0 replies; 116+ messages in thread
From: Marek Szyprowski @ 2015-05-19 10:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2015-05-06 16:01, Robin Murphy wrote:
> Hi Marek,
>
> On 04/05/15 09:15, Marek Szyprowski wrote:
>> Some devices (like frame buffers) are enabled by bootloader and 
>> configured
>> to perform DMA operations automatically (like displaying boot logo or 
>> splash
>> screen). Such devices operate and perform DMA operation usually until 
>> the
>> proper driver for them is loaded and probed. However before that 
>> happens,
>> system usually loads IOMMU drivers and configures dma parameters for 
>> each
>> device. When such initial configuration is created and enabled, it 
>> usually
>> contains empty translation rules betweem IO address space and physical
>> memory, because no buffers nor memory regions have been requested by the
>> respective driver.
>>
>> This patch adds support for "iommu-reserved-mapping", which can be used
>> to provide definitions for mappings that need to be created on system
>> boot to let such devices (enabled by bootloader) to operate properly
>> until respective driver is probed.
>
> This appears to only work if you assume the driver is going to tear 
> down the existing domain entirely; what about drivers that don't 
> manage IOMMUs explicitly, or if there are multiple active devices 
> behind the same IOMMU which (in future) start out in the same default 
> domain? If any device is happy to remain in the default domain then it 
> would be nice to clear the reservations once they are no longer needed.

Right, this need to be somehow worked out, but frankly right now I don't 
have
good idea which code should do it. The only idea that comes to my mind 
is using
a BUS_NOTIFY_BOUND_DRIVER notifier, but I don't like this approach.

> Could we not address the issue in a more robust way, like fleshing out 
> an implementation of the nascent IOMMU_DOMAIN_IDENTITY type, then just 
> flagging such devices to stipulate that their boot-time default domain 
> must be an identity-mapped one?

I'm open for any solution that will cover this case. Maybe my idea of iommu
reserved regions is a bit over-engineered? Maybe instead of defining 
reserved
ranges it will be enough to add something like 
'iommu-on-boot-identity-mapping'
property? This way one can later use it for IOMMU_DOMAIN_IDENTITY 
approach or
something else what will be agreed?

>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   Documentation/devicetree/bindings/iommu/iommu.txt |  44 +++++++++
>>   arch/arm/mm/dma-mapping.c                         | 112 
>> ++++++++++++++++++++++
>>   2 files changed, 156 insertions(+)
>>
> [...]
>> @@ -2048,6 +2092,66 @@ void arm_iommu_detach_device(struct device *dev)
>>   }
>>   EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
>>
>> +static int arm_iommu_add_reserved(struct device *dev,
>> +                       struct dma_iommu_mapping *domain, phys_addr_t 
>> phys,
>> +                       dma_addr_t dma, size_t size)
>> +{
>> +       int ret;
>> +
>> +       ret = __reserve_iova(domain, dma, size);
>> +       if (ret) {
>> +               dev_err(dev, "failed to reserve mapping\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       ret = iommu_map(domain->domain, dma, phys, size, IOMMU_READ);
>> +       if (ret != 0) {
>> +               dev_err(dev, "create IOMMU mapping\n");
>> +               return ret;
>> +       }
>> +
>> +       dev_info(dev, "created reserved DMA mapping (%pa -> %pad, %zu 
>> bytes)\n",
>> +                &phys, &dma, size);
>> +
>> +       return 0;
>> +}
>> +
>> +static int arm_iommu_init_reserved(struct device *dev,
>> +                                  struct dma_iommu_mapping *domain)
>> +{
>> +       const char *name = "iommu-reserved-mapping";
>> +       const __be32 *prop = NULL;
>> +       int len, naddr, nsize;
>> +       struct device_node *node = dev->of_node;
>> +       phys_addr_t phys;
>> +       dma_addr_t dma;
>> +       size_t size;
>> +
>> +       if (!node)
>> +               return 0;
>> +
>> +       naddr = of_n_addr_cells(node);
>> +       nsize = of_n_size_cells(node);
>> +
>> +       prop = of_get_property(node, name, &len);
>> +       if (!prop)
>> +               return 0;
>> +
>> +       len /= sizeof(u32);
>> +
>> +       if (len < 2 * naddr + nsize) {
>> +               dev_err(dev, "invalid length (%d cells) of %s 
>> property\n",
>> +                       len, name);
>> +               return -EINVAL;
>> +       }
>> +
>> +       phys = of_read_number(prop, naddr);
>> +       dma = of_read_number(prop + naddr, naddr);
>> +       size = of_read_number(prop + 2*naddr, nsize);
>> +
>> +       return arm_iommu_add_reserved(dev, domain, phys, dma, size);
> > +}
>
> I may be missing something, but I don't see how this can handle 
> multiple ranges for the same device as the binding says.
>

Right, loop is missing in the above calls.

>>   static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
>>   {
>>          return coherent ? &iommu_coherent_ops : &iommu_ops;
>> @@ -2068,6 +2172,14 @@ static bool arm_setup_iommu_dma_ops(struct 
>> device *dev, u64 dma_base, u64 size,
>>                  return false;
>>          }
>>
>> +       if (arm_iommu_init_reserved(dev, mapping) != 0) {
>> +               pr_warn("Failed to initialize reserved mapping for 
>> device %s\n",
>> +                       dev_name(dev));
>> +               __arm_iommu_detach_device(dev);
>> +               arm_iommu_release_mapping(mapping);
>> +               return false;
>> +       }
>> +
>>          if (__arm_iommu_attach_device(dev, mapping)) {
>>                  pr_warn("Failed to attached device %s to 
>> IOMMU_mapping\n",
>>                                  dev_name(dev));
>
> I'm hoping Joerg is still working on his default domain series, 
> because the domain creation in arch_setup_dma_ops turns out to be 
> horrible on a number of levels (like everything happening in the wrong 
> order for platform devices). If that doesn't negate this issue 
> entirely, it's going to significantly break this way of hooking up the 
> solution (depending on what the drivers do) - worth some 
> consideration, at least.

I would really like to have something working soon, it's been a lot of 
discussion but still
very little of code that actually implements anything...

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

end of thread, other threads:[~2015-05-19 10:49 UTC | newest]

Thread overview: 116+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-04  8:15 [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Marek Szyprowski
2015-05-04  8:15 ` Marek Szyprowski
2015-05-04  8:15 ` [PATCH v6 02/25] arm: exynos: pm_domains: register power domain driver from core_initcall Marek Szyprowski
2015-05-04  8:15   ` Marek Szyprowski
2015-05-04  8:15 ` [PATCH v6 03/25] drm/exynos: iommu: detach from default dma-mapping domain on init Marek Szyprowski
2015-05-04  8:15   ` Marek Szyprowski
2015-05-04  8:15 ` [PATCH v6 04/25] drm/exynos: fimd: ensure proper hw state in fimd_clear_channel() Marek Szyprowski
2015-05-04  8:15   ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 05/25] iommu: exynos: don't read version register on every tlb operation Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-10 12:59   ` Cho KyongHo
2015-05-10 12:59     ` Cho KyongHo
     [not found] ` <1430727380-10912-1-git-send-email-m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-04  8:15   ` [PATCH v6 01/25] arm: dma-mapping: add support for creating reserved mappings in iova space Marek Szyprowski
2015-05-04  8:15     ` Marek Szyprowski
2015-05-04 22:12     ` Rob Herring
2015-05-04 22:12       ` Rob Herring
     [not found]       ` <CAL_JsqKB4F8tspydBFrL-PH3gXcyu-pwQwBETMizJzTpAF3yzg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-05-18 12:09         ` Marek Szyprowski
2015-05-18 12:09           ` Marek Szyprowski
2015-05-06 14:01     ` Robin Murphy
2015-05-06 14:01       ` Robin Murphy
2015-05-19 10:49       ` Marek Szyprowski
2015-05-19 10:49         ` Marek Szyprowski
2015-05-04  8:16   ` [PATCH v6 06/25] iommu: exynos: remove unused functions Marek Szyprowski
2015-05-04  8:16     ` Marek Szyprowski
2015-05-10 13:01     ` Cho KyongHo
2015-05-10 13:01       ` Cho KyongHo
2015-05-04 10:30   ` [PATCH v6 27/26] iommu: exynos: add system suspend/resume support Marek Szyprowski
2015-05-04 10:30     ` Marek Szyprowski
2015-05-05 15:05   ` [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Joerg Roedel
2015-05-05 15:05     ` Joerg Roedel
2015-05-18 12:16     ` Marek Szyprowski
2015-05-18 12:16       ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 07/25] iommu: exynos: remove useless spinlock Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 08/25] iommu: exynos: refactor function parameters to simplify code Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
     [not found]   ` <1430727380-10912-9-git-send-email-m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-05 14:52     ` Joerg Roedel
2015-05-05 14:52       ` Joerg Roedel
2015-05-10 13:27     ` Cho KyongHo
2015-05-10 13:27       ` Cho KyongHo
     [not found]       ` <20150510222712.a955a6d326698ba5a09c6fe7-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-18 12:58         ` Marek Szyprowski
2015-05-18 12:58           ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 09/25] iommu: exynos: remove unused functions, part 2 Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
     [not found]   ` <1430727380-10912-10-git-send-email-m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-05 14:53     ` Joerg Roedel
2015-05-05 14:53       ` Joerg Roedel
2015-05-04  8:16 ` [PATCH v6 10/25] iommu: exynos: remove useless device_add/remove callbacks Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
     [not found]   ` <1430727380-10912-11-git-send-email-m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-05 14:55     ` Joerg Roedel
2015-05-05 14:55       ` Joerg Roedel
     [not found]       ` <20150505145538.GL15736-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2015-05-18 12:09         ` Marek Szyprowski
2015-05-18 12:09           ` Marek Szyprowski
2015-05-18 17:04           ` Joerg Roedel
2015-05-18 17:04             ` Joerg Roedel
     [not found]             ` <20150518170430.GK20611-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2015-05-18 19:37               ` Laurent Pinchart
2015-05-18 19:37                 ` Laurent Pinchart
2015-05-04  8:16 ` [PATCH v6 11/25] iommu: exynos: add support for binding more than one sysmmu to master device Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-10 13:34   ` Cho KyongHo
2015-05-10 13:34     ` Cho KyongHo
     [not found]     ` <20150510223437.b651f6d2f3f0ead49eb72488-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-18 13:03       ` Marek Szyprowski
2015-05-18 13:03         ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 12/25] iommu: exynos: add support for runtime_pm Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-10 13:38   ` Cho KyongHo
2015-05-10 13:38     ` Cho KyongHo
2015-05-18 12:25     ` Marek Szyprowski
2015-05-18 12:25       ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 13/25] iommu: exynos: rename variables to reflect their purpose Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 14/25] iommu: exynos: use struct exynos_iommu_domain in internal structures Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 15/25] iommu: exynos: document " Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
     [not found]   ` <1430727380-10912-16-git-send-email-m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-05 15:00     ` Joerg Roedel
2015-05-05 15:00       ` Joerg Roedel
2015-05-04  8:16 ` [PATCH v6 16/25] iommu: exynos: remove excessive includes and sort others alphabetically Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 17/25] iommu: exynos: init from dt-specific callback instead of initcall Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 18/25] iommu: exynos: add callback for initializing devices from device tree Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 19/25] iommu: exynos: remove unneeded code Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-04  8:16 ` [PATCH v6 20/25] ARM: dts: exynos4: add sysmmu nodes Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-05  4:08   ` Krzysztof Kozłowski
2015-05-05  4:08     ` Krzysztof Kozłowski
2015-05-04  8:16 ` [PATCH v6 21/25] ARM: dts: exynos3250: " Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-05  4:10   ` Krzysztof Kozłowski
2015-05-05  4:10     ` Krzysztof Kozłowski
2015-05-04  8:16 ` [PATCH v6 22/25] ARM: dts: exynos4415: " Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-05  4:09   ` Krzysztof Kozłowski
2015-05-05  4:09     ` Krzysztof Kozłowski
2015-05-04  8:16 ` [PATCH v6 23/25] ARM: dts: exynos5250: " Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-05  4:04   ` Krzysztof Kozłowski
2015-05-05  4:04     ` Krzysztof Kozłowski
2015-05-04  8:16 ` [PATCH v6 24/25] ARM: dts: exynos5420: " Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
2015-05-05  4:10   ` Krzysztof Kozłowski
2015-05-05  4:10     ` Krzysztof Kozłowski
2015-05-04  8:16 ` [PATCH v6 25/25] ARM: dts: exynos: add iommu reserved regions for bootloader's splash screen Marek Szyprowski
2015-05-04  8:16   ` Marek Szyprowski
     [not found]   ` <1430727380-10912-26-git-send-email-m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-05  5:50     ` Krzysztof Kozłowski
2015-05-05  5:50       ` Krzysztof Kozłowski
2015-05-11 16:00 ` [PATCH v6 00/25] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem Javier Martinez Canillas
2015-05-11 16:00   ` Javier Martinez Canillas
2015-05-12 15:35   ` Javier Martinez Canillas
2015-05-12 15:35     ` Javier Martinez Canillas
2015-05-18 13:26   ` Marek Szyprowski
2015-05-18 13:26     ` Marek Szyprowski
     [not found]     ` <5559E88E.9050108-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-18 13:32       ` Javier Martinez Canillas
2015-05-18 13:32         ` Javier Martinez Canillas

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.