Skip to content

Commit f322e8a

Browse files
rmurphy-armwilldeacon
authored andcommitted
iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
MMU-600 versions prior to r1p0 fail to correctly generate a WFE wakeup event when the command queue transitions fom full to non-full. We can easily work around this by simply hiding the SEV capability such that we fall back to polling for space in the queue - since MMU-600 implements MSIs we wouldn't expect to need SEV for sync completion either, so this should have little to no impact. Signed-off-by: Robin Murphy <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Tested-by: Nicolin Chen <[email protected]> Link: https://lore.kernel.org/r/08adbe3d01024d8382a478325f73b56851f76e49.1683731256.git.robin.murphy@arm.com Signed-off-by: Will Deacon <[email protected]>
1 parent 44c026a commit f322e8a

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

Documentation/arm64/silicon-errata.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ stable kernels.
140140
+----------------+-----------------+-----------------+-----------------------------+
141141
| ARM | MMU-500 | #841119,826419 | N/A |
142142
+----------------+-----------------+-----------------+-----------------------------+
143+
| ARM | MMU-600 | #1076982 | N/A |
144+
+----------------+-----------------+-----------------+-----------------------------+
143145
+----------------+-----------------+-----------------+-----------------------------+
144146
| Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 |
145147
+----------------+-----------------+-----------------+-----------------------------+

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3429,6 +3429,33 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
34293429
return 0;
34303430
}
34313431

3432+
#define IIDR_IMPLEMENTER_ARM 0x43b
3433+
#define IIDR_PRODUCTID_ARM_MMU_600 0x483
3434+
3435+
static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
3436+
{
3437+
u32 reg;
3438+
unsigned int implementer, productid, variant, revision;
3439+
3440+
reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR);
3441+
implementer = FIELD_GET(IIDR_IMPLEMENTER, reg);
3442+
productid = FIELD_GET(IIDR_PRODUCTID, reg);
3443+
variant = FIELD_GET(IIDR_VARIANT, reg);
3444+
revision = FIELD_GET(IIDR_REVISION, reg);
3445+
3446+
switch (implementer) {
3447+
case IIDR_IMPLEMENTER_ARM:
3448+
switch (productid) {
3449+
case IIDR_PRODUCTID_ARM_MMU_600:
3450+
/* Arm erratum 1076982 */
3451+
if (variant == 0 && revision <= 2)
3452+
smmu->features &= ~ARM_SMMU_FEAT_SEV;
3453+
break;
3454+
}
3455+
break;
3456+
}
3457+
}
3458+
34323459
static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
34333460
{
34343461
u32 reg;
@@ -3635,6 +3662,8 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
36353662

36363663
smmu->ias = max(smmu->ias, smmu->oas);
36373664

3665+
arm_smmu_device_iidr_probe(smmu);
3666+
36383667
if (arm_smmu_sva_supported(smmu))
36393668
smmu->features |= ARM_SMMU_FEAT_SVA;
36403669

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@
6969
#define IDR5_VAX GENMASK(11, 10)
7070
#define IDR5_VAX_52_BIT 1
7171

72+
#define ARM_SMMU_IIDR 0x18
73+
#define IIDR_PRODUCTID GENMASK(31, 20)
74+
#define IIDR_VARIANT GENMASK(19, 16)
75+
#define IIDR_REVISION GENMASK(15, 12)
76+
#define IIDR_IMPLEMENTER GENMASK(11, 0)
77+
7278
#define ARM_SMMU_CR0 0x20
7379
#define CR0_ATSCHK (1 << 4)
7480
#define CR0_CMDQEN (1 << 3)

0 commit comments

Comments
 (0)