Commit fb55546e authored by Anthony Koo's avatar Anthony Koo Committed by Alex Deucher

drm/amd/display: refactor init_hw to isolate pipe related init

[Why]
Pipe related init is possible to optimized if we know what we
intend to program, and if we can determine it matches what is
already programmed for the pipe.

[How]
First step is to isolate the pipe related init code
Signed-off-by: default avatarAnthony Koo <Anthony.Koo@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9c0fb8d4
......@@ -2275,6 +2275,11 @@ static void dce110_enable_per_frame_crtc_position_reset(
}
static void init_pipes(struct dc *dc, struct dc_state *context)
{
// Do nothing
}
static void init_hw(struct dc *dc)
{
int i;
......@@ -2642,6 +2647,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.program_gamut_remap = program_gamut_remap,
.program_output_csc = program_output_csc,
.init_hw = init_hw,
.init_pipes = init_pipes,
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
.apply_ctx_for_surface = dce110_apply_ctx_for_surface,
.update_plane_addr = update_plane_addr,
......
......@@ -956,6 +956,64 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
pipe_ctx->pipe_idx);
}
static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
{
int i;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i];
if (tg->funcs->is_tg_enabled(tg))
tg->funcs->lock(tg);
/* Blank controller using driver code instead of
* command table.
*/
if (tg->funcs->is_tg_enabled(tg)) {
tg->funcs->set_blank(tg, true);
hwss_wait_for_blank_complete(tg);
}
}
dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i];
struct hubp *hubp = dc->res_pool->hubps[i];
struct dpp *dpp = dc->res_pool->dpps[i];
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
dpp->funcs->dpp_reset(dpp);
pipe_ctx->stream_res.tg = tg;
pipe_ctx->pipe_idx = i;
pipe_ctx->plane_res.hubp = hubp;
pipe_ctx->plane_res.dpp = dpp;
pipe_ctx->plane_res.mpcc_inst = dpp->inst;
hubp->mpcc_id = dpp->inst;
hubp->opp_id = 0xf;
hubp->power_gated = false;
dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
hwss1_plane_atomic_disconnect(dc, pipe_ctx);
if (tg->funcs->is_tg_enabled(tg))
tg->funcs->unlock(tg);
dcn10_disable_plane(dc, pipe_ctx);
pipe_ctx->stream_res.tg = NULL;
pipe_ctx->plane_res.hubp = NULL;
tg->funcs->tg_init(tg);
}
}
static void dcn10_init_hw(struct dc *dc)
{
int i;
......@@ -963,7 +1021,6 @@ static void dcn10_init_hw(struct dc *dc)
struct dmcu *dmcu = dc->res_pool->dmcu;
struct dce_hwseq *hws = dc->hwseq;
struct dc_bios *dcb = dc->ctx->dc_bios;
struct dc_state *context = dc->current_state;
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
REG_WRITE(REFCLK_CNTL, 0);
......@@ -980,11 +1037,15 @@ static void dcn10_init_hw(struct dc *dc)
}
enable_power_gating_plane(dc->hwseq, true);
} else {
/* end of FPGA. Below if real ASIC */
return;
}
if (!dcb->funcs->is_accelerated_mode(dcb)) {
bool allow_self_fresh_force_enable =
hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub);
hububu1_is_allow_self_refresh_enabled(
dc->res_pool->hubbub);
bios_golden_init(dc);
......@@ -1018,76 +1079,6 @@ static void dcn10_init_hw(struct dc *dc)
link->link_enc->funcs->is_dig_enabled(link->link_enc))
link->link_status.link_active = true;
}
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i];
if (tg->funcs->is_tg_enabled(tg))
tg->funcs->lock(tg);
}
/* Blank controller using driver code instead of
* command table.
*/
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i];
if (tg->funcs->is_tg_enabled(tg)) {
tg->funcs->set_blank(tg, true);
hwss_wait_for_blank_complete(tg);
}
}
/* Reset all MPCC muxes */
dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc);
for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i];
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
struct hubp *hubp = dc->res_pool->hubps[i];
struct dpp *dpp = dc->res_pool->dpps[i];
pipe_ctx->stream_res.tg = tg;
pipe_ctx->pipe_idx = i;
pipe_ctx->plane_res.hubp = hubp;
pipe_ctx->plane_res.dpp = dpp;
pipe_ctx->plane_res.mpcc_inst = dpp->inst;
hubp->mpcc_id = dpp->inst;
hubp->opp_id = 0xf;
hubp->power_gated = false;
dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
hwss1_plane_atomic_disconnect(dc, pipe_ctx);
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i];
if (tg->funcs->is_tg_enabled(tg))
tg->funcs->unlock(tg);
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i];
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
dcn10_disable_plane(dc, pipe_ctx);
pipe_ctx->stream_res.tg = NULL;
pipe_ctx->plane_res.hubp = NULL;
tg->funcs->tg_init(tg);
}
/* end of FPGA. Below if real ASIC */
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
return;
for (i = 0; i < dc->res_pool->audio_count; i++) {
struct audio *audio = dc->res_pool->audios[i];
......@@ -1118,6 +1109,9 @@ static void dcn10_init_hw(struct dc *dc)
enable_power_gating_plane(dc->hwseq, true);
memset(&dc->res_pool->clk_mgr->clks, 0, sizeof(dc->res_pool->clk_mgr->clks));
if (dc->hwss.init_pipes)
dc->hwss.init_pipes(dc, dc->current_state);
}
static void reset_hw_ctx_wrap(
......@@ -2718,6 +2712,7 @@ static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx)
static const struct hw_sequencer_funcs dcn10_funcs = {
.program_gamut_remap = program_gamut_remap,
.init_hw = dcn10_init_hw,
.init_pipes = dcn10_init_pipes,
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
.apply_ctx_for_surface = dcn10_apply_ctx_for_surface,
.update_plane_addr = dcn10_update_plane_addr,
......
......@@ -70,6 +70,8 @@ struct hw_sequencer_funcs {
void (*init_hw)(struct dc *dc);
void (*init_pipes)(struct dc *dc, struct dc_state *context);
enum dc_status (*apply_ctx_to_hw)(
struct dc *dc, struct dc_state *context);
......
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