From 499e4b1c722e0e2ca40c56342b766e95f6c31f4a Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Fri, 29 May 2020 17:13:57 -0400 Subject: [PATCH] drm/amd/display: add mechanism to skip DCN init [Why] If optimized init is done in FW. DCN init can be skipped in driver. This need to be communicated between driver and fw and maintain backwards compatibility. [How] Use DMUB scratch 0 bit 2 to indicate optimized init done in fw and use DMUB scatch 4 bit 0 to indicate drive supports the optimized flow so FW will perform it. Signed-off-by: Eric Yang Acked-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 --- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 28 ++++++---------------- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 2 +- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 4 +++- drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 1 - drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c | 6 ----- drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h | 4 ---- drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 25 +------------------ 8 files changed, 12 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 105f705..631c6b1 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -4267,9 +4267,6 @@ void dc_set_power_state( dc_z10_restore(dc); - if (dc->ctx->dmub_srv) - dc_dmub_srv_wait_phy_init(dc->ctx->dmub_srv); - dc->hwss.init_hw(dc); if (dc->hwss.init_sys_ctx != NULL && diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index eef4357..d15ec32 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -179,31 +179,17 @@ bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int coun return true; } -void dc_dmub_srv_wait_phy_init(struct dc_dmub_srv *dc_dmub_srv) +bool dc_dmub_srv_optimized_init_done(struct dc_dmub_srv *dc_dmub_srv) { - struct dmub_srv *dmub = dc_dmub_srv->dmub; - struct dc_context *dc_ctx = dc_dmub_srv->ctx; - enum dmub_status status; - - for (;;) { - /* Wait up to a second for PHY init. */ - status = dmub_srv_wait_for_phy_init(dmub, 1000000); - if (status == DMUB_STATUS_OK) - /* Initialization OK */ - break; + struct dmub_srv *dmub; + union dmub_fw_boot_status status; - DC_ERROR("DMCUB PHY init failed: status=%d\n", status); - ASSERT(0); + if (!dc_dmub_srv || !dc_dmub_srv->dmub) + return false; - if (status != DMUB_STATUS_TIMEOUT) - /* - * Server likely initialized or we don't have - * DMCUB HW support - this won't end. - */ - break; + dmub = dc_dmub_srv->dmub; - /* Continue spinning so we don't hang the ASIC. */ - } + return status.bits.optimized_init_done; } bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv, diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h index 22f7b27..a5196a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h @@ -54,7 +54,7 @@ struct dc_dmub_srv { void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv); -void dc_dmub_srv_wait_phy_init(struct dc_dmub_srv *dc_dmub_srv); +bool dc_dmub_srv_optimized_init_done(struct dc_dmub_srv *dc_dmub_srv); bool dc_dmub_srv_cmd_run(struct dc_dmub_srv *dc_dmub_srv, union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 1c3b6f2..a7ad1d7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1524,7 +1524,9 @@ void dcn10_init_hw(struct dc *dc) if (!dcb->funcs->is_accelerated_mode(dcb)) hws->funcs.disable_vga(dc->hwseq); - hws->funcs.bios_golden_init(dc); + if (!dc_dmub_srv_optimized_init_done(dc->ctx->dmub_srv)) + hws->funcs.bios_golden_init(dc); + if (dc->ctx->dc_bios->fw_info_valid) { res_pool->ref_clocks.xtalin_clock_inKhz = diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index ba1715e..719bf9b 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -366,7 +366,6 @@ struct dmub_srv_hw_funcs { bool (*is_hw_init)(struct dmub_srv *dmub); - bool (*is_phy_init)(struct dmub_srv *dmub); void (*enable_dmub_boot_options)(struct dmub_srv *dmub, const struct dmub_srv_hw_params *params); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c index 51bb9bc..2d212bc 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c @@ -54,9 +54,3 @@ const struct dmub_srv_common_regs dmub_srv_dcn21_regs = { #undef DMUB_SF }; -/* Shared functions. */ - -bool dmub_dcn21_is_phy_init(struct dmub_srv *dmub) -{ - return REG_READ(DMCUB_SCRATCH10) == 0; -} diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h index 6fd5b0c..8c4033a 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h @@ -32,8 +32,4 @@ extern const struct dmub_srv_common_regs dmub_srv_dcn21_regs; -/* Hardware functions. */ - -bool dmub_dcn21_is_phy_init(struct dmub_srv *dmub); - #endif /* _DMUB_DCN21_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 92c18bf..67c53f7 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -190,11 +190,9 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) funcs->get_diagnostic_data = dmub_dcn20_get_diagnostic_data; - if (asic == DMUB_ASIC_DCN21) { + if (asic == DMUB_ASIC_DCN21) dmub->regs = &dmub_srv_dcn21_regs; - funcs->is_phy_init = dmub_dcn21_is_phy_init; - } if (asic == DMUB_ASIC_DCN30) { dmub->regs = &dmub_srv_dcn30_regs; @@ -721,27 +719,6 @@ enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub, return DMUB_STATUS_TIMEOUT; } -enum dmub_status dmub_srv_wait_for_phy_init(struct dmub_srv *dmub, - uint32_t timeout_us) -{ - uint32_t i = 0; - - if (!dmub->hw_init) - return DMUB_STATUS_INVALID; - - if (!dmub->hw_funcs.is_phy_init) - return DMUB_STATUS_OK; - - for (i = 0; i <= timeout_us; i += 10) { - if (dmub->hw_funcs.is_phy_init(dmub)) - return DMUB_STATUS_OK; - - udelay(10); - } - - return DMUB_STATUS_TIMEOUT; -} - enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub, uint32_t timeout_us) { -- 2.7.4