aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrakash Gupta <guptap@codeaurora.org>2019-09-12 13:56:22 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2019-09-15 23:41:28 -0700
commitdf59d92c2ea15fc021c25d49e6d2961dd75a1287 (patch)
tree05629c8aa1a7c58fd4891dc639de8973270ce254
parentf152e1b73d57c4c85e435ca3b6e063dcd90248d2 (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.c24
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.