Commit 5ad5b0b7 authored by Dominik Kaszewski's avatar Dominik Kaszewski Committed by Alex Deucher
Browse files

drm/amd/display: Fix and reenable UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL



[Why]
Reenable new split implementation, previously partially reverted due
to issues with ODM on high-bandwidth displays 4k144Hz, resulting
in a corrupted gray screen.

Minimal flows require two separate commits, with extra intermediate
commit to enable seamless transitions, each followed by a swap. Since
new design requires commit to be run in execute and swap in cleanup
stage, an attempt was made to reorder them from CSCS (Commit-Swap-Commit-Swap)
to CCSS (Commit-Commit-Swap-Swap). Not only is this not viable, but
was implemented incorrectly as CCS, one swap missing.

[How]
* Change UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_NEW/CURRENT to execute
and cleanup one commit, then run UPDATE_V3_FLOW_NEW_CONTEXT_SEAMLESS,
which closely matches old implementation where minimal flows fall back
to seamless.
* Fix uninitialized variable error.

Reviewed-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: default avatarDominik Kaszewski <dominik.kaszewski@amd.com>
Signed-off-by: default avatarChenyu Chen <chen-yu.chen@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent fd3fece0
Loading
Loading
Loading
Loading
+39 −41
Original line number Diff line number Diff line
@@ -784,7 +784,7 @@ bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream, uint8_t id
		       uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
{
	int i;
	struct pipe_ctx *pipe;
	struct pipe_ctx *pipe = NULL;
	struct timing_generator *tg;

	dc_exit_ips_for_hw_access(dc);
@@ -5437,35 +5437,23 @@ bool dc_update_planes_and_stream(struct dc *dc,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update)
{
	bool ret = false;
	struct dc_update_scratch_space *scratch = dc_update_planes_and_stream_init(
			dc,
			srf_updates,
			surface_count,
			stream,
			stream_update
	);
	bool more = true;

	dc_exit_ips_for_hw_access(dc);
	/*
	 * update planes and stream version 3 separates FULL and FAST updates
	 * to their own sequences. It aims to clean up frequent checks for
	 * update type resulting unnecessary branching in logic flow. It also
	 * adds a new commit minimal transition sequence, which detects the need
	 * for minimal transition based on the actual comparison of current and
	 * new states instead of "predicting" it based on per feature software
	 * policy.i.e could_mpcc_tree_change_for_active_pipes. The new commit
	 * minimal transition sequence is made universal to any power saving
	 * features that would use extra free pipes such as Dynamic ODM/MPC
	 * Combine, MPO or SubVp. Therefore there is no longer a need to
	 * specially handle compatibility problems with transitions among those
	 * features as they are now transparent to the new sequence.
	 */
	if (dc->ctx->dce_version >= DCN_VERSION_4_01 || dc->ctx->dce_version == DCN_VERSION_3_2 ||
			dc->ctx->dce_version == DCN_VERSION_3_21)
		ret = update_planes_and_stream_v3(dc, srf_updates,
				surface_count, stream, stream_update);
	else
		ret = update_planes_and_stream_v2(dc, srf_updates,
			surface_count, stream, stream_update);
	if (ret && (dc->ctx->dce_version >= DCN_VERSION_3_2 ||
		dc->ctx->dce_version == DCN_VERSION_3_01))
		clear_update_flags(srf_updates, surface_count, stream);
	while (more) {
		if (!dc_update_planes_and_stream_prepare(scratch))
			return false;

	return ret;
		dc_update_planes_and_stream_execute(scratch);
		more = dc_update_planes_and_stream_cleanup(scratch);
	}
	return true;
}

void dc_commit_updates_for_stream(struct dc *dc,
@@ -7241,7 +7229,7 @@ static bool update_planes_and_stream_cleanup_v2(
	return false;
}

static void update_planes_and_stream_cleanup_v3_intermediate(
static void update_planes_and_stream_cleanup_v3_release_minimal(
		struct dc_update_scratch_space *scratch,
		bool backup
);
@@ -7262,6 +7250,10 @@ static bool update_planes_and_stream_prepare_v3(
		struct dc_update_scratch_space *scratch
)
{
	if (scratch->flow == UPDATE_V3_FLOW_NEW_CONTEXT_SEAMLESS) {
		return true;
	}
	ASSERT(scratch->flow == UPDATE_V3_FLOW_INVALID);
	dc_exit_ips_for_hw_access(scratch->dc);

	if (!update_planes_and_stream_state(
@@ -7327,11 +7319,11 @@ static bool update_planes_and_stream_prepare_v3(
			return true;
		}

		update_planes_and_stream_cleanup_v3_intermediate(scratch, false);
		update_planes_and_stream_cleanup_v3_release_minimal(scratch, false);
	}

	restore_planes_and_stream_state(&scratch->dc->scratch.current_state, scratch->stream);
	scratch->backup_context = scratch->dc->current_state;
	restore_planes_and_stream_state(&scratch->dc->scratch.current_state, scratch->stream);
	dc_state_retain(scratch->backup_context);
	scratch->intermediate_context = create_minimal_transition_state(
			scratch->dc,
@@ -7347,7 +7339,7 @@ static bool update_planes_and_stream_prepare_v3(
			return true;
		}

		update_planes_and_stream_cleanup_v3_intermediate(scratch, true);
		update_planes_and_stream_cleanup_v3_release_minimal(scratch, true);
	}

	scratch->flow = UPDATE_V3_FLOW_INVALID;
@@ -7398,12 +7390,10 @@ static void update_planes_and_stream_execute_v3(

	case UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_NEW:
		update_planes_and_stream_execute_v3_commit(scratch, false, true);
		update_planes_and_stream_execute_v3_commit(scratch, false, false);
		break;

	case UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_CURRENT:
		update_planes_and_stream_execute_v3_commit(scratch, true, true);
		update_planes_and_stream_execute_v3_commit(scratch, false, false);
		break;

	case UPDATE_V3_FLOW_INVALID:
@@ -7419,7 +7409,7 @@ static void update_planes_and_stream_cleanup_v3_new_context(
	swap_and_release_current_context(scratch->dc, scratch->new_context, scratch->stream);
}

static void update_planes_and_stream_cleanup_v3_intermediate(
static void update_planes_and_stream_cleanup_v3_release_minimal(
		struct dc_update_scratch_space *scratch,
		bool backup
)
@@ -7432,6 +7422,16 @@ static void update_planes_and_stream_cleanup_v3_intermediate(
	);
}

static void update_planes_and_stream_cleanup_v3_intermediate(
		struct dc_update_scratch_space *scratch,
		bool backup
)
{
	swap_and_release_current_context(scratch->dc, scratch->intermediate_context, scratch->stream);
	dc_state_retain(scratch->dc->current_state);
	update_planes_and_stream_cleanup_v3_release_minimal(scratch, backup);
}

static bool update_planes_and_stream_cleanup_v3(
		struct dc_update_scratch_space *scratch
)
@@ -7448,17 +7448,15 @@ static bool update_planes_and_stream_cleanup_v3(

	case UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_NEW:
		update_planes_and_stream_cleanup_v3_intermediate(scratch, false);
		update_planes_and_stream_cleanup_v3_new_context(scratch);
		break;
		scratch->flow = UPDATE_V3_FLOW_NEW_CONTEXT_SEAMLESS;
		return true;

	case UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_CURRENT:
		swap_and_release_current_context(scratch->dc, scratch->intermediate_context, scratch->stream);
		dc_state_retain(scratch->dc->current_state);
		update_planes_and_stream_cleanup_v3_intermediate(scratch, true);
		dc_state_release(scratch->backup_context);
		restore_planes_and_stream_state(&scratch->dc->scratch.new_state, scratch->stream);
		update_planes_and_stream_cleanup_v3_new_context(scratch);
		break;
		scratch->flow = UPDATE_V3_FLOW_NEW_CONTEXT_SEAMLESS;
		return true;

	case UPDATE_V3_FLOW_INVALID:
	default: