drm/i915/ringbuffer: Clear semaphore sync registers on ring init
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / intel_ringbuffer.c
index d0ef50b..d81eaf5 100644 (file)
@@ -91,6 +91,7 @@ static int
 gen4_render_ring_flush(struct i915_request *rq, u32 mode)
 {
        u32 cmd, *cs;
+       int i;
 
        /*
         * read/write caches:
@@ -127,12 +128,45 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
                        cmd |= MI_INVALIDATE_ISP;
        }
 
-       cs = intel_ring_begin(rq, 2);
+       i = 2;
+       if (mode & EMIT_INVALIDATE)
+               i += 20;
+
+       cs = intel_ring_begin(rq, i);
        if (IS_ERR(cs))
                return PTR_ERR(cs);
 
        *cs++ = cmd;
-       *cs++ = MI_NOOP;
+
+       /*
+        * A random delay to let the CS invalidate take effect? Without this
+        * delay, the GPU relocation path fails as the CS does not see
+        * the updated contents. Just as important, if we apply the flushes
+        * to the EMIT_FLUSH branch (i.e. immediately after the relocation
+        * write and before the invalidate on the next batch), the relocations
+        * still fail. This implies that is a delay following invalidation
+        * that is required to reset the caches as opposed to a delay to
+        * ensure the memory is written.
+        */
+       if (mode & EMIT_INVALIDATE) {
+               *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
+               *cs++ = i915_ggtt_offset(rq->engine->scratch) |
+                       PIPE_CONTROL_GLOBAL_GTT;
+               *cs++ = 0;
+               *cs++ = 0;
+
+               for (i = 0; i < 12; i++)
+                       *cs++ = MI_FLUSH;
+
+               *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
+               *cs++ = i915_ggtt_offset(rq->engine->scratch) |
+                       PIPE_CONTROL_GLOBAL_GTT;
+               *cs++ = 0;
+               *cs++ = 0;
+       }
+
+       *cs++ = cmd;
+
        intel_ring_advance(rq, cs);
 
        return 0;
@@ -495,6 +529,13 @@ static int init_ring_common(struct intel_engine_cs *engine)
 
        intel_engine_reset_breadcrumbs(engine);
 
+       if (HAS_LEGACY_SEMAPHORES(engine->i915)) {
+               I915_WRITE(RING_SYNC_0(engine->mmio_base), 0);
+               I915_WRITE(RING_SYNC_1(engine->mmio_base), 0);
+               if (HAS_VEBOX(dev_priv))
+                       I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
+       }
+
        /* Enforce ordering by reading HEAD register back */
        I915_READ_HEAD(engine);
 
@@ -512,10 +553,11 @@ static int init_ring_common(struct intel_engine_cs *engine)
        /* Check that the ring offsets point within the ring! */
        GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head));
        GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->tail));
-
        intel_ring_update_space(ring);
+
+       /* First wake the ring up to an empty/idle ring */
        I915_WRITE_HEAD(engine, ring->head);
-       I915_WRITE_TAIL(engine, ring->tail);
+       I915_WRITE_TAIL(engine, ring->head);
        (void)I915_READ_TAIL(engine);
 
        I915_WRITE_CTL(engine, RING_CTL_SIZE(ring->size) | RING_VALID);
@@ -540,6 +582,12 @@ static int init_ring_common(struct intel_engine_cs *engine)
        if (INTEL_GEN(dev_priv) > 2)
                I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING));
 
+       /* Now awake, let it get started */
+       if (ring->tail != ring->head) {
+               I915_WRITE_TAIL(engine, ring->tail);
+               (void)I915_READ_TAIL(engine);
+       }
+
        /* Papering over lost _interrupts_ immediately following the restart */
        intel_engine_wakeup(engine);
 out:
@@ -574,7 +622,9 @@ static void skip_request(struct i915_request *rq)
 
 static void reset_ring(struct intel_engine_cs *engine, struct i915_request *rq)
 {
-       GEM_TRACE("%s seqno=%x\n", engine->name, rq ? rq->global_seqno : 0);
+       GEM_TRACE("%s request global=%d, current=%d\n",
+                 engine->name, rq ? rq->global_seqno : 0,
+                 intel_engine_get_seqno(engine));
 
        /*
         * Try to restore the logical GPU state to match the continuation
@@ -624,8 +674,6 @@ static int init_render_ring(struct intel_engine_cs *engine)
        if (ret)
                return ret;
 
-       intel_whitelist_workarounds_apply(engine);
-
        /* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */
        if (IS_GEN(dev_priv, 4, 6))
                I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH));
@@ -1021,8 +1069,7 @@ i915_emit_bb_start(struct i915_request *rq,
 int intel_ring_pin(struct intel_ring *ring)
 {
        struct i915_vma *vma = ring->vma;
-       enum i915_map_type map =
-               HAS_LLC(vma->vm->i915) ? I915_MAP_WB : I915_MAP_WC;
+       enum i915_map_type map = i915_coherent_map_type(vma->vm->i915);
        unsigned int flags;
        void *addr;
        int ret;