Skip to content

Commit fcf226f

Browse files
AngeloGioacchino Del Regnowilldeacon
authored andcommitted
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: Marijn Suijten <[email protected]> [Marijn: Rebased over next-20221111] Signed-off-by: AngeloGioacchino Del Regno <[email protected]> Reviewed-by: Konrad Dybcio <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 0a8c264 commit fcf226f

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

drivers/iommu/arm/arm-smmu/qcom_iommu.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,8 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
531531
* index into qcom_iommu->ctxs:
532532
*/
533533
if (WARN_ON(asid < 1) ||
534-
WARN_ON(asid > qcom_iommu->num_ctxs)) {
534+
WARN_ON(asid > qcom_iommu->num_ctxs) ||
535+
WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL)) {
535536
put_device(&iommu_pdev->dev);
536537
return -EINVAL;
537538
}
@@ -617,15 +618,26 @@ static int qcom_iommu_sec_ptbl_init(struct device *dev)
617618

618619
static int get_asid(const struct device_node *np)
619620
{
620-
u32 reg;
621+
u32 reg, val;
622+
int asid;
621623

622624
/* read the "reg" property directly to get the relative address
623625
* of the context bank, and calculate the asid from that:
624626
*/
625627
if (of_property_read_u32_index(np, "reg", 0, &reg))
626628
return -ENODEV;
627629

628-
return reg / 0x1000; /* context banks are 0x1000 apart */
630+
/*
631+
* Context banks are 0x1000 apart but, in some cases, the ASID
632+
* number doesn't match to this logic and needs to be passed
633+
* from the DT configuration explicitly.
634+
*/
635+
if (!of_property_read_u32(np, "qcom,ctx-asid", &val))
636+
asid = val;
637+
else
638+
asid = reg / 0x1000;
639+
640+
return asid;
629641
}
630642

631643
static int qcom_iommu_ctx_probe(struct platform_device *pdev)

0 commit comments

Comments
 (0)