[PATCH 09/22] drm/amd/display: fix nonseamless transition from ODM + MPO to ODM + subvp

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Wenjing Liu <wenjing.liu@xxxxxxx>

[why]
 when ODM + MPO is used for all 4 available pipes. Pipe transition will
 be nonseamless. Phantom OTG master pipe reuses the secondary OPP head
 pipe. There is no possible seamless path to transit to the new
 state. The correct logic would be to reuse a secondary DPP pipe as the
 phantom OTG master pipe. This way we are able to first transit the
 minimal transtion state of new and then transit to new state seamlessly.

 current                      New (nonseamless)
 ________________________     ________________________
 | plane0  slice0  stream0|   | plane0  slice0  stream0|
 |DPP0----OPP0----OTG0----|   |DPP0----OPP0----OTG0----|
 | plane1 |       |       |   | plane0  slice1 |       |
 |DPP2----|       |       |   |DPP2----OPP2----|       |
 | plane0  slice1 |       |   | plane0  slice0  stream1|
 |DPP1----OPP1----|       |   |DPP1----OPP1----OTG1----|
 | plane1 |               |   | plane0  slice1 |       |
 |DPP3----|               |   |DPP3----OPP3----|       |
 |________________________|   |________________________|

 New (seamless)               New (minimal transition)
 ________________________     ________________________
 | plane0  slice0  stream0|   | plane0  slice0  stream0|
 |DPP0----OPP0----OTG0----|   |DPP0----OPP0----OTG0----|
 | plane0  slice1 |       |   | plane0  slice1 |       |
 |DPP1----OPP1----|       |   |DPP1----OPP1----|       |
 | plane0  slice0  stream1|   |________________________|
 |DPP2----OPP2----OTG2----|
 | plane0  slice1 |       |
 |DPP3----OPP3----|       |
 |________________________|

[how]
Try to acquire free pipes used as secondary DPP pipes from current state
before try to acquire any free pipes for new OTG master pipe.

Reviewed-by: Alvin Lee <alvin.lee2@xxxxxxx>
Acked-by: Tom Chung <chiahsuan.chung@xxxxxxx>
Signed-off-by: Wenjing Liu <wenjing.liu@xxxxxxx>
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 44 +++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/inc/resource.h | 11 +++++
 2 files changed, 55 insertions(+)

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 ce56e47cfd0a..fa6e6184c437 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1795,6 +1795,30 @@ int recource_find_free_pipe_used_as_otg_master_in_cur_res_ctx(
 	return free_pipe_idx;
 }
 
+int resource_find_free_pipe_used_as_cur_sec_dpp(
+		const struct resource_context *cur_res_ctx,
+		struct resource_context *new_res_ctx,
+		const struct resource_pool *pool)
+{
+	int free_pipe_idx = FREE_PIPE_INDEX_NOT_FOUND;
+	const struct pipe_ctx *new_pipe, *cur_pipe;
+	int i;
+
+	for (i = 0; i < pool->pipe_count; i++) {
+		cur_pipe = &cur_res_ctx->pipe_ctx[i];
+		new_pipe = &new_res_ctx->pipe_ctx[i];
+
+		if (resource_is_pipe_type(cur_pipe, DPP_PIPE) &&
+				!resource_is_pipe_type(cur_pipe, OPP_HEAD) &&
+				resource_is_pipe_type(new_pipe, FREE_PIPE)) {
+			free_pipe_idx = i;
+			break;
+		}
+	}
+
+	return free_pipe_idx;
+}
+
 int resource_find_free_pipe_used_as_cur_sec_dpp_in_mpcc_combine(
 		const struct resource_context *cur_res_ctx,
 		struct resource_context *new_res_ctx,
@@ -3372,11 +3396,31 @@ static bool acquire_otg_master_pipe_for_stream(
 	 * any free pipes already used in current context as this could tear
 	 * down exiting ODM/MPC/MPO configuration unnecessarily.
 	 */
+
+	/*
+	 * Try to acquire the same OTG master already in use. This is not
+	 * optimal because resetting an enabled OTG master pipe for a new stream
+	 * requires an extra frame of wait. However there are test automation
+	 * and eDP assumptions that rely on reusing the same OTG master pipe
+	 * during mode change. We have to keep this logic as is for now.
+	 */
 	pipe_idx = recource_find_free_pipe_used_as_otg_master_in_cur_res_ctx(
 			&cur_ctx->res_ctx, &new_ctx->res_ctx, pool);
+	/*
+	 * Try to acquire a pipe not used in current resource context to avoid
+	 * pipe swapping.
+	 */
 	if (pipe_idx == FREE_PIPE_INDEX_NOT_FOUND)
 		pipe_idx = recource_find_free_pipe_not_used_in_cur_res_ctx(
 				&cur_ctx->res_ctx, &new_ctx->res_ctx, pool);
+	/*
+	 * If pipe swapping is unavoidable, try to acquire pipe used as
+	 * secondary DPP pipe in current state as we prioritize to support more
+	 * streams over supporting MPO planes.
+	 */
+	if (pipe_idx == FREE_PIPE_INDEX_NOT_FOUND)
+		pipe_idx = resource_find_free_pipe_used_as_cur_sec_dpp(
+				&cur_ctx->res_ctx, &new_ctx->res_ctx, pool);
 	if (pipe_idx == FREE_PIPE_INDEX_NOT_FOUND)
 		pipe_idx = resource_find_any_free_pipe(&new_ctx->res_ctx, pool);
 	if (pipe_idx != FREE_PIPE_INDEX_NOT_FOUND) {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index d17fa73d72a3..7cb0ed612716 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -508,6 +508,17 @@ int recource_find_free_pipe_used_as_otg_master_in_cur_res_ctx(
 		struct resource_context *new_res_ctx,
 		const struct resource_pool *pool);
 
+/*
+ * Look for a free pipe in new resource context that is used as a secondary DPP
+ * pipe in current resource context.
+ * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise
+ * pipe idx of the free pipe
+ */
+int resource_find_free_pipe_used_as_cur_sec_dpp(
+		const struct resource_context *cur_res_ctx,
+		struct resource_context *new_res_ctx,
+		const struct resource_pool *pool);
+
 /*
  * Look for a free pipe in new resource context that is used as a secondary DPP
  * pipe in any MPCC combine in current resource context.
-- 
2.34.1




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux