Skip to content

Commit 7ac98ff

Browse files
committed
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: Dave Airlie <[email protected]> From: Joonas Lahtinen <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents b3a9e3b + 8e68c63 commit 7ac98ff

19 files changed

+668
-373
lines changed

drivers/gpu/drm/i915/display/intel_ddi.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,14 +2579,14 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
25792579

25802580
static void
25812581
tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
2582-
u32 level)
2582+
u32 level, enum intel_output_type type)
25832583
{
25842584
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
25852585
enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
25862586
const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
25872587
u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;
25882588

2589-
if (encoder->type == INTEL_OUTPUT_HDMI) {
2589+
if (type == INTEL_OUTPUT_HDMI) {
25902590
n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
25912591
ddi_translations = tgl_dkl_phy_hdmi_ddi_trans;
25922592
} else {
@@ -2638,7 +2638,7 @@ static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder,
26382638
if (intel_phy_is_combo(dev_priv, phy))
26392639
icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
26402640
else
2641-
tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level);
2641+
tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level, type);
26422642
}
26432643

26442644
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,
29872987
ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port));
29882988
}
29892989

2990-
ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X1_MODE);
2990+
ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE);
29912991
ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE);
29922992

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

3475-
intel_dp_set_infoframes(encoder, false, old_crtc_state, old_conn_state);
3475+
if (!is_mst)
3476+
intel_dp_set_infoframes(encoder, false,
3477+
old_crtc_state, old_conn_state);
34763478

34773479
/*
34783480
* Power down sink before disabling the port, otherwise we end

drivers/gpu/drm/i915/display/intel_dp_mst.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,14 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
397397
*/
398398
drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
399399
false);
400+
401+
/*
402+
* BSpec 4287: disable DIP after the transcoder is disabled and before
403+
* the transcoder clock select is set to none.
404+
*/
405+
if (last_mst_stream)
406+
intel_dp_set_infoframes(&intel_dig_port->base, false,
407+
old_crtc_state, NULL);
400408
/*
401409
* From TGL spec: "If multi-stream slave transcoder: Configure
402410
* Transcoder Clock Select to direct no clock to the transcoder"

drivers/gpu/drm/i915/gt/intel_engine_cs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ static int engine_setup_common(struct intel_engine_cs *engine)
646646
struct measure_breadcrumb {
647647
struct i915_request rq;
648648
struct intel_ring ring;
649-
u32 cs[1024];
649+
u32 cs[2048];
650650
};
651651

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

669669
frame->ring.vaddr = frame->cs;
670670
frame->ring.size = sizeof(frame->cs);
671+
frame->ring.wrap =
672+
BITS_PER_TYPE(frame->ring.size) - ilog2(frame->ring.size);
671673
frame->ring.effective_size = frame->ring.size;
672674
intel_ring_update_space(&frame->ring);
673675
frame->rq.ring = &frame->ring;

drivers/gpu/drm/i915/gt/intel_lrc.c

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,13 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
11341134
list_move(&rq->sched.link, pl);
11351135
set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags);
11361136

1137+
/* Check in case we rollback so far we wrap [size/2] */
1138+
if (intel_ring_direction(rq->ring,
1139+
intel_ring_wrap(rq->ring,
1140+
rq->tail),
1141+
rq->ring->tail) > 0)
1142+
rq->context->lrc.desc |= CTX_DESC_FORCE_RESTORE;
1143+
11371144
active = rq;
11381145
} else {
11391146
struct intel_engine_cs *owner = rq->context->engine;
@@ -1498,8 +1505,9 @@ static u64 execlists_update_context(struct i915_request *rq)
14981505
* HW has a tendency to ignore us rewinding the TAIL to the end of
14991506
* an earlier request.
15001507
*/
1508+
GEM_BUG_ON(ce->lrc_reg_state[CTX_RING_TAIL] != rq->ring->tail);
1509+
prev = rq->ring->tail;
15011510
tail = intel_ring_set_tail(rq->ring, rq->tail);
1502-
prev = ce->lrc_reg_state[CTX_RING_TAIL];
15031511
if (unlikely(intel_ring_direction(rq->ring, tail, prev) <= 0))
15041512
desc |= CTX_DESC_FORCE_RESTORE;
15051513
ce->lrc_reg_state[CTX_RING_TAIL] = tail;
@@ -1895,17 +1903,37 @@ static void defer_active(struct intel_engine_cs *engine)
18951903

18961904
static bool
18971905
need_timeslice(const struct intel_engine_cs *engine,
1898-
const struct i915_request *rq)
1906+
const struct i915_request *rq,
1907+
const struct rb_node *rb)
18991908
{
19001909
int hint;
19011910

19021911
if (!intel_engine_has_timeslices(engine))
19031912
return false;
19041913

19051914
hint = engine->execlists.queue_priority_hint;
1915+
1916+
if (rb) {
1917+
const struct virtual_engine *ve =
1918+
rb_entry(rb, typeof(*ve), nodes[engine->id].rb);
1919+
const struct intel_engine_cs *inflight =
1920+
intel_context_inflight(&ve->context);
1921+
1922+
if (!inflight || inflight == engine) {
1923+
struct i915_request *next;
1924+
1925+
rcu_read_lock();
1926+
next = READ_ONCE(ve->request);
1927+
if (next)
1928+
hint = max(hint, rq_prio(next));
1929+
rcu_read_unlock();
1930+
}
1931+
}
1932+
19061933
if (!list_is_last(&rq->sched.link, &engine->active.requests))
19071934
hint = max(hint, rq_prio(list_next_entry(rq, sched.link)));
19081935

1936+
GEM_BUG_ON(hint >= I915_PRIORITY_UNPREEMPTABLE);
19091937
return hint >= effective_prio(rq);
19101938
}
19111939

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

1980-
static void start_timeslice(struct intel_engine_cs *engine)
2008+
static void start_timeslice(struct intel_engine_cs *engine, int prio)
19812009
{
19822010
struct intel_engine_execlists *execlists = &engine->execlists;
1983-
const int prio = queue_prio(execlists);
19842011
unsigned long duration;
19852012

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

21422169
last = NULL;
2143-
} else if (need_timeslice(engine, last) &&
2170+
} else if (need_timeslice(engine, last, rb) &&
21442171
timeslice_expired(execlists, last)) {
21452172
if (i915_request_completed(last)) {
21462173
tasklet_hi_schedule(&execlists->tasklet);
@@ -2188,7 +2215,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
21882215
* Even if ELSP[1] is occupied and not worthy
21892216
* of timeslices, our queue might be.
21902217
*/
2191-
start_timeslice(engine);
2218+
start_timeslice(engine, queue_prio(execlists));
21922219
return;
21932220
}
21942221
}
@@ -2223,7 +2250,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
22232250

22242251
if (last && !can_merge_rq(last, rq)) {
22252252
spin_unlock(&ve->base.active.lock);
2226-
start_timeslice(engine);
2253+
start_timeslice(engine, rq_prio(rq));
22272254
return; /* leave this for another sibling */
22282255
}
22292256

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

4769+
static void assert_request_valid(struct i915_request *rq)
4770+
{
4771+
struct intel_ring *ring __maybe_unused = rq->ring;
4772+
4773+
/* Can we unwind this request without appearing to go forwards? */
4774+
GEM_BUG_ON(intel_ring_direction(ring, rq->wa_tail, rq->head) <= 0);
4775+
}
4776+
47424777
/*
47434778
* Reserve space for 2 NOOPs at the end of each request to be
47444779
* 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)
47514786
*cs++ = MI_NOOP;
47524787
request->wa_tail = intel_ring_offset(request, cs);
47534788

4789+
/* Check that entire request is less than half the ring */
4790+
assert_request_valid(request);
4791+
47544792
return cs;
47554793
}
47564794

drivers/gpu/drm/i915/gt/intel_ring.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,7 @@ int intel_ring_cacheline_align(struct i915_request *rq)
315315
GEM_BUG_ON(rq->ring->emit & (CACHELINE_BYTES - 1));
316316
return 0;
317317
}
318+
319+
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
320+
#include "selftest_ring.c"
321+
#endif

0 commit comments

Comments
 (0)