aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch327
1 files changed, 327 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch b/meta-amd-bsp/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/meta-amd-bsp/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
+