drm/amd/display: Split program front end part that occur outside lock
[Why] Eventually want to lock at a higher level in stack. To do this, we need to be able to isolate the parts that need to be done after pipe unlock. [How] Split out programming that is done post unlock. 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
0b464c857c
commit
bbf5f6c3f8
10 changed files with 79 additions and 12 deletions
|
@ -786,11 +786,15 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
|
||||||
if (should_disable && old_stream) {
|
if (should_disable && old_stream) {
|
||||||
dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
|
dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
|
||||||
disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
|
disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
|
||||||
if (dc->hwss.apply_ctx_for_surface)
|
if (dc->hwss.apply_ctx_for_surface) {
|
||||||
dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
|
dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
|
||||||
|
dc->hwss.post_unlock_program_front_end(dc, dangling_context);
|
||||||
|
}
|
||||||
|
if (dc->hwss.program_front_end_for_ctx) {
|
||||||
|
dc->hwss.program_front_end_for_ctx(dc, dangling_context);
|
||||||
|
dc->hwss.post_unlock_program_front_end(dc, dangling_context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (dc->hwss.program_front_end_for_ctx)
|
|
||||||
dc->hwss.program_front_end_for_ctx(dc, dangling_context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current_ctx = dc->current_state;
|
current_ctx = dc->current_state;
|
||||||
|
@ -1219,6 +1223,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
||||||
dc, context->streams[i],
|
dc, context->streams[i],
|
||||||
context->stream_status[i].plane_count,
|
context->stream_status[i].plane_count,
|
||||||
context); /* use new pipe config in new context */
|
context); /* use new pipe config in new context */
|
||||||
|
dc->hwss.post_unlock_program_front_end(dc, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Program hardware */
|
/* Program hardware */
|
||||||
|
@ -1238,19 +1243,24 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Program all planes within new context*/
|
/* Program all planes within new context*/
|
||||||
if (dc->hwss.program_front_end_for_ctx)
|
if (dc->hwss.program_front_end_for_ctx) {
|
||||||
dc->hwss.program_front_end_for_ctx(dc, context);
|
dc->hwss.program_front_end_for_ctx(dc, context);
|
||||||
|
dc->hwss.post_unlock_program_front_end(dc, context);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < context->stream_count; i++) {
|
for (i = 0; i < context->stream_count; i++) {
|
||||||
const struct dc_link *link = context->streams[i]->link;
|
const struct dc_link *link = context->streams[i]->link;
|
||||||
|
|
||||||
if (!context->streams[i]->mode_changed)
|
if (!context->streams[i]->mode_changed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (dc->hwss.apply_ctx_for_surface)
|
if (dc->hwss.apply_ctx_for_surface) {
|
||||||
dc->hwss.apply_ctx_for_surface(
|
dc->hwss.apply_ctx_for_surface(
|
||||||
dc, context->streams[i],
|
dc, context->streams[i],
|
||||||
context->stream_status[i].plane_count,
|
context->stream_status[i].plane_count,
|
||||||
context);
|
context);
|
||||||
|
dc->hwss.post_unlock_program_front_end(dc, context);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* enable stereo
|
* enable stereo
|
||||||
|
@ -2183,6 +2193,7 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||||
if (dc->hwss.program_front_end_for_ctx)
|
if (dc->hwss.program_front_end_for_ctx)
|
||||||
dc->hwss.program_front_end_for_ctx(dc, context);
|
dc->hwss.program_front_end_for_ctx(dc, context);
|
||||||
|
|
||||||
|
dc->hwss.post_unlock_program_front_end(dc, context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2315,6 +2326,9 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||||
dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
|
dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (update_type != UPDATE_TYPE_FAST)
|
||||||
|
dc->hwss.post_unlock_program_front_end(dc, context);
|
||||||
|
|
||||||
// Fire manual trigger only when bottom plane is flipped
|
// Fire manual trigger only when bottom plane is flipped
|
||||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
||||||
|
|
|
@ -2621,6 +2621,11 @@ static void dce110_apply_ctx_for_surface(
|
||||||
enable_fbc(dc, context);
|
enable_fbc(dc, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dce110_post_unlock_program_front_end(
|
||||||
|
struct dc *dc,
|
||||||
|
struct dc_state *context)
|
||||||
|
{
|
||||||
|
}
|
||||||
static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||||
{
|
{
|
||||||
struct dce_hwseq *hws = dc->hwseq;
|
struct dce_hwseq *hws = dc->hwseq;
|
||||||
|
@ -2722,6 +2727,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
|
||||||
.init_hw = init_hw,
|
.init_hw = init_hw,
|
||||||
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
||||||
.apply_ctx_for_surface = dce110_apply_ctx_for_surface,
|
.apply_ctx_for_surface = dce110_apply_ctx_for_surface,
|
||||||
|
.post_unlock_program_front_end = dce110_post_unlock_program_front_end,
|
||||||
.update_plane_addr = update_plane_addr,
|
.update_plane_addr = update_plane_addr,
|
||||||
.update_pending_status = dce110_update_pending_status,
|
.update_pending_status = dce110_update_pending_status,
|
||||||
.enable_accelerated_mode = dce110_enable_accelerated_mode,
|
.enable_accelerated_mode = dce110_enable_accelerated_mode,
|
||||||
|
|
|
@ -2512,7 +2512,6 @@ void dcn10_apply_ctx_for_surface(
|
||||||
int i;
|
int i;
|
||||||
struct timing_generator *tg;
|
struct timing_generator *tg;
|
||||||
uint32_t underflow_check_delay_us;
|
uint32_t underflow_check_delay_us;
|
||||||
bool removed_pipe[4] = { false };
|
|
||||||
bool interdependent_update = false;
|
bool interdependent_update = false;
|
||||||
struct pipe_ctx *top_pipe_to_program =
|
struct pipe_ctx *top_pipe_to_program =
|
||||||
dcn10_find_top_pipe_for_stream(dc, context, stream);
|
dcn10_find_top_pipe_for_stream(dc, context, stream);
|
||||||
|
@ -2552,6 +2551,9 @@ void dcn10_apply_ctx_for_surface(
|
||||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||||
struct pipe_ctx *old_pipe_ctx =
|
struct pipe_ctx *old_pipe_ctx =
|
||||||
&dc->current_state->res_ctx.pipe_ctx[i];
|
&dc->current_state->res_ctx.pipe_ctx[i];
|
||||||
|
|
||||||
|
pipe_ctx->update_flags.raw = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Powergate reused pipes that are not powergated
|
* Powergate reused pipes that are not powergated
|
||||||
* fairly hacky right now, using opp_id as indicator
|
* fairly hacky right now, using opp_id as indicator
|
||||||
|
@ -2571,7 +2573,7 @@ void dcn10_apply_ctx_for_surface(
|
||||||
old_pipe_ctx->stream_res.tg == tg) {
|
old_pipe_ctx->stream_res.tg == tg) {
|
||||||
|
|
||||||
hws->funcs.plane_atomic_disconnect(dc, old_pipe_ctx);
|
hws->funcs.plane_atomic_disconnect(dc, old_pipe_ctx);
|
||||||
removed_pipe[i] = true;
|
pipe_ctx->update_flags.bits.disable = 1;
|
||||||
|
|
||||||
DC_LOG_DC("Reset mpcc for pipe %d\n",
|
DC_LOG_DC("Reset mpcc for pipe %d\n",
|
||||||
old_pipe_ctx->pipe_idx);
|
old_pipe_ctx->pipe_idx);
|
||||||
|
@ -2602,16 +2604,41 @@ void dcn10_apply_ctx_for_surface(
|
||||||
dcn10_lock_all_pipes(dc, context, false);
|
dcn10_lock_all_pipes(dc, context, false);
|
||||||
else
|
else
|
||||||
dcn10_pipe_control_lock(dc, top_pipe_to_program, false);
|
dcn10_pipe_control_lock(dc, top_pipe_to_program, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (num_planes == 0)
|
void dcn10_post_unlock_program_front_end(
|
||||||
false_optc_underflow_wa(dc, stream, tg);
|
struct dc *dc,
|
||||||
|
struct dc_state *context)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
DC_LOGGER_INIT(dc->ctx->logger);
|
||||||
|
|
||||||
|
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||||
|
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||||
|
|
||||||
|
if (!pipe_ctx->top_pipe &&
|
||||||
|
!pipe_ctx->prev_odm_pipe &&
|
||||||
|
pipe_ctx->stream) {
|
||||||
|
struct dc_stream_status *stream_status = NULL;
|
||||||
|
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||||
|
|
||||||
|
for (j = 0; j < context->stream_count; j++) {
|
||||||
|
if (pipe_ctx->stream == context->streams[j])
|
||||||
|
stream_status = &context->stream_status[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->stream_status[i].plane_count == 0)
|
||||||
|
false_optc_underflow_wa(dc, pipe_ctx->stream, tg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||||
if (removed_pipe[i])
|
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable)
|
||||||
dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
|
dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
|
||||||
|
|
||||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||||
if (removed_pipe[i]) {
|
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) {
|
||||||
dc->hwss.optimize_bandwidth(dc, context);
|
dc->hwss.optimize_bandwidth(dc, context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,9 @@ void dcn10_apply_ctx_for_surface(
|
||||||
const struct dc_stream_state *stream,
|
const struct dc_stream_state *stream,
|
||||||
int num_planes,
|
int num_planes,
|
||||||
struct dc_state *context);
|
struct dc_state *context);
|
||||||
|
void dcn10_post_unlock_program_front_end(
|
||||||
|
struct dc *dc,
|
||||||
|
struct dc_state *context);
|
||||||
void dcn10_hubp_pg_control(
|
void dcn10_hubp_pg_control(
|
||||||
struct dce_hwseq *hws,
|
struct dce_hwseq *hws,
|
||||||
unsigned int hubp_inst,
|
unsigned int hubp_inst,
|
||||||
|
|
|
@ -32,6 +32,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
||||||
.init_hw = dcn10_init_hw,
|
.init_hw = dcn10_init_hw,
|
||||||
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
||||||
.apply_ctx_for_surface = dcn10_apply_ctx_for_surface,
|
.apply_ctx_for_surface = dcn10_apply_ctx_for_surface,
|
||||||
|
.post_unlock_program_front_end = dcn10_post_unlock_program_front_end,
|
||||||
.update_plane_addr = dcn10_update_plane_addr,
|
.update_plane_addr = dcn10_update_plane_addr,
|
||||||
.update_dchub = dcn10_update_dchub,
|
.update_dchub = dcn10_update_dchub,
|
||||||
.update_pending_status = dcn10_update_pending_status,
|
.update_pending_status = dcn10_update_pending_status,
|
||||||
|
|
|
@ -1551,7 +1551,6 @@ void dcn20_program_front_end_for_ctx(
|
||||||
struct dc *dc,
|
struct dc *dc,
|
||||||
struct dc_state *context)
|
struct dc_state *context)
|
||||||
{
|
{
|
||||||
const unsigned int TIMEOUT_FOR_PIPE_ENABLE_MS = 100;
|
|
||||||
int i;
|
int i;
|
||||||
struct dce_hwseq *hws = dc->hwseq;
|
struct dce_hwseq *hws = dc->hwseq;
|
||||||
bool pipe_locked[MAX_PIPES] = {false};
|
bool pipe_locked[MAX_PIPES] = {false};
|
||||||
|
@ -1626,6 +1625,16 @@ void dcn20_program_front_end_for_ctx(
|
||||||
if (!pipe_ctx->update_flags.bits.enable)
|
if (!pipe_ctx->update_flags.bits.enable)
|
||||||
dc->hwss.pipe_control_lock(dc, &dc->current_state->res_ctx.pipe_ctx[i], false);
|
dc->hwss.pipe_control_lock(dc, &dc->current_state->res_ctx.pipe_ctx[i], false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dcn20_post_unlock_program_front_end(
|
||||||
|
struct dc *dc,
|
||||||
|
struct dc_state *context)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const unsigned int TIMEOUT_FOR_PIPE_ENABLE_MS = 100;
|
||||||
|
|
||||||
|
DC_LOGGER_INIT(dc->ctx->logger);
|
||||||
|
|
||||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||||
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable)
|
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable)
|
||||||
|
|
|
@ -35,6 +35,9 @@ bool dcn20_set_shaper_3dlut(
|
||||||
void dcn20_program_front_end_for_ctx(
|
void dcn20_program_front_end_for_ctx(
|
||||||
struct dc *dc,
|
struct dc *dc,
|
||||||
struct dc_state *context);
|
struct dc_state *context);
|
||||||
|
void dcn20_post_unlock_program_front_end(
|
||||||
|
struct dc *dc,
|
||||||
|
struct dc_state *context);
|
||||||
void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx);
|
void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||||
void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);
|
void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||||
bool dcn20_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
|
bool dcn20_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
|
||||||
|
|
|
@ -33,6 +33,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
|
||||||
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
||||||
.apply_ctx_for_surface = NULL,
|
.apply_ctx_for_surface = NULL,
|
||||||
.program_front_end_for_ctx = dcn20_program_front_end_for_ctx,
|
.program_front_end_for_ctx = dcn20_program_front_end_for_ctx,
|
||||||
|
.post_unlock_program_front_end = dcn20_post_unlock_program_front_end,
|
||||||
.update_plane_addr = dcn20_update_plane_addr,
|
.update_plane_addr = dcn20_update_plane_addr,
|
||||||
.update_dchub = dcn10_update_dchub,
|
.update_dchub = dcn10_update_dchub,
|
||||||
.update_pending_status = dcn10_update_pending_status,
|
.update_pending_status = dcn10_update_pending_status,
|
||||||
|
|
|
@ -34,6 +34,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
|
||||||
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
||||||
.apply_ctx_for_surface = NULL,
|
.apply_ctx_for_surface = NULL,
|
||||||
.program_front_end_for_ctx = dcn20_program_front_end_for_ctx,
|
.program_front_end_for_ctx = dcn20_program_front_end_for_ctx,
|
||||||
|
.post_unlock_program_front_end = dcn20_post_unlock_program_front_end,
|
||||||
.update_plane_addr = dcn20_update_plane_addr,
|
.update_plane_addr = dcn20_update_plane_addr,
|
||||||
.update_dchub = dcn10_update_dchub,
|
.update_dchub = dcn10_update_dchub,
|
||||||
.update_pending_status = dcn10_update_pending_status,
|
.update_pending_status = dcn10_update_pending_status,
|
||||||
|
|
|
@ -66,6 +66,8 @@ struct hw_sequencer_funcs {
|
||||||
int num_planes, struct dc_state *context);
|
int num_planes, struct dc_state *context);
|
||||||
void (*program_front_end_for_ctx)(struct dc *dc,
|
void (*program_front_end_for_ctx)(struct dc *dc,
|
||||||
struct dc_state *context);
|
struct dc_state *context);
|
||||||
|
void (*post_unlock_program_front_end)(struct dc *dc,
|
||||||
|
struct dc_state *context);
|
||||||
void (*update_plane_addr)(const struct dc *dc,
|
void (*update_plane_addr)(const struct dc *dc,
|
||||||
struct pipe_ctx *pipe_ctx);
|
struct pipe_ctx *pipe_ctx);
|
||||||
void (*update_dchub)(struct dce_hwseq *hws,
|
void (*update_dchub)(struct dce_hwseq *hws,
|
||||||
|
|
Loading…
Add table
Reference in a new issue