]> git.dujemihanovic.xyz Git - linux.git/commitdiff
drm/amd/display: Fix idle optimization checks for multi-display and dual eDP
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Thu, 25 Apr 2024 15:26:59 +0000 (11:26 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 8 May 2024 19:49:34 +0000 (15:49 -0400)
[Why]
Idle optimizations are blocked if there's more than one eDP connector
on the board - blocking S0i3 and IPS2 for static screen.

[How]
Fix the checks to correctly detect number of active eDP.
Also restrict the eDP support to panels that have correct feature
support.

Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c

index a5560b3fc39ba9b432e0e5605b3972810de38933..9067ca78f8511145e8c2e88789d38f0f71505abf 100644 (file)
@@ -638,22 +638,43 @@ void dcn35_power_down_on_boot(struct dc *dc)
 
 bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
 {
-       struct dc_link *edp_links[MAX_NUM_EDP];
-       int i, edp_num;
        if (dc->debug.dmcub_emulation)
                return true;
 
        if (enable) {
-               dc_get_edp_links(dc, edp_links, &edp_num);
-               if (edp_num == 0 || edp_num > 1)
-                       return false;
+               uint32_t num_active_edp = 0;
+               int i;
 
                for (i = 0; i < dc->current_state->stream_count; ++i) {
                        struct dc_stream_state *stream = dc->current_state->streams[i];
+                       struct dc_link *link = stream->link;
+                       bool is_psr = link && !link->panel_config.psr.disable_psr &&
+                                     (link->psr_settings.psr_version == DC_PSR_VERSION_1 ||
+                                      link->psr_settings.psr_version == DC_PSR_VERSION_SU_1);
+                       bool is_replay = link && link->replay_settings.replay_feature_enabled;
+
+                       /* Ignore streams that disabled. */
+                       if (stream->dpms_off)
+                               continue;
+
+                       /* Active external displays block idle optimizations. */
+                       if (!dc_is_embedded_signal(stream->signal))
+                               return false;
+
+                       /* If not PWRSEQ0 can't enter idle optimizations */
+                       if (link && link->link_index != 0)
+                               return false;
 
-                       if (!stream->dpms_off && !dc_is_embedded_signal(stream->signal))
+                       /* Check for panel power features required for idle optimizations. */
+                       if (!is_psr && !is_replay)
                                return false;
+
+                       num_active_edp += 1;
                }
+
+               /* If more than one active eDP then disallow. */
+               if (num_active_edp > 1)
+                       return false;
        }
 
        // TODO: review other cases when idle optimization is allowed