Commit 7d9ff5ee authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'amd-drm-fixes-5.7-2020-05-21' of...

Merge tag 'amd-drm-fixes-5.7-2020-05-21' of git://people.freedesktop.org/~agd5f/linux

 into drm-fixes

amd-drm-fixes-5.7-2020-05-21:

amdgpu:
- DP fix
- Floating point fix
- Fix cursor stutter issue

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200521222415.4122-1-alexander.deucher@amd.com
parents 9bf43039 31ecebee
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -220,6 +220,30 @@ static enum dpcd_training_patterns
	return dpcd_tr_pattern;
}

static uint8_t dc_dp_initialize_scrambling_data_symbols(
	struct dc_link *link,
	enum dc_dp_training_pattern pattern)
{
	uint8_t disable_scrabled_data_symbols = 0;

	switch (pattern) {
	case DP_TRAINING_PATTERN_SEQUENCE_1:
	case DP_TRAINING_PATTERN_SEQUENCE_2:
	case DP_TRAINING_PATTERN_SEQUENCE_3:
		disable_scrabled_data_symbols = 1;
		break;
	case DP_TRAINING_PATTERN_SEQUENCE_4:
		disable_scrabled_data_symbols = 0;
		break;
	default:
		ASSERT(0);
		DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n",
			__func__, pattern);
		break;
	}
	return disable_scrabled_data_symbols;
}

static inline bool is_repeater(struct dc_link *link, uint32_t offset)
{
	return (!link->is_lttpr_mode_transparent && offset != 0);
@@ -252,6 +276,9 @@ static void dpcd_set_lt_pattern_and_lane_settings(
	dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
		dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern);

	dpcd_pattern.v1_4.SCRAMBLING_DISABLE =
		dc_dp_initialize_scrambling_data_symbols(link, pattern);

	dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - DP_TRAINING_PATTERN_SET]
		= dpcd_pattern.raw;

+68 −1
Original line number Diff line number Diff line
@@ -1625,12 +1625,79 @@ void dcn10_pipe_control_lock(
		hws->funcs.verify_allow_pstate_change_high(dc);
}

/**
 * delay_cursor_until_vupdate() - Delay cursor update if too close to VUPDATE.
 *
 * Software keepout workaround to prevent cursor update locking from stalling
 * out cursor updates indefinitely or from old values from being retained in
 * the case where the viewport changes in the same frame as the cursor.
 *
 * The idea is to calculate the remaining time from VPOS to VUPDATE. If it's
 * too close to VUPDATE, then stall out until VUPDATE finishes.
 *
 * TODO: Optimize cursor programming to be once per frame before VUPDATE
 *       to avoid the need for this workaround.
 */
static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
	struct dc_stream_state *stream = pipe_ctx->stream;
	struct crtc_position position;
	uint32_t vupdate_start, vupdate_end;
	unsigned int lines_to_vupdate, us_to_vupdate, vpos;
	unsigned int us_per_line, us_vupdate;

	if (!dc->hwss.calc_vupdate_position || !dc->hwss.get_position)
		return;

	if (!pipe_ctx->stream_res.stream_enc || !pipe_ctx->stream_res.tg)
		return;

	dc->hwss.calc_vupdate_position(dc, pipe_ctx, &vupdate_start,
				       &vupdate_end);

	dc->hwss.get_position(&pipe_ctx, 1, &position);
	vpos = position.vertical_count;

	/* Avoid wraparound calculation issues */
	vupdate_start += stream->timing.v_total;
	vupdate_end += stream->timing.v_total;
	vpos += stream->timing.v_total;

	if (vpos <= vupdate_start) {
		/* VPOS is in VACTIVE or back porch. */
		lines_to_vupdate = vupdate_start - vpos;
	} else if (vpos > vupdate_end) {
		/* VPOS is in the front porch. */
		return;
	} else {
		/* VPOS is in VUPDATE. */
		lines_to_vupdate = 0;
	}

	/* Calculate time until VUPDATE in microseconds. */
	us_per_line =
		stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz;
	us_to_vupdate = lines_to_vupdate * us_per_line;

	/* 70 us is a conservative estimate of cursor update time*/
	if (us_to_vupdate > 70)
		return;

	/* Stall out until the cursor update completes. */
	us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line;
	udelay(us_to_vupdate + us_vupdate);
}

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;

	/* Prevent cursor lock from stalling out cursor updates. */
	if (lock)
		delay_cursor_until_vupdate(dc, pipe);

	dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc,
			pipe->stream_res.opp->inst, lock);
}
@@ -3236,7 +3303,7 @@ int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx)
	return vertical_line_start;
}

static void dcn10_calc_vupdate_position(
void dcn10_calc_vupdate_position(
		struct dc *dc,
		struct pipe_ctx *pipe_ctx,
		uint32_t *start_line,
+5 −0
Original line number Diff line number Diff line
@@ -34,6 +34,11 @@ struct dc;
void dcn10_hw_sequencer_construct(struct dc *dc);

int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx);
void dcn10_calc_vupdate_position(
		struct dc *dc,
		struct pipe_ctx *pipe_ctx,
		uint32_t *start_line,
		uint32_t *end_line);
void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
enum dc_status dcn10_enable_stream_timing(
		struct pipe_ctx *pipe_ctx,
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
	.set_clock = dcn10_set_clock,
	.get_clock = dcn10_get_clock,
	.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
	.calc_vupdate_position = dcn10_calc_vupdate_position,
};

static const struct hwseq_private_funcs dcn10_private_funcs = {
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
	.init_vm_ctx = dcn20_init_vm_ctx,
	.set_flip_control_gsl = dcn20_set_flip_control_gsl,
	.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
	.calc_vupdate_position = dcn10_calc_vupdate_position,
};

static const struct hwseq_private_funcs dcn20_private_funcs = {
Loading