drm/panthor: Always wait after sending a command to an AS

There's currently no situation where we want to issue a command to an
AS and not wait for this command to complete. The wait is either
explicitly done (LOCK, UNLOCK) or it's missing (UPDATE). So let's
turn write_cmd() into as_send_cmd_and_wait() that has the wait after
a command is sent.

v2:
- New patch

v3:
- Collect R-b

v4:
- No changes

Reviewed-by: Steven Price <steven.price@arm.com>
Link: https://patch.msgid.link/20251128084841.3804658-2-boris.brezillon@collabora.com
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
This commit is contained in:
Boris Brezillon 2025-11-28 09:48:35 +01:00
parent 342ccffd9f
commit d2c6fde56d

View File

@ -524,27 +524,29 @@ static int wait_ready(struct panthor_device *ptdev, u32 as_nr)
return ret;
}
static int write_cmd(struct panthor_device *ptdev, u32 as_nr, u32 cmd)
static int as_send_cmd_and_wait(struct panthor_device *ptdev, u32 as_nr, u32 cmd)
{
int status;
/* write AS_COMMAND when MMU is ready to accept another command */
status = wait_ready(ptdev, as_nr);
if (!status)
if (!status) {
gpu_write(ptdev, AS_COMMAND(as_nr), cmd);
status = wait_ready(ptdev, as_nr);
}
return status;
}
static void lock_region(struct panthor_device *ptdev, u32 as_nr,
u64 region_start, u64 size)
static int lock_region(struct panthor_device *ptdev, u32 as_nr,
u64 region_start, u64 size)
{
u8 region_width;
u64 region;
u64 region_end = region_start + size;
if (!size)
return;
return 0;
/*
* The locked region is a naturally aligned power of 2 block encoded as
@ -567,7 +569,7 @@ static void lock_region(struct panthor_device *ptdev, u32 as_nr,
/* Lock the region that needs to be updated */
gpu_write64(ptdev, AS_LOCKADDR(as_nr), region);
write_cmd(ptdev, as_nr, AS_COMMAND_LOCK);
return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_LOCK);
}
static int mmu_hw_do_operation_locked(struct panthor_device *ptdev, int as_nr,
@ -600,9 +602,7 @@ static int mmu_hw_do_operation_locked(struct panthor_device *ptdev, int as_nr,
* power it up
*/
lock_region(ptdev, as_nr, iova, size);
ret = wait_ready(ptdev, as_nr);
ret = lock_region(ptdev, as_nr, iova, size);
if (ret)
return ret;
@ -615,10 +615,7 @@ static int mmu_hw_do_operation_locked(struct panthor_device *ptdev, int as_nr,
* at the end of the GPU_CONTROL cache flush command, unlike
* AS_COMMAND_FLUSH_MEM or AS_COMMAND_FLUSH_PT.
*/
write_cmd(ptdev, as_nr, AS_COMMAND_UNLOCK);
/* Wait for the unlock command to complete */
return wait_ready(ptdev, as_nr);
return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UNLOCK);
}
static int mmu_hw_do_operation(struct panthor_vm *vm,
@ -647,7 +644,7 @@ static int panthor_mmu_as_enable(struct panthor_device *ptdev, u32 as_nr,
gpu_write64(ptdev, AS_MEMATTR(as_nr), memattr);
gpu_write64(ptdev, AS_TRANSCFG(as_nr), transcfg);
return write_cmd(ptdev, as_nr, AS_COMMAND_UPDATE);
return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
}
static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr)
@ -662,7 +659,7 @@ static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr)
gpu_write64(ptdev, AS_MEMATTR(as_nr), 0);
gpu_write64(ptdev, AS_TRANSCFG(as_nr), AS_TRANSCFG_ADRMODE_UNMAPPED);
return write_cmd(ptdev, as_nr, AS_COMMAND_UPDATE);
return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
}
static u32 panthor_mmu_fault_mask(struct panthor_device *ptdev, u32 value)