iommu/arm-smmu-qcom: Allow choosing a custom bypass emulation context

It cannot be taken for granted that the last IOMMU context is free
and available for us to use it to emulate bypass streams and, at least
on MSM8998's lpass iommu, using the last one will produce a crash;
please note that this may not be only dependant on the SoC, but also
on the firmware version.

To overcome to this issue, allow specifying a different context for
bypass emulation with the optional DT property "qcom,bypass-cbndx":
if this property is not found this means that we are either booting
with ACPI instead or that we don't want to specify a custom cb because
the default one (the last context bank) is fine.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
This commit is contained in:
AngeloGioacchino Del Regno 2021-08-04 16:39:35 +02:00 committed by Jami Kettunen
parent 28337278f5
commit b3bad314cd

View file

@ -266,7 +266,8 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
reg = arm_smmu_gr0_read(smmu, last_s2cr);
if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
qsmmu->bypass_quirk = true;
qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
if (qsmmu->bypass_cbndx == 0xff)
qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
set_bit(qsmmu->bypass_cbndx, smmu->context_map);
@ -386,6 +387,7 @@ static const struct arm_smmu_impl qcom_adreno_smmu_impl = {
static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
const struct arm_smmu_impl *impl)
{
const struct device_node *np = smmu->dev->of_node;
struct qcom_smmu *qsmmu;
/* Check to make sure qcom_scm has finished probing */
@ -397,6 +399,16 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
return ERR_PTR(-ENOMEM);
qsmmu->smmu.impl = impl;
qsmmu->bypass_cbndx = 0xff;
if (np != NULL) {
/*
* This property is optional and we expect to fail finding it if:
* - Using the default bypass_cbndx (in the .cfg_probe cb) is fine; or
* - We are booting on ACPI
*/
of_property_read_u8(np, "qcom,bypass-cbndx", &qsmmu->bypass_cbndx);
}
return &qsmmu->smmu;
}