aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1694-drm-amd-display-add-preferred-pipe-split-logic.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1694-drm-amd-display-add-preferred-pipe-split-logic.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/1694-drm-amd-display-add-preferred-pipe-split-logic.patch145
1 files changed, 145 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1694-drm-amd-display-add-preferred-pipe-split-logic.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1694-drm-amd-display-add-preferred-pipe-split-logic.patch
new file mode 100644
index 00000000..81229fa5
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1694-drm-amd-display-add-preferred-pipe-split-logic.patch
@@ -0,0 +1,145 @@
+From 5891f533f7770b52d3a1c48a8b0889841cb90b70 Mon Sep 17 00:00:00 2001
+From: Jun Lei <Jun.Lei@amd.com>
+Date: Tue, 12 Mar 2019 15:12:41 -0400
+Subject: [PATCH 1694/2940] drm/amd/display: add preferred pipe split logic
+
+[why]
+existing logic finds "first free pipe from 5 -> 0" to split
+this will cause certain sequences to require DC to move
+an MPCC from one tree to another, which is unsupported
+this leads to blackscreen
+
+to mitigate this problem, we will always try to acquire the
+"preferred" pipe, and each pipe has a unique preferred pipe
+this means we avoid most of the scenarios where
+pipe splitting leads to moving MPCC from one tree
+to another
+
+Change-Id: Ia6fc5a942cd9da243b824af80d889c0b015bb69f
+Signed-off-by: Jun Lei <Jun.Lei@amd.com>
+Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
+Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+---
+ .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 2 +-
+ .../gpu/drm/amd/display/dc/core/dc_resource.c | 54 +++++++++++++++----
+ .../drm/amd/display/dc/dcn10/dcn10_resource.c | 2 +-
+ drivers/gpu/drm/amd/display/dc/inc/resource.h | 3 +-
+ 4 files changed, 49 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+index d2083e0b59a7..e572ac59b035 100644
+--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
++++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+@@ -1141,7 +1141,7 @@ bool dcn_validate_bandwidth(
+ hsplit_pipe->pipe_dlg_param.vblank_end = pipe->pipe_dlg_param.vblank_end;
+ } else {
+ /* pipe not split previously needs split */
+- hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, pool);
++ hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, pool, pipe);
+ ASSERT(hsplit_pipe);
+ split_stream_across_pipes(
+ &context->res_ctx, pool,
+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 740602111110..788b771efcf4 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+@@ -1038,24 +1038,60 @@ enum dc_status resource_build_scaling_params_for_context(
+
+ struct pipe_ctx *find_idle_secondary_pipe(
+ struct resource_context *res_ctx,
+- const struct resource_pool *pool)
++ const struct resource_pool *pool,
++ const struct pipe_ctx *primary_pipe)
+ {
+ int i;
+ struct pipe_ctx *secondary_pipe = NULL;
+
+ /*
+- * search backwards for the second pipe to keep pipe
+- * assignment more consistent
++ * We add a preferred pipe mapping to avoid the chance that
++ * MPCCs already in use will need to be reassigned to other trees.
++ * For example, if we went with the strict, assign backwards logic:
++ *
++ * (State 1)
++ * Display A on, no surface, top pipe = 0
++ * Display B on, no surface, top pipe = 1
++ *
++ * (State 2)
++ * Display A on, no surface, top pipe = 0
++ * Display B on, surface enable, top pipe = 1, bottom pipe = 5
++ *
++ * (State 3)
++ * Display A on, surface enable, top pipe = 0, bottom pipe = 5
++ * Display B on, surface enable, top pipe = 1, bottom pipe = 4
++ *
++ * The state 2->3 transition requires remapping MPCC 5 from display B
++ * to display A.
++ *
++ * However, with the preferred pipe logic, state 2 would look like:
++ *
++ * (State 2)
++ * Display A on, no surface, top pipe = 0
++ * Display B on, surface enable, top pipe = 1, bottom pipe = 4
++ *
++ * This would then cause 2->3 to not require remapping any MPCCs.
+ */
+-
+- for (i = pool->pipe_count - 1; i >= 0; i--) {
+- if (res_ctx->pipe_ctx[i].stream == NULL) {
+- secondary_pipe = &res_ctx->pipe_ctx[i];
+- secondary_pipe->pipe_idx = i;
+- break;
++ if (primary_pipe) {
++ int preferred_pipe_idx = (pool->pipe_count - 1) - primary_pipe->pipe_idx;
++ if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) {
++ secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
++ secondary_pipe->pipe_idx = preferred_pipe_idx;
+ }
+ }
+
++ /*
++ * search backwards for the second pipe to keep pipe
++ * assignment more consistent
++ */
++ if (!secondary_pipe)
++ for (i = pool->pipe_count - 1; i >= 0; i--) {
++ if (res_ctx->pipe_ctx[i].stream == NULL) {
++ secondary_pipe = &res_ctx->pipe_ctx[i];
++ secondary_pipe->pipe_idx = i;
++ break;
++ }
++ }
+
+ return secondary_pipe;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+index e879829a34b9..29f8893e44b6 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+@@ -1081,7 +1081,7 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
+ {
+ struct resource_context *res_ctx = &context->res_ctx;
+ struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream);
+- struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool);
++ struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool, head_pipe);
+
+ if (!head_pipe) {
+ ASSERT(0);
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
+index 62e00a9f3184..028c63061767 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
+@@ -131,7 +131,8 @@ bool resource_attach_surfaces_to_context(
+
+ struct pipe_ctx *find_idle_secondary_pipe(
+ struct resource_context *res_ctx,
+- const struct resource_pool *pool);
++ const struct resource_pool *pool,
++ const struct pipe_ctx *primary_pipe);
+
+ bool resource_is_stream_unchanged(
+ struct dc_state *old_context, struct dc_stream_state *stream);
+--
+2.17.1
+