iommu/arm-smmu: support buggy implementations with invalidate-on-map
Add a workaround for some buggy hardware that requires a TLB invalidate operation to occur at map time. Activate the feature with the qcom,smmu-invalidate-on-map boolean DT property. Change-Id: I081a279fead983ae3d736b44cda371078e55a750 Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
This commit is contained in:
parent
40cd28528c
commit
e400e33389
2 changed files with 17 additions and 1 deletions
|
@ -55,6 +55,10 @@ conditions.
|
|||
aliases of secure registers have to be used during
|
||||
SMMU configuration.
|
||||
|
||||
- qcom,smmu-invalidate-on-map : Enable proper handling of buggy
|
||||
implementations that require a TLB invalidate
|
||||
operation to occur at map time.
|
||||
|
||||
- clocks : List of clocks to be used during SMMU register access. See
|
||||
Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
for information about the format. For each clock specified
|
||||
|
|
|
@ -382,6 +382,7 @@ struct arm_smmu_device {
|
|||
u32 features;
|
||||
|
||||
#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
|
||||
#define ARM_SMMU_OPT_INVALIDATE_ON_MAP (1 << 1)
|
||||
u32 options;
|
||||
enum arm_smmu_arch_version version;
|
||||
|
||||
|
@ -441,6 +442,7 @@ struct arm_smmu_option_prop {
|
|||
|
||||
static struct arm_smmu_option_prop arm_smmu_options[] = {
|
||||
{ ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" },
|
||||
{ ARM_SMMU_OPT_INVALIDATE_ON_MAP, "qcom,smmu-invalidate-on-map" },
|
||||
{ 0, NULL},
|
||||
};
|
||||
|
||||
|
@ -1678,12 +1680,22 @@ out_unlock:
|
|||
static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
|
||||
phys_addr_t paddr, size_t size, int prot)
|
||||
{
|
||||
int ret;
|
||||
struct arm_smmu_domain *smmu_domain = domain->priv;
|
||||
|
||||
if (!smmu_domain)
|
||||
return -ENODEV;
|
||||
|
||||
return arm_smmu_handle_mapping(smmu_domain, iova, paddr, size, prot);
|
||||
ret = arm_smmu_handle_mapping(smmu_domain, iova, paddr, size, prot);
|
||||
|
||||
if (!ret &&
|
||||
(smmu_domain->smmu->options & ARM_SMMU_OPT_INVALIDATE_ON_MAP)) {
|
||||
arm_smmu_enable_clocks(smmu_domain->smmu);
|
||||
arm_smmu_tlb_inv_context(smmu_domain);
|
||||
arm_smmu_disable_clocks(smmu_domain->smmu);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
|
||||
|
|
Loading…
Add table
Reference in a new issue