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

Merge tag 'drm-intel-fixes-2020-06-18' of...

Merge tag 'drm-intel-fixes-2020-06-18' of git://anongit.freedesktop.org/drm/drm-intel

 into drm-fixes

- Fix for timeslicing and virtual engines/unpremptable requests
  (+ 1 dependency patch)
- Fixes into TypeC register programming and interrupt storm detecting
- Disable DIP on MST ports with the transcoder clock still on
- Avoid missing GT workarounds at reset for HSW and older gens
- Fix for unwinding multiple requests missing force restore
- Fix encoder type check for DDI vswing sequence
- Build warning fixes

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200618124659.GA12342@jlahtine-desk.ger.corp.intel.com
parents b3a9e3b9 8e68c634
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -2579,14 +2579,14 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,

static void
tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
				u32 level)
				u32 level, enum intel_output_type type)
{
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
	const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
	u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;

	if (encoder->type == INTEL_OUTPUT_HDMI) {
	if (type == INTEL_OUTPUT_HDMI) {
		n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
		ddi_translations = tgl_dkl_phy_hdmi_ddi_trans;
	} else {
@@ -2638,7 +2638,7 @@ static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder,
	if (intel_phy_is_combo(dev_priv, phy))
		icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
	else
		tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level);
		tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level, type);
}

static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
@@ -2987,7 +2987,7 @@ icl_program_mg_dp_mode(struct intel_digital_port *intel_dig_port,
		ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port));
	}

	ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X1_MODE);
	ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE);
	ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE);

	/* DPPATC */
@@ -3472,7 +3472,9 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
					  INTEL_OUTPUT_DP_MST);
	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);

	intel_dp_set_infoframes(encoder, false, old_crtc_state, old_conn_state);
	if (!is_mst)
		intel_dp_set_infoframes(encoder, false,
					old_crtc_state, old_conn_state);

	/*
	 * Power down sink before disabling the port, otherwise we end
+8 −0
Original line number Diff line number Diff line
@@ -397,6 +397,14 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
	 */
	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
				     false);

	/*
	 * BSpec 4287: disable DIP after the transcoder is disabled and before
	 * the transcoder clock select is set to none.
	 */
	if (last_mst_stream)
		intel_dp_set_infoframes(&intel_dig_port->base, false,
					old_crtc_state, NULL);
	/*
	 * From TGL spec: "If multi-stream slave transcoder: Configure
	 * Transcoder Clock Select to direct no clock to the transcoder"
+3 −1
Original line number Diff line number Diff line
@@ -646,7 +646,7 @@ static int engine_setup_common(struct intel_engine_cs *engine)
struct measure_breadcrumb {
	struct i915_request rq;
	struct intel_ring ring;
	u32 cs[1024];
	u32 cs[2048];
};

static int measure_breadcrumb_dw(struct intel_context *ce)
@@ -668,6 +668,8 @@ static int measure_breadcrumb_dw(struct intel_context *ce)

	frame->ring.vaddr = frame->cs;
	frame->ring.size = sizeof(frame->cs);
	frame->ring.wrap =
		BITS_PER_TYPE(frame->ring.size) - ilog2(frame->ring.size);
	frame->ring.effective_size = frame->ring.size;
	intel_ring_update_space(&frame->ring);
	frame->rq.ring = &frame->ring;
+45 −7
Original line number Diff line number Diff line
@@ -1134,6 +1134,13 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
			list_move(&rq->sched.link, pl);
			set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags);

			/* Check in case we rollback so far we wrap [size/2] */
			if (intel_ring_direction(rq->ring,
						 intel_ring_wrap(rq->ring,
								 rq->tail),
						 rq->ring->tail) > 0)
				rq->context->lrc.desc |= CTX_DESC_FORCE_RESTORE;

			active = rq;
		} else {
			struct intel_engine_cs *owner = rq->context->engine;
@@ -1498,8 +1505,9 @@ static u64 execlists_update_context(struct i915_request *rq)
	 * HW has a tendency to ignore us rewinding the TAIL to the end of
	 * an earlier request.
	 */
	GEM_BUG_ON(ce->lrc_reg_state[CTX_RING_TAIL] != rq->ring->tail);
	prev = rq->ring->tail;
	tail = intel_ring_set_tail(rq->ring, rq->tail);
	prev = ce->lrc_reg_state[CTX_RING_TAIL];
	if (unlikely(intel_ring_direction(rq->ring, tail, prev) <= 0))
		desc |= CTX_DESC_FORCE_RESTORE;
	ce->lrc_reg_state[CTX_RING_TAIL] = tail;
@@ -1895,7 +1903,8 @@ static void defer_active(struct intel_engine_cs *engine)

static bool
need_timeslice(const struct intel_engine_cs *engine,
	       const struct i915_request *rq)
	       const struct i915_request *rq,
	       const struct rb_node *rb)
{
	int hint;

@@ -1903,9 +1912,28 @@ need_timeslice(const struct intel_engine_cs *engine,
		return false;

	hint = engine->execlists.queue_priority_hint;

	if (rb) {
		const struct virtual_engine *ve =
			rb_entry(rb, typeof(*ve), nodes[engine->id].rb);
		const struct intel_engine_cs *inflight =
			intel_context_inflight(&ve->context);

		if (!inflight || inflight == engine) {
			struct i915_request *next;

			rcu_read_lock();
			next = READ_ONCE(ve->request);
			if (next)
				hint = max(hint, rq_prio(next));
			rcu_read_unlock();
		}
	}

	if (!list_is_last(&rq->sched.link, &engine->active.requests))
		hint = max(hint, rq_prio(list_next_entry(rq, sched.link)));

	GEM_BUG_ON(hint >= I915_PRIORITY_UNPREEMPTABLE);
	return hint >= effective_prio(rq);
}

@@ -1977,10 +2005,9 @@ static void set_timeslice(struct intel_engine_cs *engine)
	set_timer_ms(&engine->execlists.timer, duration);
}

static void start_timeslice(struct intel_engine_cs *engine)
static void start_timeslice(struct intel_engine_cs *engine, int prio)
{
	struct intel_engine_execlists *execlists = &engine->execlists;
	const int prio = queue_prio(execlists);
	unsigned long duration;

	if (!intel_engine_has_timeslices(engine))
@@ -2140,7 +2167,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
			__unwind_incomplete_requests(engine);

			last = NULL;
		} else if (need_timeslice(engine, last) &&
		} else if (need_timeslice(engine, last, rb) &&
			   timeslice_expired(execlists, last)) {
			if (i915_request_completed(last)) {
				tasklet_hi_schedule(&execlists->tasklet);
@@ -2188,7 +2215,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
				 * Even if ELSP[1] is occupied and not worthy
				 * of timeslices, our queue might be.
				 */
				start_timeslice(engine);
				start_timeslice(engine, queue_prio(execlists));
				return;
			}
		}
@@ -2223,7 +2250,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)

			if (last && !can_merge_rq(last, rq)) {
				spin_unlock(&ve->base.active.lock);
				start_timeslice(engine);
				start_timeslice(engine, rq_prio(rq));
				return; /* leave this for another sibling */
			}

@@ -4739,6 +4766,14 @@ static int gen12_emit_flush(struct i915_request *request, u32 mode)
	return 0;
}

static void assert_request_valid(struct i915_request *rq)
{
	struct intel_ring *ring __maybe_unused = rq->ring;

	/* Can we unwind this request without appearing to go forwards? */
	GEM_BUG_ON(intel_ring_direction(ring, rq->wa_tail, rq->head) <= 0);
}

/*
 * Reserve space for 2 NOOPs at the end of each request to be
 * used as a workaround for not being allowed to do lite
@@ -4751,6 +4786,9 @@ static u32 *gen8_emit_wa_tail(struct i915_request *request, u32 *cs)
	*cs++ = MI_NOOP;
	request->wa_tail = intel_ring_offset(request, cs);

	/* Check that entire request is less than half the ring */
	assert_request_valid(request);

	return cs;
}

+4 −0
Original line number Diff line number Diff line
@@ -315,3 +315,7 @@ int intel_ring_cacheline_align(struct i915_request *rq)
	GEM_BUG_ON(rq->ring->emit & (CACHELINE_BYTES - 1));
	return 0;
}

#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftest_ring.c"
#endif
Loading