linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] msm: iommu: Use relaxed register access functions
@ 2011-03-17 20:01 Stepan Moskovchenko
  2011-03-23 12:50 ` Daniel Walker
  2011-03-24 22:21 ` [PATCHv2] " Stepan Moskovchenko
  0 siblings, 2 replies; 3+ messages in thread
From: Stepan Moskovchenko @ 2011-03-17 20:01 UTC (permalink / raw)
  To: davidb, dwalker
  Cc: linux-arm-msm, linux-arm-kernel, linux-kernel, Stepan Moskovchenko

Use the relaxed versions of readl/writel for IOMMU register
access, inserting barriers where appropriate.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
 arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h |   15 ++++++++-------
 arch/arm/mach-msm/iommu.c                      |    5 +++++
 arch/arm/mach-msm/iommu_dev.c                  |    4 ++++
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
index fc16010..6d097d5 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
@@ -20,14 +20,14 @@

 #define CTX_SHIFT 12

-#define GET_GLOBAL_REG(reg, base) (readl((base) + (reg)))
+#define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg)))
 #define GET_CTX_REG(reg, base, ctx) \
-				(readl((base) + (reg) + ((ctx) << CTX_SHIFT)))
+			(readl_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT)))

-#define SET_GLOBAL_REG(reg, base, val)	writel((val), ((base) + (reg)))
+#define SET_GLOBAL_REG(reg, base, val)	writel_relaxed((val), ((base) + (reg)))

 #define SET_CTX_REG(reg, base, ctx, val) \
-			writel((val), ((base) + (reg) + ((ctx) << CTX_SHIFT)))
+		writel_relaxed((val), ((base) + (reg) + ((ctx) << CTX_SHIFT)))

 /* Wrappers for numbered registers */
 #define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG(b, ((r) + (n << 2)), (v))
@@ -43,12 +43,13 @@
 #define SET_CONTEXT_FIELD(b, c, r, F, v)	\
 	SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT, (v))

-#define GET_FIELD(addr, mask, shift)  ((readl(addr) >> (shift)) & (mask))
+#define GET_FIELD(addr, mask, shift) ((readl_relaxed(addr) >> (shift)) & (mask))

 #define SET_FIELD(addr, mask, shift, v) \
 do { \
-	int t = readl(addr); \
-	writel((t & ~((mask) << (shift))) + (((v) & (mask)) << (shift)), addr);\
+	int t = readl_relaxed(addr); \
+	writel_relaxed((t & ~((mask) << (shift))) + (((v) & \
+		       (mask)) << (shift)), addr);\
 } while (0)


diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index 1a584e0..262491d 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -97,6 +97,7 @@ static int __flush_iotlb(struct iommu_domain *domain)
 	}
 #endif

+	mb();
 	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
 		if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent)
 			BUG();
@@ -137,6 +138,7 @@ static void __reset_context(void __iomem *base, int ctx)
 	SET_TLBLKCR(base, ctx, 0);
 	SET_PRRR(base, ctx, 0);
 	SET_NMRR(base, ctx, 0);
+	mb();
 }

 static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
@@ -205,6 +207,7 @@ static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)

 	/* Enable the MMU */
 	SET_M(base, ctx, 1);
+	mb();
 }

 static int msm_iommu_domain_init(struct iommu_domain *domain)
@@ -579,8 +582,10 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,

 	/* Invalidate context TLB */
 	SET_CTX_TLBIALL(base, ctx, 0);
+	mb();
 	SET_V2PPR(base, ctx, va & V2Pxx_VA);

+	mb();
 	par = GET_PAR(base, ctx);

 	/* We are dealing with a supersection */
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
index 8e8fb07..a8976f7 100644
--- a/arch/arm/mach-msm/iommu_dev.c
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -124,6 +124,7 @@ static void msm_iommu_reset(void __iomem *base, int ncb)
 		SET_NMRR(base, ctx, 0);
 		SET_CONTEXTIDR(base, ctx, 0);
 	}
+	mb();
 }

 static int msm_iommu_probe(struct platform_device *pdev)
@@ -216,9 +217,11 @@ static int msm_iommu_probe(struct platform_device *pdev)
 	SET_PAR(regs_base, 0, 0);
 	SET_V2PCFG(regs_base, 0, 1);
 	SET_V2PPR(regs_base, 0, 0);
+	mb();
 	par = GET_PAR(regs_base, 0);
 	SET_V2PCFG(regs_base, 0, 0);
 	SET_M(regs_base, 0, 0);
+	mb();

 	if (!par) {
 		pr_err("%s: Invalid PAR value detected\n", iommu_dev->name);
@@ -350,6 +353,7 @@ static int msm_iommu_ctx_probe(struct platform_device *pdev)
 		/* Set security bit override to be Non-secure */
 		SET_NSCFG(drvdata->base, mid, 3);
 	}
+	mb();

 	if (drvdata->clk)
 		clk_disable(drvdata->clk);
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* Re: [PATCH] msm: iommu: Use relaxed register access functions
  2011-03-17 20:01 [PATCH] msm: iommu: Use relaxed register access functions Stepan Moskovchenko
@ 2011-03-23 12:50 ` Daniel Walker
  2011-03-24 22:21 ` [PATCHv2] " Stepan Moskovchenko
  1 sibling, 0 replies; 3+ messages in thread
From: Daniel Walker @ 2011-03-23 12:50 UTC (permalink / raw)
  To: Stepan Moskovchenko; +Cc: davidb, linux-arm-msm, linux-arm-kernel, linux-kernel

On Thu, 2011-03-17 at 13:01 -0700, Stepan Moskovchenko wrote:
> Use the relaxed versions of readl/writel for IOMMU register
> access, inserting barriers where appropriate.

Could you provide comments on why you need barriers in the various
places you've placed them.

Daniel


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

* [PATCHv2] msm: iommu: Use relaxed register access functions
  2011-03-17 20:01 [PATCH] msm: iommu: Use relaxed register access functions Stepan Moskovchenko
  2011-03-23 12:50 ` Daniel Walker
@ 2011-03-24 22:21 ` Stepan Moskovchenko
  1 sibling, 0 replies; 3+ messages in thread
From: Stepan Moskovchenko @ 2011-03-24 22:21 UTC (permalink / raw)
  To: davidb, dwalker
  Cc: linux-arm-msm, linux-arm-kernel, linux-kernel, Stepan Moskovchenko

Use the relaxed versions of readl/writel for IOMMU register
access, inserting barriers where appropriate.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
v2:
Add barrier comments
Remove one unnecessary barrier in tlb flush
Add a needed barrier in device probe

 arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h |   15 ++++++++-------
 arch/arm/mach-msm/iommu.c                      |   16 ++++++++++++++++
 arch/arm/mach-msm/iommu_dev.c                  |   17 +++++++++++++++++
 3 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
index fc16010..6d097d5 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
@@ -20,14 +20,14 @@

 #define CTX_SHIFT 12

-#define GET_GLOBAL_REG(reg, base) (readl((base) + (reg)))
+#define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg)))
 #define GET_CTX_REG(reg, base, ctx) \
-				(readl((base) + (reg) + ((ctx) << CTX_SHIFT)))
+			(readl_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT)))

-#define SET_GLOBAL_REG(reg, base, val)	writel((val), ((base) + (reg)))
+#define SET_GLOBAL_REG(reg, base, val)	writel_relaxed((val), ((base) + (reg)))

 #define SET_CTX_REG(reg, base, ctx, val) \
-			writel((val), ((base) + (reg) + ((ctx) << CTX_SHIFT)))
+		writel_relaxed((val), ((base) + (reg) + ((ctx) << CTX_SHIFT)))

 /* Wrappers for numbered registers */
 #define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG(b, ((r) + (n << 2)), (v))
@@ -43,12 +43,13 @@
 #define SET_CONTEXT_FIELD(b, c, r, F, v)	\
 	SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT, (v))

-#define GET_FIELD(addr, mask, shift)  ((readl(addr) >> (shift)) & (mask))
+#define GET_FIELD(addr, mask, shift) ((readl_relaxed(addr) >> (shift)) & (mask))

 #define SET_FIELD(addr, mask, shift, v) \
 do { \
-	int t = readl(addr); \
-	writel((t & ~((mask) << (shift))) + (((v) & (mask)) << (shift)), addr);\
+	int t = readl_relaxed(addr); \
+	writel_relaxed((t & ~((mask) << (shift))) + (((v) & \
+		       (mask)) << (shift)), addr);\
 } while (0)


diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index 1a584e0..b72475b 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -137,6 +137,9 @@ static void __reset_context(void __iomem *base, int ctx)
 	SET_TLBLKCR(base, ctx, 0);
 	SET_PRRR(base, ctx, 0);
 	SET_NMRR(base, ctx, 0);
+
+	/* Make sure the reset completes before any further hardware access */
+	mb();
 }

 static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
@@ -203,8 +206,14 @@ static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
 	SET_TTBR1_ORGN(base, ctx, 1); /* WB, WA */
 #endif

+	/* Allow configuration to commit before enabling the MMU */
+	mb();
+
 	/* Enable the MMU */
 	SET_M(base, ctx, 1);
+
+	/* Make sure the MMU is enabled before returning */
+	mb();
 }

 static int msm_iommu_domain_init(struct iommu_domain *domain)
@@ -579,8 +588,15 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,

 	/* Invalidate context TLB */
 	SET_CTX_TLBIALL(base, ctx, 0);
+
+	/* Make sure the TLB is invalidated before translating */
+	mb();
+
 	SET_V2PPR(base, ctx, va & V2Pxx_VA);

+	/* Make sure the translation request is written before reading result */
+	mb();
+
 	par = GET_PAR(base, ctx);

 	/* We are dealing with a supersection */
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
index 8e8fb07..b3d06c9 100644
--- a/arch/arm/mach-msm/iommu_dev.c
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -124,6 +124,9 @@ static void msm_iommu_reset(void __iomem *base, int ncb)
 		SET_NMRR(base, ctx, 0);
 		SET_CONTEXTIDR(base, ctx, 0);
 	}
+
+	/* Make sure the reset completes before any further hardware access */
+	mb();
 }

 static int msm_iommu_probe(struct platform_device *pdev)
@@ -212,14 +215,25 @@ static int msm_iommu_probe(struct platform_device *pdev)

 	msm_iommu_reset(regs_base, iommu_dev->ncb);

+	/*
+	 * Barriers make sure that the device is configured for V2P mode prior
+	 * to doing any V2P access, and that we read the result only after
+	 * the V2P request is written.
+	 */
 	SET_M(regs_base, 0, 1);
 	SET_PAR(regs_base, 0, 0);
 	SET_V2PCFG(regs_base, 0, 1);
+	mb();
 	SET_V2PPR(regs_base, 0, 0);
+	mb();
 	par = GET_PAR(regs_base, 0);
 	SET_V2PCFG(regs_base, 0, 0);
+
 	SET_M(regs_base, 0, 0);

+	/* Make sure device state is restored before any subsequent access */
+	mb();
+
 	if (!par) {
 		pr_err("%s: Invalid PAR value detected\n", iommu_dev->name);
 		ret = -ENODEV;
@@ -351,6 +365,9 @@ static int msm_iommu_ctx_probe(struct platform_device *pdev)
 		SET_NSCFG(drvdata->base, mid, 3);
 	}

+	/* Make sure the device is fully configured before completing probe */
+	mb();
+
 	if (drvdata->clk)
 		clk_disable(drvdata->clk);
 	clk_disable(drvdata->pclk);
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

end of thread, other threads:[~2011-03-24 22:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-17 20:01 [PATCH] msm: iommu: Use relaxed register access functions Stepan Moskovchenko
2011-03-23 12:50 ` Daniel Walker
2011-03-24 22:21 ` [PATCHv2] " Stepan Moskovchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).