Merge "iommu: arm-smmu: Add PM support for actlr register"
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index cf7e9c0..e0b2f63 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -375,6 +375,7 @@
u32 tcr[2];
u32 mair[2];
struct arm_smmu_cfg *cfg;
+ u32 actlr;
u32 attributes;
};
@@ -1761,6 +1762,9 @@
writel_relaxed(cb->mair[1], cb_base + ARM_SMMU_CB_S1_MAIR1);
}
+ /* ACTLR (implementation defined) */
+ writel_relaxed(cb->actlr, cb_base + ARM_SMMU_CB_ACTLR);
+
/* SCTLR */
reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE;
@@ -2031,6 +2035,7 @@
/* Initialise the context bank with our page table cfg */
arm_smmu_init_context_bank(smmu_domain,
&smmu_domain->pgtbl_cfg);
+ arm_smmu_arch_init_context_bank(smmu_domain, dev);
arm_smmu_write_context_bank(smmu, cfg->cbndx);
/* for slave side secure, we may have to force the pagetable
* format to V8L.
@@ -2040,8 +2045,6 @@
if (ret)
goto out_clear_smmu;
- arm_smmu_arch_init_context_bank(smmu_domain, dev);
-
/*
* Request context fault interrupt. Do this last to avoid the
* handler seeing a half-initialised domain state.
@@ -3740,18 +3743,17 @@
int i;
u32 val;
struct arm_smmu_impl_def_reg *regs = smmu->impl_def_attach_registers;
- void __iomem *cb_base;
-
/*
* SCTLR.M must be disabled here per ARM SMMUv2 spec
* to prevent table walks with an inconsistent state.
*/
for (i = 0; i < smmu->num_context_banks; ++i) {
- cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, i);
+ struct arm_smmu_cb *cb = &smmu->cbs[i];
+
val = ACTLR_QCOM_ISH << ACTLR_QCOM_ISH_SHIFT |
ACTLR_QCOM_OSH << ACTLR_QCOM_OSH_SHIFT |
ACTLR_QCOM_NSH << ACTLR_QCOM_NSH_SHIFT;
- writel_relaxed(val, cb_base + ARM_SMMU_CB_ACTLR);
+ cb->actlr = val;
}
/* Program implementation defined registers */
@@ -5429,20 +5431,14 @@
struct device *dev)
{
struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct arm_smmu_cb *cb = &smmu->cbs[smmu_domain->cfg.cbndx];
struct qsmmuv500_group_iommudata *iommudata =
to_qsmmuv500_group_iommudata(dev->iommu_group);
- void __iomem *cb_base;
- const struct iommu_gather_ops *tlb;
if (!iommudata->has_actlr)
return;
- tlb = smmu_domain->pgtbl_cfg.tlb;
- cb_base = ARM_SMMU_CB_BASE(smmu) +
- ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx);
-
- writel_relaxed(iommudata->actlr, cb_base + ARM_SMMU_CB_ACTLR);
-
+ cb->actlr = iommudata->actlr;
/*
* Prefetch only works properly if the start and end of all
* buffers in the page table are aligned to 16 Kb.
@@ -5450,12 +5446,6 @@
if ((iommudata->actlr >> QSMMUV500_ACTLR_DEEP_PREFETCH_SHIFT) &
QSMMUV500_ACTLR_DEEP_PREFETCH_MASK)
smmu_domain->qsmmuv500_errata2_min_align = true;
-
- /*
- * Flush the context bank after modifying ACTLR to ensure there
- * are no cache entries with stale state
- */
- tlb->tlb_flush_all(smmu_domain);
}
static int qsmmuv500_tbu_register(struct device *dev, void *cookie)