aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1653-drm-amd-display-fix-odm-pipe-management.patch
diff options
context:
space:
mode:
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.patch130
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
+