From f1e67ff7a4394ec89b0fb1683b99be2161618944 Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Wed, 3 Apr 2013 10:10:32 +0300 Subject: 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 Reviewed-on: http://git-master/r/234120 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Krishna Reddy --- drivers/iommu/tegra-smmu.c | 56 +++++++++++++++++++++++++++++++++++++--------- 1 file 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); -- cgit v1.2.3