Use TRANSTAB == 0 as a way to detect if an AS slot is idle. This
allows us to make panthor_mmu_as_disable() a NOP when it's called
after a SOFT_RESET, which will be needed for our unplug rework.

Signed-off-by: Boris Brezillon <[email protected]>
---
 drivers/gpu/drm/panthor/panthor_mmu.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c 
b/drivers/gpu/drm/panthor/panthor_mmu.c
index 1b401fd0d2d7..a48466788f4d 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.c
+++ b/drivers/gpu/drm/panthor/panthor_mmu.c
@@ -634,6 +634,10 @@ static int panthor_mmu_as_disable(struct panthor_device 
*ptdev, u32 slot,
 
        lockdep_assert_held(&ptdev->mmu->as.slots_lock);
 
+       /* The AS was disabled already, nothing to do. */
+       if (!gpu_read64(mmu->iomem, AS_TRANSTAB(slot)))
+               return 0;
+
        panthor_mmu_irq_disable_events(&ptdev->mmu->irq,
                                       panthor_mmu_as_fault_mask(ptdev, slot));
 
@@ -656,11 +660,17 @@ static int panthor_mmu_as_disable(struct panthor_device 
*ptdev, u32 slot,
        if (recycle_slot)
                return 0;
 
-       gpu_write64(mmu->iomem, AS_TRANSTAB(slot), 0);
-       gpu_write64(mmu->iomem, AS_MEMATTR(slot), 0);
        gpu_write64(mmu->iomem, AS_TRANSCFG(slot), 
AS_TRANSCFG_ADRMODE_UNMAPPED);
+       ret = as_send_cmd_and_wait(ptdev, slot, AS_COMMAND_UPDATE);
+       if (ret)
+               return ret;
 
-       return as_send_cmd_and_wait(ptdev, slot, AS_COMMAND_UPDATE);
+       /* We reset the other fields late to ensure that, if something fails,
+        * the page table is considered active (TRANSTAB != NULL).
+        */
+       gpu_write64(mmu->iomem, AS_MEMATTR(slot), 0);
+       gpu_write64(mmu->iomem, AS_TRANSTAB(slot), 0);
+       return 0;
 }
 
 static u32 panthor_mmu_fault_mask(struct panthor_device *ptdev, u32 value)

-- 
2.55.0

Reply via email to