diff options
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 27 |
2 files changed, 63 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index dcedda85dcdb..0320bc49458c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -3881,6 +3881,7 @@ static void commit_planes_for_stream(struct dc *dc, */ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc, struct dc_stream_state *stream, + struct dc_surface_update *srf_updates, int surface_count, bool *is_plane_addition) { @@ -3918,6 +3919,40 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc, *is_plane_addition = true; } } + if (dc->config.enable_windowed_mpo_odm) { + const struct rect *guaranteed_viewport = &stream->src; + const struct rect *surface_src, *surface_dst; + bool are_cur_planes_guaranteed = true; + bool are_new_planes_guaranteed = true; + + for (i = 0; i < cur_stream_status->plane_count; i++) { + surface_src = &cur_stream_status->plane_states[i]->src_rect; + surface_dst = &cur_stream_status->plane_states[i]->dst_rect; + if ((surface_src->height > surface_dst->height && surface_src->height > guaranteed_viewport->height) || + (surface_src->width > surface_dst->width && surface_src->width > guaranteed_viewport->width)) + are_cur_planes_guaranteed = false; + } + + for (i = 0; i < surface_count; i++) { + if (srf_updates[i].scaling_info) { + surface_src = &srf_updates[i].scaling_info->src_rect; + surface_dst = &srf_updates[i].scaling_info->dst_rect; + } else { + surface_src = &srf_updates[i].surface->src_rect; + surface_dst = &srf_updates[i].surface->dst_rect; + } + if ((surface_src->height > surface_dst->height && surface_src->height > guaranteed_viewport->height) || + (surface_src->width > surface_dst->width && surface_src->width > guaranteed_viewport->width)) + are_new_planes_guaranteed = false; + } + + if (are_cur_planes_guaranteed && !are_new_planes_guaranteed) { + force_minimal_pipe_splitting = true; + *is_plane_addition = true; + } else if (!are_cur_planes_guaranteed && are_new_planes_guaranteed) { + force_minimal_pipe_splitting = true; + } + } } for (i = 0; i < dc->res_pool->pipe_count; i++) { @@ -4270,6 +4305,7 @@ bool dc_update_planes_and_stream(struct dc *dc, force_minimal_pipe_splitting = could_mpcc_tree_change_for_active_pipes( dc, stream, + srf_updates, surface_count, &is_plane_addition); diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index 883e90be2257..2358c9100cff 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -1267,6 +1267,8 @@ static bool should_allow_odm_power_optimization(struct dc *dc, { struct dc_stream_state *stream = context->streams[0]; struct pipe_slice_table slice_table; + struct dc_plane_state *plane; + struct rect guaranteed_viewport; int i; /* @@ -1331,6 +1333,31 @@ static bool should_allow_odm_power_optimization(struct dc *dc, for (i = 0; i < slice_table.odm_combine_count; i++) if (slice_table.odm_combines[i].slice_count > 1) return false; + + /* up to here we know that a plane with viewport equal to stream + * src can be validated with single DPP pipe. Therefore any + * planes with smaller or equal viewport is guaranteed to work + * regardless of its position and scaling ratio. Also we know + * any plane without downscale ratio greater than 1 should also + * work. Up until DCN3x we still have software limitation that + * doesn't implement a smooth transition between ODM combine and + * MPC combine during plane resizing when we are crossing ODM + * capability boundary. So we are adding this guaranteed + * viewport condition to limit ODM power optimization support + * for only the planes within the guaranteed viewport size. Such + * planes can be supported with ODM power optimization without + * ever the need to transition to MPC combine in any scaling + * ratios and positions. Therefore we cover the software + * limitation of this transition sequence. + */ + guaranteed_viewport = stream->src; + for (i = 0; i < context->stream_status[0].plane_count; i++) { + plane = context->stream_status[0].plane_states[i]; + + if ((plane->src_rect.height > plane->dst_rect.height && plane->src_rect.height > guaranteed_viewport.height) || + (plane->src_rect.width > plane->dst_rect.width && plane->src_rect.width > guaranteed_viewport.width)) + return false; + } } else { /* * the new ODM power optimization feature reduces software |