From: Dmytro Laktyushkin <dmytro.laktyush...@amd.com> [WHY & HOW] Enable ODM Combine + Fullscreen MPO on DCN2.1 For lower power consumption in video use cases.
Signed-off-by: Dmytro Laktyushkin <dmytro.laktyush...@amd.com> Signed-off-by: Sung Lee <sung....@amd.com> Acked-by: Aurabindo Pillai <aurabindo.pil...@amd.com> --- .../gpu/drm/amd/display/dc/core/dc_resource.c | 8 ++++++ .../drm/amd/display/dc/dcn20/dcn20_resource.c | 14 +++++++++-- .../drm/amd/display/dc/dcn21/dcn21_resource.c | 25 +++++++++++++++---- .../drm/amd/display/dc/dcn30/dcn30_resource.c | 13 +++++++++- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index f240576a87a2..75b6aee1d664 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1493,6 +1493,14 @@ bool dc_add_plane_to_context( free_pipe->clock_source = tail_pipe->clock_source; free_pipe->top_pipe = tail_pipe; tail_pipe->bottom_pipe = free_pipe; + if (!free_pipe->next_odm_pipe && tail_pipe->next_odm_pipe && tail_pipe->next_odm_pipe->bottom_pipe) { + free_pipe->next_odm_pipe = tail_pipe->next_odm_pipe->bottom_pipe; + tail_pipe->next_odm_pipe->bottom_pipe->prev_odm_pipe = free_pipe; + } + if (!free_pipe->prev_odm_pipe && tail_pipe->prev_odm_pipe && tail_pipe->prev_odm_pipe->bottom_pipe) { + free_pipe->prev_odm_pipe = tail_pipe->prev_odm_pipe->bottom_pipe; + tail_pipe->prev_odm_pipe->bottom_pipe->next_odm_pipe = free_pipe; + } } head_pipe = head_pipe->next_odm_pipe; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 01fa8de8ff86..2e613960516a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -1882,9 +1882,16 @@ bool dcn20_split_stream_for_odm( next_odm_pipe->next_odm_pipe = prev_odm_pipe->next_odm_pipe; next_odm_pipe->next_odm_pipe->prev_odm_pipe = next_odm_pipe; } + if (prev_odm_pipe->top_pipe && prev_odm_pipe->top_pipe->next_odm_pipe) { + prev_odm_pipe->top_pipe->next_odm_pipe->bottom_pipe = next_odm_pipe; + next_odm_pipe->top_pipe = prev_odm_pipe->top_pipe->next_odm_pipe; + } + if (prev_odm_pipe->bottom_pipe && prev_odm_pipe->bottom_pipe->next_odm_pipe) { + prev_odm_pipe->bottom_pipe->next_odm_pipe->top_pipe = next_odm_pipe; + next_odm_pipe->bottom_pipe = prev_odm_pipe->bottom_pipe->next_odm_pipe; + } prev_odm_pipe->next_odm_pipe = next_odm_pipe; next_odm_pipe->prev_odm_pipe = prev_odm_pipe; - ASSERT(next_odm_pipe->top_pipe == NULL); if (prev_odm_pipe->plane_state) { struct scaler_data *sd = &prev_odm_pipe->plane_res.scl_data; @@ -1922,7 +1929,10 @@ bool dcn20_split_stream_for_odm( sd->ratios.horz_c, sd->h_active - sd->recout.x)); sd->recout.x = 0; } - next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx]; + if (!next_odm_pipe->top_pipe) + next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx]; + else + next_odm_pipe->stream_res.opp = next_odm_pipe->top_pipe->stream_res.opp; if (next_odm_pipe->stream->timing.flags.DSC == 1) { dcn20_acquire_dsc(dc, res_ctx, &next_odm_pipe->stream_res.dsc, next_odm_pipe->pipe_idx); ASSERT(next_odm_pipe->stream_res.dsc); diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index c5108029f75e..8a85e07935b2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -1205,6 +1205,26 @@ static bool dcn21_fast_validate_bw( vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL); + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + struct pipe_ctx *mpo_pipe = pipe->bottom_pipe; + struct vba_vars_st *vba = &context->bw_ctx.dml.vba; + + if (!pipe->stream) + continue; + + /* We only support full screen mpo with ODM */ + if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled + && pipe->plane_state && mpo_pipe + && memcmp(&mpo_pipe->plane_res.scl_data.recout, + &pipe->plane_res.scl_data.recout, + sizeof(struct rect)) != 0) { + ASSERT(mpo_pipe->plane_state != pipe->plane_state); + goto validate_fail; + } + pipe_idx++; + } + /*initialize pipe_just_split_from to invalid idx*/ for (i = 0; i < MAX_PIPES; i++) pipe_split_from[i] = -1; @@ -1235,11 +1255,6 @@ static bool dcn21_fast_validate_bw( if (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state) continue; - /* We do not support mpo + odm at the moment */ - if (hsplit_pipe && hsplit_pipe->plane_state != pipe->plane_state - && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) - goto validate_fail; - if (split[i] == 2) { if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state) { /* pipe not split previously needs split */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 783a1d7ae7d3..060c2e65718a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -1873,11 +1873,22 @@ static bool dcn30_split_stream_for_mpc_or_odm( sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe; sec_pipe->next_odm_pipe->prev_odm_pipe = sec_pipe; } + if (pri_pipe->top_pipe && pri_pipe->top_pipe->next_odm_pipe) { + pri_pipe->top_pipe->next_odm_pipe->bottom_pipe = sec_pipe; + sec_pipe->top_pipe = pri_pipe->top_pipe->next_odm_pipe; + } + if (pri_pipe->bottom_pipe && pri_pipe->bottom_pipe->next_odm_pipe) { + pri_pipe->bottom_pipe->next_odm_pipe->top_pipe = sec_pipe; + sec_pipe->bottom_pipe = pri_pipe->bottom_pipe->next_odm_pipe; + } pri_pipe->next_odm_pipe = sec_pipe; sec_pipe->prev_odm_pipe = pri_pipe; ASSERT(sec_pipe->top_pipe == NULL); - sec_pipe->stream_res.opp = pool->opps[pipe_idx]; + if (!sec_pipe->top_pipe) + sec_pipe->stream_res.opp = pool->opps[pipe_idx]; + else + sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp; if (sec_pipe->stream->timing.flags.DSC == 1) { dcn20_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx); ASSERT(sec_pipe->stream_res.dsc); -- 2.25.1 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx