[PATCH 2/4] iommu/exynos: fix the enable sequence for no-block SysMMUs
Markuss Broks via B4 Relay <[email protected]>
| Newsgroups | dev.linux.lists.iommu,org.infradead.lists.linux-arm-kernel,org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel,org.kernel.vger.linux-samsung-soc |
|---|---|
| Message-ID | <[email protected]> |
From: Markuss Broks <[email protected]> __sysmmu_enable() writes CTRL_BLOCK before programming CFG, the page table base and the VM registers. CTRL_BLOCK has the enable bit set, so on hardware without BLOCK mode this write immediately starts translation with whatever FLPT base the registers hold: reset values on the first enable, a stale page table on re-enable. A master that is already emitting traffic at that point gets its transactions translated through that garbage. Keep the MMU disabled while it is being programmed on such hardware; the final CTRL_ENABLE write then brings it up with a consistent configuration in one step, which is also the same as the vendor driver sequence. Signed-off-by: Markuss Broks <[email protected]> --- drivers/iommu/exynos-iommu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 0319da9fd831..a3a59d8a4cf1 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -655,7 +655,12 @@ static void __sysmmu_enable(struct sysmmu_drvdata *data) __sysmmu_enable_clocks(data); spin_lock_irqsave(&data->lock, flags); - writel(CTRL_BLOCK, data->sfrbase + REG_MMU_CTRL); + /* + * On no-block hardware CTRL_BLOCK acts as a plain enable; keep the + * MMU disabled until it is fully programmed. + */ + if (!data->no_block) + writel(CTRL_BLOCK, data->sfrbase + REG_MMU_CTRL); __sysmmu_init_config(data); __sysmmu_set_ptbase(data, data->pgtable); __sysmmu_enable_vid(data); -- 2.55.0