Commit ac02dc34 authored by Eric Yang's avatar Eric Yang Committed by Alex Deucher

drm/amd/display: Add periodic detection when zstate is enabled

[Why]
When system is in Z10 HPD interrupts cannot fire, we may miss display
configuration changes.

[How]
When Zstate is enabled, if DMUB indicate DCN has lost power, do a
complete detection periodically.
Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarMikita Lipski <mikita.lipski@amd.com>
Signed-off-by: default avatarEric Yang <Eric.Yang2@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6513104b
......@@ -793,4 +793,10 @@ void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz)
// FPGA programming for this clock in diags framework that
// needs to go through dm layer, therefore leave dummy interace here
}
void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable)
{
/* TODO: add peridic detection implementation */
}
#endif
\ No newline at end of file
......@@ -142,6 +142,7 @@ static void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_ALLOW &&
new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) {
dcn31_smu_set_Z9_support(clk_mgr, true);
dm_helpers_enable_periodic_detection(clk_mgr_base->ctx, true);
clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
}
......@@ -166,6 +167,7 @@ static void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_DISALLOW &&
new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) {
dcn31_smu_set_Z9_support(clk_mgr, false);
dm_helpers_enable_periodic_detection(clk_mgr_base->ctx, false);
clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
}
......
......@@ -1562,7 +1562,7 @@ static uint8_t get_stream_mask(struct dc *dc, struct dc_state *context)
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
void dc_z10_restore(struct dc *dc)
void dc_z10_restore(const struct dc *dc)
{
if (dc->hwss.z10_restore)
dc->hwss.z10_restore(dc);
......
......@@ -1250,6 +1250,10 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
}
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
dc_z10_restore(dc);
#endif
/* get out of low power state */
if (!can_apply_seamless_boot && reason != DETECT_REASON_BOOT)
clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
......
......@@ -1363,7 +1363,7 @@ void dc_hardware_release(struct dc *dc);
bool dc_set_psr_allow_active(struct dc *dc, bool enable);
#if defined(CONFIG_DRM_AMD_DC_DCN)
void dc_z10_restore(struct dc *dc);
void dc_z10_restore(const struct dc *dc);
void dc_z10_save_init(struct dc *dc);
#endif
......
......@@ -425,7 +425,7 @@ void dcn31_z10_save_init(struct dc *dc)
dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
}
void dcn31_z10_restore(struct dc *dc)
void dcn31_z10_restore(const struct dc *dc)
{
union dmub_rb_cmd cmd;
......
......@@ -43,7 +43,7 @@ void dcn31_enable_power_gating_plane(
void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx);
void dcn31_z10_restore(struct dc *dc);
void dcn31_z10_restore(const struct dc *dc);
void dcn31_z10_save_init(struct dc *dc);
void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
......
......@@ -160,6 +160,10 @@ void dm_set_dcn_clocks(
struct dc_context *ctx,
struct dc_clocks *clks);
#if defined(CONFIG_DRM_AMD_DC_DCN)
void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable);
#endif
void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz);
bool dm_helpers_dmub_outbox_interrupt_control(struct dc_context *ctx, bool enable);
......
......@@ -236,7 +236,7 @@ struct hw_sequencer_funcs {
const struct tg_color *solid_color,
int width, int height, int offset);
void (*z10_restore)(struct dc *dc);
void (*z10_restore)(const struct dc *dc);
void (*z10_save_init)(struct dc *dc);
void (*update_visual_confirm_color)(struct dc *dc,
......
......@@ -358,6 +358,8 @@ struct dmub_srv_hw_funcs {
uint32_t (*get_current_time)(struct dmub_srv *dmub);
void (*get_diagnostic_data)(struct dmub_srv *dmub, struct dmub_diagnostic_data *dmub_oca);
bool (*should_detect)(struct dmub_srv *dmub);
};
/**
......@@ -724,6 +726,8 @@ bool dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entr
bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data);
bool dmub_srv_should_detect(struct dmub_srv *dmub);
#if defined(__cplusplus)
}
#endif
......
......@@ -432,3 +432,11 @@ void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti
REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled);
diag_data->is_cw6_enabled = is_cw6_enabled;
}
bool dmub_dcn31_should_detect(struct dmub_srv *dmub)
{
uint32_t fw_boot_status = REG_READ(DMCUB_SCRATCH0);
bool should_detect = fw_boot_status & DMUB_FW_BOOT_STATUS_BIT_DETECTION_REQUIRED;
return should_detect;
}
......@@ -245,4 +245,6 @@ uint32_t dmub_dcn31_get_current_time(struct dmub_srv *dmub);
void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data);
bool dmub_dcn31_should_detect(struct dmub_srv *dmub);
#endif /* _DMUB_DCN31_H_ */
......@@ -234,7 +234,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
funcs->set_outbox0_rptr = dmub_dcn31_set_outbox0_rptr;
funcs->get_diagnostic_data = dmub_dcn31_get_diagnostic_data;
funcs->should_detect = dmub_dcn31_should_detect;
funcs->get_current_time = dmub_dcn31_get_current_time;
break;
......@@ -816,3 +816,11 @@ bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_
dmub->hw_funcs.get_diagnostic_data(dmub, diag_data);
return true;
}
bool dmub_srv_should_detect(struct dmub_srv *dmub)
{
if (!dmub->hw_init || !dmub->hw_funcs.should_detect)
return false;
return dmub->hw_funcs.should_detect(dmub);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment