drm/amd/display: Fix idle optimization checks for multi-display and dual eDP

[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>
This commit is contained in:
Nicholas Kazlauskas 2024-04-25 11:26:59 -04:00 committed by Alex Deucher
parent 3f0b5af175
commit b436f1cbed
1 changed files with 27 additions and 6 deletions

View 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;
if (!stream->dpms_off && !dc_is_embedded_signal(stream->signal))
/* 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;
/* 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