diff options
author | Prakash Gupta <guptap@codeaurora.org> | 2019-09-12 13:56:22 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2019-09-15 23:41:28 -0700 |
commit | df59d92c2ea15fc021c25d49e6d2961dd75a1287 (patch) | |
tree | 05629c8aa1a7c58fd4891dc639de8973270ce254 | |
parent | f152e1b73d57c4c85e435ca3b6e063dcd90248d2 (diff) |
iommu: arm-smmu: reset fault registers while device resetLA.UM.8.9.r1-04100-RENNELL.0
Fault registers may can be excluded from HW reset.
Reset fault registers while device reset.
Change-Id: I8402f77958a29b40e8119528eed432ada1414d6b
Signed-off-by: Prakash Gupta <guptap@codeaurora.org>
-rw-r--r-- | drivers/iommu/arm-smmu.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index d69ac838de7a..382d39267899 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -4143,11 +4143,35 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) void __iomem *gr0_base = ARM_SMMU_GR0(smmu); int i; u32 reg; + void __iomem *cb_base; + u32 fsr; + unsigned long iova; /* clear global FSR */ reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR); writel_relaxed(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR); + for (i = 0; i < smmu->num_context_banks; ++i) { + cb_base = ARM_SMMU_CB(smmu, i); + + fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR); + writel_relaxed(fsr, cb_base + ARM_SMMU_CB_FSR); + + iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR); + writeq_relaxed(0, cb_base + ARM_SMMU_CB_FAR); + writel_relaxed(0, ARM_SMMU_GR1(smmu) + + ARM_SMMU_GR1_CBFRSYNRA(i)); + + writel_relaxed(0, cb_base + ARM_SMMU_CB_FSYNR0); + writel_relaxed(0, cb_base + ARM_SMMU_CB_FSYNR1); + pr_info("CB %d, FSR 0x%x FAR 0x%lx reset\n", i, fsr, iova); + } + + /* + * Barrier required to ensure fault registers are cleared. + */ + wmb(); + /* * Reset stream mapping groups: Initial values mark all SMRn as * invalid and all S2CRn as bypass unless overridden. |