Commit 62cc6216 authored by Alvin Lee's avatar Alvin Lee Committed by Alex Deucher
Browse files

drm/amd/display: Check Vactive for VRR active for FPO + Vactive



[Description]
- For FPO + Vactive cases, we rely on the Vactive display to be at
  it's nominal refresh rate because the Vactive pipe may not necessarily
  assert P-State allow while it's in VBLANK
- For cases where the Vactive display has a stretched VBLANK due to
  VRR, we could underflow when trying to complete an FPO + Vactive
  MCLK switch because the FPO display has limited VBLANK time in
  waiting for the Vactive display to assert P-State allow naturally
- Block FPO + Vactive if the Vactive display has VRR active (variable
  or fixed)

Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarAlex Hung <alex.hung@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 273f4799
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -2604,7 +2604,7 @@ static enum surface_update_type check_update_surfaces_for_stream(

		if (stream_update->stream && stream_update->stream->freesync_on_desktop &&
			(stream_update->vrr_infopacket || stream_update->allow_freesync ||
				stream_update->vrr_active_variable))
				stream_update->vrr_active_variable || stream_update->vrr_active_fixed))
			su_flags->bits.fams_changed = 1;

		if (su_flags->raw != 0)
@@ -2964,6 +2964,9 @@ static void copy_stream_update_to_stream(struct dc *dc,
	if (update->vrr_active_variable)
		stream->vrr_active_variable = *update->vrr_active_variable;

	if (update->vrr_active_fixed)
		stream->vrr_active_fixed = *update->vrr_active_fixed;

	if (update->crtc_timing_adjust)
		stream->adjust = *update->crtc_timing_adjust;

+2 −0
Original line number Diff line number Diff line
@@ -233,6 +233,7 @@ struct dc_stream_state {
	 */
	bool vrr_active_variable;
	bool freesync_on_desktop;
	bool vrr_active_fixed;

	bool converter_disable_audio;
	uint8_t qs_bit;
@@ -326,6 +327,7 @@ struct dc_stream_update {
	bool integer_scaling_update;
	bool *allow_freesync;
	bool *vrr_active_variable;
	bool *vrr_active_fixed;

	struct colorspace_transform *gamut_remap;
	enum dc_color_space *output_color_space;
+6 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@

#define DC_LOGGER_INIT(logger)

static const unsigned int MAX_FPO_VACTIVE_BLANK_US = 600;
static const struct subvp_high_refresh_list subvp_high_refresh_list = {
			.min_refresh = 120,
			.max_refresh = 165,
@@ -2924,6 +2925,7 @@ bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint
	unsigned int i, pipe_idx;
	const struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
	bool vactive_found = false;
	unsigned int blank_us = 0;

	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
		const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
@@ -2931,7 +2933,10 @@ bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint
		if (!pipe->stream)
			continue;

		if (vba->ActiveDRAMClockChangeLatencyMarginPerState[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]] >= vactive_margin_req_us) {
		blank_us = ((pipe->stream->timing.v_total - pipe->stream->timing.v_addressable) * pipe->stream->timing.h_total /
				(double)(pipe->stream->timing.pix_clk_100hz * 100)) * 1000000;
		if (vba->ActiveDRAMClockChangeLatencyMarginPerState[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]] >= vactive_margin_req_us &&
				!(pipe->stream->vrr_active_variable || pipe->stream->vrr_active_fixed) && blank_us < MAX_FPO_VACTIVE_BLANK_US) {
			vactive_found = true;
			break;
		}