Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1292155 > unrolled thread

[PATCH/RFC 00/10] iommu/ipmmu-vmsa: Experimental r8a7795 support

Started byMagnus Damm <magnus.damm@gmail.com>
First post2015-12-15 14:10 +0100
Last post2015-12-15 14:10 +0100
Articles 3 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH/RFC 00/10] iommu/ipmmu-vmsa: Experimental r8a7795 support Magnus Damm <magnus.damm@gmail.com> - 2015-12-15 14:10 +0100
    [PATCH/RFC 07/10] iommu/ipmmu-vmsa: Break out utlb parsing code Magnus Damm <magnus.damm@gmail.com> - 2015-12-15 14:10 +0100
    [PATCH/RFC 03/10] iommu/ipmmu-vmsa: Write IMCTR twice Magnus Damm <magnus.damm@gmail.com> - 2015-12-15 14:10 +0100

#1292155 — [PATCH/RFC 00/10] iommu/ipmmu-vmsa: Experimental r8a7795 support

FromMagnus Damm <magnus.damm@gmail.com>
Date2015-12-15 14:10 +0100
Subject[PATCH/RFC 00/10] iommu/ipmmu-vmsa: Experimental r8a7795 support
Message-ID<qFXwC-4x8-13@gated-at.bofh.it>
iommu/ipmmu-vmsa: Experimental r8a7795 support

[PATCH/RFC 01/10] iommu/ipmmu-vmsa: Introduce features, break out alias
[PATCH/RFC 02/10] iommu/ipmmu-vmsa: Add optional root device feature
[PATCH/RFC 03/10] iommu/ipmmu-vmsa: Write IMCTR twice
[PATCH/RFC 04/10] iommu/ipmmu-vmsa: Make IMBUSCTR setup optional
[PATCH/RFC 05/10] iommu/ipmmu-vmsa: Allow two bit SL0
[PATCH/RFC 06/10] iommu/ipmmu-vmsa: Also use IOMMU_OF_DECLARE()
[PATCH/RFC 07/10] iommu/ipmmu-vmsa: Break out utlb parsing code
[PATCH/RFC 08/10] iommu/ipmmu-vmsa: Break out domain allocation code
[PATCH/RFC 09/10] iommu/ipmmu-vmsa: Add new IOMMU_DOMAIN_DMA ops
[PATCH/RFC 10/10] iommu/ipmmu-vmsa: Hook up r8a7795 DT matching code

Add experimental r8a7795 support for the IPMMU driver. At this point
the code is in rather early stages of development and not ready for
upstream merge. The DT binding is undocumented and will change.

The r8a7795 IPMMU is almost register compatible with earlier devices
like r8a7790-r8a7794, however some bitfields have been shifted
slightly. On a grander scale topology has been added and interrupts
have been reworked. So now there are several "cache" IPMMU units
without interrupt that somehow communicate with IPMMU-MM that
is the only instance that supports interrupts. The code refers to
IPMMU-MM as a "root" device and the other ones as leaf nodes.
In the future the plan is to use DT to describe the relationship.

To make this more interesting the IPMMU driver needs to be shared
between 32-bit ARM for r8a7790-r8a7794 and 64-bit ARM for r8a7795.
In practice this means that two separate implementations are needed
inside the driver to attach to the rather different architecture
specific code.

CONFIG_IOMMU_DMA=y is needed on 64-bit ARM while on 32-bit ARM
the arch specific dma-mapping code is hooked up rather directly.
During init 64-bit ARM IPMMU support is relying on IOMMU_OF_DECLARE().

The code is known to build on 32-bit and 64-bit ARM and x86_64.
Tested on 32-bit ARM and 64-bit ARM with addtional DT integration
changes.

Signed-off-by: Magnus Damm <damm+renesas@opensource.se>
---

 Developed on top of renesas-drivers-2015-12-08-v4.4-rc4 and
 [PATCH 00/06] iommu/ipmmu-vmsa: IPMMU multi-arch update

 drivers/iommu/ipmmu-vmsa.c |  438 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 344 insertions(+), 94 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1292157 — [PATCH/RFC 07/10] iommu/ipmmu-vmsa: Break out utlb parsing code

FromMagnus Damm <magnus.damm@gmail.com>
Date2015-12-15 14:10 +0100
Subject[PATCH/RFC 07/10] iommu/ipmmu-vmsa: Break out utlb parsing code
Message-ID<qFXwE-4x8-57@gated-at.bofh.it>
In reply to#1292155
From: Magnus Damm <damm+renesas@opensource.se>

Break out the utlb parsing code and dev_data allocation into a
separate function. This is preparation for future code sharing.

Signed-off-by: Magnus Damm <damm+renesas@opensource.se>
---

 drivers/iommu/ipmmu-vmsa.c |  126 ++++++++++++++++++++++++--------------------
 1 file changed, 70 insertions(+), 56 deletions(-)

--- 0012/drivers/iommu/ipmmu-vmsa.c
+++ work/drivers/iommu/ipmmu-vmsa.c	2015-12-14 18:56:47.020513000 +0900
@@ -607,6 +607,69 @@ static int ipmmu_find_utlbs(struct ipmmu
 	return 0;
 }
 
+static int ipmmu_init_platform_device(struct device *dev,
+				      struct iommu_group *group)
+{
+	struct ipmmu_vmsa_dev_data *dev_data;
+	struct ipmmu_vmsa_device *mmu;
+	unsigned int *utlbs;
+	unsigned int i;
+	int num_utlbs;
+	int ret = -ENODEV;
+
+	/* Find the master corresponding to the device. */
+
+	num_utlbs = of_count_phandle_with_args(dev->of_node, "iommus",
+					       "#iommu-cells");
+	if (num_utlbs < 0)
+		return -ENODEV;
+
+	utlbs = kcalloc(num_utlbs, sizeof(*utlbs), GFP_KERNEL);
+	if (!utlbs)
+		return -ENOMEM;
+
+	spin_lock(&ipmmu_devices_lock);
+
+	list_for_each_entry(mmu, &ipmmu_devices, list) {
+		ret = ipmmu_find_utlbs(mmu, dev, utlbs, num_utlbs);
+		if (!ret) {
+			/*
+			 * TODO Take a reference to the MMU to protect
+			 * against device removal.
+			 */
+			break;
+		}
+	}
+
+	spin_unlock(&ipmmu_devices_lock);
+
+	if (ret < 0)
+		goto error;
+
+	for (i = 0; i < num_utlbs; ++i) {
+		if (utlbs[i] >= mmu->num_utlbs) {
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+
+	dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
+	if (!dev_data) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	dev_data->mmu = mmu;
+	dev_data->utlbs = utlbs;
+	dev_data->num_utlbs = num_utlbs;
+	set_dev_data(dev, dev_data);
+	return 0;
+
+error:
+	kfree(utlbs);
+	return ret;
+}
+
 #ifdef CONFIG_ARM
 static int ipmmu_map_attach(struct device *dev, struct ipmmu_vmsa_device *mmu)
 {
@@ -663,56 +726,15 @@ static inline void ipmmu_release_mapping
 
 static int ipmmu_add_device(struct device *dev)
 {
-	struct ipmmu_vmsa_dev_data *dev_data = get_dev_data(dev);
-	struct ipmmu_vmsa_device *mmu;
-	struct iommu_group *group = NULL;
-	unsigned int *utlbs;
-	unsigned int i;
-	int num_utlbs;
-	int ret = -ENODEV;
+	struct iommu_group *group;
+	int ret;
 
-	if (dev_data) {
+	if (get_dev_data(dev)) {
 		dev_warn(dev, "IOMMU driver already assigned to device %s\n",
 			 dev_name(dev));
 		return -EINVAL;
 	}
 
-	/* Find the master corresponding to the device. */
-
-	num_utlbs = of_count_phandle_with_args(dev->of_node, "iommus",
-					       "#iommu-cells");
-	if (num_utlbs < 0)
-		return -ENODEV;
-
-	utlbs = kcalloc(num_utlbs, sizeof(*utlbs), GFP_KERNEL);
-	if (!utlbs)
-		return -ENOMEM;
-
-	spin_lock(&ipmmu_devices_lock);
-
-	list_for_each_entry(mmu, &ipmmu_devices, list) {
-		ret = ipmmu_find_utlbs(mmu, dev, utlbs, num_utlbs);
-		if (!ret) {
-			/*
-			 * TODO Take a reference to the MMU to protect
-			 * against device removal.
-			 */
-			break;
-		}
-	}
-
-	spin_unlock(&ipmmu_devices_lock);
-
-	if (ret < 0)
-		return -ENODEV;
-
-	for (i = 0; i < num_utlbs; ++i) {
-		if (utlbs[i] >= mmu->num_utlbs) {
-			ret = -EINVAL;
-			goto error;
-		}
-	}
-
 	/* Create a device group and add the device to it. */
 	group = iommu_group_alloc();
 	if (IS_ERR(group)) {
@@ -730,27 +752,19 @@ static int ipmmu_add_device(struct devic
 		goto error;
 	}
 
-	dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
-	if (!dev_data) {
-		ret = -ENOMEM;
+	ret = ipmmu_init_platform_device(dev, group);
+	if (ret < 0) {
+		dev_err(dev, "Failed to init platform device\n");
 		goto error;
 	}
 
-	dev_data->mmu = mmu;
-	dev_data->utlbs = utlbs;
-	dev_data->num_utlbs = num_utlbs;
-	set_dev_data(dev, dev_data);
-
-	ret = ipmmu_map_attach(dev, mmu);
+	ret = ipmmu_map_attach(dev, get_dev_data(dev)->mmu);
 	if (ret < 0)
 		goto error;
 
 	return 0;
 
 error:
-	kfree(dev_data);
-	kfree(utlbs);
-
 	set_dev_data(dev, NULL);
 
 	if (!IS_ERR_OR_NULL(group))
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1292161 — [PATCH/RFC 03/10] iommu/ipmmu-vmsa: Write IMCTR twice

FromMagnus Damm <magnus.damm@gmail.com>
Date2015-12-15 14:10 +0100
Subject[PATCH/RFC 03/10] iommu/ipmmu-vmsa: Write IMCTR twice
Message-ID<qFXwE-4x8-63@gated-at.bofh.it>
In reply to#1292155
From: Magnus Damm <damm+renesas@opensource.se>

Write IMCTR both in the root device and the leaf node.

Signed-off-by: Magnus Damm <damm+renesas@opensource.se>
---

 drivers/iommu/ipmmu-vmsa.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

--- 0014/drivers/iommu/ipmmu-vmsa.c
+++ work/drivers/iommu/ipmmu-vmsa.c	2015-12-15 14:11:05.210513000 +0900
@@ -268,6 +268,16 @@ static void ipmmu_ctx_write(struct ipmmu
 	ipmmu_write(domain->root, domain->context_id * IM_CTX_SIZE + reg, data);
 }
 
+static void ipmmu_ctx_write2(struct ipmmu_vmsa_domain *domain, unsigned int reg,
+			     u32 data)
+{
+	if (domain->mmu != domain->root)
+		ipmmu_write(domain->mmu,
+			    domain->context_id * IM_CTX_SIZE + reg, data);
+
+	ipmmu_write(domain->root, domain->context_id * IM_CTX_SIZE + reg, data);
+}
+
 /* -----------------------------------------------------------------------------
  * TLB and microTLB Management
  */
@@ -294,7 +304,7 @@ static void ipmmu_tlb_invalidate(struct
 
 	reg = ipmmu_ctx_read(domain, IMCTR);
 	reg |= IMCTR_FLUSH;
-	ipmmu_ctx_write(domain, IMCTR, reg);
+	ipmmu_ctx_write2(domain, IMCTR, reg);
 
 	ipmmu_tlb_sync(domain);
 }
@@ -442,7 +452,8 @@ static int ipmmu_domain_init_context(str
 	 * software management as we have no use for it. Flush the TLB as
 	 * required when modifying the context registers.
 	 */
-	ipmmu_ctx_write(domain, IMCTR, IMCTR_INTEN | IMCTR_FLUSH | IMCTR_MMUEN);
+	ipmmu_ctx_write2(domain, IMCTR,
+			 IMCTR_INTEN | IMCTR_FLUSH | IMCTR_MMUEN);
 
 	return 0;
 }
@@ -457,7 +468,7 @@ static void ipmmu_domain_destroy_context
 	 *
 	 * TODO: Is TLB flush really needed ?
 	 */
-	ipmmu_ctx_write(domain, IMCTR, IMCTR_FLUSH);
+	ipmmu_ctx_write2(domain, IMCTR, IMCTR_FLUSH);
 	ipmmu_tlb_sync(domain);
 }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web