From 64c51ea5a61a7ace40d4e904d6c5609c4a5bde7d Mon Sep 17 00:00:00 2001 From: Changfeng Date: Thu, 9 Jul 2020 14:52:11 +0800 Subject: [PATCH] Revert "drm/amd/display: add mechanism to skip DCN init" To avoid s3 faild at the first cycle on renoir platform, it needs to revert this patch: drm/amd/display: add mechanism to skip DCN init Signed-off-by: changfeng Ackedy-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 28 +++++++++---- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 2 - .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 5 +-- drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 5 +-- .../gpu/drm/amd/display/dmub/src/dmub_dcn20.c | 15 ------- .../gpu/drm/amd/display/dmub/src/dmub_dcn20.h | 4 -- .../gpu/drm/amd/display/dmub/src/dmub_dcn21.c | 10 +++++ .../gpu/drm/amd/display/dmub/src/dmub_dcn21.h | 6 +++ .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 40 ++++++++++++++----- 10 files changed, 72 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 942ceb0f6383..4f97329d9daf 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2683,7 +2683,6 @@ void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src) dal_irq_service_ack(dc->res_pool->irqs, src); } - void dc_set_power_state( struct dc *dc, enum dc_acpi_cm_power_state power_state) @@ -2695,6 +2694,9 @@ void dc_set_power_state( case DC_ACPI_CM_POWER_STATE_D0: dc_resource_state_construct(dc, dc->current_state); + 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 96532f7ba480..eea2429ac67d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -106,17 +106,29 @@ void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv) DC_ERROR("Error waiting for DMUB idle: status=%d\n", status); } -bool dc_dmub_srv_optimized_init_done(struct dc_dmub_srv *dc_dmub_srv) +void dc_dmub_srv_wait_phy_init(struct dc_dmub_srv *dc_dmub_srv) { - struct dmub_srv *dmub; - union dmub_fw_boot_status status; + struct dmub_srv *dmub = dc_dmub_srv->dmub; + struct dc_context *dc_ctx = dc_dmub_srv->ctx; + enum dmub_status status; - if (!dc_dmub_srv || !dc_dmub_srv->dmub) - return false; + 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; - dmub = dc_dmub_srv->dmub; + DC_ERROR("DMCUB PHY init failed: status=%d\n", status); + ASSERT(0); - status = dmub->hw_funcs.get_fw_status(dmub); + if (status != DMUB_STATUS_TIMEOUT) + /* + * Server likely initialized or we don't have + * DMCUB HW support - this won't end. + */ + break; - return status.bits.optimized_init_done; + /* Continue spinning so we don't hang the ASIC. */ + } } 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 8bd20d0d7689..a3a09ccb6d26 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h @@ -56,6 +56,4 @@ 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); - #endif /* _DMUB_DC_SRV_H_ */ 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 6711ff908bcf..4a70e286b4fa 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 @@ -1289,10 +1289,7 @@ void dcn10_init_hw(struct dc *dc) if (!dcb->funcs->is_accelerated_mode(dcb)) hws->funcs.disable_vga(dc->hwseq); - is_optimized_init_done = dc_dmub_srv_optimized_init_done(dc->ctx->dmub_srv); - - if (!is_optimized_init_done) - hws->funcs.bios_golden_init(dc); + 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 3cac170312fc..c6a8d6c54621 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -264,10 +264,9 @@ struct dmub_srv_hw_funcs { bool (*is_hw_init)(struct dmub_srv *dmub); - void (*enable_dmub_boot_options)(struct dmub_srv *dmub); - - union dmub_fw_boot_status (*get_fw_status)(struct dmub_srv *dmub); + bool (*is_phy_init)(struct dmub_srv *dmub); + bool (*is_auto_load_done)(struct dmub_srv *dmub); void (*set_gpint)(struct dmub_srv *dmub, union dmub_gpint_data_register reg); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c index 0cd78e745e7e..2c4a2fe9311d 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c @@ -312,18 +312,3 @@ uint32_t dmub_dcn20_get_gpint_response(struct dmub_srv *dmub) { return REG_READ(DMCUB_SCRATCH7); } - -union dmub_fw_boot_status dmub_dcn20_get_fw_boot_status(struct dmub_srv *dmub) -{ - union dmub_fw_boot_status status; - - status.all = REG_READ(DMCUB_SCRATCH0); - return status; -} - -void dmub_dcn20_enable_dmub_boot_options(struct dmub_srv *dmub) -{ - union dmub_fw_boot_options boot_options = {0}; - - REG_WRITE(DMCUB_SCRATCH14, boot_options.all); -} diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h index a27b509cd6fd..a316f260f6ac 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h @@ -192,8 +192,4 @@ bool dmub_dcn20_is_gpint_acked(struct dmub_srv *dmub, uint32_t dmub_dcn20_get_gpint_response(struct dmub_srv *dmub); -void dmub_dcn20_enable_dmub_boot_options(struct dmub_srv *dmub); - -union dmub_fw_boot_status dmub_dcn20_get_fw_boot_status(struct dmub_srv *dmub); - #endif /* _DMUB_DCN20_H_ */ 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 a6047673c3f5..e8f488232e34 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c @@ -51,4 +51,14 @@ const struct dmub_srv_common_regs dmub_srv_dcn21_regs = { #undef DMUB_SF }; +/* Shared functions. */ +bool dmub_dcn21_is_auto_load_done(struct dmub_srv *dmub) +{ + return (REG_READ(DMCUB_SCRATCH0) == 3); +} + +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 8c4033ae4007..2bbea237137b 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h @@ -32,4 +32,10 @@ extern const struct dmub_srv_common_regs dmub_srv_dcn21_regs; +/* Hardware functions. */ + +bool dmub_dcn21_is_auto_load_done(struct dmub_srv *dmub); + +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 aa41dfa23020..08da423b24a1 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -153,16 +153,18 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) funcs->set_gpint = dmub_dcn20_set_gpint; funcs->is_gpint_acked = dmub_dcn20_is_gpint_acked; funcs->get_gpint_response = dmub_dcn20_get_gpint_response; - funcs->get_fw_status = dmub_dcn20_get_fw_boot_status; - funcs->enable_dmub_boot_options = dmub_dcn20_enable_dmub_boot_options; - if (asic == DMUB_ASIC_DCN21) + if (asic == DMUB_ASIC_DCN21) { dmub->regs = &dmub_srv_dcn21_regs; + funcs->is_auto_load_done = dmub_dcn21_is_auto_load_done; + funcs->is_phy_init = dmub_dcn21_is_phy_init; + } #ifdef CONFIG_DRM_AMD_DC_DCN3_0 if (asic == DMUB_ASIC_DCN30) { dmub->regs = &dmub_srv_dcn30_regs; + funcs->is_auto_load_done = dmub_dcn30_is_auto_load_done; funcs->backdoor_load = dmub_dcn30_backdoor_load; funcs->setup_windows = dmub_dcn30_setup_windows; } @@ -462,10 +464,6 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, dmub_rb_init(&dmub->inbox1_rb, &rb_params); } - /* Report to DMUB what features are supported by current driver */ - if (dmub->hw_funcs.enable_dmub_boot_options) - dmub->hw_funcs.enable_dmub_boot_options(dmub); - if (dmub->hw_funcs.reset_release) dmub->hw_funcs.reset_release(dmub); @@ -526,10 +524,11 @@ enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub, if (!dmub->hw_init) return DMUB_STATUS_INVALID; - for (i = 0; i <= timeout_us; i += 100) { - union dmub_fw_boot_status status = dmub->hw_funcs.get_fw_status(dmub); + if (!dmub->hw_funcs.is_auto_load_done) + return DMUB_STATUS_OK; - if (status.bits.dal_fw && status.bits.mailbox_rdy) + for (i = 0; i <= timeout_us; i += 100) { + if (dmub->hw_funcs.is_auto_load_done(dmub)) return DMUB_STATUS_OK; udelay(100); @@ -538,6 +537,27 @@ 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) {