Commit fcf226f1 authored by AngeloGioacchino Del Regno's avatar AngeloGioacchino Del Regno Committed by Will Deacon
Browse files

iommu/qcom: Use the asid read from device-tree if specified



As specified in this driver, the context banks are 0x1000 apart but
on some SoCs the context number does not necessarily match this
logic, hence we end up using the wrong ASID: keeping in mind that
this IOMMU implementation relies heavily on SCM (TZ) calls, it is
mandatory that we communicate the right context number.

Since this is all about how context banks are mapped in firmware,
which may be board dependent (as a different firmware version may
eventually change the expected context bank numbers), introduce a
new property "qcom,ctx-asid": when found, the ASID will be forced
as read from the devicetree.

When "qcom,ctx-asid" is not found, this driver retains the previous
behavior as to avoid breaking older devicetrees or systems that do
not require forcing ASID numbers.

Signed-off-by: default avatarMarijn Suijten <marijn.suijten@somainline.org>
[Marijn: Rebased over next-20221111]
Signed-off-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: default avatarKonrad Dybcio <konrad.dybcio@linaro.org>
Link: https://lore.kernel.org/r/20230622092742.74819-3-angelogioacchino.delregno@collabora.com


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 0a8c264d
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -531,7 +531,8 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
	 * index into qcom_iommu->ctxs:
	 */
	if (WARN_ON(asid < 1) ||
	    WARN_ON(asid > qcom_iommu->num_ctxs)) {
	    WARN_ON(asid > qcom_iommu->num_ctxs) ||
	    WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL)) {
		put_device(&iommu_pdev->dev);
		return -EINVAL;
	}
@@ -617,7 +618,8 @@ static int qcom_iommu_sec_ptbl_init(struct device *dev)

static int get_asid(const struct device_node *np)
{
	u32 reg;
	u32 reg, val;
	int asid;

	/* read the "reg" property directly to get the relative address
	 * of the context bank, and calculate the asid from that:
@@ -625,7 +627,17 @@ static int get_asid(const struct device_node *np)
	if (of_property_read_u32_index(np, "reg", 0, &reg))
		return -ENODEV;

	return reg / 0x1000;      /* context banks are 0x1000 apart */
	/*
	 * Context banks are 0x1000 apart but, in some cases, the ASID
	 * number doesn't match to this logic and needs to be passed
	 * from the DT configuration explicitly.
	 */
	if (!of_property_read_u32(np, "qcom,ctx-asid", &val))
		asid = val;
	else
		asid = reg / 0x1000;

	return asid;
}

static int qcom_iommu_ctx_probe(struct platform_device *pdev)