Commit b96150a7 authored by Wayne Lin's avatar Wayne Lin Committed by Alex Deucher
Browse files

drm/amd/display: Should support p-state under dcn21



[Why]
Under DCN21, observe flip_done timeout issue while
running 3D benchmark under MPO case. Timeout is caused
by driver fails validate_bandwidth() during
atomic_commit_tail but passes atomic_check.

Under further analysis, indicates the delta of
atomic_check and atomic_commit_tail are
dc->current_state->bw_ctx.dml.soc.sr_exit_time_us and
dc->current_state->bw_ctx.dml.soc.sr_enter_plus_exit_time_us.

We set validate_mode as DC_VALIDATE_MODE_ONLY while calling
dc_validate_global_state() at atomic_check, but set mode as
DC_VALIDATE_MODE_AND_PROGRAMMING during atomic_commit_tail.
If dc_validate_mode set as DC_VALIDATE_MODE_ONLY,
validate_bandwidth() will skip the wm and dlg calculation.

During commit_tail, validate_bandwidth() is called with
dc_validate_mode set as DC_VALIDATE_MODE_AND_PROGRAMMING and
dc_state->bw_ctx.dml.soc.sr_exit_time_us might get modified
after the wm_calculation and stored into dc->current_state.
Which means dc->current_state->bw_ctx.dml.soc.sr_exit_time_us
might not aligned with the one stored in dm_state->context.
That causes duplicated dm_state->context not aligned with
dc->current_state, and might have bandwidth validation pass
in atomic_check and fail in commit_tail later.

[How]
When the issue occurs, it fails dml_get_voltage_level() with
the condition dm_allow_self_refresh_and_mclk_switch but pass
with the condition dm_allow_self_refresh. However, we should
support p-state. So we should not pass validate_bandwidth by
allowing self refresh only. Change the policy under DCN21.

Reviewed-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: default avatarWayne Lin <Wayne.Lin@amd.com>
Signed-off-by: default avatarChuanyu Tseng <chuanyu.tseng@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 06bc20d2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2335,7 +2335,7 @@ bool dcn21_validate_bandwidth_fp(struct dc *dc, struct dc_state *context,
	/*Unsafe due to current pipe merge and split logic*/
	ASSERT(context != dc->current_state);

	out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, validate_mode);
	out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, validate_mode, false);

	if (pipe_cnt == 0)
		goto validate_out;
+18 −12
Original line number Diff line number Diff line
@@ -772,7 +772,8 @@ bool dcn21_fast_validate_bw(struct dc *dc,
			    int *pipe_cnt_out,
			    int *pipe_split_from,
			    int *vlevel_out,
			    enum dc_validate_mode validate_mode)
			    enum dc_validate_mode validate_mode,
			    bool allow_self_refresh_only)
{
	bool out = false;
	int split[MAX_PIPES] = { 0 };
@@ -803,6 +804,8 @@ bool dcn21_fast_validate_bw(struct dc *dc,
	vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);

	if (vlevel > context->bw_ctx.dml.soc.num_states) {

		if (allow_self_refresh_only) {
			/*
			 * If mode is unsupported or there's still no p-state support then
			 * fall back to favoring voltage.
@@ -815,6 +818,9 @@ bool dcn21_fast_validate_bw(struct dc *dc,
			vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
			if (vlevel > context->bw_ctx.dml.soc.num_states)
				goto validate_fail;
		} else {
			goto validate_fail;
		}
	}

	vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
+2 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ bool dcn21_fast_validate_bw(
		int *pipe_cnt_out,
		int *pipe_split_from,
		int *vlevel_out,
		enum dc_validate_mode validate_mode);
		enum dc_validate_mode validate_mode,
		bool allow_self_refresh_only);

#endif /* _DCN21_RESOURCE_H_ */