Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7ac10f5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iommu: arm-smmu: Update safe errata sequence"

parents 1faac63e 8696005a
Loading
Loading
Loading
Loading
+40 −13
Original line number Diff line number Diff line
@@ -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>
@@ -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();
	}
}