diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch new file mode 100644 index 00000000..04e36856 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch @@ -0,0 +1,327 @@ +From 213ec3d169fc76eb4bc5804e43a4d3dd642a7cdf Mon Sep 17 00:00:00 2001 +From: Nikola Cornij <nikola.cornij@amd.com> +Date: Tue, 2 Apr 2019 12:40:22 -0400 +Subject: [PATCH 2507/2940] drm/amd/display: Acquire DSC HW resource only if + required by stream + +[why] +There are ASICs that have fewer DSC engines than pipes, which makes +DSC a resource that should be used only if required. + +[how] +Acquire DSC HW resource if required by stream and release when not +required anymore. + +Signed-off-by: Nikola Cornij <nikola.cornij@amd.com> +Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com> +Acked-by: Leo Li <sunpeng.li@amd.com> +Acked-by: Hawking Zhang <Hawking.Zhang@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 19 +-- + .../drm/amd/display/dc/dcn20/dcn20_resource.c | 139 ++++++++++-------- + .../drm/amd/display/dc/dcn20/dcn20_resource.h | 2 + + .../gpu/drm/amd/display/dc/inc/core_types.h | 10 ++ + 4 files changed, 97 insertions(+), 73 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 5b26c76b906b..bcf736416ee3 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1748,19 +1748,14 @@ static void commit_planes_do_stream_update(struct dc *dc, + + #if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT) + if (stream_update->dsc_config && dc->hwss.pipe_control_lock_global) { +- if (stream_update->dsc_config->num_slices_h && +- stream_update->dsc_config->num_slices_v) { +- /* dsc enable */ +- dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true); +- dp_set_dsc_enable(pipe_ctx, true); +- dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false); +- } else { +- /* dsc disable */ +- dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true); +- dp_set_dsc_enable(pipe_ctx, false); +- dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false); +- } ++ bool enable_dsc = (stream_update->dsc_config->num_slices_h && stream_update->dsc_config->num_slices_v); ++ ++ dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true); ++ dp_set_dsc_enable(pipe_ctx, enable_dsc); ++ dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false); + ++ if (!stream->is_dsc_enabled) ++ dc->res_pool->funcs->remove_dsc_from_stream_resource(dc, context, stream); + } + #endif + /* Full fe update*/ +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 d2642cc52c85..2d6f9c4de893 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +@@ -1230,94 +1230,79 @@ enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state + + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT + +-static struct display_stream_compressor *acquire_dsc(struct resource_context *res_ctx, +- const struct resource_pool *pool) ++static void acquire_dsc(struct resource_context *res_ctx, ++ const struct resource_pool *pool, ++ struct display_stream_compressor **dsc) + { + int i; +- struct display_stream_compressor *dsc = NULL; ++ ++ ASSERT(*dsc == NULL); ++ *dsc = NULL; + + /* Find first free DSC */ + for (i = 0; i < pool->res_cap->num_dsc; i++) + if (!res_ctx->is_dsc_acquired[i]) { +- dsc = pool->dscs[i]; ++ *dsc = pool->dscs[i]; + res_ctx->is_dsc_acquired[i] = true; + break; + } +- +- return dsc; + } + + static void release_dsc(struct resource_context *res_ctx, + const struct resource_pool *pool, +- const struct display_stream_compressor *dsc) ++ struct display_stream_compressor **dsc) + { + int i; + + for (i = 0; i < pool->res_cap->num_dsc; i++) +- if (pool->dscs[i] == dsc) { ++ if (pool->dscs[i] == *dsc) { + res_ctx->is_dsc_acquired[i] = false; ++ *dsc = NULL; + break; + } + } + + #endif + +-enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream) +-{ +- enum dc_status result = DC_ERROR_UNEXPECTED; +- +- result = resource_map_pool_resources(dc, new_ctx, dc_stream); +- +- if (result == DC_OK) +- result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream); + + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +- /* Get a DSC if required and available */ +- if (result == DC_OK) { +- int i; +- const struct resource_pool *pool = dc->res_pool; +- bool is_add_dsc = true; ++enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc, ++ struct dc_state *dc_ctx, ++ struct dc_stream_state *dc_stream) ++{ ++ enum dc_status result = DC_OK; ++ int i; ++ const struct resource_pool *pool = dc->res_pool; + +- for (i = 0; i < dc->res_pool->pipe_count; i++) { +- struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i]; ++ /* Get a DSC if required and available */ ++ for (i = 0; i < dc->res_pool->pipe_count; i++) { ++ struct pipe_ctx *pipe_ctx = &dc_ctx->res_ctx.pipe_ctx[i]; + +- if (pipe_ctx->stream != dc_stream) +- continue; ++ if (pipe_ctx->stream != dc_stream) ++ continue; + +- if (IS_DIAG_DC(dc->ctx->dce_environment) || +- dc->res_pool->res_cap->num_dsc == 1) { +- // Diags build can also run on platforms that have fewer DSCs than pipes. +- // In that case, add DSC only if needed by timing. +- is_add_dsc = (dc_stream->timing.flags.DSC == 1); +- } +- if (is_add_dsc) { +- pipe_ctx->stream_res.dsc = acquire_dsc(&new_ctx->res_ctx, pool); +- +- /* The number of DSCs can be less than the number of pipes */ +- if (!pipe_ctx->stream_res.dsc) { +- dm_output_to_console("No DSCs available\n"); +- result = DC_NO_DSC_RESOURCE; +- } +- } ++ acquire_dsc(&dc_ctx->res_ctx, pool, &pipe_ctx->stream_res.dsc); + +- break; ++ /* The number of DSCs can be less than the number of pipes */ ++ if (!pipe_ctx->stream_res.dsc) { ++ dm_output_to_console("No DSCs available\n"); ++ result = DC_NO_DSC_RESOURCE; + } +- } +-#endif + +- if (result == DC_OK) +- result = dcn20_build_mapped_resource(dc, new_ctx, dc_stream); ++ break; ++ } + + return result; + } + + +-enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream) ++enum dc_status dcn20_remove_dsc_from_stream_resource(struct dc *dc, ++ struct dc_state *new_ctx, ++ struct dc_stream_state *dc_stream) + { + struct pipe_ctx *pipe_ctx = NULL; + int i; + +- /* Remove DSC */ + for (i = 0; i < MAX_PIPES; i++) { + if (new_ctx->res_ctx.pipe_ctx[i].stream == dc_stream && !new_ctx->res_ctx.pipe_ctx[i].top_pipe) { + pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i]; +@@ -1328,21 +1313,51 @@ enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ + if (!pipe_ctx) + return DC_ERROR_UNEXPECTED; + +-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT + if (pipe_ctx->stream_res.dsc) { + struct pipe_ctx *odm_pipe = dc_res_get_odm_bottom_pipe(pipe_ctx); + +- release_dsc(&new_ctx->res_ctx, dc->res_pool, pipe_ctx->stream_res.dsc); +- pipe_ctx->stream_res.dsc = NULL; +- if (odm_pipe) { +- release_dsc(&new_ctx->res_ctx, dc->res_pool, odm_pipe->stream_res.dsc); +- odm_pipe->stream_res.dsc = NULL; +- } ++ release_dsc(&new_ctx->res_ctx, dc->res_pool, &pipe_ctx->stream_res.dsc); ++ if (odm_pipe) ++ release_dsc(&new_ctx->res_ctx, dc->res_pool, &odm_pipe->stream_res.dsc); + } +-#endif + + return DC_OK; + } ++#endif ++ ++ ++enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream) ++{ ++ enum dc_status result = DC_ERROR_UNEXPECTED; ++ ++ result = resource_map_pool_resources(dc, new_ctx, dc_stream); ++ ++ if (result == DC_OK) ++ result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream); ++ ++#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT ++ /* Get a DSC if required and available */ ++ if (result == DC_OK && dc_stream->timing.flags.DSC) ++ result = dcn20_add_dsc_to_stream_resource(dc, new_ctx, dc_stream); ++#endif ++ ++ if (result == DC_OK) ++ result = dcn20_build_mapped_resource(dc, new_ctx, dc_stream); ++ ++ return result; ++} ++ ++ ++enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream) ++{ ++ enum dc_status result = DC_OK; ++ ++#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT ++ result = dcn20_remove_dsc_from_stream_resource(dc, new_ctx, dc_stream); ++#endif ++ ++ return result; ++} + + + static void swizzle_to_dml_params( +@@ -1439,8 +1454,6 @@ static bool dcn20_split_stream_for_combine( + secondary_pipe->top_pipe = primary_pipe; + + if (is_odm_combine) { +- bool is_add_dsc = true; +- + if (primary_pipe->plane_state) { + /* HACTIVE halved for odm combine */ + sd->h_active /= 2; +@@ -1477,8 +1490,8 @@ static bool dcn20_split_stream_for_combine( + } + secondary_pipe->stream_res.opp = pool->opps[secondary_pipe->pipe_idx]; + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +- if (is_add_dsc) { +- secondary_pipe->stream_res.dsc = acquire_dsc(res_ctx, pool); ++ if (secondary_pipe->stream->timing.flags.DSC == 1) { ++ acquire_dsc(res_ctx, pool, &secondary_pipe->stream_res.dsc); + ASSERT(secondary_pipe->stream_res.dsc); + if (secondary_pipe->stream_res.dsc == NULL) + return false; +@@ -1952,7 +1965,7 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, + hsplit_pipe->bottom_pipe = NULL; + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT + if (hsplit_pipe->stream_res.dsc && hsplit_pipe->stream_res.dsc != pipe->stream_res.dsc) +- release_dsc(&context->res_ctx, dc->res_pool, hsplit_pipe->stream_res.dsc); ++ release_dsc(&context->res_ctx, dc->res_pool, &hsplit_pipe->stream_res.dsc); + #endif + /* Clear plane_res and stream_res */ + memset(&hsplit_pipe->plane_res, 0, sizeof(hsplit_pipe->plane_res)); +@@ -2364,7 +2377,11 @@ static struct resource_funcs dcn20_res_pool_funcs = { + .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, + .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 ++ .set_mcif_arb_params = dcn20_set_mcif_arb_params, ++#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT ++ .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, ++ .remove_dsc_from_stream_resource = dcn20_remove_dsc_from_stream_resource ++#endif + }; + + struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx) +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 b5a75289f444..018224518011 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h +@@ -121,6 +121,8 @@ enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state + enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream); + enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream); + enum dc_status dcn20_get_default_swizzle_mode(struct dc_plane_state *plane_state); ++enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc, struct dc_state *dc_ctx, struct dc_stream_state *dc_stream); ++enum dc_status dcn20_remove_dsc_from_stream_resource(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream); + + void dcn20_patch_bounding_box( + struct dc *dc, +diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h +index e94f3c180144..61c04bd39ac6 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h +@@ -142,6 +142,16 @@ struct resource_funcs { + display_e2e_pipe_params_st *pipes, + int pipe_cnt); + #endif ++ ++#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT ++enum dc_status (*add_dsc_to_stream_resource)(struct dc *dc, ++ struct dc_state *dc_ctx, ++ struct dc_stream_state *dc_stream); ++ ++enum dc_status (*remove_dsc_from_stream_resource)(struct dc *dc, ++ struct dc_state *new_ctx, ++ struct dc_stream_state *dc_stream); ++#endif + }; + + struct audio_support{ +-- +2.17.1 + |