Loading drivers/iommu/arm-smmu.c +40 −13 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <soc/qcom/scm.h> #include <soc/qcom/secure_buffer.h> #include <linux/of_platform.h> #include <linux/msm-bus.h> Loading Loading @@ -4446,34 +4447,60 @@ qsmmuv500_errata1_required(struct arm_smmu_domain *smmu_domain, return ret; } #define SCM_CONFIG_ERRATA1_CLIENT_ALL 0x2 #define SCM_CONFIG_ERRATA1 0x3 static void __qsmmuv500_errata1_tlbiall(struct arm_smmu_domain *smmu_domain) { struct arm_smmu_device *smmu = smmu_domain->smmu; struct device *dev = smmu_domain->dev; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; void __iomem *base; int ret; ktime_t cur; u32 val; struct scm_desc desc = { .args[0] = SCM_CONFIG_ERRATA1_CLIENT_ALL, .args[1] = false, .arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL), }; base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); writel_relaxed(0, base + ARM_SMMU_CB_S1_TLBIALL); writel_relaxed(0, base + ARM_SMMU_CB_TLBSYNC); if (readl_poll_timeout_atomic(base + ARM_SMMU_CB_TLBSTATUS, val, !(val & TLBSTATUS_SACTIVE), 0, 100)) { if (!readl_poll_timeout_atomic(base + ARM_SMMU_CB_TLBSTATUS, val, !(val & TLBSTATUS_SACTIVE), 0, 100)) return; ret = scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_SMMU_PROGRAM, SCM_CONFIG_ERRATA1), &desc); if (ret) { dev_err(smmu->dev, "Calling into TZ to disable ERRATA1 failed - IOMMU hardware in bad state\n"); BUG(); return; } cur = ktime_get(); trace_tlbi_throttle_start(dev, 0); msm_bus_noc_throttle_wa(true); if (readl_poll_timeout_atomic(base + ARM_SMMU_CB_TLBSTATUS, val, !(val & TLBSTATUS_SACTIVE), 0, 10000)) { dev_err(smmu->dev, "ERRATA1 TLBSYNC timeout"); dev_err(smmu->dev, "ERRATA1 TLBSYNC timeout - IOMMU hardware in bad state"); trace_tlbsync_timeout(dev, 0); BUG(); } msm_bus_noc_throttle_wa(false); trace_tlbi_throttle_end(dev, ktime_us_delta(ktime_get(), cur)); trace_tlbi_throttle_end( dev, ktime_us_delta(ktime_get(), cur)); desc.args[1] = true; ret = scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_SMMU_PROGRAM, SCM_CONFIG_ERRATA1), &desc); if (ret) { dev_err(smmu->dev, "Calling into TZ to reenable ERRATA1 failed - IOMMU hardware in bad state\n"); BUG(); } } Loading Loading
drivers/iommu/arm-smmu.c +40 −13 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <soc/qcom/scm.h> #include <soc/qcom/secure_buffer.h> #include <linux/of_platform.h> #include <linux/msm-bus.h> Loading Loading @@ -4446,34 +4447,60 @@ qsmmuv500_errata1_required(struct arm_smmu_domain *smmu_domain, return ret; } #define SCM_CONFIG_ERRATA1_CLIENT_ALL 0x2 #define SCM_CONFIG_ERRATA1 0x3 static void __qsmmuv500_errata1_tlbiall(struct arm_smmu_domain *smmu_domain) { struct arm_smmu_device *smmu = smmu_domain->smmu; struct device *dev = smmu_domain->dev; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; void __iomem *base; int ret; ktime_t cur; u32 val; struct scm_desc desc = { .args[0] = SCM_CONFIG_ERRATA1_CLIENT_ALL, .args[1] = false, .arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL), }; base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); writel_relaxed(0, base + ARM_SMMU_CB_S1_TLBIALL); writel_relaxed(0, base + ARM_SMMU_CB_TLBSYNC); if (readl_poll_timeout_atomic(base + ARM_SMMU_CB_TLBSTATUS, val, !(val & TLBSTATUS_SACTIVE), 0, 100)) { if (!readl_poll_timeout_atomic(base + ARM_SMMU_CB_TLBSTATUS, val, !(val & TLBSTATUS_SACTIVE), 0, 100)) return; ret = scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_SMMU_PROGRAM, SCM_CONFIG_ERRATA1), &desc); if (ret) { dev_err(smmu->dev, "Calling into TZ to disable ERRATA1 failed - IOMMU hardware in bad state\n"); BUG(); return; } cur = ktime_get(); trace_tlbi_throttle_start(dev, 0); msm_bus_noc_throttle_wa(true); if (readl_poll_timeout_atomic(base + ARM_SMMU_CB_TLBSTATUS, val, !(val & TLBSTATUS_SACTIVE), 0, 10000)) { dev_err(smmu->dev, "ERRATA1 TLBSYNC timeout"); dev_err(smmu->dev, "ERRATA1 TLBSYNC timeout - IOMMU hardware in bad state"); trace_tlbsync_timeout(dev, 0); BUG(); } msm_bus_noc_throttle_wa(false); trace_tlbi_throttle_end(dev, ktime_us_delta(ktime_get(), cur)); trace_tlbi_throttle_end( dev, ktime_us_delta(ktime_get(), cur)); desc.args[1] = true; ret = scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_SMMU_PROGRAM, SCM_CONFIG_ERRATA1), &desc); if (ret) { dev_err(smmu->dev, "Calling into TZ to reenable ERRATA1 failed - IOMMU hardware in bad state\n"); BUG(); } } Loading