diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4238-drm-amd-display-split-dcn20-fast-validate-into-more-.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4238-drm-amd-display-split-dcn20-fast-validate-into-more-.patch | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4238-drm-amd-display-split-dcn20-fast-validate-into-more-.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4238-drm-amd-display-split-dcn20-fast-validate-into-more-.patch new file mode 100644 index 00000000..32ace21b --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4238-drm-amd-display-split-dcn20-fast-validate-into-more-.patch @@ -0,0 +1,373 @@ +From 5552d85b5ad24d5fa12a61d5d8e500f880a2e36d Mon Sep 17 00:00:00 2001 +From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Date: Mon, 23 Sep 2019 12:56:20 -0400 +Subject: [PATCH 4238/4736] drm/amd/display: split dcn20 fast validate into + more functions + +Split a large function into smaller, reusable chunks. + +Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Reviewed-by: Nevenko Stupar <Nevenko.Stupar@amd.com> +Acked-by: Leo Li <sunpeng.li@amd.com> +--- + .../drm/amd/display/dc/dcn20/dcn20_resource.c | 182 ++++++++++-------- + .../drm/amd/display/dc/dcn20/dcn20_resource.h | 31 +++ + .../drm/amd/display/dc/dcn21/dcn21_resource.c | 1 + + 3 files changed, 136 insertions(+), 78 deletions(-) + +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 c60f8e538cef..2ea4879b834f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +@@ -1641,7 +1641,7 @@ static void swizzle_to_dml_params( + } + } + +-static bool dcn20_split_stream_for_odm( ++bool dcn20_split_stream_for_odm( + struct resource_context *res_ctx, + const struct resource_pool *pool, + struct pipe_ctx *prev_odm_pipe, +@@ -1719,7 +1719,7 @@ static bool dcn20_split_stream_for_odm( + return true; + } + +-static void dcn20_split_stream_for_mpc( ++void dcn20_split_stream_for_mpc( + struct resource_context *res_ctx, + const struct resource_pool *pool, + struct pipe_ctx *primary_pipe, +@@ -2177,7 +2177,7 @@ void dcn20_set_mcif_arb_params( + } + + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +-static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx) ++bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx) + { + int i; + +@@ -2212,7 +2212,7 @@ static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx) + } + #endif + +-static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, ++struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, + struct resource_context *res_ctx, + const struct resource_pool *pool, + const struct pipe_ctx *primary_pipe) +@@ -2289,24 +2289,11 @@ static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, + return secondary_pipe; + } + +-bool dcn20_fast_validate_bw( ++void dcn20_merge_pipes_for_validate( + struct dc *dc, +- struct dc_state *context, +- display_e2e_pipe_params_st *pipes, +- int *pipe_cnt_out, +- int *pipe_split_from, +- int *vlevel_out) ++ struct dc_state *context) + { +- bool out = false; +- +- int pipe_cnt, i, pipe_idx, vlevel, vlevel_unsplit; +- bool force_split = false; +- int split_threshold = dc->res_pool->pipe_count / 2; +- bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC; +- +- ASSERT(pipes); +- if (!pipes) +- return false; ++ int i; + + /* merge previously split odm pipes since mode support needs to make the decision */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { +@@ -2361,31 +2348,18 @@ bool dcn20_fast_validate_bw( + if (pipe->plane_state) + resource_build_scaling_params(pipe); + } ++} + +- if (dc->res_pool->funcs->populate_dml_pipes) +- pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, +- &context->res_ctx, pipes); +- else +- pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, +- &context->res_ctx, pipes); +- +- *pipe_cnt_out = pipe_cnt; +- +- if (!pipe_cnt) { +- out = true; +- goto validate_out; +- } +- +- vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); +- +- if (vlevel > context->bw_ctx.dml.soc.num_states) +- goto validate_fail; +- +- /*initialize pipe_just_split_from to invalid idx*/ +- for (i = 0; i < MAX_PIPES; i++) +- pipe_split_from[i] = -1; ++int dcn20_validate_apply_pipe_split_flags( ++ struct dc *dc, ++ struct dc_state *context, ++ int vlevel, ++ bool *split) ++{ ++ int i, pipe_idx, vlevel_unsplit; ++ bool force_split = false; ++ bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC; + +- /* Single display only conditionals get set here */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + bool exit_loop = false; +@@ -2412,38 +2386,105 @@ bool dcn20_fast_validate_bw( + if (exit_loop) + break; + } +- +- if (context->stream_count > split_threshold) ++ /* TODO: fix dc bugs and remove this split threshold thing */ ++ if (context->stream_count > dc->res_pool->pipe_count / 2) + avoid_split = true; + +- vlevel_unsplit = vlevel; ++ if (avoid_split) { ++ for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { ++ if (!context->res_ctx.pipe_ctx[i].stream) ++ continue; ++ ++ for (vlevel_unsplit = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++) ++ if (context->bw_ctx.dml.vba.NoOfDPP[vlevel][0][pipe_idx] == 1) ++ break; ++ /* Impossible to not split this pipe */ ++ if (vlevel == context->bw_ctx.dml.soc.num_states) ++ vlevel = vlevel_unsplit; ++ pipe_idx++; ++ } ++ context->bw_ctx.dml.vba.maxMpcComb = 0; ++ } ++ + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { ++ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; ++ + if (!context->res_ctx.pipe_ctx[i].stream) + continue; +- for (; vlevel_unsplit <= context->bw_ctx.dml.soc.num_states; vlevel_unsplit++) +- if (context->bw_ctx.dml.vba.NoOfDPP[vlevel_unsplit][0][pipe_idx] == 1) +- break; ++ ++ if (force_split || context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] > 1) ++ split[i] = true; ++ if ((pipe->stream->view_format == ++ VIEW_3D_FORMAT_SIDE_BY_SIDE || ++ pipe->stream->view_format == ++ VIEW_3D_FORMAT_TOP_AND_BOTTOM) && ++ (pipe->stream->timing.timing_3d_format == ++ TIMING_3D_FORMAT_TOP_AND_BOTTOM || ++ pipe->stream->timing.timing_3d_format == ++ TIMING_3D_FORMAT_SIDE_BY_SIDE)) ++ split[i] = true; ++ if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) { ++ split[i] = true; ++ context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = true; ++ } ++ context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] ++ = context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx]; ++ /* Adjust dppclk when split is forced, do not bother with dispclk */ ++ if (split[i] && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1) ++ context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2; + pipe_idx++; + } + ++ return vlevel; ++} ++ ++bool dcn20_fast_validate_bw( ++ struct dc *dc, ++ struct dc_state *context, ++ display_e2e_pipe_params_st *pipes, ++ int *pipe_cnt_out, ++ int *pipe_split_from, ++ int *vlevel_out) ++{ ++ bool out = false; ++ bool split[MAX_PIPES] = { false }; ++ int pipe_cnt, i, pipe_idx, vlevel; ++ ++ ASSERT(pipes); ++ if (!pipes) ++ return false; ++ ++ dcn20_merge_pipes_for_validate(dc, context); ++ ++ pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, &context->res_ctx, pipes); ++ ++ *pipe_cnt_out = pipe_cnt; ++ ++ if (!pipe_cnt) { ++ out = true; ++ goto validate_out; ++ } ++ ++ vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); ++ ++ if (vlevel > context->bw_ctx.dml.soc.num_states) ++ goto validate_fail; ++ ++ vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split); ++ ++ /*initialize pipe_just_split_from to invalid idx*/ ++ for (i = 0; i < MAX_PIPES; i++) ++ pipe_split_from[i] = -1; ++ + for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe; +- bool need_split = true; +- bool need_split3d; + + if (!pipe->stream || pipe_split_from[i] >= 0) + continue; + + pipe_idx++; + +- if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) { +- force_split = true; +- context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] = true; +- context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = true; +- } +- if (force_split && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1) +- context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2; + if (!pipe->top_pipe && !pipe->plane_state && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) { + hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe); + ASSERT(hsplit_pipe); +@@ -2461,32 +2502,16 @@ bool dcn20_fast_validate_bw( + if (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state) + continue; + +- need_split3d = ((pipe->stream->view_format == +- VIEW_3D_FORMAT_SIDE_BY_SIDE || +- pipe->stream->view_format == +- VIEW_3D_FORMAT_TOP_AND_BOTTOM) && +- (pipe->stream->timing.timing_3d_format == +- TIMING_3D_FORMAT_TOP_AND_BOTTOM || +- pipe->stream->timing.timing_3d_format == +- TIMING_3D_FORMAT_SIDE_BY_SIDE)); +- +- if (avoid_split && vlevel_unsplit <= context->bw_ctx.dml.soc.num_states && !force_split && !need_split3d) { +- need_split = false; +- vlevel = vlevel_unsplit; +- context->bw_ctx.dml.vba.maxMpcComb = 0; +- } else +- need_split = context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 2; +- + /* 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 (need_split3d || need_split || force_split) { ++ if (split[i]) { + if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state) { + /* pipe not split previously needs split */ + hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe); +- ASSERT(hsplit_pipe || force_split); ++ ASSERT(hsplit_pipe); + if (!hsplit_pipe) + continue; + +@@ -2549,7 +2574,7 @@ void dcn20_calculate_wm( + context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx]; + if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx) + pipes[pipe_cnt].pipe.dest.odm_combine = +- context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx]; ++ context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]; + else + pipes[pipe_cnt].pipe.dest.odm_combine = 0; + pipe_idx++; +@@ -2558,7 +2583,7 @@ void dcn20_calculate_wm( + context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]]; + if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i]) + pipes[pipe_cnt].pipe.dest.odm_combine = +- context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_split_from[i]]; ++ context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]]; + else + pipes[pipe_cnt].pipe.dest.odm_combine = 0; + } +@@ -2929,6 +2954,7 @@ static struct resource_funcs dcn20_res_pool_funcs = { + .populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context, + .get_default_swizzle_mode = dcn20_get_default_swizzle_mode, + .set_mcif_arb_params = dcn20_set_mcif_arb_params, ++ .populate_dml_pipes = dcn20_populate_dml_pipes_from_context, + .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link + }; + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h +index 55006462f481..fe68669a1f0c 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h +@@ -113,6 +113,31 @@ void dcn20_set_mcif_arb_params( + display_e2e_pipe_params_st *pipes, + int pipe_cnt); + bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate); ++void dcn20_merge_pipes_for_validate( ++ struct dc *dc, ++ struct dc_state *context); ++int dcn20_validate_apply_pipe_split_flags( ++ struct dc *dc, ++ struct dc_state *context, ++ int vlevel, ++ bool *split); ++#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT ++bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx); ++#endif ++void dcn20_split_stream_for_mpc( ++ struct resource_context *res_ctx, ++ const struct resource_pool *pool, ++ struct pipe_ctx *primary_pipe, ++ struct pipe_ctx *secondary_pipe); ++bool dcn20_split_stream_for_odm( ++ struct resource_context *res_ctx, ++ const struct resource_pool *pool, ++ struct pipe_ctx *prev_odm_pipe, ++ struct pipe_ctx *next_odm_pipe); ++struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, ++ struct resource_context *res_ctx, ++ const struct resource_pool *pool, ++ const struct pipe_ctx *primary_pipe); + bool dcn20_fast_validate_bw( + struct dc *dc, + struct dc_state *context, +@@ -125,6 +150,12 @@ void dcn20_calculate_dlg_params( + display_e2e_pipe_params_st *pipes, + int pipe_cnt, + int vlevel); ++void dcn20_calculate_wm( ++ struct dc *dc, struct dc_state *context, ++ display_e2e_pipe_params_st *pipes, ++ int *out_pipe_cnt, ++ int *pipe_split_from, ++ int vlevel); + + enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream); + enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream); +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 2125a3e50b0b..7a87a79326ca 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -1639,6 +1639,7 @@ static struct resource_funcs dcn21_res_pool_funcs = { + .destroy = dcn21_destroy_resource_pool, + .link_enc_create = dcn21_link_encoder_create, + .validate_bandwidth = dcn21_validate_bandwidth, ++ .populate_dml_pipes = dcn20_populate_dml_pipes_from_context, + .add_stream_to_ctx = dcn20_add_stream_to_ctx, + .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, + .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, +-- +2.17.1 + |