|
@@ -146,6 +146,8 @@
|
|
|
#define ID0_CTTW (1 << 14)
|
|
|
#define ID0_NUMIRPT_SHIFT 16
|
|
|
#define ID0_NUMIRPT_MASK 0xff
|
|
|
+#define ID0_NUMSIDB_SHIFT 9
|
|
|
+#define ID0_NUMSIDB_MASK 0xf
|
|
|
#define ID0_NUMSMRG_SHIFT 0
|
|
|
#define ID0_NUMSMRG_MASK 0xff
|
|
|
|
|
@@ -524,9 +526,18 @@ static int register_smmu_master(struct arm_smmu_device *smmu,
|
|
|
master->of_node = masterspec->np;
|
|
|
master->cfg.num_streamids = masterspec->args_count;
|
|
|
|
|
|
- for (i = 0; i < master->cfg.num_streamids; ++i)
|
|
|
- master->cfg.streamids[i] = masterspec->args[i];
|
|
|
+ for (i = 0; i < master->cfg.num_streamids; ++i) {
|
|
|
+ u16 streamid = masterspec->args[i];
|
|
|
|
|
|
+ if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) &&
|
|
|
+ (streamid >= smmu->num_mapping_groups)) {
|
|
|
+ dev_err(dev,
|
|
|
+ "stream ID for master device %s greater than maximum allowed (%d)\n",
|
|
|
+ masterspec->np->name, smmu->num_mapping_groups);
|
|
|
+ return -ERANGE;
|
|
|
+ }
|
|
|
+ master->cfg.streamids[i] = streamid;
|
|
|
+ }
|
|
|
return insert_smmu_master(smmu, master);
|
|
|
}
|
|
|
|
|
@@ -1624,7 +1635,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
|
|
|
|
|
|
/* Mark all SMRn as invalid and all S2CRn as bypass */
|
|
|
for (i = 0; i < smmu->num_mapping_groups; ++i) {
|
|
|
- writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(i));
|
|
|
+ writel_relaxed(0, gr0_base + ARM_SMMU_GR0_SMR(i));
|
|
|
writel_relaxed(S2CR_TYPE_BYPASS,
|
|
|
gr0_base + ARM_SMMU_GR0_S2CR(i));
|
|
|
}
|
|
@@ -1759,6 +1770,9 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
|
|
|
dev_notice(smmu->dev,
|
|
|
"\tstream matching with %u register groups, mask 0x%x",
|
|
|
smmu->num_mapping_groups, mask);
|
|
|
+ } else {
|
|
|
+ smmu->num_mapping_groups = (id >> ID0_NUMSIDB_SHIFT) &
|
|
|
+ ID0_NUMSIDB_MASK;
|
|
|
}
|
|
|
|
|
|
/* ID1 */
|
|
@@ -1887,6 +1901,10 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
|
|
|
smmu->irqs[i] = irq;
|
|
|
}
|
|
|
|
|
|
+ err = arm_smmu_device_cfg_probe(smmu);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
i = 0;
|
|
|
smmu->masters = RB_ROOT;
|
|
|
while (!of_parse_phandle_with_args(dev->of_node, "mmu-masters",
|
|
@@ -1903,10 +1921,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
|
|
|
}
|
|
|
dev_notice(dev, "registered %d master devices\n", i);
|
|
|
|
|
|
- err = arm_smmu_device_cfg_probe(smmu);
|
|
|
- if (err)
|
|
|
- goto out_put_masters;
|
|
|
-
|
|
|
parse_driver_options(smmu);
|
|
|
|
|
|
if (smmu->version > 1 &&
|