[PATCH v2 4/5] drm/amd/display: Implement DMUB_IPS_DISABLE_DYNAMIC

sunpeng.li at amd.com sunpeng.li at amd.com
Mon Aug 19 19:22:16 UTC 2024


From: Leo Li <sunpeng.li at amd.com>

[Why]

The IPS_DISABLE_DYNAMIC configuration disables IPS in all cases except
for when the driver is put into d3 for s0ix.

[How]

Now that we have a common entry point into dc_allow_idle_optimizations
from dm, implement said configuration there.

Signed-off-by: Leo Li <sunpeng.li at amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 42 +++++++++++++++----
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  5 ++-
 2 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c99cff3650f14..f9b5966746c73 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -247,10 +247,38 @@ static bool
 is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
 				 struct drm_crtc_state *new_crtc_state);
 
+/**
+ * dm_allow_idle_optimizations_internal() - Allow or disallow idle state entry
+ * @dc: pointer to display core struct
+ * @allow: If true, DC is allowed to go into idle power states. If false, DC
+ * will immediately exit idle power states
+ * @suspend_resume_path: Set to true if the caller is part of the suspend or
+ * resume path
+ * @caller_name: Function name of the caller - for debugging purposes
+ *
+ * Debug flags are considered in this function, so any DM callers should go
+ * thorugh this rather than call dc/dmcub interfaces directly.
+ */
 void dm_allow_idle_optimizations_internal(struct dc *dc,
 					  bool allow,
+					  bool suspend_resume_path,
 					  char const *caller_name)
 {
+	/*
+	 * We can early-return here if IPS support exists, and DISABLE_ALL debug
+	 * flag is set.
+	 *
+	 * We also need special handling for IPS_DISABLE_DYNAMIC in DM to allow
+	 * IPS only for the suspend/resume call path.
+	 *
+	 * The rest of the debug flags are handled in `dc_dmub_srv_notify_idle`,
+	 * which if IPS is supported, will eventually be called.
+	 */
+	if (dc->caps.ips_support &&
+	    (dc->config.disable_ips == DMUB_IPS_DISABLE_ALL ||
+	    (!suspend_resume_path && dc->config.disable_ips == DMUB_IPS_DISABLE_DYNAMIC)))
+		return;
+
 	dc_allow_idle_optimizations_internal(dc, allow, caller_name);
 }
 
@@ -2891,7 +2919,7 @@ static int dm_suspend(void *handle)
 	if (amdgpu_in_reset(adev)) {
 		mutex_lock(&dm->dc_lock);
 
-		dm_allow_idle_optimizations(adev->dm.dc, false);
+		dm_allow_idle_optimizations_suspend(adev->dm.dc, false);
 
 		dm->cached_dc_state = dc_state_create_copy(dm->dc->current_state);
 
@@ -2918,8 +2946,9 @@ static int dm_suspend(void *handle)
 
 	hpd_rx_irq_work_suspend(dm);
 
+	/* IPS2 entry is required for standby */
 	if (adev->dm.dc->caps.ips_support)
-		dm_allow_idle_optimizations(adev->dm.dc, true);
+		dm_allow_idle_optimizations_suspend(adev->dm.dc, true);
 
 	dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
 	dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D3);
@@ -3091,9 +3120,8 @@ static int dm_resume(void *handle)
 	bool need_hotplug = false;
 	struct dc_commit_streams_params commit_params = {};
 
-	if (dm->dc->caps.ips_support) {
-		dm_allow_idle_optimizations(dm->dc, false);
-	}
+	if (dm->dc->caps.ips_support)
+		dm_allow_idle_optimizations_suspend(dm->dc, false);
 
 	if (amdgpu_in_reset(adev)) {
 		dc_state = dm->cached_dc_state;
@@ -3142,7 +3170,7 @@ static int dm_resume(void *handle)
 		commit_params.streams = dc_state->streams;
 		commit_params.stream_count = dc_state->stream_count;
 		if (dm->dc->caps.ips_support)
-			dm_allow_idle_optimizations(dm->dc, false);
+			dm_allow_idle_optimizations_suspend(dm->dc, false);
 		WARN_ON(!dc_commit_streams(dm->dc, &commit_params));
 
 		dm_gpureset_commit_state(dm->cached_dc_state, dm);
@@ -3216,7 +3244,7 @@ static int dm_resume(void *handle)
 		} else {
 			mutex_lock(&dm->dc_lock);
 			if (dm->dc->caps.ips_support)
-				dm_allow_idle_optimizations(dm->dc, false);
+				dm_allow_idle_optimizations_suspend(dm->dc, false);
 			dc_link_detect(aconnector->dc_link, DETECT_REASON_RESUMEFROMS3S4);
 			mutex_unlock(&dm->dc_lock);
 		}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 3fc3c12b3a4a1..da7283c67b13c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1009,8 +1009,11 @@ bool amdgpu_dm_is_headless(struct amdgpu_device *adev);
 
 void dm_allow_idle_optimizations_internal(struct dc *dc,
 					  bool allow,
+					  bool suspend_resume_path,
 					  char const *caller_name);
 #define dm_allow_idle_optimizations(dc, allow) \
-	dm_allow_idle_optimizations_internal(dc, allow, __func__)
+	dm_allow_idle_optimizations_internal(dc, allow, false, __func__)
+#define dm_allow_idle_optimizations_suspend(dc, allow) \
+	dm_allow_idle_optimizations_internal(dc, allow, true, __func__)
 
 #endif /* __AMDGPU_DM_H__ */
-- 
2.46.0



More information about the amd-gfx mailing list