Commit 9e7d03e8 authored by Alvin Lee's avatar Alvin Lee Committed by Alex Deucher
Browse files

drm/amd/display: Use min transition for SubVP into MPO



[Description]
- For SubVP transitioning into MPO, we want to
  use a minimal transition to prevent transient
  underflow
- Transitioning a phantom pipe directly into a
  "real" pipe can result in underflow due to the
  HUBP still having it's "phantom" programming
  when HUBP is unblanked (have to wait for next
  VUPDATE of the new OTG)
- Also ensure subvp pipe lock is acquired early
  enough for programming in dc_commit_state_no_check
- When disabling phantom planes, enable phantom OTG
  first so the disable gets the double buffer update

Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarAlan Liu <HaoPing.Liu@amd.com>
Signed-off-by: default avatarAlvin Lee <Alvin.Lee2@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a1b6667e
Loading
Loading
Loading
Loading
+20 −23
Original line number Diff line number Diff line
@@ -1054,6 +1054,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
	int i, j;
	struct dc_state *dangling_context = dc_create_state(dc);
	struct dc_state *current_ctx;
	struct pipe_ctx *pipe;

	if (dangling_context == NULL)
		return;
@@ -1096,6 +1097,16 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
		}

		if (should_disable && old_stream) {
			pipe = &dc->current_state->res_ctx.pipe_ctx[i];
			/* When disabling plane for a phantom pipe, we must turn on the
			 * phantom OTG so the disable programming gets the double buffer
			 * update. Otherwise the pipe will be left in a partially disabled
			 * state that can result in underflow or hang when enabling it
			 * again for different use.
			 */
			if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) {
				pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
			}
			dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
			disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);

@@ -1749,6 +1760,12 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
		context->stream_count == 0)
		dc->hwss.prepare_bandwidth(dc, context);

	/* When SubVP is active, all HW programming must be done while
	 * SubVP lock is acquired
	 */
	if (dc->hwss.subvp_pipe_control_lock)
		dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use);

	if (dc->debug.enable_double_buffered_dsc_pg_support)
		dc->hwss.update_dsc_pg(dc, context, false);

@@ -1776,9 +1793,6 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
		dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
	}

	if (dc->hwss.subvp_pipe_control_lock)
		dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use);

	result = dc->hwss.apply_ctx_to_hw(dc, context);

	if (result != DC_OK) {
@@ -3675,7 +3689,6 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,

	struct dc_stream_status *cur_stream_status = stream_get_status(dc->current_state, stream);
	bool force_minimal_pipe_splitting = false;
	uint32_t i;

	*is_plane_addition = false;

@@ -3707,27 +3720,11 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
		}
	}

	/* For SubVP pipe split case when adding MPO video
	 * we need to add a minimal transition. In this case
	 * there will be 2 streams (1 main stream, 1 phantom
	 * stream).
	/* For SubVP when adding MPO video we need to add a minimal transition.
	 */
	if (cur_stream_status &&
			dc->current_state->stream_count == 2 &&
			stream->mall_stream_config.type == SUBVP_MAIN) {
		bool is_pipe_split = false;

		for (i = 0; i < dc->res_pool->pipe_count; i++) {
			if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream &&
					(dc->current_state->res_ctx.pipe_ctx[i].bottom_pipe ||
					dc->current_state->res_ctx.pipe_ctx[i].next_odm_pipe)) {
				is_pipe_split = true;
				break;
			}
		}

	if (cur_stream_status && stream->mall_stream_config.type == SUBVP_MAIN) {
		/* determine if minimal transition is required due to SubVP*/
		if (surface_count > 0 && is_pipe_split) {
		if (surface_count > 0) {
			if (cur_stream_status->plane_count > surface_count) {
				force_minimal_pipe_splitting = true;
			} else if (cur_stream_status->plane_count < surface_count) {