Commit 3e80a5b0 authored by Duncan Ma's avatar Duncan Ma Committed by Alex Deucher

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: default avatarDuncan Ma <duncan.ma@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 405bb9ee
...@@ -2165,7 +2165,7 @@ static int acquire_resource_from_hw_enabled_state( ...@@ -2165,7 +2165,7 @@ static int acquire_resource_from_hw_enabled_state(
if (pipe_ctx->stream_res.tg->funcs->get_optc_source) if (pipe_ctx->stream_res.tg->funcs->get_optc_source)
pipe_ctx->stream_res.tg->funcs->get_optc_source(pipe_ctx->stream_res.tg, 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) { if (id_src[0] == 0xf && id_src[1] == 0xf) {
id_src[0] = tg_inst; id_src[0] = tg_inst;
...@@ -2177,6 +2177,8 @@ static int acquire_resource_from_hw_enabled_state( ...@@ -2177,6 +2177,8 @@ static int acquire_resource_from_hw_enabled_state(
if (id_src[i] == 0xf) if (id_src[i] == 0xf)
return -1; return -1;
pipe_ctx = &res_ctx->pipe_ctx[id_src[i]];
pipe_ctx->stream_res.tg = pool->timing_generators[tg_inst]; pipe_ctx->stream_res.tg = pool->timing_generators[tg_inst];
pipe_ctx->plane_res.mi = pool->mis[id_src[i]]; pipe_ctx->plane_res.mi = pool->mis[id_src[i]];
pipe_ctx->plane_res.hubp = pool->hubps[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( ...@@ -2190,13 +2192,17 @@ static int acquire_resource_from_hw_enabled_state(
if (pool->mpc->funcs->read_mpcc_state) { if (pool->mpc->funcs->read_mpcc_state) {
struct mpcc_state s = {0}; struct mpcc_state s = {0};
pool->mpc->funcs->read_mpcc_state(pool->mpc, pipe_ctx->plane_res.mpcc_inst, &s); pool->mpc->funcs->read_mpcc_state(pool->mpc, pipe_ctx->plane_res.mpcc_inst, &s);
if (s.dpp_id < MAX_MPCC) if (s.dpp_id < MAX_MPCC)
pool->mpc->mpcc_array[pipe_ctx->plane_res.mpcc_inst].dpp_id = pool->mpc->mpcc_array[pipe_ctx->plane_res.mpcc_inst].dpp_id =
s.dpp_id; s.dpp_id;
if (s.bot_mpcc_id < MAX_MPCC) if (s.bot_mpcc_id < MAX_MPCC)
pool->mpc->mpcc_array[pipe_ctx->plane_res.mpcc_inst].mpcc_bot = pool->mpc->mpcc_array[pipe_ctx->plane_res.mpcc_inst].mpcc_bot =
&pool->mpc->mpcc_array[s.bot_mpcc_id]; &pool->mpc->mpcc_array[s.bot_mpcc_id];
if (s.opp_id < MAX_OPP) if (s.opp_id < MAX_OPP)
pipe_ctx->stream_res.opp->mpc_tree_params.opp_id = s.opp_id; 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( ...@@ -2205,6 +2211,7 @@ static int acquire_resource_from_hw_enabled_state(
if (id_src[i] >= pool->timing_generator_count) { if (id_src[i] >= pool->timing_generator_count) {
id_src[i] = pool->timing_generator_count - 1; id_src[i] = pool->timing_generator_count - 1;
pipe_ctx->stream_res.tg = pool->timing_generators[id_src[i]]; pipe_ctx->stream_res.tg = pool->timing_generators[id_src[i]];
pipe_ctx->stream_res.opp = pool->opps[id_src[i]]; pipe_ctx->stream_res.opp = pool->opps[id_src[i]];
} }
......
...@@ -1375,6 +1375,11 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context) ...@@ -1375,6 +1375,11 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
pipe_ctx->stream_res.tg = NULL; pipe_ctx->stream_res.tg = NULL;
pipe_ctx->plane_res.hubp = 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); tg->funcs->tg_init(tg);
} }
......
...@@ -213,6 +213,26 @@ void optc31_set_drr( ...@@ -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 = { static struct timing_generator_funcs dcn31_tg_funcs = {
.validate_timing = optc1_validate_timing, .validate_timing = optc1_validate_timing,
.program_timing = optc1_program_timing, .program_timing = optc1_program_timing,
...@@ -273,6 +293,7 @@ static struct timing_generator_funcs dcn31_tg_funcs = { ...@@ -273,6 +293,7 @@ static struct timing_generator_funcs dcn31_tg_funcs = {
.program_manual_trigger = optc2_program_manual_trigger, .program_manual_trigger = optc2_program_manual_trigger,
.setup_manual_trigger = optc2_setup_manual_trigger, .setup_manual_trigger = optc2_setup_manual_trigger,
.get_hw_timing = optc1_get_hw_timing, .get_hw_timing = optc1_get_hw_timing,
.init_odm = optc3_init_odm,
}; };
void dcn31_timing_generator_init(struct optc *optc1) void dcn31_timing_generator_init(struct optc *optc1)
......
...@@ -657,7 +657,7 @@ void dcn32_init_hw(struct dc *dc) ...@@ -657,7 +657,7 @@ void dcn32_init_hw(struct dc *dc)
* Otherwise, if taking control is not possible, we need to power * Otherwise, if taking control is not possible, we need to power
* everything down. * 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); hws->funcs.init_pipes(dc, dc->current_state);
if (dc->res_pool->hubbub->funcs->allow_self_refresh_control) if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
...@@ -669,7 +669,7 @@ void dcn32_init_hw(struct dc *dc) ...@@ -669,7 +669,7 @@ void dcn32_init_hw(struct dc *dc)
* To avoid this, power down hardware on boot * To avoid this, power down hardware on boot
* if DIG is turned on and seamless boot not enabled * 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_links[MAX_NUM_EDP];
struct dc_link *edp_link; struct dc_link *edp_link;
......
...@@ -318,6 +318,8 @@ struct timing_generator_funcs { ...@@ -318,6 +318,8 @@ struct timing_generator_funcs {
int vmin, int vmax); int vmin, int vmax);
bool (*validate_vtotal_change_limit)(struct timing_generator *optc, bool (*validate_vtotal_change_limit)(struct timing_generator *optc,
uint32_t vtotal_change_limit); uint32_t vtotal_change_limit);
void (*init_odm)(struct timing_generator *tg);
}; };
#endif #endif
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