From 2d017189e2b39cf2fae63984215385401b77ea83 Mon Sep 17 00:00:00 2001 From: Duncan Ma Date: Thu, 12 May 2022 14:46:24 -0400 Subject: drm/amd/display: Blank eDP on enable drv if odm enabled [Why] For panels with pixel clock > 1200MHz that require ODM in pre-OS, when driver is disabled in OS, odm is enabled. Upon driver enablement, corruption is seen if odm was originally enabled. DP_PIXEL_COMBINE and pixelclk must be programmed prior to programming the optc-odm registers. However, eDP displays aren't blanked prior to initializing odm in this case. [How] Upon driver enablement, check whether odm is enabled, if so, blank eDP prior to programming optc-odm registers. Reviewed-by: Nicholas Kazlauskas Acked-by: Hamza Mahfooz Signed-off-by: Duncan Ma Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 20 ++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dc_link.h | 1 + drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 22 ++++++++++++++++++++++ 4 files changed, 44 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 31ffb961e18b..38a458141791 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2126,6 +2126,26 @@ void dc_link_blank_all_dp_displays(struct dc *dc) } +void dc_link_blank_all_edp_displays(struct dc *dc) +{ + unsigned int i; + uint8_t dpcd_power_state = '\0'; + enum dc_status status = DC_ERROR_UNEXPECTED; + + for (i = 0; i < dc->link_count; i++) { + if ((dc->links[i]->connector_signal != SIGNAL_TYPE_EDP) || + (!dc->links[i]->edp_sink_present)) + continue; + + /* if any of the displays are lit up turn them off */ + status = core_link_read_dpcd(dc->links[i], DP_SET_POWER, + &dpcd_power_state, sizeof(dpcd_power_state)); + + if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) + dc_link_blank_dp_stream(dc->links[i], true); + } +} + void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init) { unsigned int j; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 7bb67ab979e1..5a6c9a139e85 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -216,6 +216,7 @@ struct dc_caps { uint16_t subvp_pstate_allow_width_us; uint16_t subvp_vertical_int_margin_us; #endif + bool seamless_odm; }; struct dc_bug_wa { diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 0bec986a6de8..c4a42d758b4e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -322,6 +322,7 @@ bool dc_link_setup_psr(struct dc_link *dc_link, void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency); void dc_link_blank_all_dp_displays(struct dc *dc); +void dc_link_blank_all_edp_displays(struct dc *dc); void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init); diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c index 531dd2c65007..55f2e30b8e5a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -213,6 +213,28 @@ void dcn31_init_hw(struct dc *dc) * everything down. */ if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) { + + // we want to turn off edp displays if odm is enabled and no seamless boot + if (!dc->caps.seamless_odm) { + for (i = 0; i < dc->res_pool->timing_generator_count; i++) { + struct timing_generator *tg = dc->res_pool->timing_generators[i]; + uint32_t num_opps, opp_id_src0, opp_id_src1; + + num_opps = 1; + if (tg) { + if (tg->funcs->is_tg_enabled(tg) && tg->funcs->get_optc_source) { + tg->funcs->get_optc_source(tg, &num_opps, + &opp_id_src0, &opp_id_src1); + } + } + + if (num_opps > 1) { + dc_link_blank_all_edp_displays(dc); + break; + } + } + } + hws->funcs.init_pipes(dc, dc->current_state); if (dc->res_pool->hubbub->funcs->allow_self_refresh_control) dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, -- cgit