Skip to content

Commit 7de295d

Browse files
larunbebbrezillon
authored andcommitted
drm/panthor: flush FW AS caches in slow reset path
In the off-chance that waiting for the firmware to signal its booted status timed out in the fast reset path, one must flush the cache lines for the entire FW VM address space before reloading the regions, otherwise stale values eventually lead to a scheduler job timeout. Fixes: 647810e ("drm/panthor: Add the MMU/VM logical block") Cc: stable@vger.kernel.org Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902130237.3440720-1-adrian.larumbe@collabora.com
1 parent 76dce2a commit 7de295d

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

drivers/gpu/drm/panthor/panthor_fw.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,12 @@ int panthor_fw_post_reset(struct panthor_device *ptdev)
10891089
panthor_fw_stop(ptdev);
10901090
ptdev->fw->fast_reset = false;
10911091
drm_err(&ptdev->base, "FW fast reset failed, trying a slow reset");
1092+
1093+
ret = panthor_vm_flush_all(ptdev->fw->vm);
1094+
if (ret) {
1095+
drm_err(&ptdev->base, "FW slow reset failed (couldn't flush FW's AS l2cache)");
1096+
return ret;
1097+
}
10921098
}
10931099

10941100
/* Reload all sections, including RO ones. We're not supposed
@@ -1099,7 +1105,7 @@ int panthor_fw_post_reset(struct panthor_device *ptdev)
10991105

11001106
ret = panthor_fw_start(ptdev);
11011107
if (ret) {
1102-
drm_err(&ptdev->base, "FW slow reset failed");
1108+
drm_err(&ptdev->base, "FW slow reset failed (couldn't start the FW )");
11031109
return ret;
11041110
}
11051111

drivers/gpu/drm/panthor/panthor_mmu.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,12 @@ static int mmu_hw_do_operation_locked(struct panthor_device *ptdev, int as_nr,
576576
if (as_nr < 0)
577577
return 0;
578578

579+
/*
580+
* If the AS number is greater than zero, then we can be sure
581+
* the device is up and running, so we don't need to explicitly
582+
* power it up
583+
*/
584+
579585
if (op != AS_COMMAND_UNLOCK)
580586
lock_region(ptdev, as_nr, iova, size);
581587

@@ -874,14 +880,23 @@ static int panthor_vm_flush_range(struct panthor_vm *vm, u64 iova, u64 size)
874880
if (!drm_dev_enter(&ptdev->base, &cookie))
875881
return 0;
876882

877-
/* Flush the PTs only if we're already awake */
878-
if (pm_runtime_active(ptdev->base.dev))
879-
ret = mmu_hw_do_operation(vm, iova, size, AS_COMMAND_FLUSH_PT);
883+
ret = mmu_hw_do_operation(vm, iova, size, AS_COMMAND_FLUSH_PT);
880884

881885
drm_dev_exit(cookie);
882886
return ret;
883887
}
884888

889+
/**
890+
* panthor_vm_flush_all() - Flush L2 caches for the entirety of a VM's AS
891+
* @vm: VM whose cache to flush
892+
*
893+
* Return: 0 on success, a negative error code if flush failed.
894+
*/
895+
int panthor_vm_flush_all(struct panthor_vm *vm)
896+
{
897+
return panthor_vm_flush_range(vm, vm->base.mm_start, vm->base.mm_range);
898+
}
899+
885900
static int panthor_vm_unmap_pages(struct panthor_vm *vm, u64 iova, u64 size)
886901
{
887902
struct panthor_device *ptdev = vm->ptdev;

drivers/gpu/drm/panthor/panthor_mmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ panthor_vm_get_bo_for_va(struct panthor_vm *vm, u64 va, u64 *bo_offset);
3131
int panthor_vm_active(struct panthor_vm *vm);
3232
void panthor_vm_idle(struct panthor_vm *vm);
3333
int panthor_vm_as(struct panthor_vm *vm);
34+
int panthor_vm_flush_all(struct panthor_vm *vm);
3435

3536
struct panthor_heap_pool *
3637
panthor_vm_get_heap_pool(struct panthor_vm *vm, bool create);

0 commit comments

Comments
 (0)