diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1653-drm-amd-display-fix-odm-pipe-management.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1653-drm-amd-display-fix-odm-pipe-management.patch | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1653-drm-amd-display-fix-odm-pipe-management.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1653-drm-amd-display-fix-odm-pipe-management.patch new file mode 100644 index 00000000..22d36929 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1653-drm-amd-display-fix-odm-pipe-management.patch @@ -0,0 +1,130 @@ +From 4aea9f9fdd5124bcb38cf4bd2e61694e40d90ac1 Mon Sep 17 00:00:00 2001 +From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Date: Fri, 8 Mar 2019 20:16:45 -0500 +Subject: [PATCH 1653/2940] drm/amd/display: fix odm pipe management + +There are issues removing surfaces/streams when odm is active. +This is a step to fix that + +Change-Id: Ibdddd2aaa55ca4b504e1d8d75247e84422f1ac9b +Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> +--- + .../gpu/drm/amd/display/dc/core/dc_resource.c | 58 ++++++++++++++++--- + drivers/gpu/drm/amd/display/dc/inc/resource.h | 2 + + 2 files changed, 53 insertions(+), 7 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 1edba6c1b275..c1b04f779044 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +@@ -1251,6 +1251,40 @@ bool dc_add_plane_to_context( + return true; + } + ++struct pipe_ctx *dc_res_get_odm_bottom_pipe(struct pipe_ctx *pipe_ctx) ++{ ++ struct pipe_ctx *bottom_pipe = pipe_ctx->bottom_pipe; ++ ++ /* ODM should only be updated once per otg */ ++ if (pipe_ctx->top_pipe) ++ return NULL; ++ ++ while (bottom_pipe) { ++ if (bottom_pipe->stream_res.opp != pipe_ctx->stream_res.opp) ++ break; ++ bottom_pipe = bottom_pipe->bottom_pipe; ++ } ++ ++ return bottom_pipe; ++} ++ ++static bool dc_res_is_odm_bottom_pipe(struct pipe_ctx *pipe_ctx) ++{ ++ struct pipe_ctx *top_pipe = pipe_ctx->top_pipe; ++ bool result = false; ++ ++ if (top_pipe && top_pipe->stream_res.opp == pipe_ctx->stream_res.opp) ++ return false; ++ ++ while (top_pipe) { ++ if (!top_pipe->top_pipe && top_pipe->stream_res.opp != pipe_ctx->stream_res.opp) ++ result = true; ++ top_pipe = top_pipe->top_pipe; ++ } ++ ++ return result; ++} ++ + bool dc_remove_plane_from_context( + const struct dc *dc, + struct dc_stream_state *stream, +@@ -1274,10 +1308,14 @@ bool dc_remove_plane_from_context( + + /* release pipe for plane*/ + for (i = pool->pipe_count - 1; i >= 0; i--) { +- struct pipe_ctx *pipe_ctx; ++ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + +- if (context->res_ctx.pipe_ctx[i].plane_state == plane_state) { +- pipe_ctx = &context->res_ctx.pipe_ctx[i]; ++ if (pipe_ctx->plane_state == plane_state) { ++ if (dc_res_is_odm_bottom_pipe(pipe_ctx)) { ++ pipe_ctx->plane_state = NULL; ++ pipe_ctx->bottom_pipe = NULL; ++ continue; ++ } + + if (pipe_ctx->top_pipe) + pipe_ctx->top_pipe->bottom_pipe = pipe_ctx->bottom_pipe; +@@ -1293,11 +1331,10 @@ bool dc_remove_plane_from_context( + * For head pipe detach surfaces from pipe for tail + * pipe just zero it out + */ +- if (!pipe_ctx->top_pipe || (!pipe_ctx->top_pipe->top_pipe && +- pipe_ctx->top_pipe->stream_res.opp != pipe_ctx->stream_res.opp)) { +- pipe_ctx->top_pipe = NULL; ++ if (!pipe_ctx->top_pipe) { + pipe_ctx->plane_state = NULL; +- pipe_ctx->bottom_pipe = NULL; ++ if (!dc_res_get_odm_bottom_pipe(pipe_ctx)) ++ pipe_ctx->bottom_pipe = NULL; + } else { + memset(pipe_ctx, 0, sizeof(*pipe_ctx)); + } +@@ -1703,6 +1740,9 @@ enum dc_status dc_remove_stream_from_ctx( + for (i = 0; i < MAX_PIPES; i++) { + if (new_ctx->res_ctx.pipe_ctx[i].stream == stream && + !new_ctx->res_ctx.pipe_ctx[i].top_pipe) { ++ struct pipe_ctx *odm_pipe = ++ dc_res_get_odm_bottom_pipe(&new_ctx->res_ctx.pipe_ctx[i]); ++ + del_pipe = &new_ctx->res_ctx.pipe_ctx[i]; + + ASSERT(del_pipe->stream_res.stream_enc); +@@ -1727,6 +1767,10 @@ enum dc_status dc_remove_stream_from_ctx( + dc->res_pool->funcs->remove_stream_from_ctx(dc, new_ctx, stream); + + memset(del_pipe, 0, sizeof(*del_pipe)); ++ if (odm_pipe) ++ memset(odm_pipe, 0, sizeof(*odm_pipe)); ++ ++ break; + } + } + +diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h +index 0086a2f1d21a..62e00a9f3184 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h +@@ -172,4 +172,6 @@ void update_audio_usage( + + unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format); + ++struct pipe_ctx *dc_res_get_odm_bottom_pipe(struct pipe_ctx *pipe_ctx); ++ + #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ +-- +2.17.1 + |