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: Anthony Koo <Anthony.Koo@amd.com> Reviewed-by: Aric Cyr <Aric.Cyr@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
9c0fb8d45b
commit
fb55546ea4
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue