diff options
Diffstat (limited to 'drivers/gpu/drm/xe/xe_pm.c')
-rw-r--r-- | drivers/gpu/drm/xe/xe_pm.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index 37fbeda12d3b..9f3c14fd9f33 100644 --- a/drivers/gpu/drm/xe/xe_pm.c +++ b/drivers/gpu/drm/xe/xe_pm.c @@ -20,6 +20,7 @@ #include "xe_guc.h" #include "xe_irq.h" #include "xe_pcode.h" +#include "xe_trace.h" #include "xe_wa.h" /** @@ -69,7 +70,7 @@ */ #ifdef CONFIG_LOCKDEP -struct lockdep_map xe_pm_runtime_lockdep_map = { +static struct lockdep_map xe_pm_runtime_lockdep_map = { .name = "xe_pm_runtime_lockdep_map" }; #endif @@ -87,6 +88,7 @@ int xe_pm_suspend(struct xe_device *xe) int err; drm_dbg(&xe->drm, "Suspending device\n"); + trace_xe_pm_suspend(xe, __builtin_return_address(0)); for_each_gt(gt, xe, id) xe_gt_suspend_prepare(gt); @@ -96,12 +98,12 @@ int xe_pm_suspend(struct xe_device *xe) if (err) goto err; - xe_display_pm_suspend(xe); + xe_display_pm_suspend(xe, false); for_each_gt(gt, xe, id) { err = xe_gt_suspend(gt); if (err) { - xe_display_pm_resume(xe); + xe_display_pm_resume(xe, false); goto err; } } @@ -131,6 +133,7 @@ int xe_pm_resume(struct xe_device *xe) int err; drm_dbg(&xe->drm, "Resuming device\n"); + trace_xe_pm_resume(xe, __builtin_return_address(0)); for_each_tile(tile, xe, id) xe_wa_apply_tile_workarounds(tile); @@ -151,7 +154,7 @@ int xe_pm_resume(struct xe_device *xe) xe_irq_resume(xe); - xe_display_pm_resume(xe); + xe_display_pm_resume(xe, false); for_each_gt(gt, xe, id) xe_gt_resume(gt); @@ -326,6 +329,7 @@ int xe_pm_runtime_suspend(struct xe_device *xe) u8 id; int err = 0; + trace_xe_pm_runtime_suspend(xe, __builtin_return_address(0)); /* Disable access_ongoing asserts and prevent recursive pm calls */ xe_pm_write_callback_task(xe, current); @@ -366,6 +370,7 @@ int xe_pm_runtime_suspend(struct xe_device *xe) err = xe_bo_evict_all(xe); if (err) goto out; + xe_display_pm_suspend(xe, true); } for_each_gt(gt, xe, id) { @@ -375,7 +380,12 @@ int xe_pm_runtime_suspend(struct xe_device *xe) } xe_irq_suspend(xe); + + if (xe->d3cold.allowed) + xe_display_pm_suspend_late(xe); out: + if (err) + xe_display_pm_resume(xe, true); lock_map_release(&xe_pm_runtime_lockdep_map); xe_pm_write_callback_task(xe, NULL); return err; @@ -393,24 +403,19 @@ int xe_pm_runtime_resume(struct xe_device *xe) u8 id; int err = 0; + trace_xe_pm_runtime_resume(xe, __builtin_return_address(0)); /* Disable access_ongoing asserts and prevent recursive pm calls */ xe_pm_write_callback_task(xe, current); lock_map_acquire(&xe_pm_runtime_lockdep_map); - /* - * It can be possible that xe has allowed d3cold but other pcie devices - * in gfx card soc would have blocked d3cold, therefore card has not - * really lost power. Detecting primary Gt power is sufficient. - */ - gt = xe_device_get_gt(xe, 0); - xe->d3cold.power_lost = xe_guc_in_reset(>->uc.guc); - - if (xe->d3cold.allowed && xe->d3cold.power_lost) { + if (xe->d3cold.allowed) { err = xe_pcode_ready(xe, true); if (err) goto out; + xe_display_pm_resume_early(xe); + /* * This only restores pinned memory which is the memory * required for the GT(s) to resume. @@ -425,7 +430,8 @@ int xe_pm_runtime_resume(struct xe_device *xe) for_each_gt(gt, xe, id) xe_gt_resume(gt); - if (xe->d3cold.allowed && xe->d3cold.power_lost) { + if (xe->d3cold.allowed) { + xe_display_pm_resume(xe, true); err = xe_bo_restore_user(xe); if (err) goto out; @@ -462,6 +468,7 @@ static void pm_runtime_lockdep_prime(void) */ void xe_pm_runtime_get(struct xe_device *xe) { + trace_xe_pm_runtime_get(xe, __builtin_return_address(0)); pm_runtime_get_noresume(xe->drm.dev); if (xe_pm_read_callback_task(xe) == current) @@ -477,6 +484,7 @@ void xe_pm_runtime_get(struct xe_device *xe) */ void xe_pm_runtime_put(struct xe_device *xe) { + trace_xe_pm_runtime_put(xe, __builtin_return_address(0)); if (xe_pm_read_callback_task(xe) == current) { pm_runtime_put_noidle(xe->drm.dev); } else { @@ -494,6 +502,7 @@ void xe_pm_runtime_put(struct xe_device *xe) */ int xe_pm_runtime_get_ioctl(struct xe_device *xe) { + trace_xe_pm_runtime_get_ioctl(xe, __builtin_return_address(0)); if (WARN_ON(xe_pm_read_callback_task(xe) == current)) return -ELOOP; @@ -505,19 +514,20 @@ int xe_pm_runtime_get_ioctl(struct xe_device *xe) * xe_pm_runtime_get_if_active - Get a runtime_pm reference if device active * @xe: xe device instance * - * Returns: Any number greater than or equal to 0 for success, negative error - * code otherwise. + * Return: True if device is awake (regardless the previous number of references) + * and a new reference was taken, false otherwise. */ -int xe_pm_runtime_get_if_active(struct xe_device *xe) +bool xe_pm_runtime_get_if_active(struct xe_device *xe) { - return pm_runtime_get_if_active(xe->drm.dev); + return pm_runtime_get_if_active(xe->drm.dev) > 0; } /** - * xe_pm_runtime_get_if_in_use - Get a runtime_pm reference and resume if needed + * xe_pm_runtime_get_if_in_use - Get a new reference if device is active with previous ref taken * @xe: xe device instance * - * Returns: True if device is awake and the reference was taken, false otherwise. + * Return: True if device is awake, a previous reference had been already taken, + * and a new reference was now taken, false otherwise. */ bool xe_pm_runtime_get_if_in_use(struct xe_device *xe) { |