]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/intel_lrc.c
drm/i915: Remove forced stop ring on suspend/unload
[karo-tx-linux.git] / drivers / gpu / drm / i915 / intel_lrc.c
index cf18eace669022e54dcc64de796016df4a200474..309c5d9b1c5724d53303b5db1c9c30fe66301456 100644 (file)
        reg_state[CTX_PDP0_LDW + 1] = lower_32_bits(px_dma(&ppgtt->pml4)); \
 } while (0)
 
-enum {
-       ADVANCED_CONTEXT = 0,
-       LEGACY_32B_CONTEXT,
-       ADVANCED_AD_CONTEXT,
-       LEGACY_64B_CONTEXT
-};
-#define GEN8_CTX_ADDRESSING_MODE_SHIFT 3
-#define GEN8_CTX_ADDRESSING_MODE(dev)  (USES_FULL_48BIT_PPGTT(dev) ?\
-               LEGACY_64B_CONTEXT :\
-               LEGACY_32B_CONTEXT)
 enum {
        FAULT_AND_HANG = 0,
        FAULT_AND_HALT, /* Debug only */
@@ -224,15 +214,21 @@ enum {
        FAULT_AND_CONTINUE /* Unsupported */
 };
 #define GEN8_CTX_ID_SHIFT 32
+#define GEN8_CTX_ID_WIDTH 21
 #define GEN8_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT       0x17
 #define GEN9_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT       0x26
 
-static int intel_lr_context_pin(struct intel_context *ctx,
+/* Typical size of the average request (2 pipecontrols and a MI_BB) */
+#define EXECLISTS_REQUEST_SIZE 64 /* bytes */
+
+static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
+                                           struct intel_engine_cs *engine);
+static int intel_lr_context_pin(struct i915_gem_context *ctx,
                                struct intel_engine_cs *engine);
 
 /**
  * intel_sanitize_enable_execlists() - sanitize i915.enable_execlists
- * @dev: DRM device.
+ * @dev_priv: i915 device private
  * @enable_execlists: value of i915.enable_execlists module parameter.
  *
  * Only certain platforms support Execlists (the prerequisites being
@@ -240,23 +236,22 @@ static int intel_lr_context_pin(struct intel_context *ctx,
  *
  * Return: 1 if Execlists is supported and has to be enabled.
  */
-int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists)
+int intel_sanitize_enable_execlists(struct drm_i915_private *dev_priv, int enable_execlists)
 {
-       WARN_ON(i915.enable_ppgtt == -1);
-
        /* On platforms with execlist available, vGPU will only
         * support execlist mode, no ring buffer mode.
         */
-       if (HAS_LOGICAL_RING_CONTEXTS(dev) && intel_vgpu_active(dev))
+       if (HAS_LOGICAL_RING_CONTEXTS(dev_priv) && intel_vgpu_active(dev_priv))
                return 1;
 
-       if (INTEL_INFO(dev)->gen >= 9)
+       if (INTEL_GEN(dev_priv) >= 9)
                return 1;
 
        if (enable_execlists == 0)
                return 0;
 
-       if (HAS_LOGICAL_RING_CONTEXTS(dev) && USES_PPGTT(dev) &&
+       if (HAS_LOGICAL_RING_CONTEXTS(dev_priv) &&
+           USES_PPGTT(dev_priv) &&
            i915.use_mmio_flip >= 0)
                return 1;
 
@@ -266,19 +261,17 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists
 static void
 logical_ring_init_platform_invariants(struct intel_engine_cs *engine)
 {
-       struct drm_device *dev = engine->dev;
+       struct drm_i915_private *dev_priv = engine->i915;
 
-       if (IS_GEN8(dev) || IS_GEN9(dev))
+       if (IS_GEN8(dev_priv) || IS_GEN9(dev_priv))
                engine->idle_lite_restore_wa = ~0;
 
-       engine->disable_lite_restore_wa = (IS_SKL_REVID(dev, 0, SKL_REVID_B0) ||
-                                       IS_BXT_REVID(dev, 0, BXT_REVID_A1)) &&
+       engine->disable_lite_restore_wa = (IS_SKL_REVID(dev_priv, 0, SKL_REVID_B0) ||
+                                       IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) &&
                                        (engine->id == VCS || engine->id == VCS2);
 
        engine->ctx_desc_template = GEN8_CTX_VALID;
-       engine->ctx_desc_template |= GEN8_CTX_ADDRESSING_MODE(dev) <<
-                                  GEN8_CTX_ADDRESSING_MODE_SHIFT;
-       if (IS_GEN8(dev))
+       if (IS_GEN8(dev_priv))
                engine->ctx_desc_template |= GEN8_CTX_L3LLC_COHERENT;
        engine->ctx_desc_template |= GEN8_CTX_PRIVILEGE;
 
@@ -295,72 +288,52 @@ logical_ring_init_platform_invariants(struct intel_engine_cs *engine)
 /**
  * intel_lr_context_descriptor_update() - calculate & cache the descriptor
  *                                       descriptor for a pinned context
- *
  * @ctx: Context to work on
- * @ring: Engine the descriptor will be used with
+ * @engine: Engine the descriptor will be used with
  *
  * The context descriptor encodes various attributes of a context,
  * including its GTT address and some flags. Because it's fairly
  * expensive to calculate, we'll just do it once and cache the result,
  * which remains valid until the context is unpinned.
  *
- * This is what a descriptor looks like, from LSB to MSB:
- *    bits 0-11:    flags, GEN8_CTX_* (cached in ctx_desc_template)
- *    bits 12-31:    LRCA, GTT address of (the HWSP of) this context
- *    bits 32-51:    ctx ID, a globally unique tag (the LRCA again!)
- *    bits 52-63:    reserved, may encode the engine ID (for GuC)
+ * This is what a descriptor looks like, from LSB to MSB::
+ *
+ *      bits  0-11:    flags, GEN8_CTX_* (cached in ctx_desc_template)
+ *      bits 12-31:    LRCA, GTT address of (the HWSP of) this context
+ *      bits 32-52:    ctx ID, a globally unique tag
+ *      bits 53-54:    mbz, reserved for use by hardware
+ *      bits 55-63:    group ID, currently unused and set to 0
  */
 static void
-intel_lr_context_descriptor_update(struct intel_context *ctx,
+intel_lr_context_descriptor_update(struct i915_gem_context *ctx,
                                   struct intel_engine_cs *engine)
 {
-       uint64_t lrca, desc;
+       struct intel_context *ce = &ctx->engine[engine->id];
+       u64 desc;
 
-       lrca = ctx->engine[engine->id].lrc_vma->node.start +
-              LRC_PPHWSP_PN * PAGE_SIZE;
+       BUILD_BUG_ON(MAX_CONTEXT_HW_ID > (1<<GEN8_CTX_ID_WIDTH));
 
-       desc = engine->ctx_desc_template;                          /* bits  0-11 */
-       desc |= lrca;                                      /* bits 12-31 */
-       desc |= (lrca >> PAGE_SHIFT) << GEN8_CTX_ID_SHIFT; /* bits 32-51 */
+       desc = ctx->desc_template;                              /* bits  3-4  */
+       desc |= engine->ctx_desc_template;                      /* bits  0-11 */
+       desc |= ce->lrc_vma->node.start + LRC_PPHWSP_PN * PAGE_SIZE;
+                                                               /* bits 12-31 */
+       desc |= (u64)ctx->hw_id << GEN8_CTX_ID_SHIFT;           /* bits 32-52 */
 
-       ctx->engine[engine->id].lrc_desc = desc;
+       ce->lrc_desc = desc;
 }
 
-uint64_t intel_lr_context_descriptor(struct intel_context *ctx,
+uint64_t intel_lr_context_descriptor(struct i915_gem_context *ctx,
                                     struct intel_engine_cs *engine)
 {
        return ctx->engine[engine->id].lrc_desc;
 }
 
-/**
- * intel_execlists_ctx_id() - get the Execlists Context ID
- * @ctx: Context to get the ID for
- * @ring: Engine to get the ID for
- *
- * Do not confuse with ctx->id! Unfortunately we have a name overload
- * here: the old context ID we pass to userspace as a handler so that
- * they can refer to a context, and the new context ID we pass to the
- * ELSP so that the GPU can inform us of the context status via
- * interrupts.
- *
- * The context ID is a portion of the context descriptor, so we can
- * just extract the required part from the cached descriptor.
- *
- * Return: 20-bits globally unique context ID.
- */
-u32 intel_execlists_ctx_id(struct intel_context *ctx,
-                          struct intel_engine_cs *engine)
-{
-       return intel_lr_context_descriptor(ctx, engine) >> GEN8_CTX_ID_SHIFT;
-}
-
 static void execlists_elsp_write(struct drm_i915_gem_request *rq0,
                                 struct drm_i915_gem_request *rq1)
 {
 
        struct intel_engine_cs *engine = rq0->engine;
-       struct drm_device *dev = engine->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = rq0->i915;
        uint64_t desc[2];
 
        if (rq1) {
@@ -400,7 +373,7 @@ static void execlists_update_context(struct drm_i915_gem_request *rq)
        struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt;
        uint32_t *reg_state = rq->ctx->engine[engine->id].lrc_reg_state;
 
-       reg_state[CTX_RING_TAIL+1] = rq->tail;
+       reg_state[CTX_RING_TAIL+1] = intel_ring_offset(rq->ring, rq->tail);
 
        /* True 32b PPGTT with dynamic page allocation: update PDP
         * registers and point the unallocated PDPs to scratch page.
@@ -411,8 +384,8 @@ static void execlists_update_context(struct drm_i915_gem_request *rq)
                execlists_update_context_pdps(ppgtt, reg_state);
 }
 
-static void execlists_submit_requests(struct drm_i915_gem_request *rq0,
-                                     struct drm_i915_gem_request *rq1)
+static void execlists_elsp_submit_contexts(struct drm_i915_gem_request *rq0,
+                                          struct drm_i915_gem_request *rq1)
 {
        struct drm_i915_private *dev_priv = rq0->i915;
        unsigned int fw_domains = rq0->engine->fw_domains;
@@ -431,7 +404,21 @@ static void execlists_submit_requests(struct drm_i915_gem_request *rq0,
        spin_unlock_irq(&dev_priv->uncore.lock);
 }
 
-static void execlists_context_unqueue(struct intel_engine_cs *engine)
+static inline void execlists_context_status_change(
+               struct drm_i915_gem_request *rq,
+               unsigned long status)
+{
+       /*
+        * Only used when GVT-g is enabled now. When GVT-g is disabled,
+        * The compiler should eliminate this function as dead-code.
+        */
+       if (!IS_ENABLED(CONFIG_DRM_I915_GVT))
+               return;
+
+       atomic_notifier_call_chain(&rq->ctx->status_notifier, status, rq);
+}
+
+static void execlists_unqueue(struct intel_engine_cs *engine)
 {
        struct drm_i915_gem_request *req0 = NULL, *req1 = NULL;
        struct drm_i915_gem_request *cursor, *tmp;
@@ -442,7 +429,7 @@ static void execlists_context_unqueue(struct intel_engine_cs *engine)
         * If irqs are not active generate a warning as batches that finish
         * without the irqs may get lost and a GPU Hang may occur.
         */
-       WARN_ON(!intel_irqs_enabled(engine->dev->dev_private));
+       WARN_ON(!intel_irqs_enabled(engine->i915));
 
        /* Try to read in pairs */
        list_for_each_entry_safe(cursor, tmp, &engine->execlist_queue,
@@ -453,10 +440,24 @@ static void execlists_context_unqueue(struct intel_engine_cs *engine)
                        /* Same ctx: ignore first request, as second request
                         * will update tail past first request's workload */
                        cursor->elsp_submitted = req0->elsp_submitted;
-                       list_move_tail(&req0->execlist_link,
-                                      &engine->execlist_retired_req_list);
+                       list_del(&req0->execlist_link);
+                       i915_gem_request_put(req0);
                        req0 = cursor;
                } else {
+                       if (IS_ENABLED(CONFIG_DRM_I915_GVT)) {
+                               /*
+                                * req0 (after merged) ctx requires single
+                                * submission, stop picking
+                                */
+                               if (req0->ctx->execlists_force_single_submission)
+                                       break;
+                               /*
+                                * req0 ctx doesn't require single submission,
+                                * but next req ctx requires, stop picking
+                                */
+                               if (cursor->ctx->execlists_force_single_submission)
+                                       break;
+                       }
                        req1 = cursor;
                        WARN_ON(req1->elsp_submitted);
                        break;
@@ -466,6 +467,12 @@ static void execlists_context_unqueue(struct intel_engine_cs *engine)
        if (unlikely(!req0))
                return;
 
+       execlists_context_status_change(req0, INTEL_CONTEXT_SCHEDULE_IN);
+
+       if (req1)
+               execlists_context_status_change(req1,
+                                               INTEL_CONTEXT_SCHEDULE_IN);
+
        if (req0->elsp_submitted & engine->idle_lite_restore_wa) {
                /*
                 * WaIdleLiteRestore: make sure we never cause a lite restore
@@ -475,18 +482,15 @@ static void execlists_context_unqueue(struct intel_engine_cs *engine)
                 * resubmit the request. See gen8_emit_request() for where we
                 * prepare the padding after the end of the request.
                 */
-               struct intel_ringbuffer *ringbuf;
-
-               ringbuf = req0->ctx->engine[engine->id].ringbuf;
                req0->tail += 8;
-               req0->tail &= ringbuf->size - 1;
+               req0->tail &= req0->ring->size - 1;
        }
 
-       execlists_submit_requests(req0, req1);
+       execlists_elsp_submit_contexts(req0, req1);
 }
 
 static unsigned int
-execlists_check_remove_request(struct intel_engine_cs *engine, u32 request_id)
+execlists_check_remove_request(struct intel_engine_cs *engine, u32 ctx_id)
 {
        struct drm_i915_gem_request *head_req;
 
@@ -496,19 +500,18 @@ execlists_check_remove_request(struct intel_engine_cs *engine, u32 request_id)
                                            struct drm_i915_gem_request,
                                            execlist_link);
 
-       if (!head_req)
-               return 0;
-
-       if (unlikely(intel_execlists_ctx_id(head_req->ctx, engine) != request_id))
-               return 0;
+       if (WARN_ON(!head_req || (head_req->ctx_hw_id != ctx_id)))
+               return 0;
 
        WARN(head_req->elsp_submitted == 0, "Never submitted head request\n");
 
        if (--head_req->elsp_submitted > 0)
                return 0;
 
-       list_move_tail(&head_req->execlist_link,
-                      &engine->execlist_retired_req_list);
+       execlists_context_status_change(head_req, INTEL_CONTEXT_SCHEDULE_OUT);
+
+       list_del(&head_req->execlist_link);
+       i915_gem_request_put(head_req);
 
        return 1;
 }
@@ -517,7 +520,7 @@ static u32
 get_context_status(struct intel_engine_cs *engine, unsigned int read_pointer,
                   u32 *context_id)
 {
-       struct drm_i915_private *dev_priv = engine->dev->dev_private;
+       struct drm_i915_private *dev_priv = engine->i915;
        u32 status;
 
        read_pointer %= GEN8_CSB_ENTRIES;
@@ -533,17 +536,14 @@ get_context_status(struct intel_engine_cs *engine, unsigned int read_pointer,
        return status;
 }
 
-/**
- * intel_lrc_irq_handler() - handle Context Switch interrupts
- * @engine: Engine Command Streamer to handle.
- *
+/*
  * Check the unread Context Status Buffers and manage the submission of new
  * contexts to the ELSP accordingly.
  */
 static void intel_lrc_irq_handler(unsigned long data)
 {
        struct intel_engine_cs *engine = (struct intel_engine_cs *)data;
-       struct drm_i915_private *dev_priv = engine->dev->dev_private;
+       struct drm_i915_private *dev_priv = engine->i915;
        u32 status_pointer;
        unsigned int read_pointer, write_pointer;
        u32 csb[GEN8_CSB_ENTRIES][2];
@@ -597,7 +597,7 @@ static void intel_lrc_irq_handler(unsigned long data)
        if (submit_contexts) {
                if (!engine->disable_lite_restore_wa ||
                    (csb[i][0] & GEN8_CTX_STATUS_ACTIVE_IDLE))
-                       execlists_context_unqueue(engine);
+                       execlists_unqueue(engine);
        }
 
        spin_unlock(&engine->execlist_lock);
@@ -606,17 +606,12 @@ static void intel_lrc_irq_handler(unsigned long data)
                DRM_ERROR("More than two context complete events?\n");
 }
 
-static void execlists_context_queue(struct drm_i915_gem_request *request)
+static void execlists_submit_request(struct drm_i915_gem_request *request)
 {
        struct intel_engine_cs *engine = request->engine;
        struct drm_i915_gem_request *cursor;
        int num_elements = 0;
 
-       if (request->ctx != request->i915->kernel_context)
-               intel_lr_context_pin(request->ctx, engine);
-
-       i915_gem_request_reference(request);
-
        spin_lock_bh(&engine->execlist_lock);
 
        list_for_each_entry(cursor, &engine->execlist_queue, execlist_link)
@@ -633,74 +628,39 @@ static void execlists_context_queue(struct drm_i915_gem_request *request)
                if (request->ctx == tail_req->ctx) {
                        WARN(tail_req->elsp_submitted != 0,
                                "More than 2 already-submitted reqs queued\n");
-                       list_move_tail(&tail_req->execlist_link,
-                                      &engine->execlist_retired_req_list);
+                       list_del(&tail_req->execlist_link);
+                       i915_gem_request_put(tail_req);
                }
        }
 
+       i915_gem_request_get(request);
        list_add_tail(&request->execlist_link, &engine->execlist_queue);
+       request->ctx_hw_id = request->ctx->hw_id;
        if (num_elements == 0)
-               execlists_context_unqueue(engine);
+               execlists_unqueue(engine);
 
        spin_unlock_bh(&engine->execlist_lock);
 }
 
-static int logical_ring_invalidate_all_caches(struct drm_i915_gem_request *req)
-{
-       struct intel_engine_cs *engine = req->engine;
-       uint32_t flush_domains;
-       int ret;
-
-       flush_domains = 0;
-       if (engine->gpu_caches_dirty)
-               flush_domains = I915_GEM_GPU_DOMAINS;
-
-       ret = engine->emit_flush(req, I915_GEM_GPU_DOMAINS, flush_domains);
-       if (ret)
-               return ret;
-
-       engine->gpu_caches_dirty = false;
-       return 0;
-}
-
-static int execlists_move_to_gpu(struct drm_i915_gem_request *req,
-                                struct list_head *vmas)
+int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request)
 {
-       const unsigned other_rings = ~intel_engine_flag(req->engine);
-       struct i915_vma *vma;
-       uint32_t flush_domains = 0;
-       bool flush_chipset = false;
+       struct intel_engine_cs *engine = request->engine;
+       struct intel_context *ce = &request->ctx->engine[engine->id];
        int ret;
 
-       list_for_each_entry(vma, vmas, exec_list) {
-               struct drm_i915_gem_object *obj = vma->obj;
-
-               if (obj->active & other_rings) {
-                       ret = i915_gem_object_sync(obj, req->engine, &req);
-                       if (ret)
-                               return ret;
-               }
-
-               if (obj->base.write_domain & I915_GEM_DOMAIN_CPU)
-                       flush_chipset |= i915_gem_clflush_object(obj, false);
-
-               flush_domains |= obj->base.write_domain;
-       }
-
-       if (flush_domains & I915_GEM_DOMAIN_GTT)
-               wmb();
-
-       /* Unconditionally invalidate gpu caches and ensure that we do flush
-        * any residual writes from the previous batch.
+       /* Flush enough space to reduce the likelihood of waiting after
+        * we start building the request - in which case we will just
+        * have to repeat work.
         */
-       return logical_ring_invalidate_all_caches(req);
-}
+       request->reserved_space += EXECLISTS_REQUEST_SIZE;
 
-int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request)
-{
-       int ret = 0;
+       if (!ce->state) {
+               ret = execlists_context_deferred_alloc(request->ctx, engine);
+               if (ret)
+                       return ret;
+       }
 
-       request->ringbuf = request->ctx->engine[request->engine->id].ringbuf;
+       request->ring = ce->ring;
 
        if (i915.enable_guc_submission) {
                /*
@@ -708,21 +668,44 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request
                 * going any further, as the i915_add_request() call
                 * later on mustn't fail ...
                 */
-               struct intel_guc *guc = &request->i915->guc;
-
-               ret = i915_guc_wq_check_space(guc->execbuf_client);
+               ret = i915_guc_wq_check_space(request);
                if (ret)
                        return ret;
        }
 
-       if (request->ctx != request->i915->kernel_context)
-               ret = intel_lr_context_pin(request->ctx, request->engine);
+       ret = intel_lr_context_pin(request->ctx, engine);
+       if (ret)
+               return ret;
+
+       ret = intel_ring_begin(request, 0);
+       if (ret)
+               goto err_unpin;
+
+       if (!ce->initialised) {
+               ret = engine->init_context(request);
+               if (ret)
+                       goto err_unpin;
+
+               ce->initialised = true;
+       }
+
+       /* Note that after this point, we have committed to using
+        * this request as it is being used to both track the
+        * state of engine initialisation and liveness of the
+        * golden renderstate above. Think twice before you try
+        * to cancel/unwind this request now.
+        */
+
+       request->reserved_space -= EXECLISTS_REQUEST_SIZE;
+       return 0;
 
+err_unpin:
+       intel_lr_context_unpin(request->ctx, engine);
        return ret;
 }
 
 /*
- * intel_logical_ring_advance_and_submit() - advance the tail and submit the workload
+ * intel_logical_ring_advance() - advance the tail and prepare for submission
  * @request: Request to advance the logical ringbuffer of.
  *
  * The tail is updated in our logical ringbuffer struct, not in the actual context. What
@@ -731,14 +714,13 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request
  * point, the tail *inside* the context is updated and the ELSP written to.
  */
 static int
-intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request)
+intel_logical_ring_advance(struct drm_i915_gem_request *request)
 {
-       struct intel_ringbuffer *ringbuf = request->ringbuf;
-       struct drm_i915_private *dev_priv = request->i915;
+       struct intel_ring *ring = request->ring;
        struct intel_engine_cs *engine = request->engine;
 
-       intel_logical_ring_advance(ringbuf);
-       request->tail = ringbuf->tail;
+       intel_ring_advance(ring);
+       request->tail = ring->tail;
 
        /*
         * Here we add two extra NOOPs as padding to avoid
@@ -746,225 +728,59 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request)
         *
         * Caller must reserve WA_TAIL_DWORDS for us!
         */
-       intel_logical_ring_emit(ringbuf, MI_NOOP);
-       intel_logical_ring_emit(ringbuf, MI_NOOP);
-       intel_logical_ring_advance(ringbuf);
-
-       if (intel_engine_stopped(engine))
-               return 0;
-
-       if (engine->last_context != request->ctx) {
-               if (engine->last_context)
-                       intel_lr_context_unpin(engine->last_context, engine);
-               if (request->ctx != request->i915->kernel_context) {
-                       intel_lr_context_pin(request->ctx, engine);
-                       engine->last_context = request->ctx;
-               } else {
-                       engine->last_context = NULL;
-               }
-       }
-
-       if (dev_priv->guc.execbuf_client)
-               i915_guc_submit(dev_priv->guc.execbuf_client, request);
-       else
-               execlists_context_queue(request);
-
-       return 0;
-}
-
-int intel_logical_ring_reserve_space(struct drm_i915_gem_request *request)
-{
-       /*
-        * The first call merely notes the reserve request and is common for
-        * all back ends. The subsequent localised _begin() call actually
-        * ensures that the reservation is available. Without the begin, if
-        * the request creator immediately submitted the request without
-        * adding any commands to it then there might not actually be
-        * sufficient room for the submission commands.
+       intel_ring_emit(ring, MI_NOOP);
+       intel_ring_emit(ring, MI_NOOP);
+       intel_ring_advance(ring);
+
+       /* We keep the previous context alive until we retire the following
+        * request. This ensures that any the context object is still pinned
+        * for any residual writes the HW makes into it on the context switch
+        * into the next object following the breadcrumb. Otherwise, we may
+        * retire the context too early.
         */
-       intel_ring_reserved_space_reserve(request->ringbuf, MIN_SPACE_FOR_ADD_REQUEST);
-
-       return intel_ring_begin(request, 0);
-}
-
-/**
- * execlists_submission() - submit a batchbuffer for execution, Execlists style
- * @dev: DRM device.
- * @file: DRM file.
- * @ring: Engine Command Streamer to submit to.
- * @ctx: Context to employ for this submission.
- * @args: execbuffer call arguments.
- * @vmas: list of vmas.
- * @batch_obj: the batchbuffer to submit.
- * @exec_start: batchbuffer start virtual address pointer.
- * @dispatch_flags: translated execbuffer call flags.
- *
- * This is the evil twin version of i915_gem_ringbuffer_submission. It abstracts
- * away the submission details of the execbuffer ioctl call.
- *
- * Return: non-zero if the submission fails.
- */
-int intel_execlists_submission(struct i915_execbuffer_params *params,
-                              struct drm_i915_gem_execbuffer2 *args,
-                              struct list_head *vmas)
-{
-       struct drm_device       *dev = params->dev;
-       struct intel_engine_cs *engine = params->engine;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_ringbuffer *ringbuf = params->ctx->engine[engine->id].ringbuf;
-       u64 exec_start;
-       int instp_mode;
-       u32 instp_mask;
-       int ret;
-
-       instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
-       instp_mask = I915_EXEC_CONSTANTS_MASK;
-       switch (instp_mode) {
-       case I915_EXEC_CONSTANTS_REL_GENERAL:
-       case I915_EXEC_CONSTANTS_ABSOLUTE:
-       case I915_EXEC_CONSTANTS_REL_SURFACE:
-               if (instp_mode != 0 && engine != &dev_priv->engine[RCS]) {
-                       DRM_DEBUG("non-0 rel constants mode on non-RCS\n");
-                       return -EINVAL;
-               }
-
-               if (instp_mode != dev_priv->relative_constants_mode) {
-                       if (instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
-                               DRM_DEBUG("rel surface constants mode invalid on gen5+\n");
-                               return -EINVAL;
-                       }
-
-                       /* The HW changed the meaning on this bit on gen6 */
-                       instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
-               }
-               break;
-       default:
-               DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode);
-               return -EINVAL;
-       }
-
-       if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
-               DRM_DEBUG("sol reset is gen7 only\n");
-               return -EINVAL;
-       }
-
-       ret = execlists_move_to_gpu(params->request, vmas);
-       if (ret)
-               return ret;
-
-       if (engine == &dev_priv->engine[RCS] &&
-           instp_mode != dev_priv->relative_constants_mode) {
-               ret = intel_ring_begin(params->request, 4);
-               if (ret)
-                       return ret;
-
-               intel_logical_ring_emit(ringbuf, MI_NOOP);
-               intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(1));
-               intel_logical_ring_emit_reg(ringbuf, INSTPM);
-               intel_logical_ring_emit(ringbuf, instp_mask << 16 | instp_mode);
-               intel_logical_ring_advance(ringbuf);
-
-               dev_priv->relative_constants_mode = instp_mode;
-       }
-
-       exec_start = params->batch_obj_vm_offset +
-                    args->batch_start_offset;
-
-       ret = engine->emit_bb_start(params->request, exec_start, params->dispatch_flags);
-       if (ret)
-               return ret;
-
-       trace_i915_gem_ring_dispatch(params->request, params->dispatch_flags);
-
-       i915_gem_execbuffer_move_to_active(vmas, params->request);
-
+       request->previous_context = engine->last_context;
+       engine->last_context = request->ctx;
        return 0;
 }
 
-void intel_execlists_retire_requests(struct intel_engine_cs *engine)
+void intel_execlists_cancel_requests(struct intel_engine_cs *engine)
 {
        struct drm_i915_gem_request *req, *tmp;
-       struct list_head retired_list;
+       LIST_HEAD(cancel_list);
 
-       WARN_ON(!mutex_is_locked(&engine->dev->struct_mutex));
-       if (list_empty(&engine->execlist_retired_req_list))
-               return;
+       WARN_ON(!mutex_is_locked(&engine->i915->drm.struct_mutex));
 
-       INIT_LIST_HEAD(&retired_list);
        spin_lock_bh(&engine->execlist_lock);
-       list_replace_init(&engine->execlist_retired_req_list, &retired_list);
+       list_replace_init(&engine->execlist_queue, &cancel_list);
        spin_unlock_bh(&engine->execlist_lock);
 
-       list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) {
-               struct intel_context *ctx = req->ctx;
-               struct drm_i915_gem_object *ctx_obj =
-                               ctx->engine[engine->id].state;
-
-               if (ctx_obj && (ctx != req->i915->kernel_context))
-                       intel_lr_context_unpin(ctx, engine);
-
+       list_for_each_entry_safe(req, tmp, &cancel_list, execlist_link) {
                list_del(&req->execlist_link);
-               i915_gem_request_unreference(req);
+               i915_gem_request_put(req);
        }
 }
 
-void intel_logical_ring_stop(struct intel_engine_cs *engine)
-{
-       struct drm_i915_private *dev_priv = engine->dev->dev_private;
-       int ret;
-
-       if (!intel_engine_initialized(engine))
-               return;
-
-       ret = intel_engine_idle(engine);
-       if (ret)
-               DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n",
-                         engine->name, ret);
-
-       /* TODO: Is this correct with Execlists enabled? */
-       I915_WRITE_MODE(engine, _MASKED_BIT_ENABLE(STOP_RING));
-       if (wait_for((I915_READ_MODE(engine) & MODE_IDLE) != 0, 1000)) {
-               DRM_ERROR("%s :timed out trying to stop ring\n", engine->name);
-               return;
-       }
-       I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING));
-}
-
-int logical_ring_flush_all_caches(struct drm_i915_gem_request *req)
-{
-       struct intel_engine_cs *engine = req->engine;
-       int ret;
-
-       if (!engine->gpu_caches_dirty)
-               return 0;
-
-       ret = engine->emit_flush(req, 0, I915_GEM_GPU_DOMAINS);
-       if (ret)
-               return ret;
-
-       engine->gpu_caches_dirty = false;
-       return 0;
-}
-
-static int intel_lr_context_do_pin(struct intel_context *ctx,
-                                  struct intel_engine_cs *engine)
+static int intel_lr_context_pin(struct i915_gem_context *ctx,
+                               struct intel_engine_cs *engine)
 {
-       struct drm_device *dev = engine->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state;
-       struct intel_ringbuffer *ringbuf = ctx->engine[engine->id].ringbuf;
+       struct drm_i915_private *dev_priv = ctx->i915;
+       struct intel_context *ce = &ctx->engine[engine->id];
        void *vaddr;
        u32 *lrc_reg_state;
        int ret;
 
-       WARN_ON(!mutex_is_locked(&engine->dev->struct_mutex));
+       lockdep_assert_held(&ctx->i915->drm.struct_mutex);
 
-       ret = i915_gem_obj_ggtt_pin(ctx_obj, GEN8_LR_CONTEXT_ALIGN,
-                       PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
+       if (ce->pin_count++)
+               return 0;
+
+       ret = i915_gem_object_ggtt_pin(ce->state, NULL,
+                                      0, GEN8_LR_CONTEXT_ALIGN,
+                                      PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
        if (ret)
-               return ret;
+               goto err;
 
-       vaddr = i915_gem_object_pin_map(ctx_obj);
+       vaddr = i915_gem_object_pin_map(ce->state);
        if (IS_ERR(vaddr)) {
                ret = PTR_ERR(vaddr);
                goto unpin_ctx_obj;
@@ -972,81 +788,66 @@ static int intel_lr_context_do_pin(struct intel_context *ctx,
 
        lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
 
-       ret = intel_pin_and_map_ringbuffer_obj(engine->dev, ringbuf);
+       ret = intel_ring_pin(ce->ring);
        if (ret)
                goto unpin_map;
 
-       ctx->engine[engine->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj);
+       ce->lrc_vma = i915_gem_obj_to_ggtt(ce->state);
        intel_lr_context_descriptor_update(ctx, engine);
-       lrc_reg_state[CTX_RING_BUFFER_START+1] = ringbuf->vma->node.start;
-       ctx->engine[engine->id].lrc_reg_state = lrc_reg_state;
-       ctx_obj->dirty = true;
+
+       lrc_reg_state[CTX_RING_BUFFER_START+1] = ce->ring->vma->node.start;
+       ce->lrc_reg_state = lrc_reg_state;
+       ce->state->dirty = true;
 
        /* Invalidate GuC TLB. */
        if (i915.enable_guc_submission)
                I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
 
-       return ret;
+       i915_gem_context_get(ctx);
+       return 0;
 
 unpin_map:
-       i915_gem_object_unpin_map(ctx_obj);
+       i915_gem_object_unpin_map(ce->state);
 unpin_ctx_obj:
-       i915_gem_object_ggtt_unpin(ctx_obj);
-
+       i915_gem_object_ggtt_unpin(ce->state);
+err:
+       ce->pin_count = 0;
        return ret;
 }
 
-static int intel_lr_context_pin(struct intel_context *ctx,
-                               struct intel_engine_cs *engine)
+void intel_lr_context_unpin(struct i915_gem_context *ctx,
+                           struct intel_engine_cs *engine)
 {
-       int ret = 0;
+       struct intel_context *ce = &ctx->engine[engine->id];
 
-       if (ctx->engine[engine->id].pin_count++ == 0) {
-               ret = intel_lr_context_do_pin(ctx, engine);
-               if (ret)
-                       goto reset_pin_count;
+       lockdep_assert_held(&ctx->i915->drm.struct_mutex);
+       GEM_BUG_ON(ce->pin_count == 0);
 
-               i915_gem_context_reference(ctx);
-       }
-       return ret;
+       if (--ce->pin_count)
+               return;
 
-reset_pin_count:
-       ctx->engine[engine->id].pin_count = 0;
-       return ret;
-}
+       intel_ring_unpin(ce->ring);
 
-void intel_lr_context_unpin(struct intel_context *ctx,
-                           struct intel_engine_cs *engine)
-{
-       struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state;
+       i915_gem_object_unpin_map(ce->state);
+       i915_gem_object_ggtt_unpin(ce->state);
 
-       WARN_ON(!mutex_is_locked(&ctx->i915->dev->struct_mutex));
-       if (--ctx->engine[engine->id].pin_count == 0) {
-               i915_gem_object_unpin_map(ctx_obj);
-               intel_unpin_ringbuffer_obj(ctx->engine[engine->id].ringbuf);
-               i915_gem_object_ggtt_unpin(ctx_obj);
-               ctx->engine[engine->id].lrc_vma = NULL;
-               ctx->engine[engine->id].lrc_desc = 0;
-               ctx->engine[engine->id].lrc_reg_state = NULL;
+       ce->lrc_vma = NULL;
+       ce->lrc_desc = 0;
+       ce->lrc_reg_state = NULL;
 
-               i915_gem_context_unreference(ctx);
-       }
+       i915_gem_context_put(ctx);
 }
 
 static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req)
 {
        int ret, i;
-       struct intel_engine_cs *engine = req->engine;
-       struct intel_ringbuffer *ringbuf = req->ringbuf;
-       struct drm_device *dev = engine->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct i915_workarounds *w = &dev_priv->workarounds;
+       struct intel_ring *ring = req->ring;
+       struct i915_workarounds *w = &req->i915->workarounds;
 
        if (w->count == 0)
                return 0;
 
-       engine->gpu_caches_dirty = true;
-       ret = logical_ring_flush_all_caches(req);
+       ret = req->engine->emit_flush(req, EMIT_BARRIER);
        if (ret)
                return ret;
 
@@ -1054,17 +855,16 @@ static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req)
        if (ret)
                return ret;
 
-       intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(w->count));
+       intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(w->count));
        for (i = 0; i < w->count; i++) {
-               intel_logical_ring_emit_reg(ringbuf, w->reg[i].addr);
-               intel_logical_ring_emit(ringbuf, w->reg[i].value);
+               intel_ring_emit_reg(ring, w->reg[i].addr);
+               intel_ring_emit(ring, w->reg[i].value);
        }
-       intel_logical_ring_emit(ringbuf, MI_NOOP);
+       intel_ring_emit(ring, MI_NOOP);
 
-       intel_logical_ring_advance(ringbuf);
+       intel_ring_advance(ring);
 
-       engine->gpu_caches_dirty = true;
-       ret = logical_ring_flush_all_caches(req);
+       ret = req->engine->emit_flush(req, EMIT_BARRIER);
        if (ret)
                return ret;
 
@@ -1100,10 +900,10 @@ static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req)
  * code duplication.
  */
 static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine,
-                                               uint32_t *const batch,
+                                               uint32_t *batch,
                                                uint32_t index)
 {
-       struct drm_i915_private *dev_priv = engine->dev->dev_private;
+       struct drm_i915_private *dev_priv = engine->i915;
        uint32_t l3sqc4_flush = (0x40400000 | GEN8_LQSC_FLUSH_COHERENT_LINES);
 
        /*
@@ -1162,37 +962,24 @@ static inline int wa_ctx_end(struct i915_wa_ctx_bb *wa_ctx,
        return 0;
 }
 
-/**
- * gen8_init_indirectctx_bb() - initialize indirect ctx batch with WA
- *
- * @ring: only applicable for RCS
- * @wa_ctx: structure representing wa_ctx
- *  offset: specifies start of the batch, should be cache-aligned. This is updated
- *    with the offset value received as input.
- *  size: size of the batch in DWORDS but HW expects in terms of cachelines
- * @batch: page in which WA are loaded
- * @offset: This field specifies the start of the batch, it should be
- *  cache-aligned otherwise it is adjusted accordingly.
- *  Typically we only have one indirect_ctx and per_ctx batch buffer which are
- *  initialized at the beginning and shared across all contexts but this field
- *  helps us to have multiple batches at different offsets and select them based
- *  on a criteria. At the moment this batch always start at the beginning of the page
- *  and at this point we don't have multiple wa_ctx batch buffers.
- *
- *  The number of WA applied are not known at the beginning; we use this field
- *  to return the no of DWORDS written.
+/*
+ * Typically we only have one indirect_ctx and per_ctx batch buffer which are
+ * initialized at the beginning and shared across all contexts but this field
+ * helps us to have multiple batches at different offsets and select them based
+ * on a criteria. At the moment this batch always start at the beginning of the page
+ * and at this point we don't have multiple wa_ctx batch buffers.
  *
- *  It is to be noted that this batch does not contain MI_BATCH_BUFFER_END
- *  so it adds NOOPs as padding to make it cacheline aligned.
- *  MI_BATCH_BUFFER_END will be added to perctx batch and both of them together
- *  makes a complete batch buffer.
+ * The number of WA applied are not known at the beginning; we use this field
+ * to return the no of DWORDS written.
  *
- * Return: non-zero if we exceed the PAGE_SIZE limit.
+ * It is to be noted that this batch does not contain MI_BATCH_BUFFER_END
+ * so it adds NOOPs as padding to make it cacheline aligned.
+ * MI_BATCH_BUFFER_END will be added to perctx batch and both of them together
+ * makes a complete batch buffer.
  */
-
 static int gen8_init_indirectctx_bb(struct intel_engine_cs *engine,
                                    struct i915_wa_ctx_bb *wa_ctx,
-                                   uint32_t *const batch,
+                                   uint32_t *batch,
                                    uint32_t *offset)
 {
        uint32_t scratch_addr;
@@ -1202,7 +989,7 @@ static int gen8_init_indirectctx_bb(struct intel_engine_cs *engine,
        wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_DISABLE);
 
        /* WaFlushCoherentL3CacheLinesAtContextSwitch:bdw */
-       if (IS_BROADWELL(engine->dev)) {
+       if (IS_BROADWELL(engine->i915)) {
                int rc = gen8_emit_flush_coherentl3_wa(engine, batch, index);
                if (rc < 0)
                        return rc;
@@ -1236,26 +1023,18 @@ static int gen8_init_indirectctx_bb(struct intel_engine_cs *engine,
        return wa_ctx_end(wa_ctx, *offset = index, CACHELINE_DWORDS);
 }
 
-/**
- * gen8_init_perctx_bb() - initialize per ctx batch with WA
- *
- * @ring: only applicable for RCS
- * @wa_ctx: structure representing wa_ctx
- *  offset: specifies start of the batch, should be cache-aligned.
- *  size: size of the batch in DWORDS but HW expects in terms of cachelines
- * @batch: page in which WA are loaded
- * @offset: This field specifies the start of this batch.
- *   This batch is started immediately after indirect_ctx batch. Since we ensure
- *   that indirect_ctx ends on a cacheline this batch is aligned automatically.
+/*
+ *  This batch is started immediately after indirect_ctx batch. Since we ensure
+ *  that indirect_ctx ends on a cacheline this batch is aligned automatically.
  *
- *   The number of DWORDS written are returned using this field.
+ *  The number of DWORDS written are returned using this field.
  *
  *  This batch is terminated with MI_BATCH_BUFFER_END and so we need not add padding
  *  to align it with cacheline as padding after MI_BATCH_BUFFER_END is redundant.
  */
 static int gen8_init_perctx_bb(struct intel_engine_cs *engine,
                               struct i915_wa_ctx_bb *wa_ctx,
-                              uint32_t *const batch,
+                              uint32_t *batch,
                               uint32_t *offset)
 {
        uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS);
@@ -1270,16 +1049,16 @@ static int gen8_init_perctx_bb(struct intel_engine_cs *engine,
 
 static int gen9_init_indirectctx_bb(struct intel_engine_cs *engine,
                                    struct i915_wa_ctx_bb *wa_ctx,
-                                   uint32_t *const batch,
+                                   uint32_t *batch,
                                    uint32_t *offset)
 {
        int ret;
-       struct drm_device *dev = engine->dev;
+       struct drm_i915_private *dev_priv = engine->i915;
        uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS);
 
        /* WaDisableCtxRestoreArbitration:skl,bxt */
-       if (IS_SKL_REVID(dev, 0, SKL_REVID_D0) ||
-           IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+       if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_D0) ||
+           IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
                wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_DISABLE);
 
        /* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt */
@@ -1288,6 +1067,54 @@ static int gen9_init_indirectctx_bb(struct intel_engine_cs *engine,
                return ret;
        index = ret;
 
+       /* WaDisableGatherAtSetShaderCommonSlice:skl,bxt,kbl */
+       wa_ctx_emit(batch, index, MI_LOAD_REGISTER_IMM(1));
+       wa_ctx_emit_reg(batch, index, COMMON_SLICE_CHICKEN2);
+       wa_ctx_emit(batch, index, _MASKED_BIT_DISABLE(
+                           GEN9_DISABLE_GATHER_AT_SET_SHADER_COMMON_SLICE));
+       wa_ctx_emit(batch, index, MI_NOOP);
+
+       /* WaClearSlmSpaceAtContextSwitch:kbl */
+       /* Actual scratch location is at 128 bytes offset */
+       if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0)) {
+               uint32_t scratch_addr
+                       = engine->scratch.gtt_offset + 2*CACHELINE_BYTES;
+
+               wa_ctx_emit(batch, index, GFX_OP_PIPE_CONTROL(6));
+               wa_ctx_emit(batch, index, (PIPE_CONTROL_FLUSH_L3 |
+                                          PIPE_CONTROL_GLOBAL_GTT_IVB |
+                                          PIPE_CONTROL_CS_STALL |
+                                          PIPE_CONTROL_QW_WRITE));
+               wa_ctx_emit(batch, index, scratch_addr);
+               wa_ctx_emit(batch, index, 0);
+               wa_ctx_emit(batch, index, 0);
+               wa_ctx_emit(batch, index, 0);
+       }
+
+       /* WaMediaPoolStateCmdInWABB:bxt */
+       if (HAS_POOLED_EU(engine->i915)) {
+               /*
+                * EU pool configuration is setup along with golden context
+                * during context initialization. This value depends on
+                * device type (2x6 or 3x6) and needs to be updated based
+                * on which subslice is disabled especially for 2x6
+                * devices, however it is safe to load default
+                * configuration of 3x6 device instead of masking off
+                * corresponding bits because HW ignores bits of a disabled
+                * subslice and drops down to appropriate config. Please
+                * see render_state_setup() in i915_gem_render_state.c for
+                * possible configurations, to avoid duplication they are
+                * not shown here again.
+                */
+               u32 eu_pool_config = 0x00777000;
+               wa_ctx_emit(batch, index, GEN9_MEDIA_POOL_STATE);
+               wa_ctx_emit(batch, index, GEN9_MEDIA_POOL_ENABLE);
+               wa_ctx_emit(batch, index, eu_pool_config);
+               wa_ctx_emit(batch, index, 0);
+               wa_ctx_emit(batch, index, 0);
+               wa_ctx_emit(batch, index, 0);
+       }
+
        /* Pad to end of cacheline */
        while (index % CACHELINE_DWORDS)
                wa_ctx_emit(batch, index, MI_NOOP);
@@ -1297,15 +1124,14 @@ static int gen9_init_indirectctx_bb(struct intel_engine_cs *engine,
 
 static int gen9_init_perctx_bb(struct intel_engine_cs *engine,
                               struct i915_wa_ctx_bb *wa_ctx,
-                              uint32_t *const batch,
+                              uint32_t *batch,
                               uint32_t *offset)
 {
-       struct drm_device *dev = engine->dev;
        uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS);
 
        /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl,bxt */
-       if (IS_SKL_REVID(dev, 0, SKL_REVID_B0) ||
-           IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+       if (IS_SKL_REVID(engine->i915, 0, SKL_REVID_B0) ||
+           IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1)) {
                wa_ctx_emit(batch, index, MI_LOAD_REGISTER_IMM(1));
                wa_ctx_emit_reg(batch, index, GEN9_SLICE_COMMON_ECO_CHICKEN0);
                wa_ctx_emit(batch, index,
@@ -1314,7 +1140,7 @@ static int gen9_init_perctx_bb(struct intel_engine_cs *engine,
        }
 
        /* WaClearTdlStateAckDirtyBits:bxt */
-       if (IS_BXT_REVID(dev, 0, BXT_REVID_B0)) {
+       if (IS_BXT_REVID(engine->i915, 0, BXT_REVID_B0)) {
                wa_ctx_emit(batch, index, MI_LOAD_REGISTER_IMM(4));
 
                wa_ctx_emit_reg(batch, index, GEN8_STATE_ACK);
@@ -1333,8 +1159,8 @@ static int gen9_init_perctx_bb(struct intel_engine_cs *engine,
        }
 
        /* WaDisableCtxRestoreArbitration:skl,bxt */
-       if (IS_SKL_REVID(dev, 0, SKL_REVID_D0) ||
-           IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+       if (IS_SKL_REVID(engine->i915, 0, SKL_REVID_D0) ||
+           IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1))
                wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_ENABLE);
 
        wa_ctx_emit(batch, index, MI_BATCH_BUFFER_END);
@@ -1346,18 +1172,21 @@ static int lrc_setup_wa_ctx_obj(struct intel_engine_cs *engine, u32 size)
 {
        int ret;
 
-       engine->wa_ctx.obj = i915_gem_alloc_object(engine->dev,
-                                                  PAGE_ALIGN(size));
-       if (!engine->wa_ctx.obj) {
+       engine->wa_ctx.obj = i915_gem_object_create(&engine->i915->drm,
+                                                   PAGE_ALIGN(size));
+       if (IS_ERR(engine->wa_ctx.obj)) {
                DRM_DEBUG_DRIVER("alloc LRC WA ctx backing obj failed.\n");
-               return -ENOMEM;
+               ret = PTR_ERR(engine->wa_ctx.obj);
+               engine->wa_ctx.obj = NULL;
+               return ret;
        }
 
-       ret = i915_gem_obj_ggtt_pin(engine->wa_ctx.obj, PAGE_SIZE, 0);
+       ret = i915_gem_object_ggtt_pin(engine->wa_ctx.obj, NULL,
+                                      0, PAGE_SIZE, 0);
        if (ret) {
                DRM_DEBUG_DRIVER("pin LRC WA ctx backing obj failed: %d\n",
                                 ret);
-               drm_gem_object_unreference(&engine->wa_ctx.obj->base);
+               i915_gem_object_put(engine->wa_ctx.obj);
                return ret;
        }
 
@@ -1368,7 +1197,7 @@ static void lrc_destroy_wa_ctx_obj(struct intel_engine_cs *engine)
 {
        if (engine->wa_ctx.obj) {
                i915_gem_object_ggtt_unpin(engine->wa_ctx.obj);
-               drm_gem_object_unreference(&engine->wa_ctx.obj->base);
+               i915_gem_object_put(engine->wa_ctx.obj);
                engine->wa_ctx.obj = NULL;
        }
 }
@@ -1384,9 +1213,9 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
        WARN_ON(engine->id != RCS);
 
        /* update this when WA for higher Gen are added */
-       if (INTEL_INFO(engine->dev)->gen > 9) {
+       if (INTEL_GEN(engine->i915) > 9) {
                DRM_ERROR("WA batch buffer is not initialized for Gen%d\n",
-                         INTEL_INFO(engine->dev)->gen);
+                         INTEL_GEN(engine->i915));
                return 0;
        }
 
@@ -1406,7 +1235,7 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
        batch = kmap_atomic(page);
        offset = 0;
 
-       if (INTEL_INFO(engine->dev)->gen == 8) {
+       if (IS_GEN8(engine->i915)) {
                ret = gen8_init_indirectctx_bb(engine,
                                               &wa_ctx->indirect_ctx,
                                               batch,
@@ -1420,7 +1249,7 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
                                          &offset);
                if (ret)
                        goto out;
-       } else if (INTEL_INFO(engine->dev)->gen == 9) {
+       } else if (IS_GEN9(engine->i915)) {
                ret = gen9_init_indirectctx_bb(engine,
                                               &wa_ctx->indirect_ctx,
                                               batch,
@@ -1446,7 +1275,7 @@ out:
 
 static void lrc_init_hws(struct intel_engine_cs *engine)
 {
-       struct drm_i915_private *dev_priv = engine->dev->dev_private;
+       struct drm_i915_private *dev_priv = engine->i915;
 
        I915_WRITE(RING_HWS_PGA(engine->mmio_base),
                   (u32)engine->status_page.gfx_addr);
@@ -1455,8 +1284,7 @@ static void lrc_init_hws(struct intel_engine_cs *engine)
 
 static int gen8_init_common_ring(struct intel_engine_cs *engine)
 {
-       struct drm_device *dev = engine->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = engine->i915;
        unsigned int next_context_status_buffer_hw;
 
        lrc_init_hws(engine);
@@ -1503,8 +1331,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)
 
 static int gen8_init_render_ring(struct intel_engine_cs *engine)
 {
-       struct drm_device *dev = engine->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = engine->i915;
        int ret;
 
        ret = gen8_init_common_ring(engine);
@@ -1538,8 +1365,8 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine)
 static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req)
 {
        struct i915_hw_ppgtt *ppgtt = req->ctx->ppgtt;
+       struct intel_ring *ring = req->ring;
        struct intel_engine_cs *engine = req->engine;
-       struct intel_ringbuffer *ringbuf = req->ringbuf;
        const int num_lri_cmds = GEN8_LEGACY_PDPES * 2;
        int i, ret;
 
@@ -1547,28 +1374,27 @@ static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req)
        if (ret)
                return ret;
 
-       intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(num_lri_cmds));
+       intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_lri_cmds));
        for (i = GEN8_LEGACY_PDPES - 1; i >= 0; i--) {
                const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i);
 
-               intel_logical_ring_emit_reg(ringbuf,
-                                           GEN8_RING_PDP_UDW(engine, i));
-               intel_logical_ring_emit(ringbuf, upper_32_bits(pd_daddr));
-               intel_logical_ring_emit_reg(ringbuf,
-                                           GEN8_RING_PDP_LDW(engine, i));
-               intel_logical_ring_emit(ringbuf, lower_32_bits(pd_daddr));
+               intel_ring_emit_reg(ring, GEN8_RING_PDP_UDW(engine, i));
+               intel_ring_emit(ring, upper_32_bits(pd_daddr));
+               intel_ring_emit_reg(ring, GEN8_RING_PDP_LDW(engine, i));
+               intel_ring_emit(ring, lower_32_bits(pd_daddr));
        }
 
-       intel_logical_ring_emit(ringbuf, MI_NOOP);
-       intel_logical_ring_advance(ringbuf);
+       intel_ring_emit(ring, MI_NOOP);
+       intel_ring_advance(ring);
 
        return 0;
 }
 
 static int gen8_emit_bb_start(struct drm_i915_gem_request *req,
-                             u64 offset, unsigned dispatch_flags)
+                             u64 offset, u32 len,
+                             unsigned int dispatch_flags)
 {
-       struct intel_ringbuffer *ringbuf = req->ringbuf;
+       struct intel_ring *ring = req->ring;
        bool ppgtt = !(dispatch_flags & I915_DISPATCH_SECURE);
        int ret;
 
@@ -1581,7 +1407,7 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req,
        if (req->ctx->ppgtt &&
            (intel_engine_flag(req->engine) & req->ctx->ppgtt->pd_dirty_rings)) {
                if (!USES_FULL_48BIT_PPGTT(req->i915) &&
-                   !intel_vgpu_active(req->i915->dev)) {
+                   !intel_vgpu_active(req->i915)) {
                        ret = intel_logical_ring_emit_pdps(req);
                        if (ret)
                                return ret;
@@ -1595,61 +1421,36 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req,
                return ret;
 
        /* FIXME(BDW): Address space and security selectors. */
-       intel_logical_ring_emit(ringbuf, MI_BATCH_BUFFER_START_GEN8 |
-                               (ppgtt<<8) |
-                               (dispatch_flags & I915_DISPATCH_RS ?
-                                MI_BATCH_RESOURCE_STREAMER : 0));
-       intel_logical_ring_emit(ringbuf, lower_32_bits(offset));
-       intel_logical_ring_emit(ringbuf, upper_32_bits(offset));
-       intel_logical_ring_emit(ringbuf, MI_NOOP);
-       intel_logical_ring_advance(ringbuf);
+       intel_ring_emit(ring, MI_BATCH_BUFFER_START_GEN8 |
+                       (ppgtt<<8) |
+                       (dispatch_flags & I915_DISPATCH_RS ?
+                        MI_BATCH_RESOURCE_STREAMER : 0));
+       intel_ring_emit(ring, lower_32_bits(offset));
+       intel_ring_emit(ring, upper_32_bits(offset));
+       intel_ring_emit(ring, MI_NOOP);
+       intel_ring_advance(ring);
 
        return 0;
 }
 
-static bool gen8_logical_ring_get_irq(struct intel_engine_cs *engine)
+static void gen8_logical_ring_enable_irq(struct intel_engine_cs *engine)
 {
-       struct drm_device *dev = engine->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       unsigned long flags;
-
-       if (WARN_ON(!intel_irqs_enabled(dev_priv)))
-               return false;
-
-       spin_lock_irqsave(&dev_priv->irq_lock, flags);
-       if (engine->irq_refcount++ == 0) {
-               I915_WRITE_IMR(engine,
-                              ~(engine->irq_enable_mask | engine->irq_keep_mask));
-               POSTING_READ(RING_IMR(engine->mmio_base));
-       }
-       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
-
-       return true;
+       struct drm_i915_private *dev_priv = engine->i915;
+       I915_WRITE_IMR(engine,
+                      ~(engine->irq_enable_mask | engine->irq_keep_mask));
+       POSTING_READ_FW(RING_IMR(engine->mmio_base));
 }
 
-static void gen8_logical_ring_put_irq(struct intel_engine_cs *engine)
+static void gen8_logical_ring_disable_irq(struct intel_engine_cs *engine)
 {
-       struct drm_device *dev = engine->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dev_priv->irq_lock, flags);
-       if (--engine->irq_refcount == 0) {
-               I915_WRITE_IMR(engine, ~engine->irq_keep_mask);
-               POSTING_READ(RING_IMR(engine->mmio_base));
-       }
-       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+       struct drm_i915_private *dev_priv = engine->i915;
+       I915_WRITE_IMR(engine, ~engine->irq_keep_mask);
 }
 
-static int gen8_emit_flush(struct drm_i915_gem_request *request,
-                          u32 invalidate_domains,
-                          u32 unused)
+static int gen8_emit_flush(struct drm_i915_gem_request *request, u32 mode)
 {
-       struct intel_ringbuffer *ringbuf = request->ringbuf;
-       struct intel_engine_cs *engine = ringbuf->engine;
-       struct drm_device *dev = engine->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       uint32_t cmd;
+       struct intel_ring *ring = request->ring;
+       u32 cmd;
        int ret;
 
        ret = intel_ring_begin(request, 4);
@@ -1665,44 +1466,44 @@ static int gen8_emit_flush(struct drm_i915_gem_request *request,
         */
        cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
 
-       if (invalidate_domains & I915_GEM_GPU_DOMAINS) {
+       if (mode & EMIT_INVALIDATE) {
                cmd |= MI_INVALIDATE_TLB;
-               if (engine == &dev_priv->engine[VCS])
+               if (request->engine->id == VCS)
                        cmd |= MI_INVALIDATE_BSD;
        }
 
-       intel_logical_ring_emit(ringbuf, cmd);
-       intel_logical_ring_emit(ringbuf,
-                               I915_GEM_HWS_SCRATCH_ADDR |
-                               MI_FLUSH_DW_USE_GTT);
-       intel_logical_ring_emit(ringbuf, 0); /* upper addr */
-       intel_logical_ring_emit(ringbuf, 0); /* value */
-       intel_logical_ring_advance(ringbuf);
+       intel_ring_emit(ring, cmd);
+       intel_ring_emit(ring,
+                       I915_GEM_HWS_SCRATCH_ADDR |
+                       MI_FLUSH_DW_USE_GTT);
+       intel_ring_emit(ring, 0); /* upper addr */
+       intel_ring_emit(ring, 0); /* value */
+       intel_ring_advance(ring);
 
        return 0;
 }
 
 static int gen8_emit_flush_render(struct drm_i915_gem_request *request,
-                                 u32 invalidate_domains,
-                                 u32 flush_domains)
+                                 u32 mode)
 {
-       struct intel_ringbuffer *ringbuf = request->ringbuf;
-       struct intel_engine_cs *engine = ringbuf->engine;
+       struct intel_ring *ring = request->ring;
+       struct intel_engine_cs *engine = request->engine;
        u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
-       bool vf_flush_wa = false;
+       bool vf_flush_wa = false, dc_flush_wa = false;
        u32 flags = 0;
        int ret;
+       int len;
 
        flags |= PIPE_CONTROL_CS_STALL;
 
-       if (flush_domains) {
+       if (mode & EMIT_FLUSH) {
                flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
                flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
                flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
                flags |= PIPE_CONTROL_FLUSH_ENABLE;
        }
 
-       if (invalidate_domains) {
+       if (mode & EMIT_INVALIDATE) {
                flags |= PIPE_CONTROL_TLB_INVALIDATE;
                flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
                flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
@@ -1716,42 +1517,63 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request,
                 * On GEN9: before VF_CACHE_INVALIDATE we need to emit a NULL
                 * pipe control.
                 */
-               if (IS_GEN9(engine->dev))
+               if (IS_GEN9(request->i915))
                        vf_flush_wa = true;
+
+               /* WaForGAMHang:kbl */
+               if (IS_KBL_REVID(request->i915, 0, KBL_REVID_B0))
+                       dc_flush_wa = true;
        }
 
-       ret = intel_ring_begin(request, vf_flush_wa ? 12 : 6);
+       len = 6;
+
+       if (vf_flush_wa)
+               len += 6;
+
+       if (dc_flush_wa)
+               len += 12;
+
+       ret = intel_ring_begin(request, len);
        if (ret)
                return ret;
 
        if (vf_flush_wa) {
-               intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6));
-               intel_logical_ring_emit(ringbuf, 0);
-               intel_logical_ring_emit(ringbuf, 0);
-               intel_logical_ring_emit(ringbuf, 0);
-               intel_logical_ring_emit(ringbuf, 0);
-               intel_logical_ring_emit(ringbuf, 0);
+               intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6));
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
        }
 
-       intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6));
-       intel_logical_ring_emit(ringbuf, flags);
-       intel_logical_ring_emit(ringbuf, scratch_addr);
-       intel_logical_ring_emit(ringbuf, 0);
-       intel_logical_ring_emit(ringbuf, 0);
-       intel_logical_ring_emit(ringbuf, 0);
-       intel_logical_ring_advance(ringbuf);
+       if (dc_flush_wa) {
+               intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6));
+               intel_ring_emit(ring, PIPE_CONTROL_DC_FLUSH_ENABLE);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+       }
 
-       return 0;
-}
+       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6));
+       intel_ring_emit(ring, flags);
+       intel_ring_emit(ring, scratch_addr);
+       intel_ring_emit(ring, 0);
+       intel_ring_emit(ring, 0);
+       intel_ring_emit(ring, 0);
 
-static u32 gen8_get_seqno(struct intel_engine_cs *engine)
-{
-       return intel_read_status_page(engine, I915_GEM_HWS_INDEX);
-}
+       if (dc_flush_wa) {
+               intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6));
+               intel_ring_emit(ring, PIPE_CONTROL_CS_STALL);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+       }
 
-static void gen8_set_seqno(struct intel_engine_cs *engine, u32 seqno)
-{
-       intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno);
+       intel_ring_advance(ring);
+
+       return 0;
 }
 
 static void bxt_a_seqno_barrier(struct intel_engine_cs *engine)
@@ -1769,14 +1591,6 @@ static void bxt_a_seqno_barrier(struct intel_engine_cs *engine)
        intel_flush_status_page(engine, I915_GEM_HWS_INDEX);
 }
 
-static void bxt_a_set_seqno(struct intel_engine_cs *engine, u32 seqno)
-{
-       intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno);
-
-       /* See bxt_a_get_seqno() explaining the reason for the clflush. */
-       intel_flush_status_page(engine, I915_GEM_HWS_INDEX);
-}
-
 /*
  * Reserve space for 2 NOOPs at the end of each request to be
  * used as a workaround for not being allowed to do lite
@@ -1784,14 +1598,9 @@ static void bxt_a_set_seqno(struct intel_engine_cs *engine, u32 seqno)
  */
 #define WA_TAIL_DWORDS 2
 
-static inline u32 hws_seqno_address(struct intel_engine_cs *engine)
-{
-       return engine->status_page.gfx_addr + I915_GEM_HWS_INDEX_ADDR;
-}
-
 static int gen8_emit_request(struct drm_i915_gem_request *request)
 {
-       struct intel_ringbuffer *ringbuf = request->ringbuf;
+       struct intel_ring *ring = request->ring;
        int ret;
 
        ret = intel_ring_begin(request, 6 + WA_TAIL_DWORDS);
@@ -1801,21 +1610,20 @@ static int gen8_emit_request(struct drm_i915_gem_request *request)
        /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */
        BUILD_BUG_ON(I915_GEM_HWS_INDEX_ADDR & (1 << 5));
 
-       intel_logical_ring_emit(ringbuf,
-                               (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW);
-       intel_logical_ring_emit(ringbuf,
-                               hws_seqno_address(request->engine) |
-                               MI_FLUSH_DW_USE_GTT);
-       intel_logical_ring_emit(ringbuf, 0);
-       intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request));
-       intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT);
-       intel_logical_ring_emit(ringbuf, MI_NOOP);
-       return intel_logical_ring_advance_and_submit(request);
+       intel_ring_emit(ring, (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW);
+       intel_ring_emit(ring,
+                       intel_hws_seqno_address(request->engine) |
+                       MI_FLUSH_DW_USE_GTT);
+       intel_ring_emit(ring, 0);
+       intel_ring_emit(ring, request->fence.seqno);
+       intel_ring_emit(ring, MI_USER_INTERRUPT);
+       intel_ring_emit(ring, MI_NOOP);
+       return intel_logical_ring_advance(request);
 }
 
 static int gen8_emit_request_render(struct drm_i915_gem_request *request)
 {
-       struct intel_ringbuffer *ringbuf = request->ringbuf;
+       struct intel_ring *ring = request->ring;
        int ret;
 
        ret = intel_ring_begin(request, 8 + WA_TAIL_DWORDS);
@@ -1829,49 +1637,19 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request)
         * need a prior CS_STALL, which is emitted by the flush
         * following the batch.
         */
-       intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6));
-       intel_logical_ring_emit(ringbuf,
-                               (PIPE_CONTROL_GLOBAL_GTT_IVB |
-                                PIPE_CONTROL_CS_STALL |
-                                PIPE_CONTROL_QW_WRITE));
-       intel_logical_ring_emit(ringbuf, hws_seqno_address(request->engine));
-       intel_logical_ring_emit(ringbuf, 0);
-       intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request));
+       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6));
+       intel_ring_emit(ring,
+                       (PIPE_CONTROL_GLOBAL_GTT_IVB |
+                        PIPE_CONTROL_CS_STALL |
+                        PIPE_CONTROL_QW_WRITE));
+       intel_ring_emit(ring, intel_hws_seqno_address(request->engine));
+       intel_ring_emit(ring, 0);
+       intel_ring_emit(ring, i915_gem_request_get_seqno(request));
        /* We're thrashing one dword of HWS. */
-       intel_logical_ring_emit(ringbuf, 0);
-       intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT);
-       intel_logical_ring_emit(ringbuf, MI_NOOP);
-       return intel_logical_ring_advance_and_submit(request);
-}
-
-static int intel_lr_context_render_state_init(struct drm_i915_gem_request *req)
-{
-       struct render_state so;
-       int ret;
-
-       ret = i915_gem_render_state_prepare(req->engine, &so);
-       if (ret)
-               return ret;
-
-       if (so.rodata == NULL)
-               return 0;
-
-       ret = req->engine->emit_bb_start(req, so.ggtt_offset,
-                                      I915_DISPATCH_SECURE);
-       if (ret)
-               goto out;
-
-       ret = req->engine->emit_bb_start(req,
-                                      (so.ggtt_offset + so.aux_batch_offset),
-                                      I915_DISPATCH_SECURE);
-       if (ret)
-               goto out;
-
-       i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req);
-
-out:
-       i915_gem_render_state_fini(&so);
-       return ret;
+       intel_ring_emit(ring, 0);
+       intel_ring_emit(ring, MI_USER_INTERRUPT);
+       intel_ring_emit(ring, MI_NOOP);
+       return intel_logical_ring_advance(request);
 }
 
 static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
@@ -1890,14 +1668,12 @@ static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
        if (ret)
                DRM_ERROR("MOCS failed to program: expect performance issues.\n");
 
-       return intel_lr_context_render_state_init(req);
+       return i915_gem_render_state_init(req);
 }
 
 /**
  * intel_logical_ring_cleanup() - deallocate the Engine Command Streamer
- *
- * @ring: Engine Command Streamer.
- *
+ * @engine: Engine Command Streamer.
  */
 void intel_logical_ring_cleanup(struct intel_engine_cs *engine)
 {
@@ -1913,54 +1689,59 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine)
        if (WARN_ON(test_bit(TASKLET_STATE_SCHED, &engine->irq_tasklet.state)))
                tasklet_kill(&engine->irq_tasklet);
 
-       dev_priv = engine->dev->dev_private;
+       dev_priv = engine->i915;
 
        if (engine->buffer) {
-               intel_logical_ring_stop(engine);
                WARN_ON((I915_READ_MODE(engine) & MODE_IDLE) == 0);
        }
 
        if (engine->cleanup)
                engine->cleanup(engine);
 
-       i915_cmd_parser_fini_ring(engine);
-       i915_gem_batch_pool_fini(&engine->batch_pool);
+       intel_engine_cleanup_common(engine);
 
        if (engine->status_page.obj) {
                i915_gem_object_unpin_map(engine->status_page.obj);
                engine->status_page.obj = NULL;
        }
+       intel_lr_context_unpin(dev_priv->kernel_context, engine);
 
        engine->idle_lite_restore_wa = 0;
        engine->disable_lite_restore_wa = false;
        engine->ctx_desc_template = 0;
 
        lrc_destroy_wa_ctx_obj(engine);
-       engine->dev = NULL;
+       engine->i915 = NULL;
+}
+
+void intel_execlists_enable_submission(struct drm_i915_private *dev_priv)
+{
+       struct intel_engine_cs *engine;
+
+       for_each_engine(engine, dev_priv)
+               engine->submit_request = execlists_submit_request;
 }
 
 static void
-logical_ring_default_vfuncs(struct drm_device *dev,
-                           struct intel_engine_cs *engine)
+logical_ring_default_vfuncs(struct intel_engine_cs *engine)
 {
        /* Default vfuncs which can be overriden by each engine. */
        engine->init_hw = gen8_init_common_ring;
-       engine->emit_request = gen8_emit_request;
        engine->emit_flush = gen8_emit_flush;
-       engine->irq_get = gen8_logical_ring_get_irq;
-       engine->irq_put = gen8_logical_ring_put_irq;
+       engine->emit_request = gen8_emit_request;
+       engine->submit_request = execlists_submit_request;
+
+       engine->irq_enable = gen8_logical_ring_enable_irq;
+       engine->irq_disable = gen8_logical_ring_disable_irq;
        engine->emit_bb_start = gen8_emit_bb_start;
-       engine->get_seqno = gen8_get_seqno;
-       engine->set_seqno = gen8_set_seqno;
-       if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+       if (IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1))
                engine->irq_seqno_barrier = bxt_a_seqno_barrier;
-               engine->set_seqno = bxt_a_set_seqno;
-       }
 }
 
 static inline void
-logical_ring_default_irqs(struct intel_engine_cs *engine, unsigned shift)
+logical_ring_default_irqs(struct intel_engine_cs *engine)
 {
+       unsigned shift = engine->irq_shift;
        engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift;
        engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift;
 }
@@ -1983,33 +1764,17 @@ lrc_setup_hws(struct intel_engine_cs *engine,
        return 0;
 }
 
-static int
-logical_ring_init(struct drm_device *dev, struct intel_engine_cs *engine)
+static void
+logical_ring_setup(struct intel_engine_cs *engine)
 {
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_context *dctx = dev_priv->kernel_context;
+       struct drm_i915_private *dev_priv = engine->i915;
        enum forcewake_domains fw_domains;
-       int ret;
+
+       intel_engine_setup_common(engine);
 
        /* Intentionally left blank. */
        engine->buffer = NULL;
 
-       engine->dev = dev;
-       INIT_LIST_HEAD(&engine->active_list);
-       INIT_LIST_HEAD(&engine->request_list);
-       i915_gem_batch_pool_init(dev, &engine->batch_pool);
-       init_waitqueue_head(&engine->irq_queue);
-
-       INIT_LIST_HEAD(&engine->buffers);
-       INIT_LIST_HEAD(&engine->execlist_queue);
-       INIT_LIST_HEAD(&engine->execlist_retired_req_list);
-       spin_lock_init(&engine->execlist_lock);
-
-       tasklet_init(&engine->irq_tasklet,
-                    intel_lrc_irq_handler, (unsigned long)engine);
-
-       logical_ring_init_platform_invariants(engine);
-
        fw_domains = intel_uncore_forcewake_for_reg(dev_priv,
                                                    RING_ELSP(engine),
                                                    FW_REG_WRITE);
@@ -2024,20 +1789,33 @@ logical_ring_init(struct drm_device *dev, struct intel_engine_cs *engine)
 
        engine->fw_domains = fw_domains;
 
-       ret = i915_cmd_parser_init_ring(engine);
+       tasklet_init(&engine->irq_tasklet,
+                    intel_lrc_irq_handler, (unsigned long)engine);
+
+       logical_ring_init_platform_invariants(engine);
+       logical_ring_default_vfuncs(engine);
+       logical_ring_default_irqs(engine);
+}
+
+static int
+logical_ring_init(struct intel_engine_cs *engine)
+{
+       struct i915_gem_context *dctx = engine->i915->kernel_context;
+       int ret;
+
+       ret = intel_engine_init_common(engine);
        if (ret)
                goto error;
 
-       ret = intel_lr_context_deferred_alloc(dctx, engine);
+       ret = execlists_context_deferred_alloc(dctx, engine);
        if (ret)
                goto error;
 
        /* As this is the default context, always pin it */
-       ret = intel_lr_context_do_pin(dctx, engine);
+       ret = intel_lr_context_pin(dctx, engine);
        if (ret) {
-               DRM_ERROR(
-                       "Failed to pin and map ringbuffer %s: %d\n",
-                       engine->name, ret);
+               DRM_ERROR("Failed to pin context for %s: %d\n",
+                         engine->name, ret);
                goto error;
        }
 
@@ -2055,26 +1833,18 @@ error:
        return ret;
 }
 
-static int logical_render_ring_init(struct drm_device *dev)
+int logical_render_ring_init(struct intel_engine_cs *engine)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *engine = &dev_priv->engine[RCS];
+       struct drm_i915_private *dev_priv = engine->i915;
        int ret;
 
-       engine->name = "render ring";
-       engine->id = RCS;
-       engine->exec_id = I915_EXEC_RENDER;
-       engine->guc_id = GUC_RENDER_ENGINE;
-       engine->mmio_base = RENDER_RING_BASE;
+       logical_ring_setup(engine);
 
-       logical_ring_default_irqs(engine, GEN8_RCS_IRQ_SHIFT);
-       if (HAS_L3_DPF(dev))
+       if (HAS_L3_DPF(dev_priv))
                engine->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
 
-       logical_ring_default_vfuncs(dev, engine);
-
        /* Override some for render ring. */
-       if (INTEL_INFO(dev)->gen >= 9)
+       if (INTEL_GEN(dev_priv) >= 9)
                engine->init_hw = gen9_init_render_ring;
        else
                engine->init_hw = gen8_init_render_ring;
@@ -2083,9 +1853,7 @@ static int logical_render_ring_init(struct drm_device *dev)
        engine->emit_flush = gen8_emit_flush_render;
        engine->emit_request = gen8_emit_request_render;
 
-       engine->dev = dev;
-
-       ret = intel_init_pipe_control(engine);
+       ret = intel_init_pipe_control(engine, 4096);
        if (ret)
                return ret;
 
@@ -2100,7 +1868,7 @@ static int logical_render_ring_init(struct drm_device *dev)
                          ret);
        }
 
-       ret = logical_ring_init(dev, engine);
+       ret = logical_ring_init(engine);
        if (ret) {
                lrc_destroy_wa_ctx_obj(engine);
        }
@@ -2108,133 +1876,15 @@ static int logical_render_ring_init(struct drm_device *dev)
        return ret;
 }
 
-static int logical_bsd_ring_init(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *engine = &dev_priv->engine[VCS];
-
-       engine->name = "bsd ring";
-       engine->id = VCS;
-       engine->exec_id = I915_EXEC_BSD;
-       engine->guc_id = GUC_VIDEO_ENGINE;
-       engine->mmio_base = GEN6_BSD_RING_BASE;
-
-       logical_ring_default_irqs(engine, GEN8_VCS1_IRQ_SHIFT);
-       logical_ring_default_vfuncs(dev, engine);
-
-       return logical_ring_init(dev, engine);
-}
-
-static int logical_bsd2_ring_init(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *engine = &dev_priv->engine[VCS2];
-
-       engine->name = "bsd2 ring";
-       engine->id = VCS2;
-       engine->exec_id = I915_EXEC_BSD;
-       engine->guc_id = GUC_VIDEO_ENGINE2;
-       engine->mmio_base = GEN8_BSD2_RING_BASE;
-
-       logical_ring_default_irqs(engine, GEN8_VCS2_IRQ_SHIFT);
-       logical_ring_default_vfuncs(dev, engine);
-
-       return logical_ring_init(dev, engine);
-}
-
-static int logical_blt_ring_init(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *engine = &dev_priv->engine[BCS];
-
-       engine->name = "blitter ring";
-       engine->id = BCS;
-       engine->exec_id = I915_EXEC_BLT;
-       engine->guc_id = GUC_BLITTER_ENGINE;
-       engine->mmio_base = BLT_RING_BASE;
-
-       logical_ring_default_irqs(engine, GEN8_BCS_IRQ_SHIFT);
-       logical_ring_default_vfuncs(dev, engine);
-
-       return logical_ring_init(dev, engine);
-}
-
-static int logical_vebox_ring_init(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *engine = &dev_priv->engine[VECS];
-
-       engine->name = "video enhancement ring";
-       engine->id = VECS;
-       engine->exec_id = I915_EXEC_VEBOX;
-       engine->guc_id = GUC_VIDEOENHANCE_ENGINE;
-       engine->mmio_base = VEBOX_RING_BASE;
-
-       logical_ring_default_irqs(engine, GEN8_VECS_IRQ_SHIFT);
-       logical_ring_default_vfuncs(dev, engine);
-
-       return logical_ring_init(dev, engine);
-}
-
-/**
- * intel_logical_rings_init() - allocate, populate and init the Engine Command Streamers
- * @dev: DRM device.
- *
- * This function inits the engines for an Execlists submission style (the equivalent in the
- * legacy ringbuffer submission world would be i915_gem_init_engines). It does it only for
- * those engines that are present in the hardware.
- *
- * Return: non-zero if the initialization failed.
- */
-int intel_logical_rings_init(struct drm_device *dev)
+int logical_xcs_ring_init(struct intel_engine_cs *engine)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int ret;
-
-       ret = logical_render_ring_init(dev);
-       if (ret)
-               return ret;
-
-       if (HAS_BSD(dev)) {
-               ret = logical_bsd_ring_init(dev);
-               if (ret)
-                       goto cleanup_render_ring;
-       }
-
-       if (HAS_BLT(dev)) {
-               ret = logical_blt_ring_init(dev);
-               if (ret)
-                       goto cleanup_bsd_ring;
-       }
-
-       if (HAS_VEBOX(dev)) {
-               ret = logical_vebox_ring_init(dev);
-               if (ret)
-                       goto cleanup_blt_ring;
-       }
-
-       if (HAS_BSD2(dev)) {
-               ret = logical_bsd2_ring_init(dev);
-               if (ret)
-                       goto cleanup_vebox_ring;
-       }
+       logical_ring_setup(engine);
 
-       return 0;
-
-cleanup_vebox_ring:
-       intel_logical_ring_cleanup(&dev_priv->engine[VECS]);
-cleanup_blt_ring:
-       intel_logical_ring_cleanup(&dev_priv->engine[BCS]);
-cleanup_bsd_ring:
-       intel_logical_ring_cleanup(&dev_priv->engine[VCS]);
-cleanup_render_ring:
-       intel_logical_ring_cleanup(&dev_priv->engine[RCS]);
-
-       return ret;
+       return logical_ring_init(engine);
 }
 
 static u32
-make_rpcs(struct drm_device *dev)
+make_rpcs(struct drm_i915_private *dev_priv)
 {
        u32 rpcs = 0;
 
@@ -2242,7 +1892,7 @@ make_rpcs(struct drm_device *dev)
         * No explicit RPCS request is needed to ensure full
         * slice/subslice/EU enablement prior to Gen9.
        */
-       if (INTEL_INFO(dev)->gen < 9)
+       if (INTEL_GEN(dev_priv) < 9)
                return 0;
 
        /*
@@ -2251,24 +1901,24 @@ make_rpcs(struct drm_device *dev)
         * must make an explicit request through RPCS for full
         * enablement.
        */
-       if (INTEL_INFO(dev)->has_slice_pg) {
+       if (INTEL_INFO(dev_priv)->has_slice_pg) {
                rpcs |= GEN8_RPCS_S_CNT_ENABLE;
-               rpcs |= INTEL_INFO(dev)->slice_total <<
+               rpcs |= INTEL_INFO(dev_priv)->slice_total <<
                        GEN8_RPCS_S_CNT_SHIFT;
                rpcs |= GEN8_RPCS_ENABLE;
        }
 
-       if (INTEL_INFO(dev)->has_subslice_pg) {
+       if (INTEL_INFO(dev_priv)->has_subslice_pg) {
                rpcs |= GEN8_RPCS_SS_CNT_ENABLE;
-               rpcs |= INTEL_INFO(dev)->subslice_per_slice <<
+               rpcs |= INTEL_INFO(dev_priv)->subslice_per_slice <<
                        GEN8_RPCS_SS_CNT_SHIFT;
                rpcs |= GEN8_RPCS_ENABLE;
        }
 
-       if (INTEL_INFO(dev)->has_eu_pg) {
-               rpcs |= INTEL_INFO(dev)->eu_per_subslice <<
+       if (INTEL_INFO(dev_priv)->has_eu_pg) {
+               rpcs |= INTEL_INFO(dev_priv)->eu_per_subslice <<
                        GEN8_RPCS_EU_MIN_SHIFT;
-               rpcs |= INTEL_INFO(dev)->eu_per_subslice <<
+               rpcs |= INTEL_INFO(dev_priv)->eu_per_subslice <<
                        GEN8_RPCS_EU_MAX_SHIFT;
                rpcs |= GEN8_RPCS_ENABLE;
        }
@@ -2280,9 +1930,9 @@ static u32 intel_lr_indirect_ctx_offset(struct intel_engine_cs *engine)
 {
        u32 indirect_ctx_offset;
 
-       switch (INTEL_INFO(engine->dev)->gen) {
+       switch (INTEL_GEN(engine->i915)) {
        default:
-               MISSING_CASE(INTEL_INFO(engine->dev)->gen);
+               MISSING_CASE(INTEL_GEN(engine->i915));
                /* fall through */
        case 9:
                indirect_ctx_offset =
@@ -2298,13 +1948,12 @@ static u32 intel_lr_indirect_ctx_offset(struct intel_engine_cs *engine)
 }
 
 static int
-populate_lr_context(struct intel_context *ctx,
+populate_lr_context(struct i915_gem_context *ctx,
                    struct drm_i915_gem_object *ctx_obj,
                    struct intel_engine_cs *engine,
-                   struct intel_ringbuffer *ringbuf)
+                   struct intel_ring *ring)
 {
-       struct drm_device *dev = engine->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = ctx->i915;
        struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
        void *vaddr;
        u32 *reg_state;
@@ -2342,7 +1991,7 @@ populate_lr_context(struct intel_context *ctx,
                       RING_CONTEXT_CONTROL(engine),
                       _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH |
                                          CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT |
-                                         (HAS_RESOURCE_STREAMER(dev) ?
+                                         (HAS_RESOURCE_STREAMER(dev_priv) ?
                                            CTX_CTRL_RS_CTX_ENABLE : 0)));
        ASSIGN_CTX_REG(reg_state, CTX_RING_HEAD, RING_HEAD(engine->mmio_base),
                       0);
@@ -2355,7 +2004,7 @@ populate_lr_context(struct intel_context *ctx,
                       RING_START(engine->mmio_base), 0);
        ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_CONTROL,
                       RING_CTL(engine->mmio_base),
-                      ((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES) | RING_VALID);
+                      ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | RING_VALID);
        ASSIGN_CTX_REG(reg_state, CTX_BB_HEAD_U,
                       RING_BBADDR_UDW(engine->mmio_base), 0);
        ASSIGN_CTX_REG(reg_state, CTX_BB_HEAD_L,
@@ -2431,7 +2080,7 @@ populate_lr_context(struct intel_context *ctx,
        if (engine->id == RCS) {
                reg_state[CTX_LRI_HEADER_2] = MI_LOAD_REGISTER_IMM(1);
                ASSIGN_CTX_REG(reg_state, CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE,
-                              make_rpcs(dev));
+                              make_rpcs(dev_priv));
        }
 
        i915_gem_object_unpin_map(ctx_obj);
@@ -2439,40 +2088,9 @@ populate_lr_context(struct intel_context *ctx,
        return 0;
 }
 
-/**
- * intel_lr_context_free() - free the LRC specific bits of a context
- * @ctx: the LR context to free.
- *
- * The real context freeing is done in i915_gem_context_free: this only
- * takes care of the bits that are LRC related: the per-engine backing
- * objects and the logical ringbuffer.
- */
-void intel_lr_context_free(struct intel_context *ctx)
-{
-       int i;
-
-       for (i = I915_NUM_ENGINES; --i >= 0; ) {
-               struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf;
-               struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state;
-
-               if (!ctx_obj)
-                       continue;
-
-               if (ctx == ctx->i915->kernel_context) {
-                       intel_unpin_ringbuffer_obj(ringbuf);
-                       i915_gem_object_ggtt_unpin(ctx_obj);
-                       i915_gem_object_unpin_map(ctx_obj);
-               }
-
-               WARN_ON(ctx->engine[i].pin_count);
-               intel_ringbuffer_free(ringbuf);
-               drm_gem_object_unreference(&ctx_obj->base);
-       }
-}
-
 /**
  * intel_lr_context_size() - return the size of the context for an engine
- * @ring: which engine to find the context size for
+ * @engine: which engine to find the context size for
  *
  * Each engine may require a different amount of space for a context image,
  * so when allocating (or copying) an image, this function can be used to
@@ -2488,11 +2106,11 @@ uint32_t intel_lr_context_size(struct intel_engine_cs *engine)
 {
        int ret = 0;
 
-       WARN_ON(INTEL_INFO(engine->dev)->gen < 8);
+       WARN_ON(INTEL_GEN(engine->i915) < 8);
 
        switch (engine->id) {
        case RCS:
-               if (INTEL_INFO(engine->dev)->gen >= 9)
+               if (INTEL_GEN(engine->i915) >= 9)
                        ret = GEN9_LR_CONTEXT_RENDER_SIZE;
                else
                        ret = GEN8_LR_CONTEXT_RENDER_SIZE;
@@ -2508,97 +2126,63 @@ uint32_t intel_lr_context_size(struct intel_engine_cs *engine)
        return ret;
 }
 
-/**
- * intel_lr_context_deferred_alloc() - create the LRC specific bits of a context
- * @ctx: LR context to create.
- * @ring: engine to be used with the context.
- *
- * This function can be called more than once, with different engines, if we plan
- * to use the context with them. The context backing objects and the ringbuffers
- * (specially the ringbuffer backing objects) suck a lot of memory up, and that's why
- * the creation is a deferred call: it's better to make sure first that we need to use
- * a given ring with the context.
- *
- * Return: non-zero on error.
- */
-
-int intel_lr_context_deferred_alloc(struct intel_context *ctx,
-                                   struct intel_engine_cs *engine)
+static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
+                                           struct intel_engine_cs *engine)
 {
-       struct drm_device *dev = engine->dev;
        struct drm_i915_gem_object *ctx_obj;
+       struct intel_context *ce = &ctx->engine[engine->id];
        uint32_t context_size;
-       struct intel_ringbuffer *ringbuf;
+       struct intel_ring *ring;
        int ret;
 
-       WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL);
-       WARN_ON(ctx->engine[engine->id].state);
+       WARN_ON(ce->state);
 
        context_size = round_up(intel_lr_context_size(engine), 4096);
 
        /* One extra page as the sharing data between driver and GuC */
        context_size += PAGE_SIZE * LRC_PPHWSP_PN;
 
-       ctx_obj = i915_gem_alloc_object(dev, context_size);
-       if (!ctx_obj) {
+       ctx_obj = i915_gem_object_create(&ctx->i915->drm, context_size);
+       if (IS_ERR(ctx_obj)) {
                DRM_DEBUG_DRIVER("Alloc LRC backing obj failed.\n");
-               return -ENOMEM;
+               return PTR_ERR(ctx_obj);
        }
 
-       ringbuf = intel_engine_create_ringbuffer(engine, 4 * PAGE_SIZE);
-       if (IS_ERR(ringbuf)) {
-               ret = PTR_ERR(ringbuf);
+       ring = intel_engine_create_ring(engine, ctx->ring_size);
+       if (IS_ERR(ring)) {
+               ret = PTR_ERR(ring);
                goto error_deref_obj;
        }
 
-       ret = populate_lr_context(ctx, ctx_obj, engine, ringbuf);
+       ret = populate_lr_context(ctx, ctx_obj, engine, ring);
        if (ret) {
                DRM_DEBUG_DRIVER("Failed to populate LRC: %d\n", ret);
-               goto error_ringbuf;
+               goto error_ring_free;
        }
 
-       ctx->engine[engine->id].ringbuf = ringbuf;
-       ctx->engine[engine->id].state = ctx_obj;
+       ce->ring = ring;
+       ce->state = ctx_obj;
+       ce->initialised = engine->init_context == NULL;
 
-       if (ctx != ctx->i915->kernel_context && engine->init_context) {
-               struct drm_i915_gem_request *req;
-
-               req = i915_gem_request_alloc(engine, ctx);
-               if (IS_ERR(req)) {
-                       ret = PTR_ERR(req);
-                       DRM_ERROR("ring create req: %d\n", ret);
-                       goto error_ringbuf;
-               }
-
-               ret = engine->init_context(req);
-               i915_add_request_no_flush(req);
-               if (ret) {
-                       DRM_ERROR("ring init context: %d\n",
-                               ret);
-                       goto error_ringbuf;
-               }
-       }
        return 0;
 
-error_ringbuf:
-       intel_ringbuffer_free(ringbuf);
+error_ring_free:
+       intel_ring_free(ring);
 error_deref_obj:
-       drm_gem_object_unreference(&ctx_obj->base);
-       ctx->engine[engine->id].ringbuf = NULL;
-       ctx->engine[engine->id].state = NULL;
+       i915_gem_object_put(ctx_obj);
+       ce->ring = NULL;
+       ce->state = NULL;
        return ret;
 }
 
 void intel_lr_context_reset(struct drm_i915_private *dev_priv,
-                           struct intel_context *ctx)
+                           struct i915_gem_context *ctx)
 {
        struct intel_engine_cs *engine;
 
        for_each_engine(engine, dev_priv) {
-               struct drm_i915_gem_object *ctx_obj =
-                               ctx->engine[engine->id].state;
-               struct intel_ringbuffer *ringbuf =
-                               ctx->engine[engine->id].ringbuf;
+               struct intel_context *ce = &ctx->engine[engine->id];
+               struct drm_i915_gem_object *ctx_obj = ce->state;
                void *vaddr;
                uint32_t *reg_state;
 
@@ -2617,7 +2201,7 @@ void intel_lr_context_reset(struct drm_i915_private *dev_priv,
 
                i915_gem_object_unpin_map(ctx_obj);
 
-               ringbuf->head = 0;
-               ringbuf->tail = 0;
+               ce->ring->head = 0;
+               ce->ring->tail = 0;
        }
 }