summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi Doyu <hdoyu@nvidia.com>2013-04-03 10:10:32 +0300
committerHarshada Kale <hkale@nvidia.com>2013-06-10 03:48:00 -0700
commitf1e67ff7a4394ec89b0fb1683b99be2161618944 (patch)
tree0937e254779ba08f908c066749c2460b46fa255e
parent0dfd32925e3b4ee6d4a8e574af1fc6a65ed849f5 (diff)
iommu/tegra: smmu: Add flush_ptc_and_tlb_all()
A version of flush_ptc_and_tlb() against all entries within the same address space. bug 1286500 Change-Id: I73dfdb0f1249a89313edd89dc5a51b8229648a32 (cherry picked from commit 923f7df28db0f9e18d2698926e3896a0c77c9376) Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com> Reviewed-on: http://git-master/r/234120 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
-rw-r--r--drivers/iommu/tegra-smmu.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index ad3e5a399e73..d48296636460 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -134,6 +134,9 @@ enum {
SMMU_TLB_FLUSH_VA_MATCH_##which)
#define SMMU_PTB_ASID_CUR(n) \
((n) << SMMU_PTB_ASID_CURRENT_SHIFT)
+
+#define SMMU_TLB_FLUSH_ALL 0
+
#define SMMU_TLB_FLUSH_ASID_MATCH_disable \
(SMMU_TLB_FLUSH_ASID_MATCH_DISABLE << \
SMMU_TLB_FLUSH_ASID_MATCH_SHIFT)
@@ -435,25 +438,58 @@ static void smmu_setup_regs(struct smmu_device *smmu)
ahb_write(smmu, val, AHB_XBAR_CTRL);
}
-static void flush_ptc_and_tlb(struct smmu_device *smmu,
- struct smmu_as *as, dma_addr_t iova,
- unsigned long *pte, struct page *page, int is_pde)
+
+static void smmu_flush_ptc(struct smmu_device *smmu, unsigned long *pte,
+ struct page *page)
{
u32 val;
- unsigned long tlb_flush_va = is_pde
- ? SMMU_TLB_FLUSH_VA(iova, SECTION)
- : SMMU_TLB_FLUSH_VA(iova, GROUP);
- val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page);
+ if (pte)
+ val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page);
+ else
+ val = SMMU_PTC_FLUSH_TYPE_ALL;
+
smmu_write(smmu, val, SMMU_PTC_FLUSH);
FLUSH_SMMU_REGS(smmu);
- val = tlb_flush_va |
- SMMU_TLB_FLUSH_ASID_MATCH__ENABLE |
- (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT);
+}
+
+static void smmu_flush_tlb(struct smmu_device *smmu, struct smmu_as *as,
+ dma_addr_t iova, int is_pde)
+{
+ u32 val = SMMU_TLB_FLUSH_ALL;
+
+#if 0 /* Disabled temproary for reordering issue */
+ if (as) {
+ val |= SMMU_TLB_FLUSH_ASID_MATCH__ENABLE;
+ val |= as->asid << SMMU_TLB_FLUSH_ASID_SHIFT;
+ }
+#endif
+
+ if (iova) {
+ if (is_pde)
+ val |= SMMU_TLB_FLUSH_VA(iova, SECTION);
+ else
+ val |= SMMU_TLB_FLUSH_VA(iova, GROUP);
+ }
+
smmu_write(smmu, val, SMMU_TLB_FLUSH);
FLUSH_SMMU_REGS(smmu);
}
+static void flush_ptc_and_tlb(struct smmu_device *smmu,
+ struct smmu_as *as, dma_addr_t iova,
+ unsigned long *pte, struct page *page, int is_pde)
+{
+ smmu_flush_ptc(smmu, pte, page);
+ smmu_flush_tlb(smmu, as, iova, is_pde);
+}
+
+static inline void flush_ptc_and_tlb_all(struct smmu_device *smmu,
+ struct smmu_as *as)
+{
+ flush_ptc_and_tlb(smmu, as, 0, 0, NULL, 1);
+}
+
static void free_ptbl(struct smmu_as *as, dma_addr_t iova)
{
unsigned long pdn = SMMU_ADDR_TO_PDN(iova);