Merge tag 'drm-intel-next-2018-06-20' of git://anongit.freedesktop.org/drm/drm-intel...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / intel_lrc.c
index 091e28f0e02451dec6cb10a3d5f3afa862373432..33bc914c2ef53e83b330147a160a51d207395f49 100644 (file)
@@ -970,22 +970,19 @@ static void process_csb(struct intel_engine_cs *engine)
                        &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX];
                unsigned int head, tail;
 
-               if (unlikely(execlists->csb_use_mmio)) {
-                       buf = (u32 * __force)
-                               (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0)));
-                       execlists->csb_head = -1; /* force mmio read of CSB */
-               }
-
                /* Clear before reading to catch new interrupts */
                clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
                smp_mb__after_atomic();
 
-               if (unlikely(execlists->csb_head == -1)) { /* after a reset */
+               if (unlikely(execlists->csb_use_mmio)) {
                        if (!fw) {
                                intel_uncore_forcewake_get(i915, execlists->fw_domains);
                                fw = true;
                        }
 
+                       buf = (u32 * __force)
+                               (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0)));
+
                        head = readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)));
                        tail = GEN8_CSB_WRITE_PTR(head);
                        head = GEN8_CSB_READ_PTR(head);
@@ -1413,6 +1410,7 @@ __execlists_context_pin(struct intel_engine_cs *engine,
        ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
        ce->lrc_reg_state[CTX_RING_BUFFER_START+1] =
                i915_ggtt_offset(ce->ring->vma);
+       GEM_BUG_ON(!intel_ring_offset_valid(ce->ring, ce->ring->head));
        ce->lrc_reg_state[CTX_RING_HEAD+1] = ce->ring->head;
 
        ce->state->obj->pin_global++;
@@ -1567,19 +1565,56 @@ static u32 *gen8_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
        return batch;
 }
 
+struct lri {
+       i915_reg_t reg;
+       u32 value;
+};
+
+static u32 *emit_lri(u32 *batch, const struct lri *lri, unsigned int count)
+{
+       GEM_BUG_ON(!count || count > 63);
+
+       *batch++ = MI_LOAD_REGISTER_IMM(count);
+       do {
+               *batch++ = i915_mmio_reg_offset(lri->reg);
+               *batch++ = lri->value;
+       } while (lri++, --count);
+       *batch++ = MI_NOOP;
+
+       return batch;
+}
+
 static u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
 {
+       static const struct lri lri[] = {
+               /* WaDisableGatherAtSetShaderCommonSlice:skl,bxt,kbl,glk */
+               {
+                       COMMON_SLICE_CHICKEN2,
+                       __MASKED_FIELD(GEN9_DISABLE_GATHER_AT_SET_SHADER_COMMON_SLICE,
+                                      0),
+               },
+
+               /* BSpec: 11391 */
+               {
+                       FF_SLICE_CHICKEN,
+                       __MASKED_FIELD(FF_SLICE_CHICKEN_CL_PROVOKING_VERTEX_FIX,
+                                      FF_SLICE_CHICKEN_CL_PROVOKING_VERTEX_FIX),
+               },
+
+               /* BSpec: 11299 */
+               {
+                       _3D_CHICKEN3,
+                       __MASKED_FIELD(_3D_CHICKEN_SF_PROVOKING_VERTEX_FIX,
+                                      _3D_CHICKEN_SF_PROVOKING_VERTEX_FIX),
+               }
+       };
+
        *batch++ = MI_ARB_ON_OFF | MI_ARB_DISABLE;
 
        /* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt,glk */
        batch = gen8_emit_flush_coherentl3_wa(engine, batch);
 
-       /* WaDisableGatherAtSetShaderCommonSlice:skl,bxt,kbl,glk */
-       *batch++ = MI_LOAD_REGISTER_IMM(1);
-       *batch++ = i915_mmio_reg_offset(COMMON_SLICE_CHICKEN2);
-       *batch++ = _MASKED_BIT_DISABLE(
-                       GEN9_DISABLE_GATHER_AT_SET_SHADER_COMMON_SLICE);
-       *batch++ = MI_NOOP;
+       batch = emit_lri(batch, lri, ARRAY_SIZE(lri));
 
        /* WaClearSlmSpaceAtContextSwitch:kbl */
        /* Actual scratch location is at 128 bytes offset */
@@ -1809,7 +1844,6 @@ static bool unexpected_starting_state(struct intel_engine_cs *engine)
 
 static int gen8_init_common_ring(struct intel_engine_cs *engine)
 {
-       struct intel_engine_execlists * const execlists = &engine->execlists;
        int ret;
 
        ret = intel_mocs_init_engine(engine);
@@ -1827,10 +1861,6 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)
 
        enable_execlists(engine);
 
-       /* After a GPU reset, we may have requests to replay */
-       if (execlists->first)
-               tasklet_schedule(&execlists->tasklet);
-
        return 0;
 }
 
@@ -1964,7 +1994,7 @@ static void execlists_reset(struct intel_engine_cs *engine,
        spin_unlock(&engine->timeline.lock);
 
        /* Following the reset, we need to reload the CSB read/write pointers */
-       engine->execlists.csb_head = -1;
+       engine->execlists.csb_head = GEN8_CSB_ENTRIES - 1;
 
        local_irq_restore(flags);
 
@@ -2001,9 +2031,10 @@ static void execlists_reset(struct intel_engine_cs *engine,
 
        /* Move the RING_HEAD onto the breadcrumb, past the hanging batch */
        regs[CTX_RING_BUFFER_START + 1] = i915_ggtt_offset(request->ring->vma);
-       regs[CTX_RING_HEAD + 1] = request->postfix;
 
-       request->ring->head = request->postfix;
+       request->ring->head = intel_ring_wrap(request->ring, request->postfix);
+       regs[CTX_RING_HEAD + 1] = request->ring->head;
+
        intel_ring_update_space(request->ring);
 
        /* Reset WaIdleLiteRestore:bdw,skl as well */
@@ -2012,6 +2043,12 @@ static void execlists_reset(struct intel_engine_cs *engine,
 
 static void execlists_reset_finish(struct intel_engine_cs *engine)
 {
+       struct intel_engine_execlists * const execlists = &engine->execlists;
+
+       /* After a GPU reset, we may have requests to replay */
+       if (execlists->first)
+               tasklet_schedule(&execlists->tasklet);
+
        /*
         * Flush the tasklet while we still have the forcewake to be sure
         * that it is not allowed to sleep before we restart and reload a
@@ -2021,7 +2058,7 @@ static void execlists_reset_finish(struct intel_engine_cs *engine)
         * serialising multiple attempts to reset so that we know that we
         * are the only one manipulating tasklet state.
         */
-       __tasklet_enable_sync_once(&engine->execlists.tasklet);
+       __tasklet_enable_sync_once(&execlists->tasklet);
 
        GEM_TRACE("%s\n", engine->name);
 }
@@ -2465,7 +2502,7 @@ static int logical_ring_init(struct intel_engine_cs *engine)
                        upper_32_bits(ce->lrc_desc);
        }
 
-       engine->execlists.csb_head = -1;
+       engine->execlists.csb_head = GEN8_CSB_ENTRIES - 1;
 
        return 0;
 
@@ -2768,10 +2805,8 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
        context_size += LRC_HEADER_PAGES * PAGE_SIZE;
 
        ctx_obj = i915_gem_object_create(ctx->i915, context_size);
-       if (IS_ERR(ctx_obj)) {
-               ret = PTR_ERR(ctx_obj);
-               goto error_deref_obj;
-       }
+       if (IS_ERR(ctx_obj))
+               return PTR_ERR(ctx_obj);
 
        vma = i915_vma_instance(ctx_obj, &ctx->i915->ggtt.vm, NULL);
        if (IS_ERR(vma)) {