diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2017-03-24 05:19:01 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2017-03-24 07:11:43 -0400 |
commit | d5bf739dc7628a35b334cdb9058750388927760a (patch) | |
tree | 9929bda98dc8f1826872334ba115384b0de38ea0 | |
parent | e75276638c1423d286e425fd29375e5736c7635c (diff) |
iommu/exynos: Use smarter TLB flush method for v5 SYSMMU
SYSMMU v5 has dedicated registers to perform TLB flush range operation,
so use them instead of looping with FLUSH_ENTRY command.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r-- | drivers/iommu/exynos-iommu.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index b83df7196e76..88b26d3e8c2c 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c | |||
@@ -171,6 +171,9 @@ static u32 lv2ent_offset(sysmmu_iova_t iova) | |||
171 | #define REG_V5_PT_BASE_PFN 0x00C | 171 | #define REG_V5_PT_BASE_PFN 0x00C |
172 | #define REG_V5_MMU_FLUSH_ALL 0x010 | 172 | #define REG_V5_MMU_FLUSH_ALL 0x010 |
173 | #define REG_V5_MMU_FLUSH_ENTRY 0x014 | 173 | #define REG_V5_MMU_FLUSH_ENTRY 0x014 |
174 | #define REG_V5_MMU_FLUSH_RANGE 0x018 | ||
175 | #define REG_V5_MMU_FLUSH_START 0x020 | ||
176 | #define REG_V5_MMU_FLUSH_END 0x024 | ||
174 | #define REG_V5_INT_STATUS 0x060 | 177 | #define REG_V5_INT_STATUS 0x060 |
175 | #define REG_V5_INT_CLEAR 0x064 | 178 | #define REG_V5_INT_CLEAR 0x064 |
176 | #define REG_V5_FAULT_AR_VA 0x070 | 179 | #define REG_V5_FAULT_AR_VA 0x070 |
@@ -319,14 +322,23 @@ static void __sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data, | |||
319 | { | 322 | { |
320 | unsigned int i; | 323 | unsigned int i; |
321 | 324 | ||
322 | for (i = 0; i < num_inv; i++) { | 325 | if (MMU_MAJ_VER(data->version) < 5) { |
323 | if (MMU_MAJ_VER(data->version) < 5) | 326 | for (i = 0; i < num_inv; i++) { |
324 | writel((iova & SPAGE_MASK) | 1, | 327 | writel((iova & SPAGE_MASK) | 1, |
325 | data->sfrbase + REG_MMU_FLUSH_ENTRY); | 328 | data->sfrbase + REG_MMU_FLUSH_ENTRY); |
326 | else | 329 | iova += SPAGE_SIZE; |
330 | } | ||
331 | } else { | ||
332 | if (num_inv == 1) { | ||
327 | writel((iova & SPAGE_MASK) | 1, | 333 | writel((iova & SPAGE_MASK) | 1, |
328 | data->sfrbase + REG_V5_MMU_FLUSH_ENTRY); | 334 | data->sfrbase + REG_V5_MMU_FLUSH_ENTRY); |
329 | iova += SPAGE_SIZE; | 335 | } else { |
336 | writel((iova & SPAGE_MASK), | ||
337 | data->sfrbase + REG_V5_MMU_FLUSH_START); | ||
338 | writel((iova & SPAGE_MASK) + (num_inv - 1) * SPAGE_SIZE, | ||
339 | data->sfrbase + REG_V5_MMU_FLUSH_END); | ||
340 | writel(1, data->sfrbase + REG_V5_MMU_FLUSH_RANGE); | ||
341 | } | ||
330 | } | 342 | } |
331 | } | 343 | } |
332 | 344 | ||