drm/i915/skl: Program the DDB allocation
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_lrc.c
index c096b9b7f22a222bb80a1eb56731cd23c7603e1b..292beb0fa1dca3ea520fad0b2bf6ce9fb493eff0 100644 (file)
@@ -300,8 +300,18 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
         * Instead, we do the runtime_pm_get/put when creating/destroying requests.
         */
        spin_lock_irqsave(&dev_priv->uncore.lock, flags);
-       if (dev_priv->uncore.forcewake_count++ == 0)
-               dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL);
+       if (IS_CHERRYVIEW(dev_priv->dev)) {
+               if (dev_priv->uncore.fw_rendercount++ == 0)
+                       dev_priv->uncore.funcs.force_wake_get(dev_priv,
+                                                             FORCEWAKE_RENDER);
+               if (dev_priv->uncore.fw_mediacount++ == 0)
+                       dev_priv->uncore.funcs.force_wake_get(dev_priv,
+                                                             FORCEWAKE_MEDIA);
+       } else {
+               if (dev_priv->uncore.forcewake_count++ == 0)
+                       dev_priv->uncore.funcs.force_wake_get(dev_priv,
+                                                             FORCEWAKE_ALL);
+       }
        spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
 
        I915_WRITE(RING_ELSP(ring), desc[1]);
@@ -315,8 +325,19 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
 
        /* Release Force Wakeup (see the big comment above). */
        spin_lock_irqsave(&dev_priv->uncore.lock, flags);
-       if (--dev_priv->uncore.forcewake_count == 0)
-               dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
+       if (IS_CHERRYVIEW(dev_priv->dev)) {
+               if (--dev_priv->uncore.fw_rendercount == 0)
+                       dev_priv->uncore.funcs.force_wake_put(dev_priv,
+                                                             FORCEWAKE_RENDER);
+               if (--dev_priv->uncore.fw_mediacount == 0)
+                       dev_priv->uncore.funcs.force_wake_put(dev_priv,
+                                                             FORCEWAKE_MEDIA);
+       } else {
+               if (--dev_priv->uncore.forcewake_count == 0)
+                       dev_priv->uncore.funcs.force_wake_put(dev_priv,
+                                                             FORCEWAKE_ALL);
+       }
+
        spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
 }
 
@@ -335,9 +356,9 @@ static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tai
        return 0;
 }
 
-static int execlists_submit_context(struct intel_engine_cs *ring,
-                                   struct intel_context *to0, u32 tail0,
-                                   struct intel_context *to1, u32 tail1)
+static void execlists_submit_contexts(struct intel_engine_cs *ring,
+                                     struct intel_context *to0, u32 tail0,
+                                     struct intel_context *to1, u32 tail1)
 {
        struct drm_i915_gem_object *ctx_obj0;
        struct drm_i915_gem_object *ctx_obj1 = NULL;
@@ -357,8 +378,6 @@ static int execlists_submit_context(struct intel_engine_cs *ring,
        }
 
        execlists_elsp_write(ring, ctx_obj0, ctx_obj1);
-
-       return 0;
 }
 
 static void execlists_context_unqueue(struct intel_engine_cs *ring)
@@ -392,9 +411,9 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
 
        WARN_ON(req1 && req1->elsp_submitted);
 
-       WARN_ON(execlists_submit_context(ring, req0->ctx, req0->tail,
-                                        req1 ? req1->ctx : NULL,
-                                        req1 ? req1->tail : 0));
+       execlists_submit_contexts(ring, req0->ctx, req0->tail,
+                                 req1 ? req1->ctx : NULL,
+                                 req1 ? req1->tail : 0);
 
        req0->elsp_submitted++;
        if (req1)
@@ -1042,7 +1061,7 @@ static bool gen8_logical_ring_get_irq(struct intel_engine_cs *ring)
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long flags;
 
-       if (!dev->irq_enabled)
+       if (WARN_ON(!intel_irqs_enabled(dev_priv)))
                return false;
 
        spin_lock_irqsave(&dev_priv->irq_lock, flags);
@@ -1193,11 +1212,13 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf)
  */
 void intel_logical_ring_cleanup(struct intel_engine_cs *ring)
 {
-       struct drm_i915_private *dev_priv = ring->dev->dev_private;
+       struct drm_i915_private *dev_priv;
 
        if (!intel_ring_initialized(ring))
                return;
 
+       dev_priv = ring->dev->dev_private;
+
        intel_logical_ring_stop(ring);
        WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0);
        ring->preallocated_lazy_request = NULL;
@@ -1217,8 +1238,6 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring)
 static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring)
 {
        int ret;
-       struct intel_context *dctx = ring->default_context;
-       struct drm_i915_gem_object *dctx_obj;
 
        /* Intentionally left blank. */
        ring->buffer = NULL;
@@ -1232,18 +1251,6 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
        spin_lock_init(&ring->execlist_lock);
        ring->next_context_status_buffer = 0;
 
-       ret = intel_lr_context_deferred_create(dctx, ring);
-       if (ret)
-               return ret;
-
-       /* The status page is offset 0 from the context object in LRCs. */
-       dctx_obj = dctx->engine[ring->id].state;
-       ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(dctx_obj);
-       ring->status_page.page_addr = kmap(sg_page(dctx_obj->pages->sgl));
-       if (ring->status_page.page_addr == NULL)
-               return -ENOMEM;
-       ring->status_page.obj = dctx_obj;
-
        ret = i915_cmd_parser_init_ring(ring);
        if (ret)
                return ret;
@@ -1254,7 +1261,9 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
                        return ret;
        }
 
-       return 0;
+       ret = intel_lr_context_deferred_create(ring->default_context, ring);
+
+       return ret;
 }
 
 static int logical_render_ring_init(struct drm_device *dev)
@@ -1448,16 +1457,53 @@ cleanup_render_ring:
        return ret;
 }
 
+int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
+                                      struct intel_context *ctx)
+{
+       struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf;
+       struct render_state so;
+       struct drm_i915_file_private *file_priv = ctx->file_priv;
+       struct drm_file *file = file_priv ? file_priv->file : NULL;
+       int ret;
+
+       ret = i915_gem_render_state_prepare(ring, &so);
+       if (ret)
+               return ret;
+
+       if (so.rodata == NULL)
+               return 0;
+
+       ret = ring->emit_bb_start(ringbuf,
+                       so.ggtt_offset,
+                       I915_DISPATCH_SECURE);
+       if (ret)
+               goto out;
+
+       i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
+
+       ret = __i915_add_request(ring, file, so.obj, NULL);
+       /* intel_logical_ring_add_request moves object to inactive if it
+        * fails */
+out:
+       i915_gem_render_state_fini(&so);
+       return ret;
+}
+
 static int
 populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_obj,
                    struct intel_engine_cs *ring, struct intel_ringbuffer *ringbuf)
 {
+       struct drm_device *dev = ring->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *ring_obj = ringbuf->obj;
        struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
        struct page *page;
        uint32_t *reg_state;
        int ret;
 
+       if (!ppgtt)
+               ppgtt = dev_priv->mm.aliasing_ppgtt;
+
        ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true);
        if (ret) {
                DRM_DEBUG_DRIVER("Could not set to CPU domain\n");
@@ -1603,6 +1649,27 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring)
        return ret;
 }
 
+static int lrc_setup_hardware_status_page(struct intel_engine_cs *ring,
+               struct drm_i915_gem_object *default_ctx_obj)
+{
+       struct drm_i915_private *dev_priv = ring->dev->dev_private;
+
+       /* The status page is offset 0 from the default context object
+        * in LRC mode. */
+       ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(default_ctx_obj);
+       ring->status_page.page_addr =
+                       kmap(sg_page(default_ctx_obj->pages->sgl));
+       if (ring->status_page.page_addr == NULL)
+               return -ENOMEM;
+       ring->status_page.obj = default_ctx_obj;
+
+       I915_WRITE(RING_HWS_PGA(ring->mmio_base),
+                       (u32)ring->status_page.gfx_addr);
+       POSTING_READ(RING_HWS_PGA(ring->mmio_base));
+
+       return 0;
+}
+
 /**
  * intel_lr_context_deferred_create() - create the LRC specific bits of a context
  * @ctx: LR context to create.
@@ -1687,6 +1754,26 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
        ctx->engine[ring->id].ringbuf = ringbuf;
        ctx->engine[ring->id].state = ctx_obj;
 
+       if (ctx == ring->default_context) {
+               ret = lrc_setup_hardware_status_page(ring, ctx_obj);
+               if (ret) {
+                       DRM_ERROR("Failed to setup hardware status page\n");
+                       goto error;
+               }
+       }
+
+       if (ring->id == RCS && !ctx->rcs_initialized) {
+               ret = intel_lr_context_render_state_init(ring, ctx);
+               if (ret) {
+                       DRM_ERROR("Init render state failed: %d\n", ret);
+                       ctx->engine[ring->id].ringbuf = NULL;
+                       ctx->engine[ring->id].state = NULL;
+                       intel_destroy_ringbuffer_obj(ringbuf);
+                       goto error;
+               }
+               ctx->rcs_initialized = true;
+       }
+
        return 0;
 
 error:
This page took 0.030192 seconds and 5 git commands to generate.