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 <Eric.Yang2@amd.com> Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
bddb55ccbd
commit
499e4b1c72
8 changed files with 12 additions and 61 deletions
|
@ -4267,9 +4267,6 @@ void dc_set_power_state(
|
||||||
|
|
||||||
dc_z10_restore(dc);
|
dc_z10_restore(dc);
|
||||||
|
|
||||||
if (dc->ctx->dmub_srv)
|
|
||||||
dc_dmub_srv_wait_phy_init(dc->ctx->dmub_srv);
|
|
||||||
|
|
||||||
dc->hwss.init_hw(dc);
|
dc->hwss.init_hw(dc);
|
||||||
|
|
||||||
if (dc->hwss.init_sys_ctx != NULL &&
|
if (dc->hwss.init_sys_ctx != NULL &&
|
||||||
|
|
|
@ -179,31 +179,17 @@ bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int coun
|
||||||
return true;
|
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 dmub_srv *dmub;
|
||||||
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
|
union dmub_fw_boot_status status;
|
||||||
enum dmub_status status;
|
|
||||||
|
|
||||||
for (;;) {
|
if (!dc_dmub_srv || !dc_dmub_srv->dmub)
|
||||||
/* Wait up to a second for PHY init. */
|
return false;
|
||||||
status = dmub_srv_wait_for_phy_init(dmub, 1000000);
|
|
||||||
if (status == DMUB_STATUS_OK)
|
|
||||||
/* Initialization OK */
|
|
||||||
break;
|
|
||||||
|
|
||||||
DC_ERROR("DMCUB PHY init failed: status=%d\n", status);
|
dmub = dc_dmub_srv->dmub;
|
||||||
ASSERT(0);
|
|
||||||
|
|
||||||
if (status != DMUB_STATUS_TIMEOUT)
|
return status.bits.optimized_init_done;
|
||||||
/*
|
|
||||||
* Server likely initialized or we don't have
|
|
||||||
* DMCUB HW support - this won't end.
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Continue spinning so we don't hang the ASIC. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
|
bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
|
||||||
|
|
|
@ -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_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);
|
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);
|
||||||
|
|
||||||
|
|
|
@ -1524,7 +1524,9 @@ void dcn10_init_hw(struct dc *dc)
|
||||||
if (!dcb->funcs->is_accelerated_mode(dcb))
|
if (!dcb->funcs->is_accelerated_mode(dcb))
|
||||||
hws->funcs.disable_vga(dc->hwseq);
|
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) {
|
if (dc->ctx->dc_bios->fw_info_valid) {
|
||||||
res_pool->ref_clocks.xtalin_clock_inKhz =
|
res_pool->ref_clocks.xtalin_clock_inKhz =
|
||||||
|
|
|
@ -366,7 +366,6 @@ struct dmub_srv_hw_funcs {
|
||||||
|
|
||||||
bool (*is_hw_init)(struct dmub_srv *dmub);
|
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,
|
void (*enable_dmub_boot_options)(struct dmub_srv *dmub,
|
||||||
const struct dmub_srv_hw_params *params);
|
const struct dmub_srv_hw_params *params);
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,3 @@ const struct dmub_srv_common_regs dmub_srv_dcn21_regs = {
|
||||||
#undef DMUB_SF
|
#undef DMUB_SF
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Shared functions. */
|
|
||||||
|
|
||||||
bool dmub_dcn21_is_phy_init(struct dmub_srv *dmub)
|
|
||||||
{
|
|
||||||
return REG_READ(DMCUB_SCRATCH10) == 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -32,8 +32,4 @@
|
||||||
|
|
||||||
extern const struct dmub_srv_common_regs dmub_srv_dcn21_regs;
|
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_ */
|
#endif /* _DMUB_DCN21_H_ */
|
||||||
|
|
|
@ -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;
|
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;
|
dmub->regs = &dmub_srv_dcn21_regs;
|
||||||
|
|
||||||
funcs->is_phy_init = dmub_dcn21_is_phy_init;
|
|
||||||
}
|
|
||||||
if (asic == DMUB_ASIC_DCN30) {
|
if (asic == DMUB_ASIC_DCN30) {
|
||||||
dmub->regs = &dmub_srv_dcn30_regs;
|
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;
|
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,
|
enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub,
|
||||||
uint32_t timeout_us)
|
uint32_t timeout_us)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue