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

Commit ad52108e authored by Patrick Daly's avatar Patrick Daly
Browse files

iommu: arm-smmu: Add PM support for actlr register



Save the value of the actlr register so it can be restored upon
resume from hibernation/suspend.

Change-Id: I02dda54ee5905870adae05357e043c4d95003412
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent 6549a1ff
Loading
Loading
Loading
Loading
+10 −20
Original line number Diff line number Diff line
@@ -375,6 +375,7 @@ struct arm_smmu_cb {
	u32				tcr[2];
	u32				mair[2];
	struct arm_smmu_cfg		*cfg;
	u32				actlr;
	u32 				attributes;
};

@@ -1761,6 +1762,9 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx)
		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 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		/* 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 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		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 @@ static void qsmmuv2_device_reset(struct arm_smmu_device *smmu)
	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 @@ static void qsmmuv500_init_cb(struct arm_smmu_domain *smmu_domain,
				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 @@ static void qsmmuv500_init_cb(struct arm_smmu_domain *smmu_domain,
	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)