[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