From: Hugo Hu <hugo.hu@xxxxxxx> [Why] During system boot in second screen only mode on a seamless boot system, there is a chance that the pipe's det size might not be reset. [How] Reset the det size while resetting the pipe during seamless boot. Reviewed-by: Dmytro Laktyushkin <dmytro.laktyushkin@xxxxxxx> Acked-by: Roman Li <roman.li@xxxxxxx> Signed-off-by: Hugo Hu <hugo.hu@xxxxxxx> --- .../drm/amd/display/dc/dcn31/dcn31_hubbub.c | 23 +++++++++++++++++++ .../amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 9 ++++++++ .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h | 1 + 3 files changed, 33 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c index f6b59c29cee2..5b5b5e0775fa 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c @@ -109,6 +109,28 @@ static void dcn31_program_det_size(struct hubbub *hubbub, int hubp_inst, unsigne + hubbub2->det3_size + hubbub2->compbuf_size_segments <= hubbub2->crb_size_segs); } +static void dcn31_wait_for_det_apply(struct hubbub *hubbub, int hubp_inst) +{ + struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); + + switch (hubp_inst) { + case 0: + REG_WAIT(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, hubbub2->det0_size, 1000, 30); + break; + case 1: + REG_WAIT(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, hubbub2->det1_size, 1000, 30); + break; + case 2: + REG_WAIT(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, hubbub2->det2_size, 1000, 30); + break; + case 3: + REG_WAIT(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, hubbub2->det3_size, 1000, 30); + break; + default: + break; + } +} + static void dcn31_program_compbuf_size(struct hubbub *hubbub, unsigned int compbuf_size_kb, bool safe_to_increase) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1041,6 +1063,7 @@ static const struct hubbub_funcs hubbub31_funcs = { .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled, .verify_allow_pstate_change_high = hubbub31_verify_allow_pstate_change_high, .program_det_size = dcn31_program_det_size, + .wait_for_det_apply = dcn31_wait_for_det_apply, .program_compbuf_size = dcn31_program_compbuf_size, .init_crb = dcn31_init_crb, .hubbub_read_state = hubbub2_read_state, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c index c339f756b8e7..5daedd893923 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c @@ -585,6 +585,15 @@ void dcn31_reset_hw_ctx_wrap( pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { struct clock_source *old_clk = pipe_ctx_old->clock_source; + /* Reset pipe which is seamless boot stream. */ + if (!pipe_ctx_old->plane_state) { + dc->res_pool->hubbub->funcs->program_det_size( + dc->res_pool->hubbub, pipe_ctx_old->plane_res.hubp->inst, 0); + /* Wait det size changed. */ + dc->res_pool->hubbub->funcs->wait_for_det_apply( + dc->res_pool->hubbub, pipe_ctx_old->plane_res.hubp->inst); + } + dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); if (hws->funcs.enable_stream_gating) hws->funcs.enable_stream_gating(dc, pipe_ctx_old); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h index cea05843990c..901891316dfb 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h @@ -188,6 +188,7 @@ struct hubbub_funcs { * compressed or detiled buffers. */ void (*program_det_size)(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_in_kbyte); + void (*wait_for_det_apply)(struct hubbub *hubbub, int hubp_inst); void (*program_compbuf_size)(struct hubbub *hubbub, unsigned compbuf_size_kb, bool safe_to_increase); void (*init_crb)(struct hubbub *hubbub); void (*force_usr_retraining_allow)(struct hubbub *hubbub, bool allow); -- 2.34.1