[PATCH 5/7] drm/xe: Prepare display for D3Cold
Gupta, Anshuman
anshuman.gupta at intel.com
Thu May 9 11:36:20 UTC 2024
> -----Original Message-----
> From: Vivi, Rodrigo <rodrigo.vivi at intel.com>
> Sent: Thursday, May 9, 2024 1:37 AM
> To: intel-xe at lists.freedesktop.org
> Cc: Vivi, Rodrigo <rodrigo.vivi at intel.com>; Gupta, Anshuman
> <anshuman.gupta at intel.com>; Shankar, Uma <uma.shankar at intel.com>
> Subject: [PATCH 5/7] drm/xe: Prepare display for D3Cold
>
> Prepare power-well and DC handling for a full power lost during D3Cold,
> then sanitize it upon D3->D0.
> Otherwise we get a bunch of state mismatch.
>
> Ideally we could leave DC9 enabled and wouldn't need to move DC9->DC0 on
> every runtime resume, however, the disable_DC is part of the power-well
> checks and intrinsic to the dc_off power well. In the future that can be
> detangled so we can have even bigger power savings.
> But for now, let's focus on getting a D3Cold, which saves much more power
> by itself.
>
> v2: create new functions to avoid full-suspend-resume path, which would
> result in a deadlock between xe_gem_fault and the modeset-ioctl.
>
> v3: Only avoid the full modeset to avoid the race, for a more robust suspend-
> resume.
>
> Cc: Anshuman Gupta <anshuman.gupta at intel.com>
> Cc: Uma Shankar <uma.shankar at intel.com>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
> ---
> drivers/gpu/drm/xe/display/xe_display.c | 10 ++++++----
> drivers/gpu/drm/xe/display/xe_display.h | 8 ++++----
> drivers/gpu/drm/xe/xe_pm.c | 15 ++++++++++++---
> 3 files changed, 22 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/display/xe_display.c
> b/drivers/gpu/drm/xe/display/xe_display.c
> index 0de0566e5b39..4b3fae8b4893 100644
> --- a/drivers/gpu/drm/xe/display/xe_display.c
> +++ b/drivers/gpu/drm/xe/display/xe_display.c
> @@ -300,7 +300,7 @@ static bool suspend_to_idle(void)
> return false;
> }
>
> -void xe_display_pm_suspend(struct xe_device *xe)
> +void xe_display_pm_suspend(struct xe_device *xe, bool runtime)
> {
> bool s2idle = suspend_to_idle();
> if (!xe->info.enable_display)
> @@ -314,7 +314,8 @@ void xe_display_pm_suspend(struct xe_device *xe)
> if (has_display(xe))
> drm_kms_helper_poll_disable(&xe->drm);
>
> - intel_display_driver_suspend(xe);
> + if (!runtime)
> + intel_display_driver_suspend(xe);
There is one more reason, we won't need full modeset here apart from avoiding the full moseset,
As runtime PM will only trigger after last crtc will be turned off by dpms off.
There we already do a full modeset, so we don't need full modeset at runtime suspend/resume.
Reviewed-by: Anshuman Gupta <anshuman.gupta at intel.com>
>
> intel_dp_mst_suspend(xe);
>
> @@ -350,7 +351,7 @@ void xe_display_pm_resume_early(struct xe_device
> *xe)
> intel_power_domains_resume(xe);
> }
>
> -void xe_display_pm_resume(struct xe_device *xe)
> +void xe_display_pm_resume(struct xe_device *xe, bool runtime)
> {
> if (!xe->info.enable_display)
> return;
> @@ -365,7 +366,8 @@ void xe_display_pm_resume(struct xe_device *xe)
>
> /* MST sideband requires HPD interrupts enabled */
> intel_dp_mst_resume(xe);
> - intel_display_driver_resume(xe);
> + if (!runtime)
> + intel_display_driver_resume(xe);
>
> intel_hpd_poll_disable(xe);
> if (has_display(xe))
> diff --git a/drivers/gpu/drm/xe/display/xe_display.h
> b/drivers/gpu/drm/xe/display/xe_display.h
> index 710e56180b52..93d1f779b978 100644
> --- a/drivers/gpu/drm/xe/display/xe_display.h
> +++ b/drivers/gpu/drm/xe/display/xe_display.h
> @@ -34,10 +34,10 @@ void xe_display_irq_enable(struct xe_device *xe, u32
> gu_misc_iir); void xe_display_irq_reset(struct xe_device *xe); void
> xe_display_irq_postinstall(struct xe_device *xe, struct xe_gt *gt);
>
> -void xe_display_pm_suspend(struct xe_device *xe);
> +void xe_display_pm_suspend(struct xe_device *xe, bool runtime);
> void xe_display_pm_suspend_late(struct xe_device *xe); void
> xe_display_pm_resume_early(struct xe_device *xe); -void
> xe_display_pm_resume(struct xe_device *xe);
> +void xe_display_pm_resume(struct xe_device *xe, bool runtime);
>
> #else
>
> @@ -63,10 +63,10 @@ static inline void xe_display_irq_enable(struct
> xe_device *xe, u32 gu_misc_iir) static inline void xe_display_irq_reset(struct
> xe_device *xe) {} static inline void xe_display_irq_postinstall(struct xe_device
> *xe, struct xe_gt *gt) {}
>
> -static inline void xe_display_pm_suspend(struct xe_device *xe) {}
> +static inline void xe_display_pm_suspend(struct xe_device *xe, bool
> +runtime) {}
> static inline void xe_display_pm_suspend_late(struct xe_device *xe) {} static
> inline void xe_display_pm_resume_early(struct xe_device *xe) {} -static inline
> void xe_display_pm_resume(struct xe_device *xe) {}
> +static inline void xe_display_pm_resume(struct xe_device *xe, bool
> +runtime) {}
>
> #endif /* CONFIG_DRM_XE_DISPLAY */
> #endif /* _XE_DISPLAY_H_ */
> diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index
> c3ef2283770f..a2f5a1b11cbf 100644
> --- a/drivers/gpu/drm/xe/xe_pm.c
> +++ b/drivers/gpu/drm/xe/xe_pm.c
> @@ -96,12 +96,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;
> }
> }
> @@ -151,7 +151,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);
> @@ -366,6 +366,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 +376,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;
> @@ -411,6 +417,8 @@ int xe_pm_runtime_resume(struct xe_device *xe)
> 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.
> @@ -426,6 +434,7 @@ int xe_pm_runtime_resume(struct xe_device *xe)
> xe_gt_resume(gt);
>
> if (xe->d3cold.allowed && xe->d3cold.power_lost) {
> + xe_display_pm_resume(xe, true);
> err = xe_bo_restore_user(xe);
> if (err)
> goto out;
> --
> 2.44.0
More information about the Intel-xe
mailing list