All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/amd/display: add pipe reassignment prevention code to dcn3
@ 2020-09-29 20:43 Bhawanpreet Lakha
  2020-09-29 21:11 ` Alex Deucher
  0 siblings, 1 reply; 2+ messages in thread
From: Bhawanpreet Lakha @ 2020-09-29 20:43 UTC (permalink / raw)
  To: alexander.deucher
  Cc: Bhawanpreet Lakha, Dmytro Laktyushkin, rodrigo.siqueira,
	nicholas.kazlauskas, amd-gfx

From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>

Add code to gracefuly handle any pipe reassignment
occuring on dcn3 hardware. This should only happen when new
surfaces are used for an update rather than old ones updated.

Fixes: f64d8ebe9ed2 ("amd/drm/display: avoid dcn3 on flip opp change for slave pipes")

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
---
 .../drm/amd/display/dc/dcn30/dcn30_resource.c | 61 +++++++++++++++----
 1 file changed, 49 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index c223f8af2084..24fb39a11e5d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -1901,21 +1901,28 @@ static bool dcn30_split_stream_for_mpc_or_odm(
 
 static struct pipe_ctx *dcn30_find_split_pipe(
 		struct dc *dc,
-		struct dc_state *context)
+		struct dc_state *context,
+		int old_index)
 {
 	struct pipe_ctx *pipe = NULL;
 	int i;
 
-	for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
-		if (dc->current_state->res_ctx.pipe_ctx[i].top_pipe == NULL
-				&& dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe == NULL) {
-			if (context->res_ctx.pipe_ctx[i].stream == NULL) {
-				pipe = &context->res_ctx.pipe_ctx[i];
-				pipe->pipe_idx = i;
-				break;
+	if (old_index >= 0 && context->res_ctx.pipe_ctx[old_index].stream == NULL) {
+		pipe = &context->res_ctx.pipe_ctx[old_index];
+		pipe->pipe_idx = old_index;
+	}
+
+	if (!pipe)
+		for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+			if (dc->current_state->res_ctx.pipe_ctx[i].top_pipe == NULL
+					&& dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe == NULL) {
+				if (context->res_ctx.pipe_ctx[i].stream == NULL) {
+					pipe = &context->res_ctx.pipe_ctx[i];
+					pipe->pipe_idx = i;
+					break;
+				}
 			}
 		}
-	}
 
 	/*
 	 * May need to fix pipes getting tossed from 1 opp to another on flip
@@ -2082,8 +2089,10 @@ static bool dcn30_internal_validate_bw(
 
 	for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+		struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 		struct pipe_ctx *hsplit_pipe = NULL;
 		bool odm;
+		int old_index = -1;
 
 		if (!pipe->stream || newly_split[i])
 			continue;
@@ -2095,7 +2104,20 @@ static bool dcn30_internal_validate_bw(
 			continue;
 
 		if (split[i]) {
-			hsplit_pipe = dcn30_find_split_pipe(dc, context);
+			if (odm) {
+				if (split[i] == 4 && old_pipe->next_odm_pipe->next_odm_pipe)
+					old_index = old_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
+				else if (old_pipe->next_odm_pipe)
+					old_index = old_pipe->next_odm_pipe->pipe_idx;
+			} else {
+				if (split[i] == 4 && old_pipe->bottom_pipe->bottom_pipe &&
+						old_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
+					old_index = old_pipe->bottom_pipe->bottom_pipe->pipe_idx;
+				else if (old_pipe->bottom_pipe &&
+						old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
+					old_index = old_pipe->bottom_pipe->pipe_idx;
+			}
+			hsplit_pipe = dcn30_find_split_pipe(dc, context, old_index);
 			ASSERT(hsplit_pipe);
 			if (!hsplit_pipe)
 				goto validate_fail;
@@ -2109,8 +2131,16 @@ static bool dcn30_internal_validate_bw(
 			repopulate_pipes = true;
 		}
 		if (split[i] == 4) {
-			struct pipe_ctx *pipe_4to1 = dcn30_find_split_pipe(dc, context);
+			struct pipe_ctx *pipe_4to1;
 
+			if (odm && old_pipe->next_odm_pipe)
+				old_index = old_pipe->next_odm_pipe->pipe_idx;
+			else if (!odm && old_pipe->bottom_pipe &&
+						old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
+				old_index = old_pipe->bottom_pipe->pipe_idx;
+			else
+				old_index = -1;
+			pipe_4to1 = dcn30_find_split_pipe(dc, context, old_index);
 			ASSERT(pipe_4to1);
 			if (!pipe_4to1)
 				goto validate_fail;
@@ -2120,7 +2150,14 @@ static bool dcn30_internal_validate_bw(
 				goto validate_fail;
 			newly_split[pipe_4to1->pipe_idx] = true;
 
-			pipe_4to1 = dcn30_find_split_pipe(dc, context);
+			if (odm && old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe)
+				old_index = old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
+			else if (!odm && old_pipe->bottom_pipe->bottom_pipe->bottom_pipe &&
+						old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
+				old_index = old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->pipe_idx;
+			else
+				old_index = -1;
+			pipe_4to1 = dcn30_find_split_pipe(dc, context, old_index);
 			ASSERT(pipe_4to1);
 			if (!pipe_4to1)
 				goto validate_fail;
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] drm/amd/display: add pipe reassignment prevention code to dcn3
  2020-09-29 20:43 [PATCH] drm/amd/display: add pipe reassignment prevention code to dcn3 Bhawanpreet Lakha
@ 2020-09-29 21:11 ` Alex Deucher
  0 siblings, 0 replies; 2+ messages in thread
From: Alex Deucher @ 2020-09-29 21:11 UTC (permalink / raw)
  To: Bhawanpreet Lakha
  Cc: Deucher, Alexander, Dmytro Laktyushkin, Siqueira, Rodrigo,
	Kazlauskas, Nicholas, amd-gfx list

On Tue, Sep 29, 2020 at 4:43 PM Bhawanpreet Lakha
<Bhawanpreet.Lakha@amd.com> wrote:
>
> From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
>
> Add code to gracefuly handle any pipe reassignment
> occuring on dcn3 hardware. This should only happen when new
> surfaces are used for an update rather than old ones updated.
>
> Fixes: f64d8ebe9ed2 ("amd/drm/display: avoid dcn3 on flip opp change for slave pipes")
>
> Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
> Reviewed-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>

Acked-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  .../drm/amd/display/dc/dcn30/dcn30_resource.c | 61 +++++++++++++++----
>  1 file changed, 49 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
> index c223f8af2084..24fb39a11e5d 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
> @@ -1901,21 +1901,28 @@ static bool dcn30_split_stream_for_mpc_or_odm(
>
>  static struct pipe_ctx *dcn30_find_split_pipe(
>                 struct dc *dc,
> -               struct dc_state *context)
> +               struct dc_state *context,
> +               int old_index)
>  {
>         struct pipe_ctx *pipe = NULL;
>         int i;
>
> -       for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
> -               if (dc->current_state->res_ctx.pipe_ctx[i].top_pipe == NULL
> -                               && dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe == NULL) {
> -                       if (context->res_ctx.pipe_ctx[i].stream == NULL) {
> -                               pipe = &context->res_ctx.pipe_ctx[i];
> -                               pipe->pipe_idx = i;
> -                               break;
> +       if (old_index >= 0 && context->res_ctx.pipe_ctx[old_index].stream == NULL) {
> +               pipe = &context->res_ctx.pipe_ctx[old_index];
> +               pipe->pipe_idx = old_index;
> +       }
> +
> +       if (!pipe)
> +               for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
> +                       if (dc->current_state->res_ctx.pipe_ctx[i].top_pipe == NULL
> +                                       && dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe == NULL) {
> +                               if (context->res_ctx.pipe_ctx[i].stream == NULL) {
> +                                       pipe = &context->res_ctx.pipe_ctx[i];
> +                                       pipe->pipe_idx = i;
> +                                       break;
> +                               }
>                         }
>                 }
> -       }
>
>         /*
>          * May need to fix pipes getting tossed from 1 opp to another on flip
> @@ -2082,8 +2089,10 @@ static bool dcn30_internal_validate_bw(
>
>         for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
>                 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
> +               struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
>                 struct pipe_ctx *hsplit_pipe = NULL;
>                 bool odm;
> +               int old_index = -1;
>
>                 if (!pipe->stream || newly_split[i])
>                         continue;
> @@ -2095,7 +2104,20 @@ static bool dcn30_internal_validate_bw(
>                         continue;
>
>                 if (split[i]) {
> -                       hsplit_pipe = dcn30_find_split_pipe(dc, context);
> +                       if (odm) {
> +                               if (split[i] == 4 && old_pipe->next_odm_pipe->next_odm_pipe)
> +                                       old_index = old_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
> +                               else if (old_pipe->next_odm_pipe)
> +                                       old_index = old_pipe->next_odm_pipe->pipe_idx;
> +                       } else {
> +                               if (split[i] == 4 && old_pipe->bottom_pipe->bottom_pipe &&
> +                                               old_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
> +                                       old_index = old_pipe->bottom_pipe->bottom_pipe->pipe_idx;
> +                               else if (old_pipe->bottom_pipe &&
> +                                               old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
> +                                       old_index = old_pipe->bottom_pipe->pipe_idx;
> +                       }
> +                       hsplit_pipe = dcn30_find_split_pipe(dc, context, old_index);
>                         ASSERT(hsplit_pipe);
>                         if (!hsplit_pipe)
>                                 goto validate_fail;
> @@ -2109,8 +2131,16 @@ static bool dcn30_internal_validate_bw(
>                         repopulate_pipes = true;
>                 }
>                 if (split[i] == 4) {
> -                       struct pipe_ctx *pipe_4to1 = dcn30_find_split_pipe(dc, context);
> +                       struct pipe_ctx *pipe_4to1;
>
> +                       if (odm && old_pipe->next_odm_pipe)
> +                               old_index = old_pipe->next_odm_pipe->pipe_idx;
> +                       else if (!odm && old_pipe->bottom_pipe &&
> +                                               old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
> +                               old_index = old_pipe->bottom_pipe->pipe_idx;
> +                       else
> +                               old_index = -1;
> +                       pipe_4to1 = dcn30_find_split_pipe(dc, context, old_index);
>                         ASSERT(pipe_4to1);
>                         if (!pipe_4to1)
>                                 goto validate_fail;
> @@ -2120,7 +2150,14 @@ static bool dcn30_internal_validate_bw(
>                                 goto validate_fail;
>                         newly_split[pipe_4to1->pipe_idx] = true;
>
> -                       pipe_4to1 = dcn30_find_split_pipe(dc, context);
> +                       if (odm && old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe)
> +                               old_index = old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
> +                       else if (!odm && old_pipe->bottom_pipe->bottom_pipe->bottom_pipe &&
> +                                               old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
> +                               old_index = old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->pipe_idx;
> +                       else
> +                               old_index = -1;
> +                       pipe_4to1 = dcn30_find_split_pipe(dc, context, old_index);
>                         ASSERT(pipe_4to1);
>                         if (!pipe_4to1)
>                                 goto validate_fail;
> --
> 2.25.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-09-29 21:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-29 20:43 [PATCH] drm/amd/display: add pipe reassignment prevention code to dcn3 Bhawanpreet Lakha
2020-09-29 21:11 ` Alex Deucher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.