diff options
author | Robin Murphy <robin.murphy@arm.com> | 2019-08-15 20:37:35 +0200 |
---|---|---|
committer | Will Deacon <will@kernel.org> | 2019-08-19 17:52:48 +0200 |
commit | 3995e18689fda2434863bdf2a8cd19acea4e61f0 (patch) | |
tree | 55fa44c6b583f74c3787892192037a62166ba034 /drivers/iommu/arm-smmu-impl.c | |
parent | iommu/arm-smmu: Move Secure access quirk to implementation (diff) | |
download | linux-3995e18689fda2434863bdf2a8cd19acea4e61f0.tar.xz linux-3995e18689fda2434863bdf2a8cd19acea4e61f0.zip |
iommu/arm-smmu: Add configuration implementation hook
Probing the ID registers and setting up the SMMU configuration is an
area where overrides and workarounds may well be needed. Indeed, the
Cavium workaround detection lives there at the moment, so let's break
that out.
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Diffstat (limited to 'drivers/iommu/arm-smmu-impl.c')
-rw-r--r-- | drivers/iommu/arm-smmu-impl.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c index 0657c85580cb..696417908793 100644 --- a/drivers/iommu/arm-smmu-impl.c +++ b/drivers/iommu/arm-smmu-impl.c @@ -47,8 +47,42 @@ const struct arm_smmu_impl calxeda_impl = { }; +static int cavium_cfg_probe(struct arm_smmu_device *smmu) +{ + static atomic_t context_count = ATOMIC_INIT(0); + /* + * Cavium CN88xx erratum #27704. + * Ensure ASID and VMID allocation is unique across all SMMUs in + * the system. + */ + smmu->cavium_id_base = atomic_fetch_add(smmu->num_context_banks, + &context_count); + dev_notice(smmu->dev, "\tenabling workaround for Cavium erratum 27704\n"); + + return 0; +} + +const struct arm_smmu_impl cavium_impl = { + .cfg_probe = cavium_cfg_probe, +}; + + struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu) { + /* + * We will inevitably have to combine model-specific implementation + * quirks with platform-specific integration quirks, but everything + * we currently support happens to work out as straightforward + * mutually-exclusive assignments. + */ + switch (smmu->model) { + case CAVIUM_SMMUV2: + smmu->impl = &cavium_impl; + break; + default: + break; + } + if (of_property_read_bool(smmu->dev->of_node, "calxeda,smmu-secure-config-access")) smmu->impl = &calxeda_impl; |