drm/i915: Sync intel_ringbuffer.h with Linux 3.8.13
authorFrançois Tigeot <ftigeot@wolfpond.org>
Sat, 5 Jul 2014 15:24:25 +0000 (17:24 +0200)
committerFrançois Tigeot <ftigeot@wolfpond.org>
Sat, 5 Jul 2014 15:37:28 +0000 (17:37 +0200)
sys/dev/drm/i915/i915_drv.h
sys/dev/drm/i915/i915_gem.c
sys/dev/drm/i915/i915_gem_execbuffer.c
sys/dev/drm/i915/intel_ringbuffer.h

index 2e21fa6..ffb51a6 100644 (file)
@@ -1456,6 +1456,7 @@ int i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj);
 int i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
 int i915_gem_idle(struct drm_device *dev);
 int i915_gem_init_hw(struct drm_device *dev);
+void i915_gem_l3_remap(struct drm_device *dev);
 void i915_gem_init_swizzling(struct drm_device *dev);
 void i915_gem_init_ppgtt(struct drm_device *dev);
 void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
index e5f01dd..2f04e39 100644 (file)
@@ -2705,6 +2705,38 @@ i915_gem_idle(struct drm_device *dev)
        return (ret);
 }
 
+void i915_gem_l3_remap(struct drm_device *dev)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       u32 misccpctl;
+       int i;
+
+       if (!HAS_L3_GPU_CACHE(dev))
+               return;
+
+       if (!dev_priv->l3_parity.remap_info)
+               return;
+
+       misccpctl = I915_READ(GEN7_MISCCPCTL);
+       I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+       POSTING_READ(GEN7_MISCCPCTL);
+
+       for (i = 0; i < GEN7_L3LOG_SIZE; i += 4) {
+               u32 remap = I915_READ(GEN7_L3LOG_BASE + i);
+               if (remap && remap != dev_priv->l3_parity.remap_info[i/4])
+                       DRM_DEBUG("0x%x was already programmed to %x\n",
+                                 GEN7_L3LOG_BASE + i, remap);
+               if (remap && !dev_priv->l3_parity.remap_info[i/4])
+                       DRM_DEBUG_DRIVER("Clearing remapped register\n");
+               I915_WRITE(GEN7_L3LOG_BASE + i, dev_priv->l3_parity.remap_info[i/4]);
+       }
+
+       /* Make sure all the writes land before disabling dop clock gating */
+       POSTING_READ(GEN7_L3LOG_BASE);
+
+       I915_WRITE(GEN7_MISCCPCTL, misccpctl);
+}
+
 void
 i915_gem_init_swizzling(struct drm_device *dev)
 {
@@ -2729,41 +2761,72 @@ i915_gem_init_swizzling(struct drm_device *dev)
                I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB));
 }
 
+static bool
+intel_enable_blt(struct drm_device *dev)
+{
+       int revision;
+
+       if (!HAS_BLT(dev))
+               return false;
+
+       /* The blitter was dysfunctional on early prototypes */
+       revision = pci_read_config(dev->dev, PCIR_REVID, 1);
+       if (IS_GEN6(dev) && revision < 8) {
+               DRM_INFO("BLT not supported on this pre-production hardware;"
+                        " graphics performance will be degraded.\n");
+               return false;
+       }
+
+       return true;
+}
+
 int
 i915_gem_init_hw(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv;
+       drm_i915_private_t *dev_priv = dev->dev_private;
        int ret;
 
-       dev_priv = dev->dev_private;
+       if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1))
+               I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000);
+
+       i915_gem_l3_remap(dev);
 
        i915_gem_init_swizzling(dev);
 
        ret = intel_init_render_ring_buffer(dev);
-       if (ret != 0)
-               return (ret);
+       if (ret)
+               return ret;
 
        if (HAS_BSD(dev)) {
                ret = intel_init_bsd_ring_buffer(dev);
-               if (ret != 0)
+               if (ret)
                        goto cleanup_render_ring;
        }
 
-       if (HAS_BLT(dev)) {
+       if (intel_enable_blt(dev)) {
                ret = intel_init_blt_ring_buffer(dev);
-               if (ret != 0)
+               if (ret)
                        goto cleanup_bsd_ring;
        }
 
        dev_priv->next_seqno = 1;
+
+       /*
+        * XXX: There was some w/a described somewhere suggesting loading
+        * contexts before PPGTT.
+        */
+#if 0  /* XXX: HW context support */
+       i915_gem_context_init(dev);
+#endif
        i915_gem_init_ppgtt(dev);
-       return (0);
+
+       return 0;
 
 cleanup_bsd_ring:
        intel_cleanup_ring_buffer(&dev_priv->ring[VCS]);
 cleanup_render_ring:
        intel_cleanup_ring_buffer(&dev_priv->ring[RCS]);
-       return (ret);
+       return ret;
 }
 
 void
index 8be72f4..e23de23 100644 (file)
@@ -1153,6 +1153,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
        u32 exec_start, exec_len;
        u32 seqno;
        u32 mask;
+       u32 flags;
        int ret, mode, i;
 
        if (!i915_gem_check_execbuffer(args)) {
@@ -1164,8 +1165,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                return (0);
 
        ret = validate_exec_list(exec, args->buffer_count, &relocs_ma);
-       if (ret != 0)
-               goto pre_struct_lock_err;
+       if (ret)
+               return ret;
+
+       flags = 0;
+       if (args->flags & I915_EXEC_SECURE) {
+               flags |= I915_DISPATCH_SECURE;
+       }
+       if (args->flags & I915_EXEC_IS_PINNED)
+               flags |= I915_DISPATCH_PINNED;
 
        switch (args->flags & I915_EXEC_RING_MASK) {
        case I915_EXEC_DEFAULT:
@@ -1322,6 +1330,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
        }
        batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
 
+       /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
+        * batch" bit. Hence we need to pin secure batches into the global gtt.
+        * hsw should have this fixed, but let's be paranoid and do it
+        * unconditionally for now. */
+       if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping)
+               i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level);
+
        ret = i915_gem_execbuffer_move_to_gpu(ring, &objects);
        if (ret)
                goto err;
@@ -1377,13 +1392,14 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                        if (ret)
                                goto err;
 
-                       ret = ring->dispatch_execbuffer(ring, exec_start,
-                           exec_len);
+                       ret = ring->dispatch_execbuffer(ring,
+                                                       exec_start, exec_len);
                        if (ret)
                                goto err;
                }
        } else {
-               ret = ring->dispatch_execbuffer(ring, exec_start, exec_len);
+               ret = ring->dispatch_execbuffer(ring,
+                                               exec_start, exec_len);
                if (ret)
                        goto err;
        }
index 537377e..8a64a4c 100644 (file)
@@ -47,13 +47,13 @@ struct  intel_ring_buffer {
                BCS,
        } id;
 #define I915_NUM_RINGS 3
-       uint32_t        mmio_base;
-       void            *virtual_start;
+       u32             mmio_base;
+       void            __iomem *virtual_start;
        struct          drm_device *dev;
        struct          drm_i915_gem_object *obj;
 
-       uint32_t        head;
-       uint32_t        tail;
+       u32             head;
+       u32             tail;
        int             space;
        int             size;
        int             effective_size;
@@ -70,20 +70,21 @@ struct  intel_ring_buffer {
        u32             last_retired_head;
 
        struct lock     irq_lock;
-       u32             irq_refcount;
        u32             irq_mask;
+       u32             irq_refcount;           /* protected by dev_priv->irq_lock */
+       u32             irq_enable_mask;        /* bitmask to enable ring interrupt */
        u32             trace_irq_seqno;
        u32             sync_seqno[I915_NUM_RINGS-1];
-       bool            (*irq_get)(struct intel_ring_buffer *ring);
+       bool __must_check (*irq_get)(struct intel_ring_buffer *ring);
        void            (*irq_put)(struct intel_ring_buffer *ring);
 
        int             (*init)(struct intel_ring_buffer *ring);
 
        void            (*write_tail)(struct intel_ring_buffer *ring,
-                                     uint32_t value);
-       int             (*flush)(struct intel_ring_buffer *ring,
-                                 uint32_t      invalidate_domains,
-                                 uint32_t      flush_domains);
+                                     u32 value);
+       int __must_check (*flush)(struct intel_ring_buffer *ring,
+                                 u32   invalidate_domains,
+                                 u32   flush_domains);
        int             (*add_request)(struct intel_ring_buffer *ring,
                                       uint32_t *seqno);
        /* Some chipsets are not quite as coherent as advertised and need
@@ -96,14 +97,15 @@ struct  intel_ring_buffer {
                                     bool lazy_coherency);
        int             (*dispatch_execbuffer)(struct intel_ring_buffer *ring,
                                               uint32_t offset, uint32_t length);
+#define I915_DISPATCH_SECURE 0x1
+#define I915_DISPATCH_PINNED 0x2
        void            (*cleanup)(struct intel_ring_buffer *ring);
        int             (*sync_to)(struct intel_ring_buffer *ring,
                                   struct intel_ring_buffer *to,
                                   u32 seqno);
+
        u32             semaphore_register[3]; /*our mbox written by others */
        u32             signal_mbox[2]; /* mboxes this ring signals to */
-
        /**
         * List of objects currently involved in rendering from the
         * ringbuffer.
@@ -122,25 +124,25 @@ struct  intel_ring_buffer {
         */
        struct list_head request_list;
 
-       /**
-        * List of objects currently pending a GPU write flush.
-        *
-        * All elements on this list will belong to either the
-        * active_list or flushing_list, last_rendering_seqno can
-        * be used to differentiate between the two elements.
-        */
        struct list_head gpu_write_list;
 
        /**
         * Do we have some not yet emitted requests outstanding?
         */
-       uint32_t outstanding_lazy_request;
+       u32 outstanding_lazy_request;
        bool gpu_caches_dirty;
 
        wait_queue_head_t irq_queue;
 
        drm_local_map_t map;
 
+       /**
+        * Do an explicit TLB flush before MI_SET_CONTEXT
+        */
+       bool itlb_before_ctx_switch;
+       struct i915_hw_context *default_context;
+       struct drm_i915_gem_object *last_context_obj;
+
        void *private;
 };