summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOvidiu Bunea <ovidiu.bunea@amd.com>2026-01-03 01:48:59 +0300
committerSasha Levin <sashal@kernel.org>2026-03-04 15:20:07 +0300
commit9c220eb332fc45f1dca2e43de0e281bdd3520a6d (patch)
tree079f4c222fa5c11066474ecdee2ee637c33c4b2b
parentd964a7256c1ca2e70584f36b7c6500fcb08c6fc1 (diff)
downloadlinux-9c220eb332fc45f1dca2e43de0e281bdd3520a6d.tar.xz
drm/amd/display: Disable FEC when powering down encoders
[ Upstream commit 8cee62904caf95e5698fa0f2d420f5f22b4dea15 ] [why & how] VBIOS DMCUB FW can enable FEC for capable eDPs, but S/W DC state is only updated for link0 when transitioning into OS with driver loaded. This causes issues when the eDP is immediately hidden and DIG0 is assigned to another link that does not support FEC. Driver will attempt to disable FEC but FEC enablement occurs based on the link state, which does not have fec_state updated since it is a different link. Thus, FEC disablement on DIG0 will get skipped and cause no light up. Reviewed-by: Karen Chen <karen.chen@amd.com> Signed-off-by: Ovidiu Bunea <ovidiu.bunea@amd.com> Signed-off-by: Matthew Stewart <matthew.stewart2@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 9f7087ac41f2..3d2673a22759 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -59,6 +59,7 @@
#include "dc_state_priv.h"
#include "dpcd_defs.h"
#include "dsc.h"
+#include "dc_dp_types.h"
/* include DCE11 register header files */
#include "dce/dce_11_0_d.h"
#include "dce/dce_11_0_sh_mask.h"
@@ -1736,20 +1737,25 @@ static void power_down_encoders(struct dc *dc)
int i;
for (i = 0; i < dc->link_count; i++) {
- enum signal_type signal = dc->links[i]->connector_signal;
-
- dc->link_srv->blank_dp_stream(dc->links[i], false);
+ struct dc_link *link = dc->links[i];
+ struct link_encoder *link_enc = link->link_enc;
+ enum signal_type signal = link->connector_signal;
+ dc->link_srv->blank_dp_stream(link, false);
if (signal != SIGNAL_TYPE_EDP)
signal = SIGNAL_TYPE_NONE;
- if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY)
- dc->links[i]->link_enc->funcs->disable_output(
- dc->links[i]->link_enc, signal);
+ if (link->ep_type == DISPLAY_ENDPOINT_PHY)
+ link_enc->funcs->disable_output(link_enc, signal);
+
+ if (link->fec_state == dc_link_fec_enabled) {
+ link_enc->funcs->fec_set_enable(link_enc, false);
+ link_enc->funcs->fec_set_ready(link_enc, false);
+ link->fec_state = dc_link_fec_not_ready;
+ }
- dc->links[i]->link_status.link_active = false;
- memset(&dc->links[i]->cur_link_settings, 0,
- sizeof(dc->links[i]->cur_link_settings));
+ link->link_status.link_active = false;
+ memset(&link->cur_link_settings, 0, sizeof(link->cur_link_settings));
}
}