Skip to contentSkip to conversation

Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem

PATCH New Marek Szyprowski 8 participants 50 messages May 19, 2015 – Jun 4, 2015

Subsystems (8)
lore
Share & tools
lore

Marek Szyprowski

author maintainer
#0 lore raw

v7 cover Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem

Hello Everyone,

This is yet another attempt to get Exynos SYSMMU driver with integrated with IOMMU & DMA-mapping subsystems. This version includes minor fixes suggested by Joerg Roedel, Cho KyongHo and Robin Murphy.

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

My plan for merging this patchset is as follows:
- DTS changes and power domain changes should go via Samsung tree to avoid conflicts with other pending DTS patches
- all exynos-iommu patches and dma-mapping/reserved iommu region should go via IOMMU tree,
- all Exynos DRM patches should go via DRM/Exynos tree.

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

There are knowns issues with Exynos DRM driver and IOMMU support (i.e. Xorg freeze reported by Javier Martinez Canillas:
http://www.spinics.net/lists/linux-samsung-soc/msg44350.html ). They will be handled by a separate fixes to Exynos DRM drivers. This patchset fixes only those issues in Exynos DRM FIMD driver, which prevents booting to console.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland

Changelog:

v7:
- rebased onto v4.1-rc4
- restored iommu_gruops support
- added missing suspend/resume support patch
- rearanged patch order and squashed some patches for better code readability
- changed patch prefixes to match maintainer's requirements
- fixed minor issues pointed by Joerg Roedel, Cho KyongHo and Robin Murphy
- added Krzysztof's acks for dts patches

v6: http://www.spinics.net/lists/linux-samsung-soc/msg44065.html
- 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):
drm/exynos: iommu: detach from default dma-mapping domain on init drm/exynos: fimd: ensure proper hw state in fimd_clear_channel()
iommu: Init iommu-groups support earlier, in core_initcall iommu/exynos: Don't read version register on every tlb operation iommu/exynos: Remove unused functions
iommu/exynos: Remove useless members from exynos_iommu_owner structure iommu/exynos: Refactor function parameters to simplify code iommu/exynos: Rename variables to reflect their purpose iommu/exynos: Use struct exynos_iommu_domain in internal structures iommu/exynos: Remove excessive includes and sort others alphabetically iommu/exynos: Document internal structures
iommu/exynos: Add/remove callbacks should fail if no iommu is
available
iommu/exynos: Add support for binding more than one sysmmu to master
device
iommu/exynos: Add support for runtime_pm
iommu/exynos: Add system suspend/resume support iommu/exynos: Init from dt-specific callback instead of initcall iommu/exynos: Add callback for initializing devices from device tree
ARM: Exynos: pm_domains: register power domain driver from
core_initcall
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: DMA-mapping: add support for creating reserved mappings in iova
space
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                         | 121 +++++
 drivers/gpu/drm/exynos/exynos_drm_fimd.c          |  27 +-
 drivers/gpu/drm/exynos/exynos_drm_iommu.c         |   3 +
 drivers/iommu/exynos-iommu.c                      | 526 +++++++++++-----------
 drivers/iommu/iommu.c                             |   2 +-
 22 files changed, 1156 insertions(+), 280 deletions(-)
Signature · 1 line
1.9.2
author maintainer
#1 lore raw

PATCH v7 1/25 drm/exynos: iommu: detach from default dma-mapping domain on init

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

---
 drivers/gpu/drm/exynos/exynos_drm_iommu.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/exynos/exynos_drm_iommu.c +3 -0
index b32b291f88ff..323601a52a25 100644
@@ -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");
Signature · 1 line
1.9.2
author maintainer
#2 lore raw

PATCH v7 2/25 drm/exynos: fimd: ensure proper hw state in fimd_clear_channel()

In reply to Marek Szyprowski

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.

---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_fimd.c +17 -10
index 9819fa6a9e2a..cf64550df59d 100644
@@ -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");
Signature · 1 line
1.9.2
author maintainer
#3 lore raw

PATCH v7 3/25 iommu: Init iommu-groups support earlier, in core_initcall

In reply to Marek Szyprowski

iommu_group_alloc might be called very early in case of iommu controllers activated from of_iommu, so ensure that this part of subsystem is ready when devices are being populated from device-tree (core_initcall seems to be okay for this case).

---
 drivers/iommu/iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/iommu.c +1 -1
index d4f527e56679..37a6aa8f318b 100644
@@ -1207,7 +1207,7 @@ static int __init iommu_init(void)
 
 	return 0;
 }
-arch_initcall(iommu_init);
+core_initcall(iommu_init);
 
 int iommu_domain_get_attr(struct iommu_domain *domain,
 			  enum iommu_attr attr, void *data)
Signature · 1 line
1.9.2
#4 lore raw

PATCH v7 3/25 iommu: Init iommu-groups support earlier, in core_initcall

Hi Marek,

Thank you for the patch.

Quoted 15 lines · On Tuesday 19 May 2015 15:20:23 Marek Szyprowski wrote:

iommu_group_alloc might be called very early in case of iommu controllers activated from of_iommu, so ensure that this part of subsystem is ready when devices are being populated from device-tree (core_initcall seems to be okay for this case).

---
 drivers/iommu/iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/iommu.c +0 -0
index d4f527e56679..37a6aa8f318b 100644

drivers/iommu/iommu.c static int __init iommu_init(void) · line 1210

Quoted 5 lines
drivers/iommu/iommu.c +1 -1
@@ -1207,7 +1207,7 @@ static int __init iommu_init(void)
 
 	return 0;
 }
-arch_initcall(iommu_init);
+core_initcall(iommu_init);

I'll let Joerg comment on this, but this initcall ordering dance always makes me feel that something isn't quite right. Have you had a chance to look at the patch series I posted about a week ago to implement IOMMU probe deferral support ?

Quoted 2 lines
drivers/iommu/iommu.c +0 -0
 int iommu_domain_get_attr(struct iommu_domain *domain,
 			  enum iommu_attr attr, void *data)
Signature · 3 lines
Regards,

Laurent Pinchart
author maintainer
#5 lore raw

PATCH v7 3/25 iommu: Init iommu-groups support earlier, in core_initcall

Hello,

Quoted 21 lines · Laurent Pinchart

Hi Marek,

Thank you for the patch.

Quoted 16 lines · On Tuesday 19 May 2015 15:20:23 Marek Szyprowski wrote:

iommu_group_alloc might be called very early in case of iommu controllers activated from of_iommu, so ensure that this part of subsystem is ready when devices are being populated from device-tree (core_initcall seems to be okay for this case).

---
  drivers/iommu/iommu.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/iommu.c +0 -0
index d4f527e56679..37a6aa8f318b 100644
@@ -1207,7 +1207,7 @@ static int __init iommu_init(void)
 
Quoted 8 lines

drivers/iommu/iommu.c static int __init iommu_init(void) · line 1210

Quoted 4 lines
drivers/iommu/iommu.c +1 -1
  	return 0;
  }
-arch_initcall(iommu_init);
+core_initcall(iommu_init);

I'll let Joerg comment on this, but this initcall ordering dance always makes me feel that something isn't quite right. Have you had a chance to look at the patch series I posted about a week ago to implement IOMMU probe deferral support ?

I will try to check your IOMMU probe deferal, but for the time being changing the
initcall priority was the simplest way to get everything working with iommu_groups
(what was a requirement from Joerg).

I also don't like the initcall ordering hacks, but this change seems to be the
right approach. Probe deferal is convenient for development purpose and all king of
hotpluggable solutions, but imho for typical cases system should be tuned to avoid
deferal to reduce overhead on boot.

If possible I would like to avoid having dependency on your deferal-probe patches
and get the basic Exynos IOMMU support finally merged. There are still other enhancements to Exynos IOMMU driver that depend on it and need real discussion
(like real runtime pm and exposing particular iommu controllers via dma api).

Quoted 4 lines

drivers/iommu/iommu.c static int __init iommu_init(void) · line 1213

Quoted 3 lines
drivers/iommu/iommu.c +0 -0
  int iommu_domain_get_attr(struct iommu_domain *domain,
  			  enum iommu_attr attr, void *data)

Best regards

Signature · 2 lines
Marek Szyprowski, PhD
Samsung R&D Institute Poland
maintainer
#6 lore raw

PATCH v7 3/25 iommu: Init iommu-groups support earlier, in core_initcall

In reply to Laurent Pinchart
Quoted 8 lines · Laurent Pinchart

drivers/iommu/iommu.c static int __init iommu_init(void) · line 1210

Quoted 2 lines · On Tuesday 19 May 2015 15:20:23 Marek Szyprowski wrote:
drivers/iommu/iommu.c +1 -1
-arch_initcall(iommu_init);
+core_initcall(iommu_init);

I'll let Joerg comment on this, but this initcall ordering dance always makes me feel that something isn't quite right. Have you had a chance to look at the patch series I posted about a week ago to implement IOMMU probe deferral support ?

Yeah, this is hacky, but I can live with it until your probe deferal patch-set is merged.

Joerg

author maintainer
#7 lore raw

PATCH v7 4/25 iommu/exynos: Don't read version register on every tlb operation

In reply to Marek Szyprowski

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

---
 drivers/iommu/exynos-iommu.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)
drivers/iommu/exynos-iommu.c +5 -8
index 3e898504a7c4..e9385ef0b8df 100644
@@ -213,6 +213,7 @@ struct sysmmu_drvdata {
 	spinlock_t lock;
 	struct iommu_domain *domain;
 	phys_addr_t pgtable;
+	unsigned 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)) {
Signature · 1 line
1.9.2
author maintainer
#8 lore raw

PATCH v7 5/25 iommu/exynos: Remove unused functions

In reply to Marek Szyprowski

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

---
 drivers/iommu/exynos-iommu.c | 31 -------------------------------
 1 file changed, 31 deletions(-)
drivers/iommu/exynos-iommu.c +0 -31
index e9385ef0b8df..c9806868c14f 100644
@@ -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;
Signature · 1 line
1.9.2
author maintainer
#9 lore raw

PATCH v7 6/25 iommu/exynos: Remove useless members from exynos_iommu_owner structure

In reply to Marek Szyprowski

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.

---
 drivers/iommu/exynos-iommu.c | 21 ++-------------------
 1 file changed, 2 insertions(+), 19 deletions(-)
drivers/iommu/exynos-iommu.c +2 -19
index c9806868c14f..4f6090361af1 100644
@@ -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 {
@@ -477,44 +474,34 @@ 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));
 
-	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;
 }
 
 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));
 
-	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;
 }
 
@@ -762,10 +749,8 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 	spin_lock_irqsave(&priv->lock, flags);
 
 	ret = __exynos_sysmmu_enable(dev, pagetable, domain);
-	if (ret == 0) {
+	if (ret == 0)
 		list_add_tail(&owner->client, &priv->clients);
-		owner->domain = domain;
-	}
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -793,10 +778,8 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 
 	list_for_each_entry(owner, &priv->clients, client) {
 		if (owner == dev->archdata.iommu) {
-			if (exynos_sysmmu_disable(dev)) {
+			if (exynos_sysmmu_disable(dev))
 				list_del_init(&owner->client);
-				owner->domain = NULL;
-			}
 			break;
 		}
 	}
Signature · 1 line
1.9.2
author maintainer
#10 lore raw

PATCH v7 7/25 iommu/exynos: Refactor function parameters to simplify code

In reply to Marek Szyprowski

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

After above refactoring some functions were never used, so remove also them completely.

---
 drivers/iommu/exynos-iommu.c | 134 ++++++++++++++++---------------------------
 1 file changed, 48 insertions(+), 86 deletions(-)
drivers/iommu/exynos-iommu.c +48 -86
index 4f6090361af1..741149622db3 100644
@@ -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;
 	unsigned int version;
 };
@@ -464,47 +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;
-	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)
-{
-	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)
 {
@@ -512,12 +470,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);
@@ -531,14 +487,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)) {
@@ -568,8 +520,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);
 }
@@ -709,7 +661,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, *next;
 	unsigned long flags;
 	int i;
 
@@ -717,14 +669,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_safe(data, next, &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++)
@@ -742,17 +692,25 @@ 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);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
+	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);
+		}
+	}
 
 	if (ret < 0) {
 		dev_err(dev, "%s: Failed to attach IOMMU with pgtable %pa\n",
@@ -769,24 +727,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);
+	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
@@ -833,12 +796,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);
 		}
 	}
@@ -873,13 +835,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);
 
@@ -984,13 +946,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);
 }
Signature · 1 line
1.9.2
author maintainer
#11 lore raw

PATCH v7 8/25 iommu/exynos: Rename variables to reflect their purpose

In reply to Marek Szyprowski

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.

---
 drivers/iommu/exynos-iommu.c | 187 ++++++++++++++++++++++---------------------
 1 file changed, 94 insertions(+), 93 deletions(-)
drivers/iommu/exynos-iommu.c +94 -93
index 741149622db3..1cb3c27e9125 100644
@@ -435,8 +435,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;
@@ -444,7 +444,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);
 
@@ -609,91 +609,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, *next;
 	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_safe(data, next, &priv->clients, domain_node) {
+	list_for_each_entry_safe(data, next, &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;
 
@@ -702,13 +702,13 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
 
 	data = dev_get_drvdata(owner->sysmmu);
 	if (data) {
-		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);
 		}
 	}
 
@@ -724,11 +724,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;
 	unsigned long flags;
 	bool found = false;
@@ -736,8 +736,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(data, &priv->clients, domain_node) {
+	spin_lock_irqsave(&domain->lock, flags);
+	list_for_each_entry(data, &domain->clients, domain_node) {
 		if (data->master == dev) {
 			if (__sysmmu_disable(data)) {
 				data->master = NULL;
@@ -747,7 +747,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
 			break;
 		}
 	}
-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&domain->lock, flags);
 
 	if (found)
 		dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
@@ -756,7 +756,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)) {
@@ -798,17 +798,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)
 {
@@ -833,17 +833,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;
 }
@@ -903,74 +903,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)) {
@@ -1004,7 +1005,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;
 	}
 
@@ -1018,15 +1019,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);
@@ -1034,17 +1035,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);
@@ -1057,7 +1058,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;
 }
Signature · 1 line
1.9.2
author maintainer
#12 lore raw

PATCH v7 9/25 iommu/exynos: Use struct exynos_iommu_domain in internal structures

In reply to Marek Szyprowski

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

---
 drivers/iommu/exynos-iommu.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/iommu/exynos-iommu.c +5 -5
index 1cb3c27e9125..33118aa9fdc1 100644
@@ -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;
 	phys_addr_t pgtable;
 	unsigned int version;
@@ -337,7 +337,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);
 	}
 
@@ -436,7 +436,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;
@@ -444,7 +444,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);
 
@@ -702,7 +702,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
 
 	data = dev_get_drvdata(owner->sysmmu);
 	if (data) {
-		ret = __sysmmu_enable(data, pagetable, iommu_domain);
+		ret = __sysmmu_enable(data, pagetable, domain);
 		if (ret >= 0) {
 			data->master = dev;
 
Signature · 1 line
1.9.2
author maintainer
#13 lore raw

PATCH v7 10/25 iommu/exynos: Remove excessive includes and sort others alphabetically

In reply to Marek Szyprowski

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

---
 drivers/iommu/exynos-iommu.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)
drivers/iommu/exynos-iommu.c +5 -9
index 33118aa9fdc1..646adb547cba 100644
@@ -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>
Signature · 1 line
1.9.2
author maintainer
#14 lore raw

PATCH v7 11/25 iommu/exynos: Document internal structures

In reply to Marek Szyprowski

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

---
 drivers/iommu/exynos-iommu.c | 53 +++++++++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 18 deletions(-)
drivers/iommu/exynos-iommu.c +35 -18
index 646adb547cba..0e7250fda087 100644
@@ -180,32 +180,49 @@ 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 device *sysmmu;
+	struct device *sysmmu;		/* sysmmu controller for given master */
 };
 
+/*
+ * 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 */
-	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 pgtablelock; /* lock for modifying page table @ pgtable */
+	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 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;
-	phys_addr_t pgtable;
-	unsigned int version;
+	struct device *sysmmu;		/* SYSMMU controller device */
+	struct device *master;		/* master device (owner) */
+	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 state */
+	struct exynos_iommu_domain *domain; /* domain we belong to */
+	struct list_head domain_node;	/* node for domain clients list */
+	phys_addr_t pgtable;		/* assigned page table structure */
+	unsigned int version;		/* our version */
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
Signature · 1 line
1.9.2
author maintainer
#15 lore raw

PATCH v7 12/25 iommu/exynos: Add/remove callbacks should fail if no iommu is available

In reply to Marek Szyprowski

Return fail if given master device passed to add_device/remove_device callbacks doesn't has associated any sysmmu controller.

---
 drivers/iommu/exynos-iommu.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/iommu/exynos-iommu.c +6 -0
index 0e7250fda087..a5f0c99602c2 100644
@@ -1081,6 +1081,9 @@ static int exynos_iommu_add_device(struct device *dev)
 	struct iommu_group *group;
 	int ret;
 
+	if (!has_sysmmu(dev))
+		return -ENODEV;
+
 	group = iommu_group_get(dev);
 
 	if (!group) {
@@ -1099,6 +1102,9 @@ static int exynos_iommu_add_device(struct device *dev)
 
 static void exynos_iommu_remove_device(struct device *dev)
 {
+	if (!has_sysmmu(dev))
+		return;
+
 	iommu_group_remove_device(dev);
 }
 
Signature · 1 line
1.9.2
author maintainer
#16 lore raw

PATCH v7 13/25 iommu/exynos: Add support for binding more than one sysmmu to master device

In reply to Marek Szyprowski

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.

---
 drivers/iommu/exynos-iommu.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/iommu/exynos-iommu.c +5 -6
index a5f0c99602c2..946f95ae46bc 100644
@@ -187,7 +187,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
  * pointer.
 */
 struct exynos_iommu_owner {
-	struct device *sysmmu;		/* sysmmu controller for given master */
+	struct list_head controllers;	/* list of sysmmu_drvdata.owner_node */
 };
 
 /*
@@ -221,6 +221,7 @@ struct sysmmu_drvdata {
 	spinlock_t lock;		/* lock for modyfying 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 controllers list */
 	phys_addr_t pgtable;		/* assigned page table structure */
 	unsigned int version;		/* our version */
 };
@@ -713,8 +714,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
 	if (!has_sysmmu(dev))
 		return -ENODEV;
 
-	data = dev_get_drvdata(owner->sysmmu);
-	if (data) {
+	list_for_each_entry(data, &owner->controllers, owner_node) {
 		ret = __sysmmu_enable(data, pagetable, domain);
 		if (ret >= 0) {
 			data->master = dev;
@@ -742,7 +742,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
 {
 	struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
 	phys_addr_t pagetable = virt_to_phys(domain->pgtable);
-	struct sysmmu_drvdata *data;
+	struct sysmmu_drvdata *data, *next;
 	unsigned long flags;
 	bool found = false;
 
@@ -750,14 +750,13 @@ static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
 		return;
 
 	spin_lock_irqsave(&domain->lock, flags);
-	list_for_each_entry(data, &domain->clients, domain_node) {
+	list_for_each_entry_safe(data, next, &domain->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(&domain->lock, flags);
Signature · 1 line
1.9.2
author maintainer
#17 lore raw

PATCH v7 14/25 iommu/exynos: Add support for runtime_pm

In reply to Marek Szyprowski

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

---
 drivers/iommu/exynos-iommu.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/iommu/exynos-iommu.c +2 -0
index 946f95ae46bc..fcd23e9c409a 100644
@@ -715,6 +715,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
 		return -ENODEV;
 
 	list_for_each_entry(data, &owner->controllers, owner_node) {
+		pm_runtime_get_sync(data->sysmmu);
 		ret = __sysmmu_enable(data, pagetable, domain);
 		if (ret >= 0) {
 			data->master = dev;
@@ -756,6 +757,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
 				data->master = NULL;
 				list_del_init(&data->domain_node);
 			}
+			pm_runtime_put(data->sysmmu);
 			found = true;
 		}
 	}
Signature · 1 line
1.9.2
author maintainer
#18 lore raw

PATCH v7 15/25 iommu/exynos: Add system suspend/resume support

In reply to Marek Szyprowski

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.

---
 drivers/iommu/exynos-iommu.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
drivers/iommu/exynos-iommu.c +31 -0
index fcd23e9c409a..15551f17fa37 100644
@@ -601,6 +601,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", },
 	{ },
@@ -611,6 +641,7 @@ static struct platform_driver exynos_sysmmu_driver __refdata = {
 	.driver	= {
 		.name		= "exynos-sysmmu",
 		.of_match_table	= sysmmu_of_match,
+		.pm		= &sysmmu_pm_ops,
 	}
 };
 
Signature · 1 line
1.9.2
author maintainer
#19 lore raw

PATCH v7 16/25 iommu/exynos: Init from dt-specific callback instead of initcall

In reply to Marek Szyprowski

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.

---
 drivers/iommu/exynos-iommu.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)
drivers/iommu/exynos-iommu.c +28 -9
index 15551f17fa37..a157e43bd113 100644
@@ -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;
@@ -1140,7 +1145,7 @@ static void exynos_iommu_remove_device(struct device *dev)
 	iommu_group_remove_device(dev);
 }
 
-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,
@@ -1154,17 +1159,12 @@ 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;
 	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) {
@@ -1193,6 +1193,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);
@@ -1202,4 +1204,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);
Signature · 1 line
1.9.2
author maintainer
#20 lore raw

PATCH v7 17/25 iommu/exynos: Add callback for initializing devices from device tree

In reply to Marek Szyprowski

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.

---
 drivers/iommu/exynos-iommu.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
drivers/iommu/exynos-iommu.c +28 -0
index a157e43bd113..27143f1cbc27 100644
@@ -1145,6 +1145,33 @@ static void exynos_iommu_remove_device(struct device *dev)
 	iommu_group_remove_device(dev);
 }
 
+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->controllers);
+		dev->archdata.iommu = owner;
+	}
+
+	list_add_tail(&data->owner_node, &owner->controllers);
+	return 0;
+}
+
 static struct iommu_ops exynos_iommu_ops = {
 	.domain_alloc = exynos_iommu_domain_alloc,
 	.domain_free = exynos_iommu_domain_free,
@@ -1157,6 +1184,7 @@ static struct iommu_ops exynos_iommu_ops = {
 	.add_device = exynos_iommu_add_device,
 	.remove_device = exynos_iommu_remove_device,
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
+	.of_xlate = exynos_iommu_of_xlate,
 };
 
 static bool init_done;
Signature · 1 line
1.9.2
author maintainer
#21 lore raw

PATCH v7 18/25 ARM: Exynos: pm_domains: register power domain driver from core_initcall

In reply to Marek Szyprowski

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.

---
 arch/arm/mach-exynos/pm_domains.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)
arch/arm/mach-exynos/pm_domains.c +7 -11
index a9686535f9ed..6864178e21b9 100644
@@ -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);
Signature · 1 line
1.9.2
#22 lore raw

PATCH v7 18/25 ARM: Exynos: pm_domains: register power domain driver from core_initcall

Quoted 10 lines · Marek Szyprowski

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.

---
 arch/arm/mach-exynos/pm_domains.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

Looks good:

Best regards,
Krzysztof

author maintainer
#23 lore raw

PATCH v7 19/25 ARM: dts: exynos4: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 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(+)
arch/arm/boot/dts/exynos4.dtsi +118 -0
index e20cdc24c3bb..32593a8ac7c2 100644
@@ -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>;
+	};
 };
arch/arm/boot/dts/exynos4210.dtsi +23 -0
index be89f83f70e7..19a8e711e616 100644
@@ -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>;
+	};
 };
arch/arm/boot/dts/exynos4x12.dtsi +82 -0

110 lines not on this page · raw message

Signature · 1 line
1.9.2
author maintainer
#24 lore raw

PATCH v7 20/25 ARM: dts: exynos3250: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 arch/arm/boot/dts/exynos3250.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
arch/arm/boot/dts/exynos3250.dtsi +22 -0
index e3bfb11c6ef8..36361e0cb802 100644
@@ -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>;
Signature · 1 line
1.9.2
author maintainer
#25 lore raw

PATCH v7 21/25 ARM: dts: exynos4415: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 arch/arm/boot/dts/exynos4415.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)
arch/arm/boot/dts/exynos4415.dtsi +11 -0
index 5caea996e090..7c4e44cfe75d 100644
@@ -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>;
Signature · 1 line
1.9.2
author maintainer
#26 lore raw

PATCH v7 22/25 ARM: dts: exynos5250: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 arch/arm/boot/dts/exynos5250.dtsi | 250 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 250 insertions(+)
arch/arm/boot/dts/exynos5250.dtsi +250 -0
index 257e2f10525d..96471eabeb24 100644
@@ -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>;
+	};
 };
Signature · 1 line
1.9.2
author maintainer
#27 lore raw

PATCH v7 23/25 ARM: dts: exynos5420: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 arch/arm/boot/dts/exynos5420.dtsi | 181 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 181 insertions(+)
arch/arm/boot/dts/exynos5420.dtsi +181 -0
index 45317538bbae..e93732f4fb4f 100644
@@ -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 {
@@ -562,6 +564,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 {
@@ -749,6 +753,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>;
 	};
 
@@ -759,6 +764,7 @@
 		clocks = <&clock CLK_GSCL0>;
 		clock-names = "gscl";
 		power-domains = <&gsc_pd>;
+		iommus = <&sysmmu_gscl0>;
 	};
 
 	gsc_1: video-scaler at 13e10000 {
@@ -768,6 +774,7 @@
 		clocks = <&clock CLK_GSCL1>;
 		clock-names = "gscl";
 		power-domains = <&gsc_pd>;
+		iommus = <&sysmmu_gscl1>;
 	};
 
 	pmu_system_controller: system-controller at 10040000 {
@@ -962,4 +969,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>;
+	};
 };
Signature · 1 line
1.9.2
author maintainer
#28 lore raw

PATCH v7 24/25 ARM: DMA-mapping: add support for creating reserved mappings in iova space

In reply to Marek Szyprowski

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

---
 Documentation/devicetree/bindings/iommu/iommu.txt |  44 ++++++++
 arch/arm/mm/dma-mapping.c                         | 121 ++++++++++++++++++++++
 2 files changed, 165 insertions(+)
Documentation/devicetree/bindings/iommu/iommu.txt +44 -0
index 5a8b4624defc..da620d1ff976 100644
@@ -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 between 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:
 ----------------------------------------------
 
arch/arm/mm/dma-mapping.c +121 -0

139 lines not on this page · raw message

Signature · 1 line
1.9.2
author maintainer
#29 lore raw

PATCH v7 25/25 ARM: dts: exynos: add iommu reserved regions for bootloader's splash screen

In reply to Marek Szyprowski

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.

---
 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(+)
arch/arm/boot/dts/exynos3250-rinato.dts +1 -0
index 0b9906880c0c..71641f47f6bb 100644
@@ -203,6 +203,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x40000000 0x40000000 0x1ff00000>;
 
 	i80-if-timings {
 		cs-setup = <0>;
arch/arm/boot/dts/exynos4210-trats.dts +1 -0
index 32c5fd8f6269..becc84b881a6 100644
@@ -424,6 +424,7 @@
 
 	fimd at 11c00000 {
 		status = "okay";
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x40000000>;
 	};
 
 	tmu at 100C0000 {
arch/arm/boot/dts/exynos4210-universal_c210.dts +1 -0
index d4f2b11319dd..ecc95263ff4c 100644
@@ -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>;
arch/arm/boot/dts/exynos4412-trats2.dts +1 -0
index 173ffa479ad3..78532629f396 100644
@@ -758,6 +758,7 @@
 
 	fimd at 11c00000 {
 		status = "okay";
+		iommu-reserved-mapping = <0x40000000 0x40000000 0x40000000>;
 	};
 
 	camera: camera {
arch/arm/boot/dts/exynos5250-snow.dts +1 -0
index 1eca97ee4bd6..236b953077ac 100644
@@ -286,6 +286,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x40000000 0x40000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
arch/arm/boot/dts/exynos5250-spring.dts +1 -0
index d03f9b8d376d..334d98925d4b 100644
@@ -84,6 +84,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x40000000 0x40000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
arch/arm/boot/dts/exynos5420-peach-pit.dts +1 -0
index 146e71118a72..72442e120d46 100644
@@ -166,6 +166,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x20000000 0x20000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
arch/arm/boot/dts/exynos5800-peach-pi.dts +1 -0
index 02eb8b15374f..005d2941be93 100644
@@ -153,6 +153,7 @@
 
 &fimd {
 	status = "okay";
+	iommu-reserved-mapping = <0x20000000 0x20000000 0x80000000>;
 	samsung,invert-vclk;
 };
 
Signature · 1 line
1.9.2
#30 lore raw

v7 cover Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem

In reply to Marek Szyprowski

Hello Marek,

Quoted 21 lines · Marek Szyprowski

Hello Everyone,

This is yet another attempt to get Exynos SYSMMU driver with integrated with IOMMU & DMA-mapping subsystems. This version includes minor fixes suggested by Joerg Roedel, Cho KyongHo and Robin Murphy.

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

My plan for merging this patchset is as follows:
- DTS changes and power domain changes should go via Samsung tree to avoid conflicts with other pending DTS patches
- all exynos-iommu patches and dma-mapping/reserved iommu region should go via IOMMU tree,
- all Exynos DRM patches should go via DRM/Exynos tree.

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

Quoted 7 lines

There are knowns issues with Exynos DRM driver and IOMMU support (i.e. Xorg freeze reported by Javier Martinez Canillas:
http://www.spinics.net/lists/linux-samsung-soc/msg44350.html ). They will be handled by a separate fixes to Exynos DRM drivers. This patchset fixes only those issues in Exynos DRM FIMD driver, which prevents booting to console.

I tested your v7 using exynos_defconfig + CONFIG_EXYNOS_IOMMU on both Exynos5250 Snow and Exynos5420 Peach Pit Chromebooks.

I can only reproduce the complete system hang on Xorg if I use the xf86-video-armsoc DDX. If I use the -fbdev DDX instead, X starts correctly and the system does not freeze. Also, this only happens on Exynos5420 Peach Pit, Exynos5250 Snow is working correctly even when using the -armsoc DDX.

So as you said, this is a separate issue with the Exynos DRM driver IOMMU support and is not related to your series. For the whole series:

Best regards,
Javier

#31 lore raw

v7 cover Exynos SYSMMU (IOMMU) integration with DT andDMA-mapping subsystem

Quoted 42 lines · Javier Martinez Canillas

Hello Marek,

Quoted 21 lines · Marek Szyprowski

Hello Everyone,

This is yet another attempt to get Exynos SYSMMU driver with integrated with IOMMU & DMA-mapping subsystems. This version includes minor fixes suggested by Joerg Roedel, Cho KyongHo and Robin Murphy.

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

My plan for merging this patchset is as follows:
- DTS changes and power domain changes should go via Samsung tree to avoid conflicts with other pending DTS patches
- all exynos-iommu patches and dma-mapping/reserved iommu region should go via IOMMU tree,
- all Exynos DRM patches should go via DRM/Exynos tree.

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

Quoted 7 lines

There are knowns issues with Exynos DRM driver and IOMMU support (i.e. Xorg freeze reported by Javier Martinez Canillas:
http://www.spinics.net/lists/linux-samsung-soc/msg44350.html ). They will be handled by a separate fixes to Exynos DRM drivers. This patchset fixes only those issues in Exynos DRM FIMD driver, which prevents booting to console.

I tested your v7 using exynos_defconfig + CONFIG_EXYNOS_IOMMU on both Exynos5250 Snow and Exynos5420 Peach Pit Chromebooks.

I can only reproduce the complete system hang on Xorg if I use the xf86-video-armsoc DDX. If I use the -fbdev DDX instead, X starts correctly and the system does not freeze. Also, this only happens on Exynos5420 Peach Pit, Exynos5250 Snow is working correctly even when using the -armsoc DDX.

Quoted 5 lines

So as you said, this is a separate issue with the Exynos DRM driver IOMMU support and is not related to your series. For the whole series:

Thanks for your test on the boards.

I'll sort out the arch/ side changes into samsung tree in this weekend.

- Kukjin

#32 lore raw

v7 cover Exynos SYSMMU (IOMMU) integration with DT andDMA-mapping subsystem

Quoted 43 lines · Kukjin Kim
Quoted 42 lines · Javier Martinez Canillas

Hello Marek,

Quoted 21 lines · Marek Szyprowski

Hello Everyone,

This is yet another attempt to get Exynos SYSMMU driver with integrated with IOMMU & DMA-mapping subsystems. This version includes minor fixes suggested by Joerg Roedel, Cho KyongHo and Robin Murphy.

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

My plan for merging this patchset is as follows:
- DTS changes and power domain changes should go via Samsung tree to avoid conflicts with other pending DTS patches
- all exynos-iommu patches and dma-mapping/reserved iommu region should go via IOMMU tree,
- all Exynos DRM patches should go via DRM/Exynos tree.

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

Quoted 7 lines

There are knowns issues with Exynos DRM driver and IOMMU support (i.e. Xorg freeze reported by Javier Martinez Canillas:
http://www.spinics.net/lists/linux-samsung-soc/msg44350.html ). They will be handled by a separate fixes to Exynos DRM drivers. This patchset fixes only those issues in Exynos DRM FIMD driver, which prevents booting to console.

I tested your v7 using exynos_defconfig + CONFIG_EXYNOS_IOMMU on both Exynos5250 Snow and Exynos5420 Peach Pit Chromebooks.

I can only reproduce the complete system hang on Xorg if I use the xf86-video-armsoc DDX. If I use the -fbdev DDX instead, X starts correctly and the system does not freeze. Also, this only happens on Exynos5420 Peach Pit, Exynos5250 Snow is working correctly even when using the -armsoc DDX.

Quoted 8 lines
Quoted 5 lines

So as you said, this is a separate issue with the Exynos DRM driver IOMMU support and is not related to your series. For the whole series:

Thanks for your test on the boards.

I'll sort out the arch/ side changes into samsung tree in this weekend.

Hi Kukjin,

How is the progress of sorting out this patchset? There will be some conflicts between this and DTS-label-rework so maybe you want something to be rebased?

Best regards,
Krzysztpf

maintainer Applied
#33 lore raw

v7 cover Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem

In reply to Marek Szyprowski
Quoted 23 lines · Marek Szyprowski

Marek Szyprowski (25):
drm/exynos: iommu: detach from default dma-mapping domain on init drm/exynos: fimd: ensure proper hw state in fimd_clear_channel()
iommu: Init iommu-groups support earlier, in core_initcall iommu/exynos: Don't read version register on every tlb operation iommu/exynos: Remove unused functions
iommu/exynos: Remove useless members from exynos_iommu_owner structure iommu/exynos: Refactor function parameters to simplify code iommu/exynos: Rename variables to reflect their purpose iommu/exynos: Use struct exynos_iommu_domain in internal structures iommu/exynos: Remove excessive includes and sort others alphabetically iommu/exynos: Document internal structures
iommu/exynos: Add/remove callbacks should fail if no iommu is
available
iommu/exynos: Add support for binding more than one sysmmu to master
device
iommu/exynos: Add support for runtime_pm
iommu/exynos: Add system suspend/resume support iommu/exynos: Init from dt-specific callback instead of initcall iommu/exynos: Add callback for initializing devices from device tree
ARM: Exynos: pm_domains: register power domain driver from
core_initcall
ARM: dts: exynos4: add sysmmu nodes

Quoted 8 lines

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: DMA-mapping: add support for creating reserved mappings in iova
space
ARM: dts: exynos: add iommu reserved regions for bootloader's splash
screen

Applied patches 3-17 to arm/exynos, thanks.

author maintainer
#34 lore raw

cover Exynos SYSMMU (IOMMU) dts and arch updates

In reply to Marek Szyprowski

Hello,

Main changes for Exynos SYSMMU (IOMMU) driver has been finally scheduled for merging - see
https://git.kernel.org/cgit/linux/kernel/git/joro/iommu.git/commit/?h=next
In meantime there have been quite a lot of changes related to Exynos DTS files queued for merging and my patches don't apply anymore. To ease merge process I've decided to rebased all Exynos SYSMMU dts changes onto latest exynos next tree from: https://github.com/krzk/linux dt-for-next

While rebasing I've fixes a few spotted issues: some nodes still used old 'samsung,power-domain' properties (now replaced with 'power-domains') and added properties to jpeg codec merged recently.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland

Marek Szyprowski (6):
ARM: Exynos: pm_domains: register power domain driver from
core_initcall
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

 arch/arm/boot/dts/exynos3250.dtsi |  33 +++++
 arch/arm/boot/dts/exynos4.dtsi    | 118 ++++++++++++++++++
 arch/arm/boot/dts/exynos4210.dtsi |  23 ++++
 arch/arm/boot/dts/exynos4415.dtsi |  11 ++
 arch/arm/boot/dts/exynos4x12.dtsi |  82 +++++++++++++
 arch/arm/boot/dts/exynos5250.dtsi | 250 ++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/exynos5420.dtsi | 183 ++++++++++++++++++++++++++++
 arch/arm/mach-exynos/pm_domains.c |  25 ++--
 8 files changed, 707 insertions(+), 18 deletions(-)
Signature · 1 line
1.9.2
author maintainer
#35 lore raw

PATCH 1/6 ARM: Exynos: pm_domains: register power domain driver from core_initcall

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.

---
 arch/arm/mach-exynos/pm_domains.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)
arch/arm/mach-exynos/pm_domains.c +7 -18
index 1639645bddeb..6001f1c9d136 100644
@@ -121,22 +121,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);
-		if (!pdev) {
-			pr_err("%s: failed to find device for node %s\n",
-					__func__, np->name);
-			of_node_put(np);
-			continue;
-		}
-		dev = &pdev->dev;
 
 		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 		if (!pd) {
@@ -145,8 +134,8 @@ static __init int exynos4_pm_init_power_domain(void)
 			of_node_put(np);
 			return -ENOMEM;
 		}
-
-		pd->pd.name = kstrdup(dev_name(dev), GFP_KERNEL);
+		pd->pd.name = kstrdup_const(strrchr(np->full_name, '/') + 1,
+					    GFP_KERNEL);
 		if (!pd->pd.name) {
 			kfree(pd);
 			of_node_put(np);
@@ -156,7 +145,7 @@ static __init int exynos4_pm_init_power_domain(void)
 		pd->name = pd->pd.name;
 		pd->base = of_iomap(np, 0);
 		if (!pd->base) {
-			dev_warn(&pdev->dev, "Failed to map memory\n");
+			pr_warn("%s: failed to map memory\n", __func__);
 			kfree(pd->pd.name);
 			kfree(pd);
 			of_node_put(np);
@@ -170,12 +159,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;
 
@@ -183,7 +172,7 @@ 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;
 			/*
@@ -234,4 +223,4 @@ next_pd:
 
 	return 0;
 }
-arch_initcall(exynos4_pm_init_power_domain);
+core_initcall(exynos4_pm_init_power_domain);
Signature · 1 line
1.9.2
author maintainer
#36 lore raw

PATCH 2/6 ARM: dts: exynos4: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 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(+)
arch/arm/boot/dts/exynos4.dtsi +118 -0
index 3ae22ee32cab..f716e2b7d0b9 100644
@@ -189,6 +189,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc0>;
 			status = "disabled";
 		};
 
@@ -200,6 +201,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc1>;
 			status = "disabled";
 		};
 
@@ -211,6 +213,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc2>;
 			status = "disabled";
 		};
 
@@ -222,6 +225,7 @@
 			clock-names = "fimc", "sclk_fimc";
 			power-domains = <&pd_cam>;
 			samsung,sysreg = <&sys_reg>;
+			iommus = <&sysmmu_fimc3>;
 			status = "disabled";
 		};
 
@@ -416,6 +420,8 @@
 		power-domains = <&pd_mfc>;
 		clocks = <&clock CLK_MFC>, <&clock CLK_SCLK_MFC>;
 		clock-names = "mfc", "sclk_mfc";
+		iommus = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+		iommu-names = "left", "right";
 		status = "disabled";
 	};
 
@@ -680,6 +686,7 @@
 		clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
 		clock-names = "sclk_fimd", "fimd";
 		power-domains = <&pd_lcd0>;
+		iommus = <&sysmmu_fimd0>;
 		samsung,sysreg = <&sys_reg>;
 		status = "disabled";
 	};
@@ -717,6 +724,7 @@
 		interrupts = <0 91 0>;
 		reg = <0x12C10000 0x2100>, <0x12c00000 0x300>;
 		power-domains = <&pd_tv>;
+		iommus = <&sysmmu_tv>;
 		status = "disabled";
 	};
 
@@ -827,4 +835,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>;
+	};
 };
arch/arm/boot/dts/exynos4210.dtsi +23 -0
index a9a55304e31a..10d3c173396e 100644
@@ -173,6 +173,7 @@
 		interrupts = <0 89 0>;
 		clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
 		clock-names = "sclk_fimg2d", "fimg2d";
+		iommus = <&sysmmu_g2d>;
 		status = "disabled";
 	};
 
@@ -222,6 +223,28 @@
 		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>;
+	};
 };
 
 &gic {
arch/arm/boot/dts/exynos4x12.dtsi +82 -0

112 lines not on this page · raw message

Signature · 1 line
1.9.2
author maintainer
#37 lore raw

PATCH 3/6 ARM: dts: exynos3250: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 arch/arm/boot/dts/exynos3250.dtsi | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
arch/arm/boot/dts/exynos3250.dtsi +33 -0
index 4728c77ed6e4..d7201333e3bc 100644
@@ -253,9 +253,20 @@
 			assigned-clocks = <&cmu CLK_MOUT_CAM_BLK>, <&cmu CLK_SCLK_JPEG>;
 			assigned-clock-rates = <0>, <150000000>;
 			assigned-clock-parents = <&cmu CLK_DIV_MPLL_PRE>;
+			iommus = <&sysmmu_jpeg>;
 			status = "disabled";
 		};
 
+		sysmmu_jpeg: sysmmu at 11A60000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11a60000 0x1000>;
+			interrupts = <0 156 0>, <0 161 0>;
+			clock-names = "sysmmu", "master";
+			clocks = <&cmu CLK_SMMUJPEG>, <&cmu CLK_JPEG>;
+			power-domains = <&pd_cam>;
+			#iommu-cells = <0>;
+		};
+
 		fimd: fimd at 11c00000 {
 			compatible = "samsung,exynos3250-fimd";
 			reg = <0x11c00000 0x30000>;
@@ -264,6 +275,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";
 		};
@@ -283,6 +295,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>;
+			power-domains = <&pd_lcd0>;
+			#iommu-cells = <0>;
+		};
+
 		hsotg: hsotg at 12480000 {
 			compatible = "snps,dwc2";
 			reg = <0x12480000 0x20000>;
@@ -377,9 +399,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>;
+			power-domains = <&pd_mfc>;
+			#iommu-cells = <0>;
+		};
+
 		serial_0: serial at 13800000 {
 			compatible = "samsung,exynos4210-uart";
 			reg = <0x13800000 0x100>;
Signature · 1 line
1.9.2
author maintainer
#38 lore raw

PATCH 4/6 ARM: dts: exynos4415: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 arch/arm/boot/dts/exynos4415.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)
arch/arm/boot/dts/exynos4415.dtsi +11 -0
index 6a83d7999d8a..ad764842fff5 100644
@@ -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>;
+			power-domains = <&pd_lcd0>;
+			#iommu-cells = <0>;
+		};
+
 		hsotg: hsotg at 12480000 {
 			compatible = "samsung,s3c6400-hsotg";
 			reg = <0x12480000 0x20000>;
Signature · 1 line
1.9.2
author maintainer
#39 lore raw

PATCH 5/6 ARM: dts: exynos5250: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 arch/arm/boot/dts/exynos5250.dtsi | 250 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 250 insertions(+)
arch/arm/boot/dts/exynos5250.dtsi +250 -0
index 916871bb3f05..bf9bee67c416 100644
@@ -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";
 	};
 
 	tmu: tmu at 10060000 {
@@ -693,6 +696,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL0>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc0>;
 	};
 
 	gsc_1:  gsc at 13e10000 {
@@ -702,6 +706,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL1>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc1>;
 	};
 
 	gsc_2:  gsc at 13e20000 {
@@ -711,6 +716,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL2>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc2>;
 	};
 
 	gsc_3:  gsc at 13e30000 {
@@ -720,6 +726,7 @@
 		power-domains = <&pd_gsc>;
 		clocks = <&clock CLK_GSCL3>;
 		clock-names = "gscl";
+		iommu = <&sysmmu_gsc3>;
 	};
 
 	hdmi: hdmi {
@@ -743,6 +750,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 {
@@ -770,6 +778,247 @@
 		clocks = <&clock CLK_SSS>;
 		clock-names = "secss";
 	};
+
+	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_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_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>;
+	};
+
+	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_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_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>;
+	};
 };
 
 &dp {
@@ -784,6 +1033,7 @@
 	power-domains = <&pd_disp1>;
 	clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
 	clock-names = "sclk_fimd", "fimd";
+	iommus = <&sysmmu_fimd1>;
 };
 
 &rtc {
Signature · 1 line
1.9.2
author maintainer
#40 lore raw

PATCH 6/6 ARM: dts: exynos5420: add sysmmu nodes

In reply to Marek Szyprowski

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

---
 arch/arm/boot/dts/exynos5420.dtsi | 183 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 183 insertions(+)
arch/arm/boot/dts/exynos5420.dtsi +183 -0
index d0be412dfbea..534f27ceb10b 100644
@@ -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 {
@@ -713,6 +715,7 @@
 			 <&clock CLK_SCLK_HDMI>;
 		clock-names = "mixer", "hdmi", "sclk_hdmi";
 		power-domains = <&disp_pd>;
+		iommus = <&sysmmu_tv>;
 	};
 
 	gsc_0: video-scaler at 13e00000 {
@@ -722,6 +725,7 @@
 		clocks = <&clock CLK_GSCL0>;
 		clock-names = "gscl";
 		power-domains = <&gsc_pd>;
+		iommus = <&sysmmu_gscl0>;
 	};
 
 	gsc_1: video-scaler at 13e10000 {
@@ -731,6 +735,7 @@
 		clocks = <&clock CLK_GSCL1>;
 		clock-names = "gscl";
 		power-domains = <&gsc_pd>;
+		iommus = <&sysmmu_gscl1>;
 	};
 
 	jpeg_0: jpeg at 11F50000 {
@@ -739,6 +744,7 @@
 		interrupts = <0 89 0>;
 		clock-names = "jpeg";
 		clocks = <&clock CLK_JPEG>;
+		iommus = <&sysmmu_jpeg0>;
 	};
 
 	jpeg_1: jpeg at 11F60000 {
@@ -747,6 +753,7 @@
 		interrupts = <0 168 0>;
 		clock-names = "jpeg";
 		clocks = <&clock CLK_JPEG2>;
+		iommus = <&sysmmu_jpeg1>;
 	};
 
 	pmu_system_controller: system-controller at 10040000 {
@@ -941,6 +948,180 @@
 		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>;
+		power-domains = <&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_jpeg0: 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_jpeg1: 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>;
+		power-domains = <&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>;
+		power-domains = <&disp_pd>;
+		#iommu-cells = <0>;
+	};
 };
 
 &dp {
@@ -955,6 +1136,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";
 };
 
 &rtc {
Signature · 1 line
1.9.2
#41 lore raw

Exynos 5410 support (was [PATCH 6/6] ARM: dts: exynos5420: add sysmmu nodes)

Quoted 2 lines · Marek Szyprowski

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

Apologies in advance if Thunderbird mangles this message; my usual mail configuration has suffered an unfortunate run-in with a mug of tea.

As someone who has devoted a few weekends trying to make the mainline kernel usable on an Odroid XU2, I can't help but notice that nearly every patchset that has hit this list recently excludes the Exynos 541x devices, including series which appear to go out of their way to support older devices. I would attribute this to the lack of publicly accessible documentation, but many of these patches are coming from Samsung employees. Worse, the few patches that have been submitted for the 5410 have languished in queue-purgatory. What is going on with support for this silicon?

These devices really aren't that old but if Samsung insists that they aren't worth putting engineering time towards then perhaps they could at least release documentation? The Hardkernel folks are on the record[2] as saying there was a document under review. Perhaps this document could be quickly trimmed into a disclosable state? Even a quick-and-dirty documentation release would help my efforts substantially.

Cheers,

- Ben

[1] https://github.com/bgamari/linux/commits/odroid-3.19
[2] http://forum.odroid.com/viewtopic.php?f=65&t=1932#p20457

#42 lore raw

Exynos 5410 support (was [PATCH 6/6] ARM: dts: exynos5420: add sysmmu nodes)

2015-06-02 4:12 GMT+09:00 Ben Gamari <[email protected]>:

Quoted 6 lines · Marek Szyprowski
Quoted 3 lines

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

(...)

Quoted 2 lines

Worse, the few patches
that have been submitted for the 5410 have languished in queue-purgatory.

What patches do you have in mind?

Beside of that actually many submissions for different Exynos SoCs and parts of it were ignored on the list. It is a pity because that means someone's effort got lost.
Recently I tried to help in that matter and replied to some emails about resubmitting. If you have anything pending just please let me know.

To make it clear - I am speaking for myself, not for any company or employer. Also I do not know anything about other people's motivation behind doing patches only for chosen SoCs. I leave these questions to them.

Best regards,
Krzysztof

#43 lore raw

Exynos 5410 support (was [PATCH 6/6] ARM: dts: exynos5420: add sysmmu nodes)

Quoted 6 lines · Krzysztof Koz?owski

2015-06-02 4:12 GMT+09:00 Ben Gamari <[email protected]>:
(...)

Quoted 2 lines

Worse, the few patches
that have been submitted for the 5410 have languished in queue-purgatory.

What patches do you have in mind?

Hmm, my apologies; I guess the reference was dropped somewhere. In particular I was referring to this set[1], which added pinctrl support for the 5410 and a devicetree for the Odroid XU.

Cheers,

- Ben

[1]
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/330819.html

#44 lore raw

Exynos 5410 support (was [PATCH 6/6] ARM: dts: exynos5420: add sysmmu nodes)

2015-06-02 17:13 GMT+09:00 Ben Gamari <[email protected]>:

Quoted 7 lines · Krzysztof Koz?owski
Quoted 4 lines

2015-06-02 4:12 GMT+09:00 Ben Gamari <[email protected]>:
(...)

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

Worse, the few patches
that have been submitted for the 5410 have languished in queue-purgatory.

What patches do you have in mind?

Hmm, my apologies; I guess the reference was dropped somewhere. In particular I was referring to this set[1], which added pinctrl support for the 5410 and a devicetree for the Odroid XU.

Thanks. I will take a look at them.

If you have any other stuff which was missed/skipped/ignored, don't hesitate to resend (if you're the author) or ping.

Best regards,
Krzysztof

Quoted 8 lines

Cheers,

- Ben

[1]
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/330819.html

#45 lore raw

Exynos 5410 support (was [PATCH 6/6] ARM: dts: exynos5420: add sysmmu nodes)

In reply to Ben Gamari
Quoted 17 lines · Ben Gamari
Quoted 2 lines · Marek Szyprowski

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

Apologies in advance if Thunderbird mangles this message; my usual mail configuration has suffered an unfortunate run-in with a mug of tea.

As someone who has devoted a few weekends trying to make the mainline kernel usable on an Odroid XU2, I can't help but notice that nearly every patchset that has hit this list recently excludes the Exynos 541x devices, including series which appear to go out of their way to support older devices. I would attribute this to the lack of publicly accessible documentation, but many of these patches are coming from Samsung employees. Worse, the few patches that have been submitted for the 5410 have languished in queue-purgatory. What is going on with support for this silicon?

Quoted 7 lines

These devices really aren't that old but if Samsung insists that they aren't worth putting engineering time towards then perhaps they could at least release documentation? The Hardkernel folks are on the record[2] as saying there was a document under review. Perhaps this document could be quickly trimmed into a disclosable state? Even a quick-and-dirty documentation release would help my efforts substantially.

Could someone from Samsung please provide some sort of feedback here? It would be greatly appreciated.

Thanks,

- Ben

#46 lore raw

cover Exynos SYSMMU (IOMMU) dts and arch updates

In reply to Marek Szyprowski

W dniu 01.06.2015 o 19:10, Marek Szyprowski pisze:

Quoted 10 lines

Hello,

Main changes for Exynos SYSMMU (IOMMU) driver has been finally scheduled for merging - see
https://git.kernel.org/cgit/linux/kernel/git/joro/iommu.git/commit/?h=next
In meantime there have been quite a lot of changes related to Exynos DTS files queued for merging and my patches don't apply anymore. To ease merge process I've decided to rebased all Exynos SYSMMU dts changes onto latest exynos next tree from: https://github.com/krzk/linux dt-for-next

Quoted 4 lines

While rebasing I've fixes a few spotted issues: some nodes still used old 'samsung,power-domain' properties (now replaced with 'power-domains') and added properties to jpeg codec merged recently.

Thanks for rebasing this stuff.

I picked whole patchset with Javier's tested-by. I'll send it to Kukjin later or directly to arm-soc (depending what will happen with last pull request).

Kukjin, you mentioned that you will do something with this patchset the previous weekend. Since then nothing happened so I am not sure what are your plans... Can you share them? Do you want to pick it by yourself, do you have any comments or maybe you need something from our side? (I checked the patches and they look fine)

Best regards,
Krzysztof

#47 lore raw

cover Exynos SYSMMU (IOMMU) dts and arch updates

Quoted 11 lines · Krzysztof Kozlowski

W dniu 01.06.2015 o 19:10, Marek Szyprowski pisze:

Quoted 10 lines

Hello,

Main changes for Exynos SYSMMU (IOMMU) driver has been finally scheduled for merging - see
https://git.kernel.org/cgit/linux/kernel/git/joro/iommu.git/commit/?h=next
In meantime there have been quite a lot of changes related to Exynos DTS files queued for merging and my patches don't apply anymore. To ease merge process I've decided to rebased all Exynos SYSMMU dts changes onto latest exynos next tree from: https://github.com/krzk/linux dt-for-next

Quoted 7 lines
Quoted 4 lines

While rebasing I've fixes a few spotted issues: some nodes still used old 'samsung,power-domain' properties (now replaced with 'power-domains') and added properties to jpeg codec merged recently.

Thanks for rebasing this stuff.

Same here ;-)

Quoted 10 lines

I picked whole patchset with Javier's tested-by. I'll send it to Kukjin later or directly to arm-soc (depending what will happen with last pull request).

Kukjin, you mentioned that you will do something with this patchset the previous weekend. Since then nothing happened so I am not sure what are your plans... Can you share them? Do you want to pick it by yourself, do you have any comments or maybe you need something from our side? (I checked the patches and they look fine)

Done, thanks.

- Kukjin

#48 lore raw

cover Exynos SYSMMU (IOMMU) dts and arch updates

Quoted 25 lines · Kukjin Kim
Quoted 11 lines · Krzysztof Kozlowski

W dniu 01.06.2015 o 19:10, Marek Szyprowski pisze:

Quoted 10 lines

Hello,

Main changes for Exynos SYSMMU (IOMMU) driver has been finally scheduled for merging - see
https://git.kernel.org/cgit/linux/kernel/git/joro/iommu.git/commit/?h=next
In meantime there have been quite a lot of changes related to Exynos DTS files queued for merging and my patches don't apply anymore. To ease merge process I've decided to rebased all Exynos SYSMMU dts changes onto latest exynos next tree from: https://github.com/krzk/linux dt-for-next

Quoted 7 lines
Quoted 4 lines

While rebasing I've fixes a few spotted issues: some nodes still used old 'samsung,power-domain' properties (now replaced with 'power-domains') and added properties to jpeg codec merged recently.

Thanks for rebasing this stuff.

Same here ;-)

Quoted 4 lines

I picked whole patchset with Javier's tested-by. I'll send it to Kukjin later or directly to arm-soc (depending what will happen with last pull request).

Quoted 7 lines
Quoted 6 lines

Kukjin, you mentioned that you will do something with this patchset the previous weekend. Since then nothing happened so I am not sure what are your plans... Can you share them? Do you want to pick it by yourself, do you have any comments or maybe you need something from our side? (I checked the patches and they look fine)

Done, thanks.

Thank you, I tested the for-next branch on some of my boards and everything looked fine.

Best regards,
Krzysztof

#49 lore raw

cover Exynos SYSMMU (IOMMU) dts and arch updates

Quoted 32 lines · Krzysztof Kozlowski
Quoted 31 lines · Kukjin Kim
Quoted 11 lines · Krzysztof Kozlowski

W dniu 01.06.2015 o 19:10, Marek Szyprowski pisze:

Quoted 10 lines

Hello,

Main changes for Exynos SYSMMU (IOMMU) driver has been finally scheduled for merging - see
https://git.kernel.org/cgit/linux/kernel/git/joro/iommu.git/commit/?h=next
In meantime there have been quite a lot of changes related to Exynos DTS files queued for merging and my patches don't apply anymore. To ease merge process I've decided to rebased all Exynos SYSMMU dts changes onto latest exynos next tree from: https://github.com/krzk/linux dt-for-next

Quoted 7 lines
Quoted 4 lines

While rebasing I've fixes a few spotted issues: some nodes still used old 'samsung,power-domain' properties (now replaced with 'power-domains') and added properties to jpeg codec merged recently.

Thanks for rebasing this stuff.

Same here ;-)

Quoted 10 lines

I picked whole patchset with Javier's tested-by. I'll send it to Kukjin later or directly to arm-soc (depending what will happen with last pull request).

Kukjin, you mentioned that you will do something with this patchset the previous weekend. Since then nothing happened so I am not sure what are your plans... Can you share them? Do you want to pick it by yourself, do you have any comments or maybe you need something from our side? (I checked the patches and they look fine)

Quoted 4 lines
Quoted 1 line

Done, thanks.

Thank you, I tested the for-next branch on some of my boards and everything looked fine.

Oh, something wrong happened on some of configs/boards:

Arndale Octa: multi_v7_defconfig
Last tests on samsung tree fail:
1.
http://kernelci.org/boot/exynos5420-arndale-octa_rootfs:nfs/job/samsung/kernel/v4.1-rc6-146-g1c07c562d9d5/defconfig/multi_v7_defconfig/lab/lab-tbaker/?_id=556fbaee59b5146b5cda4447
2.
http://kernelci.org/boot/exynos5420-arndale-octa_rootfs:nfs/job/samsung/kernel/v4.1-rc6-137-g1730fe10f4a8/defconfig/multi_v7_defconfig/lab/lab-tbaker/?_id=556e948659b5144e74da4445

Odroid XU3: multi_v7_defconfig
Last commit fails:
http://kernelci.org/boot/exynos5422-odroidxu3_rootfs:nfs/job/samsung/kernel/v4.1-rc6-146-g1c07c562d9d5/defconfig/multi_v7_defconfig/lab/lab-tbaker/?_id=556fbb2d59b5146b63da4449

I can test tonight on Odroid XU3 but I don't have access to Arndale Octa board. Maybe guys from SRPOL could test it?

Best regards,
Krzysztof