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

Commit 56cbbdfb authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iommu: arm-smmu: Add error message for hibernation usecase"

parents d6df3215 c2beab3f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1578,7 +1578,7 @@ static int device_add_class_symlinks(struct device *dev)
	struct device_node *of_node = dev_of_node(dev);
	int error;

	if (of_node) {
	if (of_node && of_node_kobj(of_node)) {
		error = sysfs_create_link(&dev->kobj, of_node_kobj(of_node), "of_node");
		if (error)
			dev_warn(dev, "Error %d creating of_node link\n",error);
+37 −22
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ struct arm_smmu_cb {
	u32				tcr[2];
	u32				mair[2];
	struct arm_smmu_cfg		*cfg;
	u32				actlr;
};

struct arm_smmu_master_cfg {
@@ -514,6 +515,11 @@ static void arm_smmu_secure_domain_unlock(struct arm_smmu_domain *smmu_domain)
		mutex_unlock(&smmu_domain->assign_lock);
}

static bool arm_smmu_opt_hibernation(struct arm_smmu_device *smmu)
{
	return IS_ENABLED(CONFIG_HIBERNATION);
}

/*
 * init()
 * Hook for additional device tree parsing at probe time.
@@ -1586,6 +1592,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;

@@ -1684,6 +1693,14 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		goto out_unlock;
	}

	if (arm_smmu_has_secure_vmid(smmu_domain) &&
	    arm_smmu_opt_hibernation(smmu)) {
		dev_err(smmu->dev,
			"Secure usecases not supported with hibernation\n");
		ret = -EPERM;
		goto out_unlock;
	}

	/*
	 * Mapping the requested stage onto what we support is surprisingly
	 * complicated, mainly because the spec allows S1+S2 SMMUs without
@@ -1864,11 +1881,9 @@ 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,
						smmu_domain->attributes );

		arm_smmu_arch_init_context_bank(smmu_domain, dev);

		/* for slave side secure, we may have to force the pagetable
		 * format to V8L.
		 */
@@ -1877,7 +1892,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		if (ret)
			goto out_clear_smmu;


		/*
		 * Request context fault interrupt. Do this last to avoid the
		 * handler seeing a half-initialised domain state.
@@ -3620,18 +3634,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(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 */
@@ -3720,7 +3733,7 @@ static void arm_smmu_context_bank_reset(struct arm_smmu_device *smmu)
	for (i = 0; i < smmu->num_context_banks; ++i) {
		cb_base = ARM_SMMU_CB(smmu, i);

		writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR);
		arm_smmu_write_context_bank(smmu, i, 0);
		writel_relaxed(FSR_FAULT, cb_base + ARM_SMMU_CB_FSR);
		/*
		 * Disable MMU-500's not-particularly-beneficial next-page
@@ -4258,6 +4271,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
				 sizeof(*smmu->cbs), GFP_KERNEL);
	if (!smmu->cbs)
		return -ENOMEM;
	for (i = 0; i < smmu->num_context_banks; i++) {
		void __iomem *cb_base;

		cb_base = ARM_SMMU_CB(smmu, i);
		smmu->cbs[i].actlr = readl_relaxed(cb_base + ARM_SMMU_CB_ACTLR);
	}

	/* ID2 */
	id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID2);
@@ -4674,8 +4693,15 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
{
	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
	int ret;

	ret = arm_smmu_power_on(smmu->pwr);
	if (ret)
		return ret;

	arm_smmu_device_reset(smmu);
	arm_smmu_power_off(smmu->pwr);

	return 0;
}

@@ -5181,19 +5207,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(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 ARM_SMMU_MIN_IOVA_ALIGN.
@@ -5201,12 +5222,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_errata1_min_iova_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)