Split hardware component suspend/resume from the top-level device PM path and protect those transitions with a dedicated mutex and state flag.
This lets access-window arbitration suspend or resume GPU components while runtime PM state remains controlled by the outer PM path. Signed-off-by: Karunika Choo <[email protected]> --- drivers/gpu/drm/panthor/panthor_aw.c | 1 - drivers/gpu/drm/panthor/panthor_device.c | 50 +++++++++++++++++++++--- drivers/gpu/drm/panthor/panthor_device.h | 9 +++++ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_aw.c b/drivers/gpu/drm/panthor/panthor_aw.c index 00a52175f3a3..146907a3098d 100644 --- a/drivers/gpu/drm/panthor/panthor_aw.c +++ b/drivers/gpu/drm/panthor/panthor_aw.c @@ -192,7 +192,6 @@ static void panthor_aw_handle_message(struct panthor_aw *aw) drm_warn(&ptdev->base, "Unsupported msg id (0x%x)", msg_id); } - static irqreturn_t panthor_aw_irq_raw_hander(int irq, void *data) { struct panthor_irq *pirq = data; diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c index 7248e2aa9da2..a8aedbee7c97 100644 --- a/drivers/gpu/drm/panthor/panthor_device.c +++ b/drivers/gpu/drm/panthor/panthor_device.c @@ -179,6 +179,10 @@ int panthor_device_init(struct panthor_device *ptdev) if (ret) return ret; + ret = drmm_mutex_init(&ptdev->base, &ptdev->pm.hw_component_lock); + if (ret) + return ret; + ret = drmm_mutex_init(&ptdev->base, &ptdev->pm.mmio_lock); if (ret) return ret; @@ -289,6 +293,9 @@ int panthor_device_init(struct panthor_device *ptdev) if (ret) goto err_unplug_mmu; + atomic_set(&ptdev->pm.hw_component_state, + PANTHOR_DEVICE_PM_STATE_ACTIVE); + ret = panthor_sched_init(ptdev); if (ret) goto err_unplug_fw; @@ -477,21 +484,55 @@ int panthor_device_mmap_io(struct panthor_device *ptdev, struct vm_area_struct * return 0; } -static int panthor_device_resume_hw_components(struct panthor_device *ptdev) +int panthor_device_suspend_hw_components(struct panthor_device *ptdev) +{ + guard(mutex)(&ptdev->pm.hw_component_lock); + + if (atomic_read(&ptdev->pm.hw_component_state) == + PANTHOR_DEVICE_PM_STATE_SUSPENDED) + return 0; + + if (!pm_runtime_suspended(ptdev->base.dev)) { + panthor_fw_suspend(ptdev); + panthor_mmu_suspend(ptdev); + panthor_gpu_suspend(ptdev); + panthor_pwr_suspend(ptdev); + } + + atomic_set(&ptdev->pm.hw_component_state, + PANTHOR_DEVICE_PM_STATE_SUSPENDED); + + return 0; +} + +int panthor_device_resume_hw_components(struct panthor_device *ptdev) { int ret; + guard(mutex)(&ptdev->pm.hw_component_lock); + + if (atomic_read(&ptdev->pm.hw_component_state) == + PANTHOR_DEVICE_PM_STATE_ACTIVE) + return 0; + panthor_pwr_resume(ptdev); panthor_gpu_resume(ptdev); panthor_mmu_resume(ptdev); ret = panthor_fw_resume(ptdev); - if (!ret) + if (!ret) { + atomic_set(&ptdev->pm.hw_component_state, + PANTHOR_DEVICE_PM_STATE_ACTIVE); return 0; + } panthor_mmu_suspend(ptdev); panthor_gpu_suspend(ptdev); panthor_pwr_suspend(ptdev); + + atomic_set(&ptdev->pm.hw_component_state, + PANTHOR_DEVICE_PM_STATE_SUSPENDED); + return ret; } @@ -602,10 +643,7 @@ int panthor_device_suspend(struct device *dev) * The end of the reset will happen in the resume path though. */ panthor_sched_suspend(ptdev); - panthor_fw_suspend(ptdev); - panthor_mmu_suspend(ptdev); - panthor_gpu_suspend(ptdev); - panthor_pwr_suspend(ptdev); + panthor_device_suspend_hw_components(ptdev); drm_dev_exit(cookie); } diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h index a1092d02a1fe..d7beb7165577 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -350,6 +350,12 @@ struct panthor_device { /** @recovery_needed: True when a resume attempt failed. */ atomic_t recovery_needed; + + /** @hw_component_lock: Lock protects HW component PM state transitions */ + struct mutex hw_component_lock; + + /** @hw_component_state: HW component PM state */ + atomic_t hw_component_state; } pm; /** @profile_mask: User-set profiling flags for job accounting. */ @@ -439,6 +445,9 @@ int panthor_device_mmap_io(struct panthor_device *ptdev, int panthor_device_resume(struct device *dev); int panthor_device_suspend(struct device *dev); +int panthor_device_suspend_hw_components(struct panthor_device *ptdev); +int panthor_device_resume_hw_components(struct panthor_device *ptdev); + static inline int panthor_device_resume_and_get(struct panthor_device *ptdev) { int ret = pm_runtime_resume_and_get(ptdev->base.dev); -- 2.43.0
