diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index cc5bcd14b6df..7a74750076c5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -559,10 +559,12 @@ static int init_ring_common(struct intel_engine_cs *engine) } } - if (I915_NEED_GFX_HWS(dev_priv)) - intel_ring_setup_status_page(engine); - else + if (HWS_NEEDS_PHYSICAL(dev_priv)) ring_setup_phys_status_page(engine); + else + intel_ring_setup_status_page(engine); + + intel_engine_reset_irq(engine); /* Enforce ordering by reading HEAD register back */ I915_READ_HEAD(engine); @@ -577,34 +579,33 @@ static int init_ring_common(struct intel_engine_cs *engine) if (I915_READ_HEAD(engine)) DRM_DEBUG("%s initialization failed [head=%08x], fudging\n", engine->name, I915_READ_HEAD(engine)); - I915_WRITE_HEAD(engine, 0); - (void)I915_READ_HEAD(engine); + + intel_ring_update_space(ring); + I915_WRITE_HEAD(engine, ring->head); + I915_WRITE_TAIL(engine, ring->tail); + (void)I915_READ_TAIL(engine); I915_WRITE_CTL(engine, ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | RING_VALID); /* If the head is still not zero, the ring is dead */ - if (wait_for((I915_READ_CTL(engine) & RING_VALID) != 0 && - I915_READ_START(engine) == i915_ggtt_offset(ring->vma) && - (I915_READ_HEAD(engine) & HEAD_ADDR) == 0, 50)) { + if (intel_wait_for_register_fw(dev_priv, RING_CTL(engine->mmio_base), + RING_VALID, RING_VALID, + 50)) { DRM_ERROR("%s initialization failed " - "ctl %08x (valid? %d) head %08x tail %08x start %08x [expected %08x]\n", + "ctl %08x (valid? %d) head %08x [%08x] tail %08x [%08x] start %08x [expected %08x]\n", engine->name, I915_READ_CTL(engine), I915_READ_CTL(engine) & RING_VALID, - I915_READ_HEAD(engine), I915_READ_TAIL(engine), + I915_READ_HEAD(engine), ring->head, + I915_READ_TAIL(engine), ring->tail, I915_READ_START(engine), i915_ggtt_offset(ring->vma)); ret = -EIO; goto out; } - ring->last_retired_head = -1; - ring->head = I915_READ_HEAD(engine); - ring->tail = I915_READ_TAIL(engine) & TAIL_ADDR; - intel_ring_update_space(ring); - intel_engine_init_hangcheck(engine); out: @@ -613,6 +614,15 @@ out: return ret; } +static void reset_ring_common(struct intel_engine_cs *engine, + struct drm_i915_gem_request *request) +{ + struct intel_ring *ring = request->ring; + + ring->head = request->postfix; + ring->last_retired_head = -1; +} + static int intel_ring_workarounds_emit(struct drm_i915_gem_request *req) { struct intel_ring *ring = req->ring; @@ -951,7 +961,7 @@ static int skl_tune_iz_hashing(struct intel_engine_cs *engine) * Only consider slices where one, and only one, subslice has 7 * EUs */ - if (!is_power_of_2(dev_priv->info.subslice_7eu[i])) + if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i])) continue; /* @@ -960,7 +970,7 @@ static int skl_tune_iz_hashing(struct intel_engine_cs *engine) * * -> 0 <= ss <= 3; */ - ss = ffs(dev_priv->info.subslice_7eu[i]) - 1; + ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1; vals[i] = 3 - ss; } @@ -2007,7 +2017,6 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size) } ring->vma = vma; - list_add(&ring->link, &engine->buffers); return ring; } @@ -2015,7 +2024,6 @@ void intel_ring_free(struct intel_ring *ring) { i915_vma_put(ring->vma); - list_del(&ring->link); kfree(ring); } @@ -2109,13 +2117,13 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine) goto error; } - if (I915_NEED_GFX_HWS(dev_priv)) { - ret = init_status_page(engine); + if (HWS_NEEDS_PHYSICAL(dev_priv)) { + WARN_ON(engine->id != RCS); + ret = init_phys_status_page(engine); if (ret) goto error; } else { - WARN_ON(engine->id != RCS); - ret = init_phys_status_page(engine); + ret = init_status_page(engine); if (ret) goto error; } @@ -2155,11 +2163,11 @@ void intel_engine_cleanup(struct intel_engine_cs *engine) if (engine->cleanup) engine->cleanup(engine); - if (I915_NEED_GFX_HWS(dev_priv)) { - cleanup_status_page(engine); - } else { + if (HWS_NEEDS_PHYSICAL(dev_priv)) { WARN_ON(engine->id != RCS); cleanup_phys_status_page(engine); + } else { + cleanup_status_page(engine); } intel_engine_cleanup_common(engine); @@ -2169,6 +2177,16 @@ void intel_engine_cleanup(struct intel_engine_cs *engine) engine->i915 = NULL; } +void intel_legacy_submission_resume(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *engine; + + for_each_engine(engine, dev_priv) { + engine->buffer->head = engine->buffer->tail; + engine->buffer->last_retired_head = -1; + } +} + int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request) { int ret; @@ -2223,13 +2241,12 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes) if (WARN_ON(&target->ring_link == &ring->request_list)) return -ENOSPC; - ret = i915_wait_request(target, true, NULL, NO_WAITBOOST); + ret = i915_wait_request(target, + I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, + NULL, NO_WAITBOOST); if (ret) return ret; - if (i915_reset_in_progress(&target->i915->gpu_error)) - return -EAGAIN; - i915_gem_request_retire_upto(target); intel_ring_update_space(ring); @@ -2655,6 +2672,7 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, intel_ring_init_semaphores(dev_priv, engine); engine->init_hw = init_ring_common; + engine->reset_hw = reset_ring_common; engine->emit_request = i9xx_emit_request; if (i915.semaphores) |