aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/arm-smmu.c
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2016-05-09 12:20:09 -0400
committerJoerg Roedel <jroedel@suse.de>2016-05-09 13:38:39 -0400
commitd546635731317a5f8923b1045d0f4403e8024a7d (patch)
tree9bc9478a80b2c124cd2ef47d441ecf2349471596 /drivers/iommu/arm-smmu.c
parent3b6b7e19e31a816ee02a8d4372cbea9ad7db3784 (diff)
iommu/arm-smmu: Use per-domain page sizes.
Now that we can accurately reflect the context format we choose for each domain, do that instead of imposing the global lowest-common-denominator restriction and potentially ending up with nothing. We currently have a strict 1:1 correspondence between domains and context banks, so we don't need to entertain the possibility of multiple formats _within_ a domain. Signed-off-by: Will Deacon <will.deacon@arm.com> [rm: split from original patch, added SMMUv3] Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/arm-smmu.c')
-rw-r--r--drivers/iommu/arm-smmu.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 7cd4ad98904a..0360919a5737 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -351,6 +351,7 @@ struct arm_smmu_device {
351 unsigned long va_size; 351 unsigned long va_size;
352 unsigned long ipa_size; 352 unsigned long ipa_size;
353 unsigned long pa_size; 353 unsigned long pa_size;
354 unsigned long pgsize_bitmap;
354 355
355 u32 num_global_irqs; 356 u32 num_global_irqs;
356 u32 num_context_irqs; 357 u32 num_context_irqs;
@@ -396,8 +397,6 @@ struct arm_smmu_domain {
396 struct iommu_domain domain; 397 struct iommu_domain domain;
397}; 398};
398 399
399static struct iommu_ops arm_smmu_ops;
400
401static DEFINE_SPINLOCK(arm_smmu_devices_lock); 400static DEFINE_SPINLOCK(arm_smmu_devices_lock);
402static LIST_HEAD(arm_smmu_devices); 401static LIST_HEAD(arm_smmu_devices);
403 402
@@ -957,7 +956,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
957 } 956 }
958 957
959 pgtbl_cfg = (struct io_pgtable_cfg) { 958 pgtbl_cfg = (struct io_pgtable_cfg) {
960 .pgsize_bitmap = arm_smmu_ops.pgsize_bitmap, 959 .pgsize_bitmap = smmu->pgsize_bitmap,
961 .ias = ias, 960 .ias = ias,
962 .oas = oas, 961 .oas = oas,
963 .tlb = &arm_smmu_gather_ops, 962 .tlb = &arm_smmu_gather_ops,
@@ -971,8 +970,8 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
971 goto out_clear_smmu; 970 goto out_clear_smmu;
972 } 971 }
973 972
974 /* Update our support page sizes to reflect the page table format */ 973 /* Update the domain's page sizes to reflect the page table format */
975 arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; 974 domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
976 975
977 /* Initialise the context bank with our page table cfg */ 976 /* Initialise the context bank with our page table cfg */
978 arm_smmu_init_context_bank(smmu_domain, &pgtbl_cfg); 977 arm_smmu_init_context_bank(smmu_domain, &pgtbl_cfg);
@@ -1814,19 +1813,23 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1814 } 1813 }
1815 1814
1816 /* Now we've corralled the various formats, what'll it do? */ 1815 /* Now we've corralled the various formats, what'll it do? */
1817 size = 0;
1818 if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_S) 1816 if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_S)
1819 size |= SZ_4K | SZ_64K | SZ_1M | SZ_16M; 1817 smmu->pgsize_bitmap |= SZ_4K | SZ_64K | SZ_1M | SZ_16M;
1820 if (smmu->features & 1818 if (smmu->features &
1821 (ARM_SMMU_FEAT_FMT_AARCH32_L | ARM_SMMU_FEAT_FMT_AARCH64_4K)) 1819 (ARM_SMMU_FEAT_FMT_AARCH32_L | ARM_SMMU_FEAT_FMT_AARCH64_4K))
1822 size |= SZ_4K | SZ_2M | SZ_1G; 1820 smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G;
1823 if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH64_16K) 1821 if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH64_16K)
1824 size |= SZ_16K | SZ_32M; 1822 smmu->pgsize_bitmap |= SZ_16K | SZ_32M;
1825 if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH64_64K) 1823 if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH64_64K)
1826 size |= SZ_64K | SZ_512M; 1824 smmu->pgsize_bitmap |= SZ_64K | SZ_512M;
1825
1826 if (arm_smmu_ops.pgsize_bitmap == -1UL)
1827 arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap;
1828 else
1829 arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap;
1830 dev_notice(smmu->dev, "\tSupported page sizes: 0x%08lx\n",
1831 smmu->pgsize_bitmap);
1827 1832
1828 arm_smmu_ops.pgsize_bitmap &= size;
1829 dev_notice(smmu->dev, "\tSupported page sizes: 0x%08lx\n", size);
1830 1833
1831 if (smmu->features & ARM_SMMU_FEAT_TRANS_S1) 1834 if (smmu->features & ARM_SMMU_FEAT_TRANS_S1)
1832 dev_notice(smmu->dev, "\tStage-1: %lu-bit VA -> %lu-bit IPA\n", 1835 dev_notice(smmu->dev, "\tStage-1: %lu-bit VA -> %lu-bit IPA\n",