Skip to contentSkip to conversation

msm: iommu: Clock control for the IOMMU driver

PATCH In review Stepan Moskovchenko 3 participants 10 messages Feb 25, 2011 – Mar 8, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/4 msm: iommu: Clock control for the IOMMU driver

Add clock control to the IOMMU driver. The IOMMU bus clock (and potentially an AXI clock) need to be on to gain access to IOMMU registers. Actively control these clocks when needed instead of leaving them on.

---
 arch/arm/mach-msm/include/mach/iommu.h |    9 ++++-
 arch/arm/mach-msm/iommu.c              |   58 ++++++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 5 deletions(-)
arch/arm/mach-msm/include/mach/iommu.h +7 -2
index 296c0f1..8738a44 100644
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
 #define MSM_IOMMU_H
 
 #include <linux/interrupt.h>
+#include <linux/clk.h>
 
 /* Sharability attributes of MSM IOMMU mappings */
 #define MSM_IOMMU_ATTR_NON_SH		0x0
@@ -74,13 +75,17 @@ struct msm_iommu_ctx_dev {
  * struct msm_iommu_drvdata - A single IOMMU hardware instance
  * @base:	IOMMU config port base address (VA)
  * @irq:	Interrupt number
-  *
+ * @clk:	The bus clock for this IOMMU hardware instance
+ * @pclk:	The clock for the IOMMU bus interconnect
+ *
  * A msm_iommu_drvdata holds the global driver data about a single piece
  * of an IOMMU hardware instance.
  */
 struct msm_iommu_drvdata {
 	void __iomem *base;
 	int irq;
+	struct clk *clk;
+	struct clk *pclk;
 };
 
 /**
arch/arm/mach-msm/iommu.c +55 -3

127 lines not on this page · raw message

--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#1 lore raw

PATCH 2/4 msm: iommu: Rework clock logic and add IOMMU bus clock control

Clean up the clock control code in the probe calls, and add support for controlling the clock for the IOMMU bus interconnect. With the (proper) clock driver in place, the clock control logic in the probe function can be made much cleaner since it does not have to deal with the placeholder driver anymore.

---
 arch/arm/mach-msm/devices-iommu.c      |    5 -
 arch/arm/mach-msm/include/mach/iommu.h |    5 -
 arch/arm/mach-msm/iommu_dev.c          |  206 +++++++++++++++++++-------------
 3 files changed, 121 insertions(+), 95 deletions(-)
arch/arm/mach-msm/devices-iommu.c +0 -5
index c0206b7..af97afe 100644
@@ -280,7 +280,6 @@ static struct platform_device msm_root_iommu_dev = {
 
 static struct msm_iommu_dev jpegd_iommu = {
 	.name = "jpegd",
-	.clk_rate = -1
 };
 
 static struct msm_iommu_dev vpe_iommu = {
@@ -305,7 +304,6 @@ static struct msm_iommu_dev ijpeg_iommu = {
 
 static struct msm_iommu_dev vfe_iommu = {
 	.name = "vfe",
-	.clk_rate = -1
 };
 
 static struct msm_iommu_dev vcodec_a_iommu = {
@@ -318,17 +316,14 @@ static struct msm_iommu_dev vcodec_b_iommu = {
 
 static struct msm_iommu_dev gfx3d_iommu = {
 	.name = "gfx3d",
-	.clk_rate = 27000000
 };
 
 static struct msm_iommu_dev gfx2d0_iommu = {
 	.name = "gfx2d0",
-	.clk_rate = 27000000
 };
 
 static struct msm_iommu_dev gfx2d1_iommu = {
 	.name = "gfx2d1",
-	.clk_rate = 27000000
 };
 
 static struct platform_device msm_device_iommu_jpegd = {
arch/arm/mach-msm/include/mach/iommu.h +0 -5
index 8738a44..4dfe7ef 100644
@@ -45,14 +45,9 @@
 /**
  * struct msm_iommu_dev - a single IOMMU hardware instance
  * name		Human-readable name given to this IOMMU HW instance
- * clk_rate	Rate to set for this IOMMU's clock, if applicable to this
- *		particular IOMMU. 0 means don't set a rate.
- *		-1 means it is an AXI clock with no valid rate
- *
  */
 struct msm_iommu_dev {
 	const char *name;
-	int clk_rate;
 };
 
 /**
arch/arm/mach-msm/iommu_dev.c +121 -85

276 lines not on this page · raw message

--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#2 lore raw

Re: [PATCH 2/4] msm: iommu: Rework clock logic and add IOMMU bus clock control

Hi Steve,

Quoted 21 lines

/**

arch/arm/mach-msm/iommu_dev.c +2 -1
index b83c73b..69acd1e 100644
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,7 @@
 
 #include <mach/iommu_hw-8xxx.h>
 #include <mach/iommu.h>
+#include <mach/clk.h>
 
 struct iommu_ctx_iter_data {
 	/* input */

arch/arm/mach-msm/iommu_dev.c static int msm_iommu_probe(struct platform_device *pdev) · line 136

Quoted 6 lines
arch/arm/mach-msm/iommu_dev.c +1 -0
@@ -130,117 +131,134 @@ static int msm_iommu_probe(struct platform_device *pdev)
 {
 	struct resource *r, *r2;
 	struct clk *iommu_clk;
+	struct clk *iommu_pclk;
 	struct msm_iommu_drvdata *drvdata;
 	struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;

const please.

arch/arm/mach-msm/iommu_dev.c static int msm_iommu_probe(struct platform_device *pdev) · line 162

Quoted 5 lines
arch/arm/mach-msm/iommu_dev.c +5 -0
+	iommu_pclk = clk_get(NULL, "smmu_pclk");
+	if (IS_ERR(iommu_pclk)) {
+		ret = -ENODEV;
+		goto fail;
+	}

I am not a big fan of this when you have the "device" around. You should just do

iommu_pclk = clk_get(&pdev->dev, NULL);

...error logic...

iommu_clk = clk_get(&pdev->dev, "iommu_clk");

...error logic...

Quoted 31 lines
arch/arm/mach-msm/iommu_dev.c +20 -7
+
+	ret = clk_enable(iommu_pclk);
+	if (ret)
+		goto fail_enable;
+
+	iommu_clk = clk_get(&pdev->dev, "iommu_clk");
+
+	if (!IS_ERR(iommu_clk))	{
+		if (clk_get_rate(iommu_clk) == 0)
+			clk_set_min_rate(iommu_clk, 1);
+
+		ret = clk_enable(iommu_clk);
+		if (ret) {
 			clk_put(iommu_clk);
+			goto fail_pclk;
 		}
+	} else
+		iommu_clk = NULL;
 
-		r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						 "physbase");
-		if (!r) {
-			ret = -ENODEV;
-			goto fail;
-		}
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "physbase");
 
-		len = r->end - r->start + 1;
+	if (!r) {
+		ret = -ENODEV;
+		goto fail_clk;

arch/arm/mach-msm/iommu_dev.c static int msm_iommu_probe(struct platform_device *pdev) · line 189

Quoted 10 lines
arch/arm/mach-msm/iommu_dev.c +2 -7
+	}
 
-		r2 = request_mem_region(r->start, len, r->name);
-		if (!r2) {
-			pr_err("Could not request memory region: "
-			"start=%p, len=%d\n", (void *) r->start, len);
-			ret = -EBUSY;
-			goto fail;
-		}
+	len = r->end - r->start + 1;

resource_size please.

---Trilok Soni

Signature · 2 lines
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
#3 lore raw

Re: [PATCH 2/4] msm: iommu: Rework clock logic and add IOMMU bus clock control

Quoted 1 line · Trilok Soni

Hi Steve,

Hello

Quoted 9 lines

arch/arm/mach-msm/iommu_dev.c static int msm_iommu_probe(struct platform_device *pdev) · line 136

Quoted 7 lines
arch/arm/mach-msm/iommu_dev.c +1 -0
@@ -130,117 +131,134 @@ static int msm_iommu_probe(struct platform_device *pdev)
  {
  	struct resource *r, *r2;
  	struct clk *iommu_clk;
+	struct clk *iommu_pclk;
  	struct msm_iommu_drvdata *drvdata;
  	struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;

const please.

I am not clear on what you mean. Please be more specific here.

Quoted 7 lines

arch/arm/mach-msm/iommu_dev.c static int msm_iommu_probe(struct platform_device *pdev) · line 162

Quoted 5 lines
arch/arm/mach-msm/iommu_dev.c +5 -0
+	iommu_pclk = clk_get(NULL, "smmu_pclk");
+	if (IS_ERR(iommu_pclk)) {
+		ret = -ENODEV;
+		goto fail;
+	}

I am not a big fan of this when you have the "device" around. You should just do

Quoted 8 lines

iommu_pclk = clk_get(&pdev->dev, NULL);

...error logic...

iommu_clk = clk_get(&pdev->dev, "iommu_clk");

...error logic...

The pclk is a "special" bus clock and does not have a specific device instance associated with it, so passing a device would not be appropriate in this case. I pass the device for other clocks that are indeed associated with devices, but this is not one of them. I suppose we could create 11 or 12 aliases for the pclk and associate it with all the IOMMU devices, but I would prefer to avoid doing that as I believe the current approach is cleaner.

Quoted 7 lines

arch/arm/mach-msm/iommu_dev.c static int msm_iommu_probe(struct platform_device *pdev) · line 189

Quoted 4 lines
arch/arm/mach-msm/iommu_dev.c +1 -3
-			ret = -EBUSY;
-			goto fail;
-		}
+	len = r->end - r->start + 1;

resource_size please.

Ok

#4 lore raw

Re: [PATCH 2/4] msm: iommu: Rework clock logic and add IOMMU bus clock control

Hi Steve,

Quoted 15 lines · Stepan Moskovchenko
Quoted 1 line · Trilok Soni

Hi Steve,

Hello

Quoted 9 lines

arch/arm/mach-msm/iommu_dev.c static int msm_iommu_probe(struct platform_device *pdev) · line 136

Quoted 7 lines
arch/arm/mach-msm/iommu_dev.c +1 -0
@@ -130,117 +131,134 @@ static int msm_iommu_probe(struct platform_device *pdev)
  {
      struct resource *r, *r2;
      struct clk *iommu_clk;
+    struct clk *iommu_pclk;
      struct msm_iommu_drvdata *drvdata;
      struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;

const please.

Quoted 1 line

I am not clear on what you mean. Please be more specific here.

I mean

const struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;

Now I see that this change is not part of this patch so you can ignore my comment.

Quoted 10 lines
Quoted 10 lines

arch/arm/mach-msm/iommu_dev.c static int msm_iommu_probe(struct platform_device *pdev) · line 162

Quoted 6 lines
arch/arm/mach-msm/iommu_dev.c +5 -0
+    iommu_pclk = clk_get(NULL, "smmu_pclk");
+    if (IS_ERR(iommu_pclk)) {
+        ret = -ENODEV;
+        goto fail;
+    }

I am not a big fan of this when you have the "device" around. You should just do

iommu_pclk = clk_get(&pdev->dev, NULL);

Quoted 8 lines
Quoted 6 lines

...error logic...

iommu_clk = clk_get(&pdev->dev, "iommu_clk");

...error logic...

The pclk is a "special" bus clock and does not have a specific device instance associated with it, so passing a device would not be appropriate in this case. I pass the device for other clocks that are indeed associated with devices, but this is not one of them. I suppose we could create 11 or 12 aliases for the pclk and associate it with all the IOMMU devices, but I would prefer to avoid doing that as I believe the current approach is cleaner.

ok.

Quoted 10 lines
Quoted 8 lines

arch/arm/mach-msm/iommu_dev.c static int msm_iommu_probe(struct platform_device *pdev) · line 189

Quoted 5 lines
arch/arm/mach-msm/iommu_dev.c +1 -3
-            ret = -EBUSY;
-            goto fail;
-        }
+    len = r->end - r->start + 1;

resource_size please.

Ok

Thanks.

---Trilok Soni

Signature · 2 lines
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
#5 lore raw

PATCH v2 2/4 msm: iommu: Rework clock logic and add IOMMU bus clock control

In reply to Stepan Moskovchenko

Clean up the clock control code in the probe calls, and add support for controlling the clock for the IOMMU bus interconnect. With the (proper) clock driver in place, the clock control logic in the probe function can be made much cleaner since it does not have to deal with the placeholder driver anymore.

---
v2: Use resource_size.

 arch/arm/mach-msm/devices-iommu.c      |    5 -
 arch/arm/mach-msm/include/mach/iommu.h |    5 -
 arch/arm/mach-msm/iommu_dev.c          |  206 +++++++++++++++++++-------------
 3 files changed, 121 insertions(+), 95 deletions(-)
arch/arm/mach-msm/devices-iommu.c +0 -5
index c0206b7..af97afe 100644
@@ -280,7 +280,6 @@ static struct platform_device msm_root_iommu_dev = {
 
 static struct msm_iommu_dev jpegd_iommu = {
 	.name = "jpegd",
-	.clk_rate = -1
 };
 
 static struct msm_iommu_dev vpe_iommu = {
@@ -305,7 +304,6 @@ static struct msm_iommu_dev ijpeg_iommu = {
 
 static struct msm_iommu_dev vfe_iommu = {
 	.name = "vfe",
-	.clk_rate = -1
 };
 
 static struct msm_iommu_dev vcodec_a_iommu = {
@@ -318,17 +316,14 @@ static struct msm_iommu_dev vcodec_b_iommu = {
 
 static struct msm_iommu_dev gfx3d_iommu = {
 	.name = "gfx3d",
-	.clk_rate = 27000000
 };
 
 static struct msm_iommu_dev gfx2d0_iommu = {
 	.name = "gfx2d0",
-	.clk_rate = 27000000
 };
 
 static struct msm_iommu_dev gfx2d1_iommu = {
 	.name = "gfx2d1",
-	.clk_rate = 27000000
 };
 
 static struct platform_device msm_device_iommu_jpegd = {
arch/arm/mach-msm/include/mach/iommu.h +0 -5
index 8738a44..4dfe7ef 100644
@@ -45,14 +45,9 @@
 /**
  * struct msm_iommu_dev - a single IOMMU hardware instance
  * name		Human-readable name given to this IOMMU HW instance
- * clk_rate	Rate to set for this IOMMU's clock, if applicable to this
- *		particular IOMMU. 0 means don't set a rate.
- *		-1 means it is an AXI clock with no valid rate
- *
  */
 struct msm_iommu_dev {
 	const char *name;
-	int clk_rate;
 };
 
 /**
arch/arm/mach-msm/iommu_dev.c +121 -85

276 lines not on this page · raw message

--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

Reviewed-by on v2 2/4
#6 lore raw

Re: [PATCH v2 2/4] msm: iommu: Rework clock logic and add IOMMU bus clock control

Hi Steve,

Quoted 10 lines · Stepan Moskovchenko

Clean up the clock control code in the probe calls, and add support for controlling the clock for the IOMMU bus interconnect. With the (proper) clock driver in place, the clock control logic in the probe function can be made much cleaner since it does not have to deal with the placeholder driver anymore.

---
v2: Use resource_size.

Looks good to me.

---Trilok Soni

Signature · 2 lines
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
#7 lore raw

PATCH 3/4 msm: iommu: Use ASID tagging instead of VMID tagging

In reply to Stepan Moskovchenko

Use ASID tags in the TLB instead of VMID tags in preparation for changes to the secure environment.

---
 arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h |    4 +++-
 arch/arm/mach-msm/iommu.c                      |    9 ++++-----
 arch/arm/mach-msm/iommu_dev.c                  |   11 +++++++----
 3 files changed, 14 insertions(+), 10 deletions(-)
arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h +3 -1
index c2c3da9..bbd397c 100644
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -68,6 +68,7 @@ do { \
 #define FL_CACHEABLE		(1 << 3)
 #define FL_TEX0			(1 << 12)
 #define FL_OFFSET(va)		(((va) & 0xFFF00000) >> 20)
+#define FL_NG			(1 << 17)
 
 /* Second-level page table bits */
 #define SL_BASE_MASK_LARGE	0xFFFF0000
@@ -81,6 +82,7 @@ do { \
 #define SL_CACHEABLE		(1 << 3)
 #define SL_TEX0			(1 << 6)
 #define SL_OFFSET(va)		(((va) & 0xFF000) >> 12)
+#define SL_NG			(1 << 11)
 
 /* Memory type and cache policy attributes */
 #define MT_SO			0
arch/arm/mach-msm/iommu.c +4 -5
index cde3cd0..9c08740 100644
@@ -137,7 +137,6 @@ static void __reset_context(void __iomem *base, int ctx)
 	SET_TLBLKCR(base, ctx, 0);
 	SET_PRRR(base, ctx, 0);
 	SET_NMRR(base, ctx, 0);
-	SET_CONTEXTIDR(base, ctx, 0);
 }
 
 static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
@@ -418,11 +417,11 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
 		for (i = 0; i < 16; i++)
 			*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION |
 				  FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT |
-				  FL_SHARED | pgprot;
+				  FL_SHARED | FL_NG | pgprot;
 	}
 
 	if (len == SZ_1M)
-		*fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE |
+		*fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE | FL_NG |
 					    FL_TYPE_SECT | FL_SHARED | pgprot;
 
 	/* Need a 2nd level table */
@@ -447,7 +446,7 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
 
 
 	if (len == SZ_4K)
-		*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 |
+		*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 | SL_NG |
 					  SL_SHARED | SL_TYPE_SMALL | pgprot;
 
 	if (len == SZ_64K) {
@@ -455,7 +454,7 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
 
 		for (i = 0; i < 16; i++)
 			*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 |
-				SL_AP1 | SL_SHARED | SL_TYPE_LARGE | pgprot;
+			    SL_NG | SL_AP1 | SL_SHARED | SL_TYPE_LARGE | pgprot;
 	}
 
 	ret = __flush_iotlb(domain);
arch/arm/mach-msm/iommu_dev.c +7 -4
index 69acd1e..c1722eb 100644
@@ -330,14 +330,17 @@ static int msm_iommu_ctx_probe(struct platform_device *pdev)
 		SET_M2VCBR_N(drvdata->base, mid, 0);
 		SET_CBACR_N(drvdata->base, c->num, 0);
 
-		/* Set VMID = MID */
-		SET_VMID(drvdata->base, mid, mid);
+		/* Set VMID = 0 */
+		SET_VMID(drvdata->base, mid, 0);
 
 		/* Set the context number for that MID to this context */
 		SET_CBNDX(drvdata->base, mid, c->num);
 
-		/* Set MID associated with this context bank */
-		SET_CBVMID(drvdata->base, c->num, mid);
+		/* Set MID associated with this context bank to 0*/
+		SET_CBVMID(drvdata->base, c->num, 0);
+
+		/* Set the ASID for TLB tagging for this context */
+		SET_CONTEXTIDR_ASID(drvdata->base, c->num, c->num);
 
 		/* Set security bit override to be Non-secure */
 		SET_NSCFG(drvdata->base, mid, 3);

--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#8 lore raw

PATCH 4/4 msm: iommu: Remove dependency on IDR

In reply to Stepan Moskovchenko

Remove the depencency on the IOMMU IDR register, as it may not be accessible depending on the security configuraton. This involves moving the NCB field of IDR into the platform data.

---
 arch/arm/mach-msm/devices-iommu.c      |   26 +++++++++++++++++++-------
 arch/arm/mach-msm/include/mach/iommu.h |    4 ++++
 arch/arm/mach-msm/iommu.c              |    5 ++---
 arch/arm/mach-msm/iommu_dev.c          |   29 +++++++++++++++++------------
 4 files changed, 42 insertions(+), 22 deletions(-)
arch/arm/mach-msm/devices-iommu.c +19 -7
index af97afe..24030d0 100644
@@ -280,50 +280,62 @@ static struct platform_device msm_root_iommu_dev = {
 
 static struct msm_iommu_dev jpegd_iommu = {
 	.name = "jpegd",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev vpe_iommu = {
-	.name = "vpe"
+	.name = "vpe",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev mdp0_iommu = {
-	.name = "mdp0"
+	.name = "mdp0",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev mdp1_iommu = {
-	.name = "mdp1"
+	.name = "mdp1",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev rot_iommu = {
-	.name = "rot"
+	.name = "rot",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev ijpeg_iommu = {
-	.name = "ijpeg"
+	.name = "ijpeg",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev vfe_iommu = {
 	.name = "vfe",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev vcodec_a_iommu = {
-	.name = "vcodec_a"
+	.name = "vcodec_a",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev vcodec_b_iommu = {
-	.name = "vcodec_b"
+	.name = "vcodec_b",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev gfx3d_iommu = {
 	.name = "gfx3d",
+	.ncb = 3,
 };
 
 static struct msm_iommu_dev gfx2d0_iommu = {
 	.name = "gfx2d0",
+	.ncb = 2,
 };
 
 static struct msm_iommu_dev gfx2d1_iommu = {
 	.name = "gfx2d1",
+	.ncb = 2,
 };
 
 static struct platform_device msm_device_iommu_jpegd = {
arch/arm/mach-msm/include/mach/iommu.h +4 -0
index 4dfe7ef..5c7c955 100644
@@ -45,9 +45,11 @@
 /**
  * struct msm_iommu_dev - a single IOMMU hardware instance
  * name		Human-readable name given to this IOMMU HW instance
+ * ncb		Number of context banks present on this IOMMU HW instance
  */
 struct msm_iommu_dev {
 	const char *name;
+	int ncb;
 };
 
 /**
@@ -69,6 +71,7 @@ struct msm_iommu_ctx_dev {
 /**
  * struct msm_iommu_drvdata - A single IOMMU hardware instance
  * @base:	IOMMU config port base address (VA)
+ * @ncb		The number of contexts on this IOMMU
  * @irq:	Interrupt number
  * @clk:	The bus clock for this IOMMU hardware instance
  * @pclk:	The clock for the IOMMU bus interconnect
@@ -79,6 +82,7 @@ struct msm_iommu_ctx_dev {
 struct msm_iommu_drvdata {
 	void __iomem *base;
 	int irq;
+	int ncb;
 	struct clk *clk;
 	struct clk *pclk;
 };
arch/arm/mach-msm/iommu.c +2 -3
index 9c08740..0146f519 100644
@@ -636,7 +636,7 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 	struct msm_iommu_drvdata *drvdata = dev_id;
 	void __iomem *base;
 	unsigned int fsr;
-	int ncb, i, ret;
+	int i, ret;
 
 	spin_lock(&msm_iommu_lock);
 
@@ -654,8 +654,7 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 	if (ret)
 		goto fail;
 
-	ncb = GET_NCB(base)+1;
-	for (i = 0; i < ncb; i++) {
+	for (i = 0; i < drvdata->ncb; i++) {
 		fsr = GET_FSR(base, i);
 		if (fsr) {
 			pr_err("Fault occurred in context %d.\n", i);
arch/arm/mach-msm/iommu_dev.c +17 -12
index c1722eb..826a21d 100644
@@ -85,9 +85,9 @@ fail:
 }
 EXPORT_SYMBOL(msm_iommu_get_ctx);
 
-static void msm_iommu_reset(void __iomem *base)
+static void msm_iommu_reset(void __iomem *base, int ncb)
 {
-	int ctx, ncb;
+	int ctx;
 
 	SET_RPUE(base, 0);
 	SET_RPUEIE(base, 0);
@@ -100,7 +100,6 @@ static void msm_iommu_reset(void __iomem *base)
 	SET_GLOBAL_TLBIALL(base, 0);
 	SET_RPU_ACR(base, 0);
 	SET_TLBLKCRWE(base, 1);
-	ncb = GET_NCB(base)+1;
 
 	for (ctx = 0; ctx < ncb; ctx++) {
 		SET_BPRCOSH(base, ctx, 0);
@@ -136,7 +135,7 @@ static int msm_iommu_probe(struct platform_device *pdev)
 	struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
 	void __iomem *regs_base;
 	resource_size_t	len;
-	int ret, ncb, nm2v, irq;
+	int ret, irq, par;
 
 	if (pdev->id == -1) {
 		msm_iommu_root_dev = pdev;
@@ -211,10 +210,18 @@ static int msm_iommu_probe(struct platform_device *pdev)
 		goto fail_io;
 	}
 
-	mb();
+	msm_iommu_reset(regs_base, iommu_dev->ncb);
 
-	if (GET_IDR(regs_base) == 0) {
-		pr_err("Invalid IDR value detected\n");
+	SET_M(regs_base, 0, 1);
+	SET_PAR(regs_base, 0, 0);
+	SET_V2PCFG(regs_base, 0, 1);
+	SET_V2PPR(regs_base, 0, 0);
+	par = GET_PAR(regs_base, 0);
+	SET_V2PCFG(regs_base, 0, 0);
+	SET_M(regs_base, 0, 0);
+
+	if (!par) {
+		pr_err("%s: Invalid PAR value detected\n", iommu_dev->name);
 		ret = -ENODEV;
 		goto fail_io;
 	}
@@ -226,17 +233,15 @@ static int msm_iommu_probe(struct platform_device *pdev)
 		goto fail_io;
 	}
 
-	msm_iommu_reset(regs_base);
+
 	drvdata->pclk = iommu_pclk;
 	drvdata->clk = iommu_clk;
 	drvdata->base = regs_base;
 	drvdata->irq = irq;
-
-	nm2v = GET_NM2VCBMT((unsigned long) regs_base);
-	ncb = GET_NCB((unsigned long) regs_base);
+	drvdata->ncb = iommu_dev->ncb;
 
 	pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
-			iommu_dev->name, regs_base, irq, ncb+1);
+		iommu_dev->name, regs_base, irq, iommu_dev->ncb);
 
 	platform_set_drvdata(pdev, drvdata);
 

--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#9 lore raw
In reply to Stepan Moskovchenko

Stepan Moskovchenko (6):
msm: iommu: Clock control for the IOMMU driver
msm: iommu: Rework clock logic and add IOMMU bus clock control
msm: iommu: Use ASID tagging instead of VMID tagging
msm: iommu: Remove dependency on IDR
msm: iommu: Don't read from write-only registers
msm: iommu: Enable HTW L2 redirection on MSM8960

 arch/arm/mach-msm/Kconfig                      |    2 +-
 arch/arm/mach-msm/devices-iommu.c              |   31 ++--
 arch/arm/mach-msm/include/mach/iommu.h         |   18 ++-
 arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h |   32 +---
 arch/arm/mach-msm/iommu.c                      |   72 +++++++--
 arch/arm/mach-msm/iommu_dev.c                  |  230 ++++++++++++++----------
 6 files changed, 232 insertions(+), 153 deletions(-)

I have pulled these changes into my MSM tree, which can be found at

git://codeaurora.org/quic/kernel/davidb/linux-msm.git

in the for-next branch

This patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)

The path will hopefully also be merged in Linus' tree for the next -rc kernel release.

Thanks,
David

Signature · 2 lines
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.