diff options
| author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2014-05-15 06:40:49 -0400 |
|---|---|---|
| committer | Joerg Roedel <jroedel@suse.de> | 2014-05-26 05:22:25 -0400 |
| commit | dda7c2e4d3f160aecf21ca56d73ceb0ff6ede587 (patch) | |
| tree | 4ecd22517afc46bf543967408ca1714e46eb48eb | |
| parent | 9009f256596da78567d63c434691f7e409a99400 (diff) | |
iommu/ipmmu-vmsa: Support 2MB mappings
Add support for 2MB block mappings at the PMD level.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
| -rw-r--r-- | drivers/iommu/ipmmu-vmsa.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 87703c3faf58..7f0522048c6b 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c | |||
| @@ -479,7 +479,7 @@ static void ipmmu_free_pmds(pud_t *pud) | |||
| 479 | unsigned int i; | 479 | unsigned int i; |
| 480 | 480 | ||
| 481 | for (i = 0; i < IPMMU_PTRS_PER_PMD; ++i) { | 481 | for (i = 0; i < IPMMU_PTRS_PER_PMD; ++i) { |
| 482 | if (pmd_none(*pmd)) | 482 | if (!pmd_table(*pmd)) |
| 483 | continue; | 483 | continue; |
| 484 | 484 | ||
| 485 | ipmmu_free_ptes(pmd); | 485 | ipmmu_free_ptes(pmd); |
| @@ -610,6 +610,18 @@ static int ipmmu_alloc_init_pte(struct ipmmu_vmsa_device *mmu, pmd_t *pmd, | |||
| 610 | return 0; | 610 | return 0; |
| 611 | } | 611 | } |
| 612 | 612 | ||
| 613 | static int ipmmu_alloc_init_pmd(struct ipmmu_vmsa_device *mmu, pmd_t *pmd, | ||
| 614 | unsigned long iova, unsigned long pfn, | ||
| 615 | int prot) | ||
| 616 | { | ||
| 617 | pmdval_t pmdval = ipmmu_page_prot(prot, PMD_TYPE_SECT); | ||
| 618 | |||
| 619 | *pmd = pfn_pmd(pfn, __pgprot(pmdval)); | ||
| 620 | ipmmu_flush_pgtable(mmu, pmd, sizeof(*pmd)); | ||
| 621 | |||
| 622 | return 0; | ||
| 623 | } | ||
| 624 | |||
| 613 | static int ipmmu_handle_mapping(struct ipmmu_vmsa_domain *domain, | 625 | static int ipmmu_handle_mapping(struct ipmmu_vmsa_domain *domain, |
| 614 | unsigned long iova, phys_addr_t paddr, | 626 | unsigned long iova, phys_addr_t paddr, |
| 615 | size_t size, int prot) | 627 | size_t size, int prot) |
| @@ -642,7 +654,18 @@ static int ipmmu_handle_mapping(struct ipmmu_vmsa_domain *domain, | |||
| 642 | goto done; | 654 | goto done; |
| 643 | } | 655 | } |
| 644 | 656 | ||
| 645 | ret = ipmmu_alloc_init_pte(mmu, pmd, iova, pfn, size, prot); | 657 | switch (size) { |
| 658 | case SZ_2M: | ||
| 659 | ret = ipmmu_alloc_init_pmd(mmu, pmd, iova, pfn, prot); | ||
| 660 | break; | ||
| 661 | case SZ_64K: | ||
| 662 | case SZ_4K: | ||
| 663 | ret = ipmmu_alloc_init_pte(mmu, pmd, iova, pfn, size, prot); | ||
| 664 | break; | ||
| 665 | default: | ||
| 666 | ret = -EINVAL; | ||
| 667 | break; | ||
| 668 | } | ||
| 646 | 669 | ||
| 647 | done: | 670 | done: |
| 648 | spin_unlock_irqrestore(&domain->lock, flags); | 671 | spin_unlock_irqrestore(&domain->lock, flags); |
| @@ -792,6 +815,9 @@ static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain, | |||
| 792 | if (pmd_none(pmd)) | 815 | if (pmd_none(pmd)) |
| 793 | return 0; | 816 | return 0; |
| 794 | 817 | ||
| 818 | if (pmd_sect(pmd)) | ||
| 819 | return __pfn_to_phys(pmd_pfn(pmd)) | (iova & ~PMD_MASK); | ||
| 820 | |||
| 795 | pte = *(pmd_page_vaddr(pmd) + pte_index(iova)); | 821 | pte = *(pmd_page_vaddr(pmd) + pte_index(iova)); |
| 796 | if (pte_none(pte)) | 822 | if (pte_none(pte)) |
| 797 | return 0; | 823 | return 0; |
| @@ -930,7 +956,7 @@ static struct iommu_ops ipmmu_ops = { | |||
| 930 | .iova_to_phys = ipmmu_iova_to_phys, | 956 | .iova_to_phys = ipmmu_iova_to_phys, |
| 931 | .add_device = ipmmu_add_device, | 957 | .add_device = ipmmu_add_device, |
| 932 | .remove_device = ipmmu_remove_device, | 958 | .remove_device = ipmmu_remove_device, |
| 933 | .pgsize_bitmap = SZ_64K | SZ_4K, | 959 | .pgsize_bitmap = SZ_2M | SZ_64K | SZ_4K, |
| 934 | }; | 960 | }; |
| 935 | 961 | ||
| 936 | /* ----------------------------------------------------------------------------- | 962 | /* ----------------------------------------------------------------------------- |
