Skip to content

Commit f2d9848

Browse files
hannahawawilldeacon
authored andcommitted
iommu/arm-smmu: Workaround for Marvell Armada-AP806 SoC erratum #582743
Due to erratum #582743, the Marvell Armada-AP806 can't access 64bit to ARM SMMUv2 registers. Provide implementation relevant hooks: - split the writeq/readq to two accesses of writel/readl. - mask the MMU_IDR2.PTFSv8 fields to not use AArch64 format (but only AARCH32_L) since with AArch64 format 32 bits access is not supported. Note that most 64-bit registers like TTBRn can be accessed as two 32-bit halves without issue, and AArch32 format ensures that the register writes which must be atomic (for TLBI etc.) need only be 32-bit. Signed-off-by: Hanna Hawa <[email protected]> Signed-off-by: Gregory CLEMENT <[email protected]> Signed-off-by: Tomasz Nowicki <[email protected]> Reviewed-by: Robin Murphy <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 6a79a5a commit f2d9848

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

Documentation/arm64/silicon-errata.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ stable kernels.
125125
| Cavium | ThunderX2 Core | #219 | CAVIUM_TX2_ERRATUM_219 |
126126
+----------------+-----------------+-----------------+-----------------------------+
127127
+----------------+-----------------+-----------------+-----------------------------+
128+
| Marvell | ARM-MMU-500 | #582743 | N/A |
129+
+----------------+-----------------+-----------------+-----------------------------+
130+
+----------------+-----------------+-----------------+-----------------------------+
128131
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
129132
+----------------+-----------------+-----------------+-----------------------------+
130133
+----------------+-----------------+-----------------+-----------------------------+

drivers/iommu/arm-smmu-impl.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,48 @@ static const struct arm_smmu_impl arm_mmu500_impl = {
147147
.reset = arm_mmu500_reset,
148148
};
149149

150+
static u64 mrvl_mmu500_readq(struct arm_smmu_device *smmu, int page, int off)
151+
{
152+
/*
153+
* Marvell Armada-AP806 erratum #582743.
154+
* Split all the readq to double readl
155+
*/
156+
return hi_lo_readq_relaxed(arm_smmu_page(smmu, page) + off);
157+
}
158+
159+
static void mrvl_mmu500_writeq(struct arm_smmu_device *smmu, int page, int off,
160+
u64 val)
161+
{
162+
/*
163+
* Marvell Armada-AP806 erratum #582743.
164+
* Split all the writeq to double writel
165+
*/
166+
hi_lo_writeq_relaxed(val, arm_smmu_page(smmu, page) + off);
167+
}
168+
169+
static int mrvl_mmu500_cfg_probe(struct arm_smmu_device *smmu)
170+
{
171+
172+
/*
173+
* Armada-AP806 erratum #582743.
174+
* Hide the SMMU_IDR2.PTFSv8 fields to sidestep the AArch64
175+
* formats altogether and allow using 32 bits access on the
176+
* interconnect.
177+
*/
178+
smmu->features &= ~(ARM_SMMU_FEAT_FMT_AARCH64_4K |
179+
ARM_SMMU_FEAT_FMT_AARCH64_16K |
180+
ARM_SMMU_FEAT_FMT_AARCH64_64K);
181+
182+
return 0;
183+
}
184+
185+
static const struct arm_smmu_impl mrvl_mmu500_impl = {
186+
.read_reg64 = mrvl_mmu500_readq,
187+
.write_reg64 = mrvl_mmu500_writeq,
188+
.cfg_probe = mrvl_mmu500_cfg_probe,
189+
.reset = arm_mmu500_reset,
190+
};
191+
150192

151193
struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
152194
{
@@ -177,5 +219,8 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
177219
of_device_is_compatible(np, "qcom,sm8250-smmu-500"))
178220
return qcom_smmu_impl_init(smmu);
179221

222+
if (of_device_is_compatible(np, "marvell,ap806-smmu-500"))
223+
smmu->impl = &mrvl_mmu500_impl;
224+
180225
return smmu;
181226
}

0 commit comments

Comments
 (0)