diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2018-11-26 07:28:21 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2018-11-26 09:20:43 -0500 |
commit | b7f21899276a3e06ea3c98d0b3771f09eefc6e3d (patch) | |
tree | 556c867b6f626fca57a65b90572cc471ab20cba3 /drivers/gpu/drm/i915/intel_ringbuffer.c | |
parent | 0e39037b3165567660b0e03f67534da5269a0465 (diff) |
drm/i915/ringbuffer: 2-step restart
We may be simply restarting too fast for the culmudgeonly gen3/gen4 as
we still see missing interrupts following a reset. So let's try
restarting a little slower, first wake up the ring empty and then tell
it about the work it has to perform.
References: https://bugs.freedesktop.org/show_bug.cgi?id=108735
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181126122821.4537-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 87eebc13c0d8..e18a64d41843 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -546,10 +546,11 @@ static int init_ring_common(struct intel_engine_cs *engine) | |||
546 | /* Check that the ring offsets point within the ring! */ | 546 | /* Check that the ring offsets point within the ring! */ |
547 | GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head)); | 547 | GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head)); |
548 | GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->tail)); | 548 | GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->tail)); |
549 | |||
550 | intel_ring_update_space(ring); | 549 | intel_ring_update_space(ring); |
550 | |||
551 | /* First wake the ring up to an empty/idle ring */ | ||
551 | I915_WRITE_HEAD(engine, ring->head); | 552 | I915_WRITE_HEAD(engine, ring->head); |
552 | I915_WRITE_TAIL(engine, ring->tail); | 553 | I915_WRITE_TAIL(engine, ring->head); |
553 | (void)I915_READ_TAIL(engine); | 554 | (void)I915_READ_TAIL(engine); |
554 | 555 | ||
555 | I915_WRITE_CTL(engine, RING_CTL_SIZE(ring->size) | RING_VALID); | 556 | I915_WRITE_CTL(engine, RING_CTL_SIZE(ring->size) | RING_VALID); |
@@ -574,6 +575,12 @@ static int init_ring_common(struct intel_engine_cs *engine) | |||
574 | if (INTEL_GEN(dev_priv) > 2) | 575 | if (INTEL_GEN(dev_priv) > 2) |
575 | I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); | 576 | I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); |
576 | 577 | ||
578 | /* Now awake, let it get started */ | ||
579 | if (ring->tail != ring->head) { | ||
580 | I915_WRITE_TAIL(engine, ring->tail); | ||
581 | (void)I915_READ_TAIL(engine); | ||
582 | } | ||
583 | |||
577 | /* Papering over lost _interrupts_ immediately following the restart */ | 584 | /* Papering over lost _interrupts_ immediately following the restart */ |
578 | intel_engine_wakeup(engine); | 585 | intel_engine_wakeup(engine); |
579 | out: | 586 | out: |