From 3e80a5b068a5fedc69ada30ba1a2d1e0b76dfc25 Mon Sep 17 00:00:00 2001 From: Duncan Ma Date: Thu, 31 Mar 2022 15:13:22 -0400 Subject: [PATCH] drm/amd/display: Add ODM seamless boot support Revised validation logic when marking for seamless boot. Init resources accordingly when Pre-OS has ODM enabled. Reset ODM when transitioning Pre-OS odm to Post-OS non-odm to avoid corruption. Apply logic to set odm accordingly upon commit. Signed-off-by: Duncan Ma Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 9 ++++++++- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 5 +++++ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c | 21 +++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 4 ++-- .../drm/amd/display/dc/inc/hw/timing_generator.h | 2 ++ 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index b087452..7072b79 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2165,7 +2165,7 @@ static int acquire_resource_from_hw_enabled_state( if (pipe_ctx->stream_res.tg->funcs->get_optc_source) pipe_ctx->stream_res.tg->funcs->get_optc_source(pipe_ctx->stream_res.tg, - &numPipes, &id_src[0], &id_src[1]); + &numPipes, &id_src[0], &id_src[1]); if (id_src[0] == 0xf && id_src[1] == 0xf) { id_src[0] = tg_inst; @@ -2177,6 +2177,8 @@ static int acquire_resource_from_hw_enabled_state( if (id_src[i] == 0xf) return -1; + pipe_ctx = &res_ctx->pipe_ctx[id_src[i]]; + pipe_ctx->stream_res.tg = pool->timing_generators[tg_inst]; pipe_ctx->plane_res.mi = pool->mis[id_src[i]]; pipe_ctx->plane_res.hubp = pool->hubps[id_src[i]]; @@ -2190,13 +2192,17 @@ static int acquire_resource_from_hw_enabled_state( if (pool->mpc->funcs->read_mpcc_state) { struct mpcc_state s = {0}; + pool->mpc->funcs->read_mpcc_state(pool->mpc, pipe_ctx->plane_res.mpcc_inst, &s); + if (s.dpp_id < MAX_MPCC) pool->mpc->mpcc_array[pipe_ctx->plane_res.mpcc_inst].dpp_id = s.dpp_id; + if (s.bot_mpcc_id < MAX_MPCC) pool->mpc->mpcc_array[pipe_ctx->plane_res.mpcc_inst].mpcc_bot = &pool->mpc->mpcc_array[s.bot_mpcc_id]; + if (s.opp_id < MAX_OPP) pipe_ctx->stream_res.opp->mpc_tree_params.opp_id = s.opp_id; } @@ -2205,6 +2211,7 @@ static int acquire_resource_from_hw_enabled_state( if (id_src[i] >= pool->timing_generator_count) { id_src[i] = pool->timing_generator_count - 1; + pipe_ctx->stream_res.tg = pool->timing_generators[id_src[i]]; pipe_ctx->stream_res.opp = pool->opps[id_src[i]]; } 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 1cb206d..e3a6287 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 @@ -1375,6 +1375,11 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context) pipe_ctx->stream_res.tg = NULL; pipe_ctx->plane_res.hubp = NULL; + if (tg->funcs->is_tg_enabled(tg)) { + if (tg->funcs->init_odm) + tg->funcs->init_odm(tg); + } + tg->funcs->tg_init(tg); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c index 96fac71..c4304f2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c @@ -213,6 +213,26 @@ void optc31_set_drr( } } +void optc3_init_odm(struct timing_generator *optc) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_SET_5(OPTC_DATA_SOURCE_SELECT, 0, + OPTC_NUM_OF_INPUT_SEGMENT, 0, + OPTC_SEG0_SRC_SEL, optc->inst, + OPTC_SEG1_SRC_SEL, 0xf, + OPTC_SEG2_SRC_SEL, 0xf, + OPTC_SEG3_SRC_SEL, 0xf + ); + + REG_SET(OTG_H_TIMING_CNTL, 0, + OTG_H_TIMING_DIV_MODE, 0); + + REG_SET(OPTC_MEMORY_CONFIG, 0, + OPTC_MEM_SEL, 0); + optc1->opp_count = 1; +} + static struct timing_generator_funcs dcn31_tg_funcs = { .validate_timing = optc1_validate_timing, .program_timing = optc1_program_timing, @@ -273,6 +293,7 @@ static struct timing_generator_funcs dcn31_tg_funcs = { .program_manual_trigger = optc2_program_manual_trigger, .setup_manual_trigger = optc2_setup_manual_trigger, .get_hw_timing = optc1_get_hw_timing, + .init_odm = optc3_init_odm, }; void dcn31_timing_generator_init(struct optc *optc1) diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 0436055..a10ec59 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -657,7 +657,7 @@ void dcn32_init_hw(struct dc *dc) * Otherwise, if taking control is not possible, we need to power * everything down. */ - if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.seamless_boot_edp_requested) { + if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) { hws->funcs.init_pipes(dc, dc->current_state); if (dc->res_pool->hubbub->funcs->allow_self_refresh_control) dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, @@ -669,7 +669,7 @@ void dcn32_init_hw(struct dc *dc) * To avoid this, power down hardware on boot * if DIG is turned on and seamless boot not enabled */ - if (dc->config.seamless_boot_edp_requested) { + if (!dc->config.seamless_boot_edp_requested) { struct dc_link *edp_links[MAX_NUM_EDP]; struct dc_link *edp_link; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h index a89b223..62d4683 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h @@ -318,6 +318,8 @@ struct timing_generator_funcs { int vmin, int vmax); bool (*validate_vtotal_change_limit)(struct timing_generator *optc, uint32_t vtotal_change_limit); + + void (*init_odm)(struct timing_generator *tg); }; #endif -- 2.7.4