From: Natanel Roizenman <natanel.roizenman@xxxxxxx> [WHY] Previously, we'd disabled HPO whenever an HPO display was disconnected. This caused other HPO displays to blank whenever one was unplugged. [HOW] This change restricts HPO enable/disable to dce110_apply_ctx_to_hw and adds a helper function (dce110_is_hpo_enabled) that returns true if any HPO displays are present in a context. We compare the current and previous dc ctx to check whether HPO is transitioning from on to off or vice versa, and adjust the HPO state accordingly. Reviewed-by: Wenjing Liu <wenjing.liu@xxxxxxx> Reviewed-by: Chris Park <chris.park@xxxxxxx> Acked-by: Tom Chung <chiahsuan.chung@xxxxxxx> Signed-off-by: Natanel Roizenman <natanel.roizenman@xxxxxxx> --- .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 29 ++++++++++++------- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 5 ---- 2 files changed, 19 insertions(+), 15 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 0ba1feaf96c0..de5542c20103 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 @@ -1192,16 +1192,6 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, link_enc->transmitter - TRANSMITTER_UNIPHY_A); } - - if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { - /* TODO: This looks like a bug to me as we are disabling HPO IO when - * we are just disabling a single HPO stream. Shouldn't we disable HPO - * HW control only when HPOs for all streams are disabled? - */ - if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control) - pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control( - pipe_ctx->stream->ctx->dc->hwseq, false); - } } void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, @@ -2288,6 +2278,19 @@ static void dce110_setup_audio_dto( } } +static bool dce110_is_hpo_enabled(struct dc_state *context) +{ + int i; + + for (i = 0; i < MAX_HPO_DP2_ENCODERS; i++) { + if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i]) { + return true; + } + } + + return false; +} + enum dc_status dce110_apply_ctx_to_hw( struct dc *dc, struct dc_state *context) @@ -2296,6 +2299,8 @@ enum dc_status dce110_apply_ctx_to_hw( struct dc_bios *dcb = dc->ctx->dc_bios; enum dc_status status; int i; + bool was_hpo_enabled = dce110_is_hpo_enabled(dc->current_state); + bool is_hpo_enabled = dce110_is_hpo_enabled(context); /* reset syncd pipes from disabled pipes */ if (dc->config.use_pipe_ctx_sync_logic) @@ -2338,6 +2343,10 @@ enum dc_status dce110_apply_ctx_to_hw( dce110_setup_audio_dto(dc, context); + if (dc->hwseq->funcs.setup_hpo_hw_control && was_hpo_enabled != is_hpo_enabled) { + dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, is_hpo_enabled); + } + for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.pipe_ctx[i]; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index 8b3536c380b8..eae71f448143 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -2892,11 +2892,6 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; - if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { - if (dc->hwseq->funcs.setup_hpo_hw_control) - dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true); - } - if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { dto_params.otg_inst = tg->inst; dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10; -- 2.34.1