iommu/arm-smmu: add option to skip SMR mask sanity check
Usually when an SMMU probes we do a sanity check on the SMR registers to make sure they can fully support all of the mask bits. This check can cause problems for use cases where the SMMU is already in use when the SMMU probes. For example, for continuous splash screen support, the stream matching table is programmed before control is even turned over to Linux. Add an option to skip this sanity check. Change-Id: I51a9231fcd8b73034f1a1ca69e4fbb7e632635fa Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org> Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
This commit is contained in:
parent
b854c94f3d
commit
240d67c2b0
2 changed files with 25 additions and 13 deletions
|
@ -104,6 +104,14 @@ conditions.
|
||||||
enabled for stage 1 translation" (Section 2.1: "Overview
|
enabled for stage 1 translation" (Section 2.1: "Overview
|
||||||
of SMMU operation").
|
of SMMU operation").
|
||||||
|
|
||||||
|
- qcom,no-smr-check : Usually when an SMMU probes we do a sanity check on
|
||||||
|
the SMR registers to make sure they can fully support all
|
||||||
|
of the mask bits. This check can cause problems for use
|
||||||
|
cases where the SMMU is already in use when the SMMU
|
||||||
|
probes. For example, for continuous splash screen
|
||||||
|
support, the stream matching table is programmed before
|
||||||
|
control is even turned over to Linux.
|
||||||
|
|
||||||
- clocks : List of clocks to be used during SMMU register access. See
|
- clocks : List of clocks to be used during SMMU register access. See
|
||||||
Documentation/devicetree/bindings/clock/clock-bindings.txt
|
Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||||
for information about the format. For each clock specified
|
for information about the format. For each clock specified
|
||||||
|
|
|
@ -434,6 +434,7 @@ struct arm_smmu_device {
|
||||||
#define ARM_SMMU_OPT_FATAL_ASF (1 << 6)
|
#define ARM_SMMU_OPT_FATAL_ASF (1 << 6)
|
||||||
#define ARM_SMMU_OPT_ERRATA_TZ_ATOS (1 << 7)
|
#define ARM_SMMU_OPT_ERRATA_TZ_ATOS (1 << 7)
|
||||||
#define ARM_SMMU_OPT_NO_M (1 << 8)
|
#define ARM_SMMU_OPT_NO_M (1 << 8)
|
||||||
|
#define ARM_SMMU_OPT_NO_SMR_CHECK (1 << 9)
|
||||||
u32 options;
|
u32 options;
|
||||||
enum arm_smmu_arch_version version;
|
enum arm_smmu_arch_version version;
|
||||||
|
|
||||||
|
@ -509,6 +510,7 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
|
||||||
{ ARM_SMMU_OPT_FATAL_ASF, "qcom,fatal-asf" },
|
{ ARM_SMMU_OPT_FATAL_ASF, "qcom,fatal-asf" },
|
||||||
{ ARM_SMMU_OPT_ERRATA_TZ_ATOS, "qcom,errata-tz-atos" },
|
{ ARM_SMMU_OPT_ERRATA_TZ_ATOS, "qcom,errata-tz-atos" },
|
||||||
{ ARM_SMMU_OPT_NO_M, "qcom,no-mmu-enable" },
|
{ ARM_SMMU_OPT_NO_M, "qcom,no-mmu-enable" },
|
||||||
|
{ ARM_SMMU_OPT_NO_SMR_CHECK, "qcom,no-smr-check" },
|
||||||
{ 0, NULL},
|
{ 0, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2517,18 +2519,20 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
smr = SMR_MASK_MASK << SMR_MASK_SHIFT;
|
if (!(smmu->options & ARM_SMMU_OPT_NO_SMR_CHECK)) {
|
||||||
smr |= (SMR_ID_MASK << SMR_ID_SHIFT);
|
smr = SMR_MASK_MASK << SMR_MASK_SHIFT;
|
||||||
writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
|
smr |= (SMR_ID_MASK << SMR_ID_SHIFT);
|
||||||
smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
|
writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
|
||||||
|
smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
|
||||||
|
|
||||||
mask = (smr >> SMR_MASK_SHIFT) & SMR_MASK_MASK;
|
mask = (smr >> SMR_MASK_SHIFT) & SMR_MASK_MASK;
|
||||||
sid = (smr >> SMR_ID_SHIFT) & SMR_ID_MASK;
|
sid = (smr >> SMR_ID_SHIFT) & SMR_ID_MASK;
|
||||||
if ((mask & sid) != sid) {
|
if ((mask & sid) != sid) {
|
||||||
dev_err(smmu->dev,
|
dev_err(smmu->dev,
|
||||||
"SMR mask bits (0x%x) insufficient for ID field (0x%x)\n",
|
"SMR mask bits (0x%x) insufficient for ID field (0x%x)\n",
|
||||||
mask, sid);
|
mask, sid);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_notice(smmu->dev,
|
dev_notice(smmu->dev,
|
||||||
|
@ -2710,6 +2714,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
|
||||||
if (err)
|
if (err)
|
||||||
goto out_put_masters;
|
goto out_put_masters;
|
||||||
|
|
||||||
|
parse_driver_options(smmu);
|
||||||
|
|
||||||
arm_smmu_enable_regulators(smmu);
|
arm_smmu_enable_regulators(smmu);
|
||||||
arm_smmu_enable_clocks(smmu);
|
arm_smmu_enable_clocks(smmu);
|
||||||
err = arm_smmu_device_cfg_probe(smmu);
|
err = arm_smmu_device_cfg_probe(smmu);
|
||||||
|
@ -2718,8 +2724,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
|
||||||
if (err)
|
if (err)
|
||||||
goto out_put_masters;
|
goto out_put_masters;
|
||||||
|
|
||||||
parse_driver_options(smmu);
|
|
||||||
|
|
||||||
if (of_device_is_compatible(dev->of_node, "qcom,smmu-v2"))
|
if (of_device_is_compatible(dev->of_node, "qcom,smmu-v2"))
|
||||||
smmu->model = SMMU_MODEL_QCOM_V2;
|
smmu->model = SMMU_MODEL_QCOM_V2;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue