]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/gpu/drm/i915/intel_ringbuffer.h
Merge tag 'drm-intel-next-fixes-2016-05-25' of git://anongit.freedesktop.org/drm...
[mirror_ubuntu-artful-kernel.git] / drivers / gpu / drm / i915 / intel_ringbuffer.h
index 566b0ae10ce00f6a3eec840734c0c26c30aef27e..ff126485d398aaa0ffbaa104861a446e23b035b1 100644 (file)
@@ -52,34 +52,32 @@ struct  intel_hw_status_page {
 /* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to
  * do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
  */
-#define i915_semaphore_seqno_size sizeof(uint64_t)
+#define gen8_semaphore_seqno_size sizeof(uint64_t)
+#define GEN8_SEMAPHORE_OFFSET(__from, __to)                         \
+       (((__from) * I915_NUM_ENGINES  + (__to)) * gen8_semaphore_seqno_size)
 #define GEN8_SIGNAL_OFFSET(__ring, to)                      \
        (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
-       ((__ring)->id * I915_NUM_RINGS * i915_semaphore_seqno_size) +   \
-       (i915_semaphore_seqno_size * (to)))
-
+        GEN8_SEMAPHORE_OFFSET((__ring)->id, (to)))
 #define GEN8_WAIT_OFFSET(__ring, from)                      \
        (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
-       ((from) * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
-       (i915_semaphore_seqno_size * (__ring)->id))
+        GEN8_SEMAPHORE_OFFSET(from, (__ring)->id))
 
-#define GEN8_RING_SEMAPHORE_INIT do { \
+#define GEN8_RING_SEMAPHORE_INIT(e) do { \
        if (!dev_priv->semaphore_obj) { \
                break; \
        } \
-       ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(ring, RCS); \
-       ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(ring, VCS); \
-       ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(ring, BCS); \
-       ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(ring, VECS); \
-       ring->semaphore.signal_ggtt[VCS2] = GEN8_SIGNAL_OFFSET(ring, VCS2); \
-       ring->semaphore.signal_ggtt[ring->id] = MI_SEMAPHORE_SYNC_INVALID; \
+       (e)->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET((e), RCS); \
+       (e)->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET((e), VCS); \
+       (e)->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET((e), BCS); \
+       (e)->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET((e), VECS); \
+       (e)->semaphore.signal_ggtt[VCS2] = GEN8_SIGNAL_OFFSET((e), VCS2); \
+       (e)->semaphore.signal_ggtt[(e)->id] = MI_SEMAPHORE_SYNC_INVALID; \
        } while(0)
 
 enum intel_ring_hangcheck_action {
        HANGCHECK_IDLE = 0,
        HANGCHECK_WAIT,
        HANGCHECK_ACTIVE,
-       HANGCHECK_ACTIVE_LOOP,
        HANGCHECK_KICK,
        HANGCHECK_HUNG,
 };
@@ -88,8 +86,8 @@ enum intel_ring_hangcheck_action {
 
 struct intel_ring_hangcheck {
        u64 acthd;
-       u64 max_acthd;
        u32 seqno;
+       unsigned user_interrupts;
        int score;
        enum intel_ring_hangcheck_action action;
        int deadlock;
@@ -101,7 +99,7 @@ struct intel_ringbuffer {
        void __iomem *virtual_start;
        struct i915_vma *vma;
 
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        struct list_head link;
 
        u32 head;
@@ -110,8 +108,6 @@ struct intel_ringbuffer {
        int size;
        int effective_size;
        int reserved_size;
-       int reserved_tail;
-       bool reserved_in_use;
 
        /** We track the position of the requests in the ring buffer, and
         * when each is retired we increment last_retired_head as the GPU
@@ -125,7 +121,7 @@ struct intel_ringbuffer {
 };
 
 struct intel_context;
-struct drm_i915_reg_descriptor;
+struct drm_i915_reg_table;
 
 /*
  * we use a single page to load ctx workarounds so all of these
@@ -148,17 +144,18 @@ struct  i915_ctx_workarounds {
 
 struct  intel_engine_cs {
        const char      *name;
-       enum intel_ring_id {
+       enum intel_engine_id {
                RCS = 0,
                BCS,
                VCS,
                VCS2,   /* Keep instances of the same type engine together. */
                VECS
        } id;
-#define I915_NUM_RINGS 5
+#define I915_NUM_ENGINES 5
 #define _VCS(n) (VCS + (n))
        unsigned int exec_id;
-       unsigned int guc_id;
+       unsigned int hw_id;
+       unsigned int guc_id; /* XXX same as hw_id? */
        u32             mmio_base;
        struct          drm_device *dev;
        struct intel_ringbuffer *buffer;
@@ -196,8 +193,8 @@ struct  intel_engine_cs {
         * seen value is good enough. Note that the seqno will always be
         * monotonic, even if not coherent.
         */
-       u32             (*get_seqno)(struct intel_engine_cs *ring,
-                                    bool lazy_coherency);
+       void            (*irq_seqno_barrier)(struct intel_engine_cs *ring);
+       u32             (*get_seqno)(struct intel_engine_cs *ring);
        void            (*set_seqno)(struct intel_engine_cs *ring,
                                     u32 seqno);
        int             (*dispatch_execbuffer)(struct drm_i915_gem_request *req,
@@ -246,16 +243,16 @@ struct  intel_engine_cs {
         *  ie. transpose of f(x, y)
         */
        struct {
-               u32     sync_seqno[I915_NUM_RINGS-1];
+               u32     sync_seqno[I915_NUM_ENGINES-1];
 
                union {
                        struct {
                                /* our mbox written by others */
-                               u32             wait[I915_NUM_RINGS];
+                               u32             wait[I915_NUM_ENGINES];
                                /* mboxes this ring signals to */
-                               i915_reg_t      signal[I915_NUM_RINGS];
+                               i915_reg_t      signal[I915_NUM_ENGINES];
                        } mbox;
-                       u64             signal_ggtt[I915_NUM_RINGS];
+                       u64             signal_ggtt[I915_NUM_ENGINES];
                };
 
                /* AKA wait() */
@@ -268,10 +265,13 @@ struct  intel_engine_cs {
        } semaphore;
 
        /* Execlists */
-       spinlock_t execlist_lock;
+       struct tasklet_struct irq_tasklet;
+       spinlock_t execlist_lock; /* used inside tasklet, use spin_lock_bh */
        struct list_head execlist_queue;
        struct list_head execlist_retired_req_list;
-       u8 next_context_status_buffer;
+       unsigned int fw_domains;
+       unsigned int next_context_status_buffer;
+       unsigned int idle_lite_restore_wa;
        bool disable_lite_restore_wa;
        u32 ctx_desc_template;
        u32             irq_keep_mask; /* bitmask for interrupts that should not be masked */
@@ -306,6 +306,7 @@ struct  intel_engine_cs {
         * inspecting request list.
         */
        u32 last_submitted_seqno;
+       unsigned user_interrupts;
 
        bool gpu_caches_dirty;
 
@@ -332,15 +333,8 @@ struct  intel_engine_cs {
        /*
         * Table of registers allowed in commands that read/write registers.
         */
-       const struct drm_i915_reg_descriptor *reg_table;
-       int reg_count;
-
-       /*
-        * Table of registers allowed in commands that read/write registers, but
-        * only from the DRM master.
-        */
-       const struct drm_i915_reg_descriptor *master_reg_table;
-       int master_reg_count;
+       const struct drm_i915_reg_table *reg_tables;
+       int reg_table_count;
 
        /*
         * Returns the bitmask for the length field of the specified command.
@@ -356,19 +350,19 @@ struct  intel_engine_cs {
 };
 
 static inline bool
-intel_ring_initialized(struct intel_engine_cs *ring)
+intel_engine_initialized(struct intel_engine_cs *engine)
 {
-       return ring->dev != NULL;
+       return engine->dev != NULL;
 }
 
 static inline unsigned
-intel_ring_flag(struct intel_engine_cs *ring)
+intel_engine_flag(struct intel_engine_cs *engine)
 {
-       return 1 << ring->id;
+       return 1 << engine->id;
 }
 
 static inline u32
-intel_ring_sync_index(struct intel_engine_cs *ring,
+intel_ring_sync_index(struct intel_engine_cs *engine,
                      struct intel_engine_cs *other)
 {
        int idx;
@@ -381,34 +375,33 @@ intel_ring_sync_index(struct intel_engine_cs *ring,
         * vcs2 -> 0 = rcs, 1 = vcs, 2 = bcs, 3 = vecs;
         */
 
-       idx = (other - ring) - 1;
+       idx = (other - engine) - 1;
        if (idx < 0)
-               idx += I915_NUM_RINGS;
+               idx += I915_NUM_ENGINES;
 
        return idx;
 }
 
 static inline void
-intel_flush_status_page(struct intel_engine_cs *ring, int reg)
+intel_flush_status_page(struct intel_engine_cs *engine, int reg)
 {
-       drm_clflush_virt_range(&ring->status_page.page_addr[reg],
-                              sizeof(uint32_t));
+       mb();
+       clflush(&engine->status_page.page_addr[reg]);
+       mb();
 }
 
 static inline u32
-intel_read_status_page(struct intel_engine_cs *ring,
-                      int reg)
+intel_read_status_page(struct intel_engine_cs *engine, int reg)
 {
        /* Ensure that the compiler doesn't optimize away the load. */
-       barrier();
-       return ring->status_page.page_addr[reg];
+       return READ_ONCE(engine->status_page.page_addr[reg]);
 }
 
 static inline void
-intel_write_status_page(struct intel_engine_cs *ring,
+intel_write_status_page(struct intel_engine_cs *engine,
                        int reg, u32 value)
 {
-       ring->status_page.page_addr[reg] = value;
+       engine->status_page.page_addr[reg] = value;
 }
 
 /*
@@ -439,42 +432,41 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
 void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf);
 void intel_ringbuffer_free(struct intel_ringbuffer *ring);
 
-void intel_stop_ring_buffer(struct intel_engine_cs *ring);
-void intel_cleanup_ring_buffer(struct intel_engine_cs *ring);
+void intel_stop_engine(struct intel_engine_cs *engine);
+void intel_cleanup_engine(struct intel_engine_cs *engine);
 
 int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request);
 
 int __must_check intel_ring_begin(struct drm_i915_gem_request *req, int n);
 int __must_check intel_ring_cacheline_align(struct drm_i915_gem_request *req);
-static inline void intel_ring_emit(struct intel_engine_cs *ring,
+static inline void intel_ring_emit(struct intel_engine_cs *engine,
                                   u32 data)
 {
-       struct intel_ringbuffer *ringbuf = ring->buffer;
+       struct intel_ringbuffer *ringbuf = engine->buffer;
        iowrite32(data, ringbuf->virtual_start + ringbuf->tail);
        ringbuf->tail += 4;
 }
-static inline void intel_ring_emit_reg(struct intel_engine_cs *ring,
+static inline void intel_ring_emit_reg(struct intel_engine_cs *engine,
                                       i915_reg_t reg)
 {
-       intel_ring_emit(ring, i915_mmio_reg_offset(reg));
+       intel_ring_emit(engine, i915_mmio_reg_offset(reg));
 }
-static inline void intel_ring_advance(struct intel_engine_cs *ring)
+static inline void intel_ring_advance(struct intel_engine_cs *engine)
 {
-       struct intel_ringbuffer *ringbuf = ring->buffer;
+       struct intel_ringbuffer *ringbuf = engine->buffer;
        ringbuf->tail &= ringbuf->size - 1;
 }
 int __intel_ring_space(int head, int tail, int size);
 void intel_ring_update_space(struct intel_ringbuffer *ringbuf);
-int intel_ring_space(struct intel_ringbuffer *ringbuf);
-bool intel_ring_stopped(struct intel_engine_cs *ring);
+bool intel_engine_stopped(struct intel_engine_cs *engine);
 
-int __must_check intel_ring_idle(struct intel_engine_cs *ring);
-void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno);
+int __must_check intel_engine_idle(struct intel_engine_cs *engine);
+void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno);
 int intel_ring_flush_all_caches(struct drm_i915_gem_request *req);
 int intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req);
 
-void intel_fini_pipe_control(struct intel_engine_cs *ring);
-int intel_init_pipe_control(struct intel_engine_cs *ring);
+void intel_fini_pipe_control(struct intel_engine_cs *engine);
+int intel_init_pipe_control(struct intel_engine_cs *engine);
 
 int intel_init_render_ring_buffer(struct drm_device *dev);
 int intel_init_bsd_ring_buffer(struct drm_device *dev);
@@ -482,9 +474,9 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev);
 int intel_init_blt_ring_buffer(struct drm_device *dev);
 int intel_init_vebox_ring_buffer(struct drm_device *dev);
 
-u64 intel_ring_get_active_head(struct intel_engine_cs *ring);
+u64 intel_ring_get_active_head(struct intel_engine_cs *engine);
 
-int init_workarounds_ring(struct intel_engine_cs *ring);
+int init_workarounds_ring(struct intel_engine_cs *engine);
 
 static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf)
 {