iommu/msm: Add TLB sync operations
The hardware requires a TLB sync operation at the end of
each TLB maintenance operation.
Change-Id: I8102253cfc12af530216346efa5bb9760db25352
Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
diff --git a/drivers/iommu/msm_iommu-v2.c b/drivers/iommu/msm_iommu-v2.c
index 26e967d..48edf96 100644
--- a/drivers/iommu/msm_iommu-v2.c
+++ b/drivers/iommu/msm_iommu-v2.c
@@ -67,6 +67,17 @@
clk_disable_unprepare(drvdata->pclk);
}
+static void __sync_tlb(void __iomem *base, int ctx)
+{
+ SET_TLBSYNC(base, ctx, 0);
+
+ /* No barrier needed due to register proximity */
+ while (GET_CB_TLBSTATUS_SACTIVE(base, ctx))
+ cpu_relax();
+
+ /* No barrier needed due to read dependency */
+}
+
static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va)
{
struct msm_priv *priv = domain->priv;
@@ -92,6 +103,7 @@
SET_TLBIVA(iommu_drvdata->base, ctx_drvdata->num,
asid | (va & CB_TLBIVA_VA));
mb();
+ __sync_tlb(iommu_drvdata->base, ctx_drvdata->num);
__disable_clocks(iommu_drvdata);
}
fail:
@@ -121,6 +133,7 @@
SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, asid);
mb();
+ __sync_tlb(iommu_drvdata->base, ctx_drvdata->num);
__disable_clocks(iommu_drvdata);
}