From: Eric Yang <Eric.Yang2@xxxxxxx> Change-Id: I751733ea632c9f00182568ab3539854cacb2eda3 Signed-off-by: Eric Yang <Eric.Yang2 at amd.com> Reviewed-by: Tony Cheng <Tony.Cheng at amd.com> Acked-by: Harry Wentland <Harry.Wentland at amd.com> --- drivers/gpu/drm/amd/display/dc/core/dc.c | 45 +++++++++++++--------- .../amd/display/dc/dce110/dce110_hw_sequencer.c | 17 ++++++-- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 29 ++++++++++---- drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 +- 4 files changed, 64 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 748e709c611f..f305780c36ce 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -978,10 +978,10 @@ static bool dc_commit_context_no_check(struct dc *dc, struct validate_context *c const struct dc_sink *sink = context->streams[i]->sink; for (j = 0; j < context->stream_status[i].plane_count; j++) { - const struct dc_plane_state *plane_state = - context->stream_status[i].plane_states[j]; - - core_dc->hwss.apply_ctx_for_surface(core_dc, plane_state, context); + core_dc->hwss.apply_ctx_for_surface( + core_dc, context->streams[i], + context->stream_status[i].plane_count, + context); /* * enable stereo @@ -1391,6 +1391,21 @@ enum surface_update_type dc_check_update_surfaces_for_stream( return overall_type; } +static struct dc_stream_status *stream_get_status( + struct validate_context *ctx, + struct dc_stream_state *stream) +{ + uint8_t i; + + for (i = 0; i < ctx->stream_count; i++) { + if (stream == ctx->streams[i]) { + return &ctx->stream_status[i]; + } + } + + return NULL; +} + enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL; void dc_update_planes_and_stream(struct dc *dc, @@ -1405,16 +1420,6 @@ void dc_update_planes_and_stream(struct dc *dc, const struct dc_stream_status *stream_status; struct dc_context *dc_ctx = core_dc->ctx; - /* Currently this function do not result in any HW programming - * when called with 0 surface. But proceeding will cause - * SW state to be updated in validate_context. So we might as - * well make it not do anything at all until the hw programming - * is implemented properly to handle 0 surface case. - * TODO: fix hw programming then remove this early return - */ - if (surface_count == 0) - return; - stream_status = dc_stream_get_status(stream); ASSERT(stream_status); @@ -1595,7 +1600,7 @@ void dc_update_planes_and_stream(struct dc *dc, } if (surface_count == 0) - core_dc->hwss.apply_ctx_for_surface(core_dc, NULL, context); + core_dc->hwss.apply_ctx_for_surface(core_dc, stream, surface_count, context); /* Lock pipes for provided surfaces, or all active if full update*/ for (i = 0; i < surface_count; i++) { @@ -1625,12 +1630,16 @@ void dc_update_planes_and_stream(struct dc *dc, bool is_new_pipe_surface = cur_pipe_ctx->plane_state != pipe_ctx->plane_state; struct dc_cursor_position position = { 0 }; + if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state) continue; - if (!pipe_ctx->top_pipe) + if (!pipe_ctx->top_pipe && pipe_ctx->stream) { + struct dc_stream_status *stream_status = stream_get_status(context, pipe_ctx->stream); + core_dc->hwss.apply_ctx_for_surface( - core_dc, pipe_ctx->plane_state, context); + core_dc, pipe_ctx->stream, stream_status->plane_count, context); + } /* TODO: this is a hack w/a for switching from mpo to pipe split */ dc_stream_set_cursor_position(pipe_ctx->stream, &position); @@ -1653,7 +1662,7 @@ void dc_update_planes_and_stream(struct dc *dc, if (update_type == UPDATE_TYPE_MED) core_dc->hwss.apply_ctx_for_surface( - core_dc, plane_state, context); + core_dc, stream, surface_count, context); for (j = 0; j < core_dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index d3368a8bd1d5..59925723271e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2614,18 +2614,27 @@ static void dce110_program_front_end_for_pipe( static void dce110_apply_ctx_for_surface( struct core_dc *dc, - const struct dc_plane_state *plane_state, + const struct dc_stream_state *stream, + int num_planes, struct validate_context *context) { - int i; + int i, be_idx; - if (!plane_state) + if (num_planes == 0) return; + be_idx = -1; + for (i = 0; i < dc->res_pool->pipe_count; i++) { + if (stream == context->res_ctx.pipe_ctx[i].stream) { + be_idx = context->res_ctx.pipe_ctx[i].stream_res.tg->inst; + break; + } + } + for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - if (pipe_ctx->plane_state != plane_state) + if (pipe_ctx->stream == stream) continue; dce110_program_front_end_for_pipe(dc, pipe_ctx); 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 114dd279fe47..948aaeb73122 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 @@ -2151,7 +2151,8 @@ static void dcn10_pplib_apply_display_requirements( static void dcn10_apply_ctx_for_surface( struct core_dc *dc, - const struct dc_plane_state *plane_state, + const struct dc_stream_state *stream, + int num_planes, struct validate_context *context) { int i, be_idx; @@ -2159,12 +2160,26 @@ static void dcn10_apply_ctx_for_surface( if (dc->public.debug.sanity_checks) verify_allow_pstate_change_high(dc->hwseq); - if (!plane_state) - return; - - for (be_idx = 0; be_idx < dc->res_pool->pipe_count; be_idx++) - if (plane_state == context->res_ctx.pipe_ctx[be_idx].plane_state) + be_idx = -1; + for (i = 0; i < dc->res_pool->pipe_count; i++) { + if (stream == context->res_ctx.pipe_ctx[i].stream) { + be_idx = context->res_ctx.pipe_ctx[i].stream_res.tg->inst; break; + } + } + + ASSERT(be_idx != -1); + + if (num_planes == 0) { + for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) { + struct pipe_ctx *old_pipe_ctx = + &dc->current_context->res_ctx.pipe_ctx[i]; + + if (old_pipe_ctx->stream_res.tg && old_pipe_ctx->stream_res.tg->inst == be_idx) + dcn10_power_down_fe(dc, old_pipe_ctx->pipe_idx); + } + return; + } /* reset unused mpcc */ for (i = 0; i < dc->res_pool->pipe_count; i++) { @@ -2229,7 +2244,7 @@ static void dcn10_apply_ctx_for_surface( for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - if (pipe_ctx->plane_state != plane_state) + if (pipe_ctx->stream != stream) continue; /* looking for top pipe to program */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 5d075f93b4b9..7689e372b9da 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -59,7 +59,8 @@ struct hw_sequencer_funcs { void (*apply_ctx_for_surface)( struct core_dc *dc, - const struct dc_plane_state *plane_state, + const struct dc_stream_state *stream, + int num_planes, struct validate_context *context); void (*set_plane_config)( -- 2.11.0