Commit b2a7b0ce authored by Aric Cyr's avatar Aric Cyr Committed by Alex Deucher
Browse files

drm/amd/display: Use cursor locking to prevent flip delays



[Why]
Current locking scheme for cursor can result in a flip missing
its vsync, deferring it for one or more vsyncs.  Result is a
potential for stuttering when cursor is moved.

[How]
Use cursor update lock so that flips are not blocked while cursor
is being programmed.

Signed-off-by: default avatarAric Cyr <aric.cyr@amd.com>
Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 668a6741
Loading
Loading
Loading
Loading
+4 −36
Original line number Diff line number Diff line
@@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status(
	return dc_stream_get_status_from_state(dc->current_state, stream);
}

static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc)
{
#if defined(CONFIG_DRM_AMD_DC_DCN)
	unsigned int vupdate_line;
	unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos;
	struct dc_stream_state *stream = pipe_ctx->stream;
	unsigned int us_per_line;

	if (!dc->hwss.get_vupdate_offset_from_vsync)
		return;

	vupdate_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
	if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos))
		return;

	if (vpos >= vupdate_line)
		return;

	us_per_line =
		stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz;
	lines_to_vupdate = vupdate_line - vpos;
	us_to_vupdate = lines_to_vupdate * us_per_line;

	/* 70 us is a conservative estimate of cursor update time*/
	if (us_to_vupdate < 70)
		udelay(us_to_vupdate);
#endif
}

/**
 * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address
@@ -298,9 +270,7 @@ bool dc_stream_set_cursor_attributes(

		if (!pipe_to_program) {
			pipe_to_program = pipe_ctx;

			delay_cursor_until_vupdate(pipe_ctx, dc);
			dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
			dc->hwss.cursor_lock(dc, pipe_to_program, true);
		}

		dc->hwss.set_cursor_attribute(pipe_ctx);
@@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes(
	}

	if (pipe_to_program)
		dc->hwss.pipe_control_lock(dc, pipe_to_program, false);
		dc->hwss.cursor_lock(dc, pipe_to_program, false);

	return true;
}
@@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position(

		if (!pipe_to_program) {
			pipe_to_program = pipe_ctx;

			delay_cursor_until_vupdate(pipe_ctx, dc);
			dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
			dc->hwss.cursor_lock(dc, pipe_to_program, true);
		}

		dc->hwss.set_cursor_position(pipe_ctx);
	}

	if (pipe_to_program)
		dc->hwss.pipe_control_lock(dc, pipe_to_program, false);
		dc->hwss.cursor_lock(dc, pipe_to_program, false);

	return true;
}
+1 −0
Original line number Diff line number Diff line
@@ -2757,6 +2757,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
	.disable_plane = dce110_power_down_fe,
	.pipe_control_lock = dce_pipe_control_lock,
	.interdependent_update_lock = NULL,
	.cursor_lock = dce_pipe_control_lock,
	.prepare_bandwidth = dce110_prepare_bandwidth,
	.optimize_bandwidth = dce110_optimize_bandwidth,
	.set_drr = set_drr,
+10 −0
Original line number Diff line number Diff line
@@ -1625,6 +1625,16 @@ void dcn10_pipe_control_lock(
		hws->funcs.verify_allow_pstate_change_high(dc);
}

void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock)
{
	/* cursor lock is per MPCC tree, so only need to lock one pipe per stream */
	if (!pipe || pipe->top_pipe)
		return;

	dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc,
			pipe->stream_res.opp->inst, lock);
}

static bool wait_for_reset_trigger_to_occur(
	struct dc_context *dc_ctx,
	struct timing_generator *tg)
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ void dcn10_pipe_control_lock(
	struct dc *dc,
	struct pipe_ctx *pipe,
	bool lock);
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock);
void dcn10_blank_pixel_data(
		struct dc *dc,
		struct pipe_ctx *pipe_ctx,
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
	.disable_audio_stream = dce110_disable_audio_stream,
	.disable_plane = dcn10_disable_plane,
	.pipe_control_lock = dcn10_pipe_control_lock,
	.cursor_lock = dcn10_cursor_lock,
	.interdependent_update_lock = dcn10_lock_all_pipes,
	.prepare_bandwidth = dcn10_prepare_bandwidth,
	.optimize_bandwidth = dcn10_optimize_bandwidth,
Loading