diff mbox series

[10/31] drm/xe/display: Spin-off xe_display runtime/d3cold sequences

Message ID 20240924204222.246862-11-rodrigo.vivi@intel.com (mailing list archive)
State New, archived
Headers show
Series Reconcile i915's and xe's display power mgt sequences | expand

Commit Message

Rodrigo Vivi Sept. 24, 2024, 8:35 p.m. UTC
No functional change. This patch only splits the xe_display_pm
suspend/resume functions in the regular suspend/resume from the
runtime/d3cold ones.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/xe/display/xe_display.c | 68 ++++++++++++++++---------
 1 file changed, 45 insertions(+), 23 deletions(-)

Comments

Cavitt, Jonathan Oct. 7, 2024, 8:43 p.m. UTC | #1
-----Original Message-----
From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of Rodrigo Vivi
Sent: Tuesday, September 24, 2024 1:36 PM
To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
Cc: Deak, Imre <imre.deak@intel.com>; Vivi, Rodrigo <rodrigo.vivi@intel.com>
Subject: [PATCH 10/31] drm/xe/display: Spin-off xe_display runtime/d3cold sequences
> 
> No functional change. This patch only splits the xe_display_pm
> suspend/resume functions in the regular suspend/resume from the
> runtime/d3cold ones.
> 
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> ---
>  drivers/gpu/drm/xe/display/xe_display.c | 68 ++++++++++++++++---------
>  1 file changed, 45 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c
> index be431d9907df..a4705a452adb 100644
> --- a/drivers/gpu/drm/xe/display/xe_display.c
> +++ b/drivers/gpu/drm/xe/display/xe_display.c
> @@ -308,8 +308,41 @@ static void xe_display_flush_cleanup_work(struct xe_device *xe)
>  	}
>  }
>  
> -/* TODO: System and runtime suspend/resume sequences will be sanitized as a follow-up. */
> -static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
> +static void xe_display_to_d3cold(struct xe_device *xe)
> +{
> +	struct intel_display *display = &xe->display;
> +
> +	/* We do a lot of poking in a lot of registers, make sure they work properly. */
> +	intel_power_domains_disable(xe);
> +
> +	xe_display_flush_cleanup_work(xe);
> +
> +	intel_hpd_cancel_work(xe);
> +
> +	intel_opregion_suspend(display, PCI_D3cold);
> +
> +	intel_dmc_suspend(display);
> +}
> +
> +static void xe_display_from_d3cold(struct xe_device *xe)
> +{
> +	struct intel_display *display = &xe->display;
> +
> +	intel_dmc_resume(display);
> +
> +	if (has_display(xe))
> +		drm_mode_config_reset(&xe->drm);
> +
> +	intel_display_driver_init_hw(xe);
> +
> +	intel_hpd_init(xe);
> +
> +	intel_opregion_resume(display);
> +
> +	intel_power_domains_enable(xe);
> +}

xe_display_to_d3cold and xe_display_from_d3cold sound like conversion functions
that take an xe_display and return a d3cold, and vice versa, respectively.  Perhaps 
we should consider a different naming scheme?  Something like:

xe_display_enable_d3cold
xe_display_disable_d3cold

Also, we're going to need to move these functions in patch 31 later, so perhaps it
would be for the best to put these functions in the correct place from the start?

I won't block on this, but do consider renaming these functions.

Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
-Jonathan Cavitt

> +
> +void xe_display_pm_suspend(struct xe_device *xe)
>  {
>  	struct intel_display *display = &xe->display;
>  	bool s2idle = suspend_to_idle();
> @@ -321,10 +354,10 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
>  	 * properly.
>  	 */
>  	intel_power_domains_disable(xe);
> -	if (!runtime)
> -		intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true);
>  
> -	if (!runtime && has_display(xe)) {
> +	intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true);
> +
> +	if (has_display(xe)) {
>  		drm_kms_helper_poll_disable(&xe->drm);
>  		intel_display_driver_disable_user_access(xe);
>  		intel_display_driver_suspend(xe);
> @@ -334,7 +367,7 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
>  
>  	intel_hpd_cancel_work(xe);
>  
> -	if (!runtime && has_display(xe)) {
> +	if (has_display(xe)) {
>  		intel_display_driver_suspend_access(xe);
>  		intel_encoder_suspend_all(&xe->display);
>  	}
> @@ -344,11 +377,6 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
>  	intel_dmc_suspend(display);
>  }
>  
> -void xe_display_pm_suspend(struct xe_device *xe)
> -{
> -	__xe_display_pm_suspend(xe, false);
> -}
> -
>  void xe_display_pm_shutdown(struct xe_device *xe)
>  {
>  	if (!xe->info.probe_display)
> @@ -379,7 +407,7 @@ void xe_display_pm_runtime_suspend(struct xe_device *xe)
>  		return;
>  
>  	if (xe->d3cold.allowed)
> -		__xe_display_pm_suspend(xe, true);
> +		xe_display_to_d3cold(xe);
>  
>  	intel_hpd_poll_enable(xe);
>  }
> @@ -405,7 +433,7 @@ void xe_display_pm_resume_early(struct xe_device *xe)
>  	intel_power_domains_resume(xe);
>  }
>  
> -static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
> +void xe_display_pm_resume(struct xe_device *xe)
>  {
>  	struct intel_display *display = &xe->display;
>  
> @@ -419,12 +447,12 @@ static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
>  
>  	intel_display_driver_init_hw(xe);
>  
> -	if (!runtime && has_display(xe))
> +	if (has_display(xe))
>  		intel_display_driver_resume_access(xe);
>  
>  	intel_hpd_init(xe);
>  
> -	if (!runtime && has_display(xe)) {
> +	if (has_display(xe)) {
>  		intel_display_driver_resume(xe);
>  		drm_kms_helper_poll_enable(&xe->drm);
>  		intel_display_driver_enable_user_access(xe);
> @@ -433,17 +461,11 @@ static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
>  
>  	intel_opregion_resume(display);
>  
> -	if (!runtime)
> -		intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false);
> +	intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false);
>  
>  	intel_power_domains_enable(xe);
>  }
>  
> -void xe_display_pm_resume(struct xe_device *xe)
> -{
> -	__xe_display_pm_resume(xe, false);
> -}
> -
>  void xe_display_pm_runtime_resume(struct xe_device *xe)
>  {
>  	if (!xe->info.probe_display)
> @@ -452,7 +474,7 @@ void xe_display_pm_runtime_resume(struct xe_device *xe)
>  	intel_hpd_poll_disable(xe);
>  
>  	if (xe->d3cold.allowed)
> -		__xe_display_pm_resume(xe, true);
> +		xe_display_from_d3cold(xe);
>  }
>  
>  
> -- 
> 2.46.0
> 
>
Imre Deak Oct. 8, 2024, 4:27 p.m. UTC | #2
On Tue, Sep 24, 2024 at 04:35:31PM -0400, Rodrigo Vivi wrote:
> No functional change. This patch only splits the xe_display_pm
> suspend/resume functions in the regular suspend/resume from the
> runtime/d3cold ones.
> 
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> ---
>  drivers/gpu/drm/xe/display/xe_display.c | 68 ++++++++++++++++---------
>  1 file changed, 45 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c
> index be431d9907df..a4705a452adb 100644
> --- a/drivers/gpu/drm/xe/display/xe_display.c
> +++ b/drivers/gpu/drm/xe/display/xe_display.c
> @@ -308,8 +308,41 @@ static void xe_display_flush_cleanup_work(struct xe_device *xe)
>  	}
>  }
>  
> -/* TODO: System and runtime suspend/resume sequences will be sanitized as a follow-up. */
> -static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
> +static void xe_display_to_d3cold(struct xe_device *xe)
> +{
> +	struct intel_display *display = &xe->display;
> +
> +	/* We do a lot of poking in a lot of registers, make sure they work properly. */
> +	intel_power_domains_disable(xe);
> +
> +	xe_display_flush_cleanup_work(xe);
> +
> +	intel_hpd_cancel_work(xe);

This cancels a work synchronously that takes a runtime PM reference, so
it could dead-lock. I know that xe adds a way to get an RPM reference in
the runtime suspend/resume handlers, not sure if that's a good approach
in general. Also, not sure if it's ok to to drop all interrupts - in
intel_hpd_cancel_work() - here that got raised before runtime suspend,
instead of handling them as expected. So I think intel_hpd_cancel_work()
shouldn't be called here.

> +
> +	intel_opregion_suspend(display, PCI_D3cold);
> +
> +	intel_dmc_suspend(display);
> +}
> +
> +static void xe_display_from_d3cold(struct xe_device *xe)
> +{
> +	struct intel_display *display = &xe->display;
> +
> +	intel_dmc_resume(display);
> +
> +	if (has_display(xe))
> +		drm_mode_config_reset(&xe->drm);

The above is the counterpart of intel_encoder_suspend_all() which is
only called during system suspend.

> +
> +	intel_display_driver_init_hw(xe);
> +
> +	intel_hpd_init(xe);
> +
> +	intel_opregion_resume(display);
> +
> +	intel_power_domains_enable(xe);
> +}
> +
> +void xe_display_pm_suspend(struct xe_device *xe)
>  {
>  	struct intel_display *display = &xe->display;
>  	bool s2idle = suspend_to_idle();
> @@ -321,10 +354,10 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
>  	 * properly.
>  	 */
>  	intel_power_domains_disable(xe);
> -	if (!runtime)
> -		intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true);
>  
> -	if (!runtime && has_display(xe)) {
> +	intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true);
> +
> +	if (has_display(xe)) {
>  		drm_kms_helper_poll_disable(&xe->drm);
>  		intel_display_driver_disable_user_access(xe);
>  		intel_display_driver_suspend(xe);
> @@ -334,7 +367,7 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
>  
>  	intel_hpd_cancel_work(xe);
>  
> -	if (!runtime && has_display(xe)) {
> +	if (has_display(xe)) {
>  		intel_display_driver_suspend_access(xe);
>  		intel_encoder_suspend_all(&xe->display);
>  	}
> @@ -344,11 +377,6 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
>  	intel_dmc_suspend(display);
>  }
>  
> -void xe_display_pm_suspend(struct xe_device *xe)
> -{
> -	__xe_display_pm_suspend(xe, false);
> -}
> -
>  void xe_display_pm_shutdown(struct xe_device *xe)
>  {
>  	if (!xe->info.probe_display)
> @@ -379,7 +407,7 @@ void xe_display_pm_runtime_suspend(struct xe_device *xe)
>  		return;
>  
>  	if (xe->d3cold.allowed)
> -		__xe_display_pm_suspend(xe, true);
> +		xe_display_to_d3cold(xe);
>  
>  	intel_hpd_poll_enable(xe);
>  }
> @@ -405,7 +433,7 @@ void xe_display_pm_resume_early(struct xe_device *xe)
>  	intel_power_domains_resume(xe);
>  }
>  
> -static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
> +void xe_display_pm_resume(struct xe_device *xe)
>  {
>  	struct intel_display *display = &xe->display;
>  
> @@ -419,12 +447,12 @@ static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
>  
>  	intel_display_driver_init_hw(xe);
>  
> -	if (!runtime && has_display(xe))
> +	if (has_display(xe))
>  		intel_display_driver_resume_access(xe);
>  
>  	intel_hpd_init(xe);
>  
> -	if (!runtime && has_display(xe)) {
> +	if (has_display(xe)) {
>  		intel_display_driver_resume(xe);
>  		drm_kms_helper_poll_enable(&xe->drm);
>  		intel_display_driver_enable_user_access(xe);
> @@ -433,17 +461,11 @@ static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
>  
>  	intel_opregion_resume(display);
>  
> -	if (!runtime)
> -		intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false);
> +	intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false);
>  
>  	intel_power_domains_enable(xe);
>  }
>  
> -void xe_display_pm_resume(struct xe_device *xe)
> -{
> -	__xe_display_pm_resume(xe, false);
> -}
> -
>  void xe_display_pm_runtime_resume(struct xe_device *xe)
>  {
>  	if (!xe->info.probe_display)
> @@ -452,7 +474,7 @@ void xe_display_pm_runtime_resume(struct xe_device *xe)
>  	intel_hpd_poll_disable(xe);
>  
>  	if (xe->d3cold.allowed)
> -		__xe_display_pm_resume(xe, true);
> +		xe_display_from_d3cold(xe);
>  }
>  
>  
> -- 
> 2.46.0
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c
index be431d9907df..a4705a452adb 100644
--- a/drivers/gpu/drm/xe/display/xe_display.c
+++ b/drivers/gpu/drm/xe/display/xe_display.c
@@ -308,8 +308,41 @@  static void xe_display_flush_cleanup_work(struct xe_device *xe)
 	}
 }
 
-/* TODO: System and runtime suspend/resume sequences will be sanitized as a follow-up. */
-static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
+static void xe_display_to_d3cold(struct xe_device *xe)
+{
+	struct intel_display *display = &xe->display;
+
+	/* We do a lot of poking in a lot of registers, make sure they work properly. */
+	intel_power_domains_disable(xe);
+
+	xe_display_flush_cleanup_work(xe);
+
+	intel_hpd_cancel_work(xe);
+
+	intel_opregion_suspend(display, PCI_D3cold);
+
+	intel_dmc_suspend(display);
+}
+
+static void xe_display_from_d3cold(struct xe_device *xe)
+{
+	struct intel_display *display = &xe->display;
+
+	intel_dmc_resume(display);
+
+	if (has_display(xe))
+		drm_mode_config_reset(&xe->drm);
+
+	intel_display_driver_init_hw(xe);
+
+	intel_hpd_init(xe);
+
+	intel_opregion_resume(display);
+
+	intel_power_domains_enable(xe);
+}
+
+void xe_display_pm_suspend(struct xe_device *xe)
 {
 	struct intel_display *display = &xe->display;
 	bool s2idle = suspend_to_idle();
@@ -321,10 +354,10 @@  static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
 	 * properly.
 	 */
 	intel_power_domains_disable(xe);
-	if (!runtime)
-		intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true);
 
-	if (!runtime && has_display(xe)) {
+	intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true);
+
+	if (has_display(xe)) {
 		drm_kms_helper_poll_disable(&xe->drm);
 		intel_display_driver_disable_user_access(xe);
 		intel_display_driver_suspend(xe);
@@ -334,7 +367,7 @@  static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
 
 	intel_hpd_cancel_work(xe);
 
-	if (!runtime && has_display(xe)) {
+	if (has_display(xe)) {
 		intel_display_driver_suspend_access(xe);
 		intel_encoder_suspend_all(&xe->display);
 	}
@@ -344,11 +377,6 @@  static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
 	intel_dmc_suspend(display);
 }
 
-void xe_display_pm_suspend(struct xe_device *xe)
-{
-	__xe_display_pm_suspend(xe, false);
-}
-
 void xe_display_pm_shutdown(struct xe_device *xe)
 {
 	if (!xe->info.probe_display)
@@ -379,7 +407,7 @@  void xe_display_pm_runtime_suspend(struct xe_device *xe)
 		return;
 
 	if (xe->d3cold.allowed)
-		__xe_display_pm_suspend(xe, true);
+		xe_display_to_d3cold(xe);
 
 	intel_hpd_poll_enable(xe);
 }
@@ -405,7 +433,7 @@  void xe_display_pm_resume_early(struct xe_device *xe)
 	intel_power_domains_resume(xe);
 }
 
-static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
+void xe_display_pm_resume(struct xe_device *xe)
 {
 	struct intel_display *display = &xe->display;
 
@@ -419,12 +447,12 @@  static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
 
 	intel_display_driver_init_hw(xe);
 
-	if (!runtime && has_display(xe))
+	if (has_display(xe))
 		intel_display_driver_resume_access(xe);
 
 	intel_hpd_init(xe);
 
-	if (!runtime && has_display(xe)) {
+	if (has_display(xe)) {
 		intel_display_driver_resume(xe);
 		drm_kms_helper_poll_enable(&xe->drm);
 		intel_display_driver_enable_user_access(xe);
@@ -433,17 +461,11 @@  static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
 
 	intel_opregion_resume(display);
 
-	if (!runtime)
-		intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false);
+	intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false);
 
 	intel_power_domains_enable(xe);
 }
 
-void xe_display_pm_resume(struct xe_device *xe)
-{
-	__xe_display_pm_resume(xe, false);
-}
-
 void xe_display_pm_runtime_resume(struct xe_device *xe)
 {
 	if (!xe->info.probe_display)
@@ -452,7 +474,7 @@  void xe_display_pm_runtime_resume(struct xe_device *xe)
 	intel_hpd_poll_disable(xe);
 
 	if (xe->d3cold.allowed)
-		__xe_display_pm_resume(xe, true);
+		xe_display_from_d3cold(xe);
 }