1e3adcf8fSFrançois Tigeot #ifndef _INTEL_RINGBUFFER_H_ 2e3adcf8fSFrançois Tigeot #define _INTEL_RINGBUFFER_H_ 3e3adcf8fSFrançois Tigeot 4ba55f2f5SFrançois Tigeot #include <linux/hashtable.h> 519c468b4SFrançois Tigeot #include "i915_gem_batch_pool.h" 671f41f3eSFrançois Tigeot #include "i915_gem_request.h" 74be47400SFrançois Tigeot #include "i915_gem_timeline.h" 8*a85cb24fSFrançois Tigeot #include "i915_selftest.h" 9ba55f2f5SFrançois Tigeot 10ba55f2f5SFrançois Tigeot #define I915_CMD_HASH_ORDER 9 11ba55f2f5SFrançois Tigeot 121b13d190SFrançois Tigeot /* Early gen2 devices have a cacheline of just 32 bytes, using 64 is overkill, 131b13d190SFrançois Tigeot * but keeps the logic simple. Indeed, the whole purpose of this macro is just 141b13d190SFrançois Tigeot * to give some inclination as to some of the magic values used in the various 151b13d190SFrançois Tigeot * workarounds! 161b13d190SFrançois Tigeot */ 171b13d190SFrançois Tigeot #define CACHELINE_BYTES 64 18a05eeebfSFrançois Tigeot #define CACHELINE_DWORDS (CACHELINE_BYTES / sizeof(uint32_t)) 191b13d190SFrançois Tigeot 20f4e1c372SFrançois Tigeot /* 21f4e1c372SFrançois Tigeot * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use" 22f4e1c372SFrançois Tigeot * Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use" 23f4e1c372SFrançois Tigeot * Gen4+ BSpec "vol1c Memory Interface and Command Stream" / 5.3.4.5 "Ring Buffer Use" 24f4e1c372SFrançois Tigeot * 25f4e1c372SFrançois Tigeot * "If the Ring Buffer Head Pointer and the Tail Pointer are on the same 26f4e1c372SFrançois Tigeot * cacheline, the Head Pointer must not be greater than the Tail 27f4e1c372SFrançois Tigeot * Pointer." 28f4e1c372SFrançois Tigeot */ 29f4e1c372SFrançois Tigeot #define I915_RING_FREE_SPACE 64 30f4e1c372SFrançois Tigeot 31e3adcf8fSFrançois Tigeot struct intel_hw_status_page { 321e12ee3bSFrançois Tigeot struct i915_vma *vma; 33f4e1c372SFrançois Tigeot u32 *page_addr; 341e12ee3bSFrançois Tigeot u32 ggtt_offset; 35e3adcf8fSFrançois Tigeot }; 36e3adcf8fSFrançois Tigeot 3787df8fc6SFrançois Tigeot #define I915_READ_TAIL(engine) I915_READ(RING_TAIL((engine)->mmio_base)) 3887df8fc6SFrançois Tigeot #define I915_WRITE_TAIL(engine, val) I915_WRITE(RING_TAIL((engine)->mmio_base), val) 39e3adcf8fSFrançois Tigeot 4087df8fc6SFrançois Tigeot #define I915_READ_START(engine) I915_READ(RING_START((engine)->mmio_base)) 4187df8fc6SFrançois Tigeot #define I915_WRITE_START(engine, val) I915_WRITE(RING_START((engine)->mmio_base), val) 42e3adcf8fSFrançois Tigeot 4387df8fc6SFrançois Tigeot #define I915_READ_HEAD(engine) I915_READ(RING_HEAD((engine)->mmio_base)) 4487df8fc6SFrançois Tigeot #define I915_WRITE_HEAD(engine, val) I915_WRITE(RING_HEAD((engine)->mmio_base), val) 45e3adcf8fSFrançois Tigeot 4687df8fc6SFrançois Tigeot #define I915_READ_CTL(engine) I915_READ(RING_CTL((engine)->mmio_base)) 4787df8fc6SFrançois Tigeot #define I915_WRITE_CTL(engine, val) I915_WRITE(RING_CTL((engine)->mmio_base), val) 48e3adcf8fSFrançois Tigeot 4987df8fc6SFrançois Tigeot #define I915_READ_IMR(engine) I915_READ(RING_IMR((engine)->mmio_base)) 5087df8fc6SFrançois Tigeot #define I915_WRITE_IMR(engine, val) I915_WRITE(RING_IMR((engine)->mmio_base), val) 51e3adcf8fSFrançois Tigeot 5287df8fc6SFrançois Tigeot #define I915_READ_MODE(engine) I915_READ(RING_MI_MODE((engine)->mmio_base)) 5387df8fc6SFrançois Tigeot #define I915_WRITE_MODE(engine, val) I915_WRITE(RING_MI_MODE((engine)->mmio_base), val) 54ba55f2f5SFrançois Tigeot 5524edb884SFrançois Tigeot /* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to 5624edb884SFrançois Tigeot * do the writes, and that must have qw aligned offsets, simply pretend it's 8b. 5724edb884SFrançois Tigeot */ 588621f407SFrançois Tigeot #define gen8_semaphore_seqno_size sizeof(uint64_t) 598621f407SFrançois Tigeot #define GEN8_SEMAPHORE_OFFSET(__from, __to) \ 608621f407SFrançois Tigeot (((__from) * I915_NUM_ENGINES + (__to)) * gen8_semaphore_seqno_size) 6124edb884SFrançois Tigeot #define GEN8_SIGNAL_OFFSET(__ring, to) \ 621e12ee3bSFrançois Tigeot (dev_priv->semaphore->node.start + \ 638621f407SFrançois Tigeot GEN8_SEMAPHORE_OFFSET((__ring)->id, (to))) 6424edb884SFrançois Tigeot #define GEN8_WAIT_OFFSET(__ring, from) \ 651e12ee3bSFrançois Tigeot (dev_priv->semaphore->node.start + \ 668621f407SFrançois Tigeot GEN8_SEMAPHORE_OFFSET(from, (__ring)->id)) 6724edb884SFrançois Tigeot 6871f41f3eSFrançois Tigeot enum intel_engine_hangcheck_action { 69*a85cb24fSFrançois Tigeot ENGINE_IDLE = 0, 70*a85cb24fSFrançois Tigeot ENGINE_WAIT, 71*a85cb24fSFrançois Tigeot ENGINE_ACTIVE_SEQNO, 72*a85cb24fSFrançois Tigeot ENGINE_ACTIVE_HEAD, 73*a85cb24fSFrançois Tigeot ENGINE_ACTIVE_SUBUNITS, 74*a85cb24fSFrançois Tigeot ENGINE_WAIT_KICK, 75*a85cb24fSFrançois Tigeot ENGINE_DEAD, 769edbd4a0SFrançois Tigeot }; 775d0b1887SFrançois Tigeot 78*a85cb24fSFrançois Tigeot static inline const char * 79*a85cb24fSFrançois Tigeot hangcheck_action_to_str(const enum intel_engine_hangcheck_action a) 80*a85cb24fSFrançois Tigeot { 81*a85cb24fSFrançois Tigeot switch (a) { 82*a85cb24fSFrançois Tigeot case ENGINE_IDLE: 83*a85cb24fSFrançois Tigeot return "idle"; 84*a85cb24fSFrançois Tigeot case ENGINE_WAIT: 85*a85cb24fSFrançois Tigeot return "wait"; 86*a85cb24fSFrançois Tigeot case ENGINE_ACTIVE_SEQNO: 87*a85cb24fSFrançois Tigeot return "active seqno"; 88*a85cb24fSFrançois Tigeot case ENGINE_ACTIVE_HEAD: 89*a85cb24fSFrançois Tigeot return "active head"; 90*a85cb24fSFrançois Tigeot case ENGINE_ACTIVE_SUBUNITS: 91*a85cb24fSFrançois Tigeot return "active subunits"; 92*a85cb24fSFrançois Tigeot case ENGINE_WAIT_KICK: 93*a85cb24fSFrançois Tigeot return "wait kick"; 94*a85cb24fSFrançois Tigeot case ENGINE_DEAD: 95*a85cb24fSFrançois Tigeot return "dead"; 96*a85cb24fSFrançois Tigeot } 97*a85cb24fSFrançois Tigeot 98*a85cb24fSFrançois Tigeot return "unknown"; 99*a85cb24fSFrançois Tigeot } 100ba55f2f5SFrançois Tigeot 1011e12ee3bSFrançois Tigeot #define I915_MAX_SLICES 3 1021e12ee3bSFrançois Tigeot #define I915_MAX_SUBSLICES 3 1031e12ee3bSFrançois Tigeot 1041e12ee3bSFrançois Tigeot #define instdone_slice_mask(dev_priv__) \ 1051e12ee3bSFrançois Tigeot (INTEL_GEN(dev_priv__) == 7 ? \ 1061e12ee3bSFrançois Tigeot 1 : INTEL_INFO(dev_priv__)->sseu.slice_mask) 1071e12ee3bSFrançois Tigeot 1081e12ee3bSFrançois Tigeot #define instdone_subslice_mask(dev_priv__) \ 1091e12ee3bSFrançois Tigeot (INTEL_GEN(dev_priv__) == 7 ? \ 1101e12ee3bSFrançois Tigeot 1 : INTEL_INFO(dev_priv__)->sseu.subslice_mask) 1111e12ee3bSFrançois Tigeot 1121e12ee3bSFrançois Tigeot #define for_each_instdone_slice_subslice(dev_priv__, slice__, subslice__) \ 1131e12ee3bSFrançois Tigeot for ((slice__) = 0, (subslice__) = 0; \ 1141e12ee3bSFrançois Tigeot (slice__) < I915_MAX_SLICES; \ 1151e12ee3bSFrançois Tigeot (subslice__) = ((subslice__) + 1) < I915_MAX_SUBSLICES ? (subslice__) + 1 : 0, \ 1161e12ee3bSFrançois Tigeot (slice__) += ((subslice__) == 0)) \ 1171e12ee3bSFrançois Tigeot for_each_if((BIT(slice__) & instdone_slice_mask(dev_priv__)) && \ 1181e12ee3bSFrançois Tigeot (BIT(subslice__) & instdone_subslice_mask(dev_priv__))) 1191e12ee3bSFrançois Tigeot 1201e12ee3bSFrançois Tigeot struct intel_instdone { 1211e12ee3bSFrançois Tigeot u32 instdone; 1221e12ee3bSFrançois Tigeot /* The following exist only in the RCS engine */ 1231e12ee3bSFrançois Tigeot u32 slice_common; 1241e12ee3bSFrançois Tigeot u32 sampler[I915_MAX_SLICES][I915_MAX_SUBSLICES]; 1251e12ee3bSFrançois Tigeot u32 row[I915_MAX_SLICES][I915_MAX_SUBSLICES]; 1261e12ee3bSFrançois Tigeot }; 1271e12ee3bSFrançois Tigeot 12871f41f3eSFrançois Tigeot struct intel_engine_hangcheck { 129ba55f2f5SFrançois Tigeot u64 acthd; 1305d0b1887SFrançois Tigeot u32 seqno; 13171f41f3eSFrançois Tigeot enum intel_engine_hangcheck_action action; 132*a85cb24fSFrançois Tigeot unsigned long action_timestamp; 133ba55f2f5SFrançois Tigeot int deadlock; 1341e12ee3bSFrançois Tigeot struct intel_instdone instdone; 135*a85cb24fSFrançois Tigeot bool stalled; 1365d0b1887SFrançois Tigeot }; 1375d0b1887SFrançois Tigeot 13871f41f3eSFrançois Tigeot struct intel_ring { 139c0e85e96SFrançois Tigeot struct i915_vma *vma; 1401e12ee3bSFrançois Tigeot void *vaddr; 141e3adcf8fSFrançois Tigeot 1428621f407SFrançois Tigeot struct intel_engine_cs *engine; 1431b13d190SFrançois Tigeot 14471f41f3eSFrançois Tigeot struct list_head request_list; 14571f41f3eSFrançois Tigeot 14615ac6249SFrançois Tigeot u32 head; 14715ac6249SFrançois Tigeot u32 tail; 148*a85cb24fSFrançois Tigeot u32 emit; 149*a85cb24fSFrançois Tigeot 150e3adcf8fSFrançois Tigeot int space; 151e3adcf8fSFrançois Tigeot int size; 152e3adcf8fSFrançois Tigeot int effective_size; 153ba55f2f5SFrançois Tigeot }; 154ba55f2f5SFrançois Tigeot 1551487f786SFrançois Tigeot struct i915_gem_context; 1568621f407SFrançois Tigeot struct drm_i915_reg_table; 1572c9916cdSFrançois Tigeot 158a05eeebfSFrançois Tigeot /* 159a05eeebfSFrançois Tigeot * we use a single page to load ctx workarounds so all of these 160a05eeebfSFrançois Tigeot * values are referred in terms of dwords 161a05eeebfSFrançois Tigeot * 162a05eeebfSFrançois Tigeot * struct i915_wa_ctx_bb: 163a05eeebfSFrançois Tigeot * offset: specifies batch starting position, also helpful in case 164a05eeebfSFrançois Tigeot * if we want to have multiple batches at different offsets based on 165a05eeebfSFrançois Tigeot * some criteria. It is not a requirement at the moment but provides 166a05eeebfSFrançois Tigeot * an option for future use. 167a05eeebfSFrançois Tigeot * size: size of the batch in DWORDS 168a05eeebfSFrançois Tigeot */ 169a05eeebfSFrançois Tigeot struct i915_ctx_workarounds { 170a05eeebfSFrançois Tigeot struct i915_wa_ctx_bb { 171a05eeebfSFrançois Tigeot u32 offset; 172a05eeebfSFrançois Tigeot u32 size; 173a05eeebfSFrançois Tigeot } indirect_ctx, per_ctx; 1741e12ee3bSFrançois Tigeot struct i915_vma *vma; 175a05eeebfSFrançois Tigeot }; 176a05eeebfSFrançois Tigeot 177303bf270SFrançois Tigeot struct drm_i915_gem_request; 1784be47400SFrançois Tigeot struct intel_render_state; 179303bf270SFrançois Tigeot 180*a85cb24fSFrançois Tigeot /* 181*a85cb24fSFrançois Tigeot * Engine IDs definitions. 182*a85cb24fSFrançois Tigeot * Keep instances of the same type engine together. 183*a85cb24fSFrançois Tigeot */ 1848621f407SFrançois Tigeot enum intel_engine_id { 185c0e85e96SFrançois Tigeot RCS = 0, 186ba55f2f5SFrançois Tigeot BCS, 187c0e85e96SFrançois Tigeot VCS, 188*a85cb24fSFrançois Tigeot VCS2, 189c0e85e96SFrançois Tigeot #define _VCS(n) (VCS + (n)) 190*a85cb24fSFrançois Tigeot VECS 191*a85cb24fSFrançois Tigeot }; 192*a85cb24fSFrançois Tigeot 193*a85cb24fSFrançois Tigeot struct intel_engine_cs { 194*a85cb24fSFrançois Tigeot struct drm_i915_private *i915; 195*a85cb24fSFrançois Tigeot const char *name; 196*a85cb24fSFrançois Tigeot enum intel_engine_id id; 197c0e85e96SFrançois Tigeot unsigned int exec_id; 198*a85cb24fSFrançois Tigeot unsigned int hw_id; 199*a85cb24fSFrançois Tigeot unsigned int guc_id; 200ba55f2f5SFrançois Tigeot u32 mmio_base; 20187df8fc6SFrançois Tigeot unsigned int irq_shift; 20271f41f3eSFrançois Tigeot struct intel_ring *buffer; 2034be47400SFrançois Tigeot struct intel_timeline *timeline; 2044be47400SFrançois Tigeot 2054be47400SFrançois Tigeot struct intel_render_state *render_state; 206ba55f2f5SFrançois Tigeot 207*a85cb24fSFrançois Tigeot atomic_t irq_count; 208*a85cb24fSFrançois Tigeot unsigned long irq_posted; 209*a85cb24fSFrançois Tigeot #define ENGINE_IRQ_BREADCRUMB 0 210*a85cb24fSFrançois Tigeot #define ENGINE_IRQ_EXECLIST 1 211*a85cb24fSFrançois Tigeot 212303bf270SFrançois Tigeot /* Rather than have every client wait upon all user interrupts, 213303bf270SFrançois Tigeot * with the herd waking after every interrupt and each doing the 214303bf270SFrançois Tigeot * heavyweight seqno dance, we delegate the task (of being the 215303bf270SFrançois Tigeot * bottom-half of the user interrupt) to the first client. After 216303bf270SFrançois Tigeot * every interrupt, we wake up one client, who does the heavyweight 217303bf270SFrançois Tigeot * coherent seqno read and either goes back to sleep (if incomplete), 218303bf270SFrançois Tigeot * or wakes up all the completed clients in parallel, before then 219303bf270SFrançois Tigeot * transferring the bottom-half status to the next client in the queue. 220303bf270SFrançois Tigeot * 221303bf270SFrançois Tigeot * Compared to walking the entire list of waiters in a single dedicated 222303bf270SFrançois Tigeot * bottom-half, we reduce the latency of the first waiter by avoiding 223303bf270SFrançois Tigeot * a context switch, but incur additional coherent seqno reads when 224303bf270SFrançois Tigeot * following the chain of request breadcrumbs. Since it is most likely 225303bf270SFrançois Tigeot * that we have a single client waiting on each seqno, then reducing 226303bf270SFrançois Tigeot * the overhead of waking that client is much preferred. 227303bf270SFrançois Tigeot */ 228303bf270SFrançois Tigeot struct intel_breadcrumbs { 229*a85cb24fSFrançois Tigeot spinlock_t irq_lock; /* protects irq_*; irqsafe */ 230*a85cb24fSFrançois Tigeot struct intel_wait *irq_wait; /* oldest waiter by retirement */ 231303bf270SFrançois Tigeot 232*a85cb24fSFrançois Tigeot spinlock_t rb_lock; /* protects the rb and wraps irq_lock */ 233303bf270SFrançois Tigeot struct rb_root waiters; /* sorted by retirement, priority */ 234303bf270SFrançois Tigeot struct rb_root signals; /* sorted by retirement */ 235303bf270SFrançois Tigeot struct task_struct *signaler; /* used for fence signalling */ 236*a85cb24fSFrançois Tigeot struct drm_i915_gem_request __rcu *first_signal; 237303bf270SFrançois Tigeot struct timer_list fake_irq; /* used after a missed interrupt */ 2381e12ee3bSFrançois Tigeot struct timer_list hangcheck; /* detect missed interrupts */ 2391e12ee3bSFrançois Tigeot 240*a85cb24fSFrançois Tigeot unsigned int hangcheck_interrupts; 241303bf270SFrançois Tigeot 242*a85cb24fSFrançois Tigeot bool irq_armed : 1; 243303bf270SFrançois Tigeot bool irq_enabled : 1; 244*a85cb24fSFrançois Tigeot I915_SELFTEST_DECLARE(bool mock : 1); 245303bf270SFrançois Tigeot } breadcrumbs; 246303bf270SFrançois Tigeot 24719c468b4SFrançois Tigeot /* 24819c468b4SFrançois Tigeot * A pool of objects to use as shadow copies of client batch buffers 24919c468b4SFrançois Tigeot * when the command parser is enabled. Prevents the client from 25019c468b4SFrançois Tigeot * modifying the batch contents after software parsing. 25119c468b4SFrançois Tigeot */ 25219c468b4SFrançois Tigeot struct i915_gem_batch_pool batch_pool; 25319c468b4SFrançois Tigeot 254ba55f2f5SFrançois Tigeot struct intel_hw_status_page status_page; 255a05eeebfSFrançois Tigeot struct i915_ctx_workarounds wa_ctx; 2561e12ee3bSFrançois Tigeot struct i915_vma *scratch; 257e3adcf8fSFrançois Tigeot 258303bf270SFrançois Tigeot u32 irq_keep_mask; /* always keep these interrupts */ 25915ac6249SFrançois Tigeot u32 irq_enable_mask; /* bitmask to enable ring interrupt */ 26087df8fc6SFrançois Tigeot void (*irq_enable)(struct intel_engine_cs *engine); 26187df8fc6SFrançois Tigeot void (*irq_disable)(struct intel_engine_cs *engine); 262e3adcf8fSFrançois Tigeot 26387df8fc6SFrançois Tigeot int (*init_hw)(struct intel_engine_cs *engine); 2641e12ee3bSFrançois Tigeot void (*reset_hw)(struct intel_engine_cs *engine, 2651e12ee3bSFrançois Tigeot struct drm_i915_gem_request *req); 266e3adcf8fSFrançois Tigeot 267*a85cb24fSFrançois Tigeot void (*set_default_submission)(struct intel_engine_cs *engine); 268*a85cb24fSFrançois Tigeot 269*a85cb24fSFrançois Tigeot int (*context_pin)(struct intel_engine_cs *engine, 270*a85cb24fSFrançois Tigeot struct i915_gem_context *ctx); 271*a85cb24fSFrançois Tigeot void (*context_unpin)(struct intel_engine_cs *engine, 272*a85cb24fSFrançois Tigeot struct i915_gem_context *ctx); 273*a85cb24fSFrançois Tigeot int (*request_alloc)(struct drm_i915_gem_request *req); 274a05eeebfSFrançois Tigeot int (*init_context)(struct drm_i915_gem_request *req); 2751b13d190SFrançois Tigeot 27671f41f3eSFrançois Tigeot int (*emit_flush)(struct drm_i915_gem_request *request, 27771f41f3eSFrançois Tigeot u32 mode); 27871f41f3eSFrançois Tigeot #define EMIT_INVALIDATE BIT(0) 27971f41f3eSFrançois Tigeot #define EMIT_FLUSH BIT(1) 28071f41f3eSFrançois Tigeot #define EMIT_BARRIER (EMIT_INVALIDATE | EMIT_FLUSH) 28171f41f3eSFrançois Tigeot int (*emit_bb_start)(struct drm_i915_gem_request *req, 28271f41f3eSFrançois Tigeot u64 offset, u32 length, 28371f41f3eSFrançois Tigeot unsigned int dispatch_flags); 28471f41f3eSFrançois Tigeot #define I915_DISPATCH_SECURE BIT(0) 28571f41f3eSFrançois Tigeot #define I915_DISPATCH_PINNED BIT(1) 28671f41f3eSFrançois Tigeot #define I915_DISPATCH_RS BIT(2) 2874be47400SFrançois Tigeot void (*emit_breadcrumb)(struct drm_i915_gem_request *req, 288*a85cb24fSFrançois Tigeot u32 *cs); 2894be47400SFrançois Tigeot int emit_breadcrumb_sz; 2901e12ee3bSFrançois Tigeot 2911e12ee3bSFrançois Tigeot /* Pass the request to the hardware queue (e.g. directly into 2921e12ee3bSFrançois Tigeot * the legacy ringbuffer or to the end of an execlist). 2931e12ee3bSFrançois Tigeot * 2941e12ee3bSFrançois Tigeot * This is called from an atomic context with irqs disabled; must 2951e12ee3bSFrançois Tigeot * be irq safe. 2961e12ee3bSFrançois Tigeot */ 29771f41f3eSFrançois Tigeot void (*submit_request)(struct drm_i915_gem_request *req); 2981e12ee3bSFrançois Tigeot 2994be47400SFrançois Tigeot /* Call when the priority on a request has changed and it and its 3004be47400SFrançois Tigeot * dependencies may need rescheduling. Note the request itself may 3014be47400SFrançois Tigeot * not be ready to run! 3024be47400SFrançois Tigeot * 3034be47400SFrançois Tigeot * Called under the struct_mutex. 3044be47400SFrançois Tigeot */ 3054be47400SFrançois Tigeot void (*schedule)(struct drm_i915_gem_request *request, 3064be47400SFrançois Tigeot int priority); 3074be47400SFrançois Tigeot 308b030f26bSFrançois Tigeot /* Some chipsets are not quite as coherent as advertised and need 309b030f26bSFrançois Tigeot * an expensive kick to force a true read of the up-to-date seqno. 310b030f26bSFrançois Tigeot * However, the up-to-date seqno is not always required and the last 311b030f26bSFrançois Tigeot * seen value is good enough. Note that the seqno will always be 312b030f26bSFrançois Tigeot * monotonic, even if not coherent. 313b030f26bSFrançois Tigeot */ 31487df8fc6SFrançois Tigeot void (*irq_seqno_barrier)(struct intel_engine_cs *engine); 31587df8fc6SFrançois Tigeot void (*cleanup)(struct intel_engine_cs *engine); 316e3adcf8fSFrançois Tigeot 31724edb884SFrançois Tigeot /* GEN8 signal/wait table - never trust comments! 31824edb884SFrançois Tigeot * signal to signal to signal to signal to signal to 31924edb884SFrançois Tigeot * RCS VCS BCS VECS VCS2 32024edb884SFrançois Tigeot * -------------------------------------------------------------------- 32124edb884SFrançois Tigeot * RCS | NOP (0x00) | VCS (0x08) | BCS (0x10) | VECS (0x18) | VCS2 (0x20) | 32224edb884SFrançois Tigeot * |------------------------------------------------------------------- 32324edb884SFrançois Tigeot * VCS | RCS (0x28) | NOP (0x30) | BCS (0x38) | VECS (0x40) | VCS2 (0x48) | 32424edb884SFrançois Tigeot * |------------------------------------------------------------------- 32524edb884SFrançois Tigeot * BCS | RCS (0x50) | VCS (0x58) | NOP (0x60) | VECS (0x68) | VCS2 (0x70) | 32624edb884SFrançois Tigeot * |------------------------------------------------------------------- 32724edb884SFrançois Tigeot * VECS | RCS (0x78) | VCS (0x80) | BCS (0x88) | NOP (0x90) | VCS2 (0x98) | 32824edb884SFrançois Tigeot * |------------------------------------------------------------------- 32924edb884SFrançois Tigeot * VCS2 | RCS (0xa0) | VCS (0xa8) | BCS (0xb0) | VECS (0xb8) | NOP (0xc0) | 33024edb884SFrançois Tigeot * |------------------------------------------------------------------- 33124edb884SFrançois Tigeot * 33224edb884SFrançois Tigeot * Generalization: 33324edb884SFrançois Tigeot * f(x, y) := (x->id * NUM_RINGS * seqno_size) + (seqno_size * y->id) 33424edb884SFrançois Tigeot * ie. transpose of g(x, y) 33524edb884SFrançois Tigeot * 33624edb884SFrançois Tigeot * sync from sync from sync from sync from sync from 33724edb884SFrançois Tigeot * RCS VCS BCS VECS VCS2 33824edb884SFrançois Tigeot * -------------------------------------------------------------------- 33924edb884SFrançois Tigeot * RCS | NOP (0x00) | VCS (0x28) | BCS (0x50) | VECS (0x78) | VCS2 (0xa0) | 34024edb884SFrançois Tigeot * |------------------------------------------------------------------- 34124edb884SFrançois Tigeot * VCS | RCS (0x08) | NOP (0x30) | BCS (0x58) | VECS (0x80) | VCS2 (0xa8) | 34224edb884SFrançois Tigeot * |------------------------------------------------------------------- 34324edb884SFrançois Tigeot * BCS | RCS (0x10) | VCS (0x38) | NOP (0x60) | VECS (0x88) | VCS2 (0xb0) | 34424edb884SFrançois Tigeot * |------------------------------------------------------------------- 34524edb884SFrançois Tigeot * VECS | RCS (0x18) | VCS (0x40) | BCS (0x68) | NOP (0x90) | VCS2 (0xb8) | 34624edb884SFrançois Tigeot * |------------------------------------------------------------------- 34724edb884SFrançois Tigeot * VCS2 | RCS (0x20) | VCS (0x48) | BCS (0x70) | VECS (0x98) | NOP (0xc0) | 34824edb884SFrançois Tigeot * |------------------------------------------------------------------- 34924edb884SFrançois Tigeot * 35024edb884SFrançois Tigeot * Generalization: 35124edb884SFrançois Tigeot * g(x, y) := (y->id * NUM_RINGS * seqno_size) + (seqno_size * x->id) 35224edb884SFrançois Tigeot * ie. transpose of f(x, y) 35324edb884SFrançois Tigeot */ 354ba55f2f5SFrançois Tigeot struct { 35524edb884SFrançois Tigeot union { 3561e12ee3bSFrançois Tigeot #define GEN6_SEMAPHORE_LAST VECS_HW 3571e12ee3bSFrançois Tigeot #define GEN6_NUM_SEMAPHORES (GEN6_SEMAPHORE_LAST + 1) 3581e12ee3bSFrançois Tigeot #define GEN6_SEMAPHORES_MASK GENMASK(GEN6_SEMAPHORE_LAST, 0) 359ba55f2f5SFrançois Tigeot struct { 3605d0b1887SFrançois Tigeot /* our mbox written by others */ 3611e12ee3bSFrançois Tigeot u32 wait[GEN6_NUM_SEMAPHORES]; 3625d0b1887SFrançois Tigeot /* mboxes this ring signals to */ 3631e12ee3bSFrançois Tigeot i915_reg_t signal[GEN6_NUM_SEMAPHORES]; 364ba55f2f5SFrançois Tigeot } mbox; 3658621f407SFrançois Tigeot u64 signal_ggtt[I915_NUM_ENGINES]; 36624edb884SFrançois Tigeot }; 367ba55f2f5SFrançois Tigeot 368ba55f2f5SFrançois Tigeot /* AKA wait() */ 36971f41f3eSFrançois Tigeot int (*sync_to)(struct drm_i915_gem_request *req, 37071f41f3eSFrançois Tigeot struct drm_i915_gem_request *signal); 371*a85cb24fSFrançois Tigeot u32 *(*signal)(struct drm_i915_gem_request *req, u32 *cs); 372ba55f2f5SFrançois Tigeot } semaphore; 3735d0b1887SFrançois Tigeot 3741b13d190SFrançois Tigeot /* Execlists */ 3758621f407SFrançois Tigeot struct tasklet_struct irq_tasklet; 3761e12ee3bSFrançois Tigeot struct execlist_port { 3771e12ee3bSFrançois Tigeot struct drm_i915_gem_request *request; 3781e12ee3bSFrançois Tigeot unsigned int count; 379*a85cb24fSFrançois Tigeot GEM_DEBUG_DECL(u32 context_id); 3801e12ee3bSFrançois Tigeot } execlist_port[2]; 3814be47400SFrançois Tigeot struct rb_root execlist_queue; 3824be47400SFrançois Tigeot struct rb_node *execlist_first; 3838621f407SFrançois Tigeot unsigned int fw_domains; 384e3adcf8fSFrançois Tigeot 385*a85cb24fSFrançois Tigeot /* Contexts are pinned whilst they are active on the GPU. The last 386*a85cb24fSFrançois Tigeot * context executed remains active whilst the GPU is idle - the 387*a85cb24fSFrançois Tigeot * switch away and write to the context object only occurs on the 388*a85cb24fSFrançois Tigeot * next execution. Contexts are only unpinned on retirement of the 389*a85cb24fSFrançois Tigeot * following request ensuring that we can always write to the object 390*a85cb24fSFrançois Tigeot * on the context switch even after idling. Across suspend, we switch 391*a85cb24fSFrançois Tigeot * to the kernel context and trash it as the save may not happen 392*a85cb24fSFrançois Tigeot * before the hardware is powered down. 393*a85cb24fSFrançois Tigeot */ 394*a85cb24fSFrançois Tigeot struct i915_gem_context *last_retired_context; 395*a85cb24fSFrançois Tigeot 396*a85cb24fSFrançois Tigeot /* We track the current MI_SET_CONTEXT in order to eliminate 397*a85cb24fSFrançois Tigeot * redudant context switches. This presumes that requests are not 398*a85cb24fSFrançois Tigeot * reordered! Or when they are the tracking is updated along with 399*a85cb24fSFrançois Tigeot * the emission of individual requests into the legacy command 400*a85cb24fSFrançois Tigeot * stream (ring). 401*a85cb24fSFrançois Tigeot */ 402*a85cb24fSFrançois Tigeot struct i915_gem_context *legacy_active_context; 403*a85cb24fSFrançois Tigeot 404*a85cb24fSFrançois Tigeot /* status_notifier: list of callbacks for context-switch changes */ 405*a85cb24fSFrançois Tigeot struct atomic_notifier_head context_status_notifier; 4065d0b1887SFrançois Tigeot 40771f41f3eSFrançois Tigeot struct intel_engine_hangcheck hangcheck; 40815ac6249SFrançois Tigeot 409ba55f2f5SFrançois Tigeot bool needs_cmd_parser; 410ba55f2f5SFrançois Tigeot 411ba55f2f5SFrançois Tigeot /* 412ba55f2f5SFrançois Tigeot * Table of commands the command parser needs to know about 41371f41f3eSFrançois Tigeot * for this engine. 414ba55f2f5SFrançois Tigeot */ 415ba55f2f5SFrançois Tigeot DECLARE_HASHTABLE(cmd_hash, I915_CMD_HASH_ORDER); 416ba55f2f5SFrançois Tigeot 417ba55f2f5SFrançois Tigeot /* 418ba55f2f5SFrançois Tigeot * Table of registers allowed in commands that read/write registers. 419ba55f2f5SFrançois Tigeot */ 4208621f407SFrançois Tigeot const struct drm_i915_reg_table *reg_tables; 4218621f407SFrançois Tigeot int reg_table_count; 422ba55f2f5SFrançois Tigeot 423ba55f2f5SFrançois Tigeot /* 424ba55f2f5SFrançois Tigeot * Returns the bitmask for the length field of the specified command. 425ba55f2f5SFrançois Tigeot * Return 0 for an unrecognized/invalid command. 426ba55f2f5SFrançois Tigeot * 42771f41f3eSFrançois Tigeot * If the command parser finds an entry for a command in the engine's 428ba55f2f5SFrançois Tigeot * cmd_tables, it gets the command's length based on the table entry. 42971f41f3eSFrançois Tigeot * If not, it calls this function to determine the per-engine length 43071f41f3eSFrançois Tigeot * field encoding for the command (i.e. different opcode ranges use 43171f41f3eSFrançois Tigeot * certain bits to encode the command length in the header). 432ba55f2f5SFrançois Tigeot */ 433ba55f2f5SFrançois Tigeot u32 (*get_cmd_length_mask)(u32 cmd_header); 434e3adcf8fSFrançois Tigeot }; 435e3adcf8fSFrançois Tigeot 436*a85cb24fSFrançois Tigeot static inline unsigned int 437303bf270SFrançois Tigeot intel_engine_flag(const struct intel_engine_cs *engine) 438e3adcf8fSFrançois Tigeot { 439*a85cb24fSFrançois Tigeot return BIT(engine->id); 440352ff8bdSFrançois Tigeot } 441352ff8bdSFrançois Tigeot 442f4e1c372SFrançois Tigeot static inline u32 4438621f407SFrançois Tigeot intel_read_status_page(struct intel_engine_cs *engine, int reg) 444e3adcf8fSFrançois Tigeot { 445f4e1c372SFrançois Tigeot /* Ensure that the compiler doesn't optimize away the load. */ 4468621f407SFrançois Tigeot return READ_ONCE(engine->status_page.page_addr[reg]); 447e3adcf8fSFrançois Tigeot } 448e3adcf8fSFrançois Tigeot 449a2fdbec6SFrançois Tigeot static inline void 450*a85cb24fSFrançois Tigeot intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value) 451a2fdbec6SFrançois Tigeot { 452*a85cb24fSFrançois Tigeot /* Writing into the status page should be done sparingly. Since 453*a85cb24fSFrançois Tigeot * we do when we are uncertain of the device state, we take a bit 454*a85cb24fSFrançois Tigeot * of extra paranoia to try and ensure that the HWS takes the value 455*a85cb24fSFrançois Tigeot * we give and that it doesn't end up trapped inside the CPU! 456*a85cb24fSFrançois Tigeot */ 457*a85cb24fSFrançois Tigeot if (static_cpu_has(X86_FEATURE_CLFLUSH)) { 458*a85cb24fSFrançois Tigeot mb(); 459*a85cb24fSFrançois Tigeot linux_clflush(&engine->status_page.page_addr[reg]); 4608621f407SFrançois Tigeot engine->status_page.page_addr[reg] = value; 461*a85cb24fSFrançois Tigeot linux_clflush(&engine->status_page.page_addr[reg]); 462*a85cb24fSFrançois Tigeot mb(); 463*a85cb24fSFrançois Tigeot } else { 464*a85cb24fSFrançois Tigeot WRITE_ONCE(engine->status_page.page_addr[reg], value); 465*a85cb24fSFrançois Tigeot } 466a2fdbec6SFrançois Tigeot } 467a2fdbec6SFrançois Tigeot 468c0e85e96SFrançois Tigeot /* 469f4e1c372SFrançois Tigeot * Reads a dword out of the status page, which is written to from the command 470f4e1c372SFrançois Tigeot * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or 471f4e1c372SFrançois Tigeot * MI_STORE_DATA_IMM. 472f4e1c372SFrançois Tigeot * 473f4e1c372SFrançois Tigeot * The following dwords have a reserved meaning: 474f4e1c372SFrançois Tigeot * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes. 475f4e1c372SFrançois Tigeot * 0x04: ring 0 head pointer 476f4e1c372SFrançois Tigeot * 0x05: ring 1 head pointer (915-class) 477f4e1c372SFrançois Tigeot * 0x06: ring 2 head pointer (915-class) 478f4e1c372SFrançois Tigeot * 0x10-0x1b: Context status DWords (GM45) 479f4e1c372SFrançois Tigeot * 0x1f: Last written status offset. (GM45) 480477eb7f9SFrançois Tigeot * 0x20-0x2f: Reserved (Gen6+) 481f4e1c372SFrançois Tigeot * 482477eb7f9SFrançois Tigeot * The area from dword 0x30 to 0x3ff is available for driver usage. 483f4e1c372SFrançois Tigeot */ 484477eb7f9SFrançois Tigeot #define I915_GEM_HWS_INDEX 0x30 485c0e85e96SFrançois Tigeot #define I915_GEM_HWS_INDEX_ADDR (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT) 486477eb7f9SFrançois Tigeot #define I915_GEM_HWS_SCRATCH_INDEX 0x40 487f4e1c372SFrançois Tigeot #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) 488e3adcf8fSFrançois Tigeot 48971f41f3eSFrançois Tigeot struct intel_ring * 49071f41f3eSFrançois Tigeot intel_engine_create_ring(struct intel_engine_cs *engine, int size); 491*a85cb24fSFrançois Tigeot int intel_ring_pin(struct intel_ring *ring, unsigned int offset_bias); 492*a85cb24fSFrançois Tigeot void intel_ring_reset(struct intel_ring *ring, u32 tail); 493*a85cb24fSFrançois Tigeot void intel_ring_update_space(struct intel_ring *ring); 49471f41f3eSFrançois Tigeot void intel_ring_unpin(struct intel_ring *ring); 49571f41f3eSFrançois Tigeot void intel_ring_free(struct intel_ring *ring); 4961b13d190SFrançois Tigeot 49771f41f3eSFrançois Tigeot void intel_engine_stop(struct intel_engine_cs *engine); 49871f41f3eSFrançois Tigeot void intel_engine_cleanup(struct intel_engine_cs *engine); 499f4e1c372SFrançois Tigeot 5001e12ee3bSFrançois Tigeot void intel_legacy_submission_resume(struct drm_i915_private *dev_priv); 5011e12ee3bSFrançois Tigeot 502a05eeebfSFrançois Tigeot int __must_check intel_ring_cacheline_align(struct drm_i915_gem_request *req); 50387df8fc6SFrançois Tigeot 504*a85cb24fSFrançois Tigeot u32 __must_check *intel_ring_begin(struct drm_i915_gem_request *req, int n); 50587df8fc6SFrançois Tigeot 506*a85cb24fSFrançois Tigeot static inline void 507*a85cb24fSFrançois Tigeot intel_ring_advance(struct drm_i915_gem_request *req, u32 *cs) 50887df8fc6SFrançois Tigeot { 50971f41f3eSFrançois Tigeot /* Dummy function. 51071f41f3eSFrançois Tigeot * 51171f41f3eSFrançois Tigeot * This serves as a placeholder in the code so that the reader 51271f41f3eSFrançois Tigeot * can compare against the preceding intel_ring_begin() and 51371f41f3eSFrançois Tigeot * check that the number of dwords emitted matches the space 51471f41f3eSFrançois Tigeot * reserved for the command packet (i.e. the value passed to 51571f41f3eSFrançois Tigeot * intel_ring_begin()). 51671f41f3eSFrançois Tigeot */ 517*a85cb24fSFrançois Tigeot GEM_BUG_ON((req->ring->vaddr + req->ring->emit) != cs); 51887df8fc6SFrançois Tigeot } 51987df8fc6SFrançois Tigeot 520*a85cb24fSFrançois Tigeot static inline u32 521*a85cb24fSFrançois Tigeot intel_ring_wrap(const struct intel_ring *ring, u32 pos) 522*a85cb24fSFrançois Tigeot { 523*a85cb24fSFrançois Tigeot return pos & (ring->size - 1); 524*a85cb24fSFrançois Tigeot } 525*a85cb24fSFrançois Tigeot 526*a85cb24fSFrançois Tigeot static inline u32 527*a85cb24fSFrançois Tigeot intel_ring_offset(const struct drm_i915_gem_request *req, void *addr) 528aee94f86SFrançois Tigeot { 52971f41f3eSFrançois Tigeot /* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */ 530*a85cb24fSFrançois Tigeot u32 offset = addr - req->ring->vaddr; 531*a85cb24fSFrançois Tigeot GEM_BUG_ON(offset > req->ring->size); 532*a85cb24fSFrançois Tigeot return intel_ring_wrap(req->ring, offset); 5339edbd4a0SFrançois Tigeot } 53487df8fc6SFrançois Tigeot 535*a85cb24fSFrançois Tigeot static inline void 536*a85cb24fSFrançois Tigeot assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail) 537*a85cb24fSFrançois Tigeot { 538*a85cb24fSFrançois Tigeot /* We could combine these into a single tail operation, but keeping 539*a85cb24fSFrançois Tigeot * them as seperate tests will help identify the cause should one 540*a85cb24fSFrançois Tigeot * ever fire. 541*a85cb24fSFrançois Tigeot */ 542*a85cb24fSFrançois Tigeot GEM_BUG_ON(!IS_ALIGNED(tail, 8)); 543*a85cb24fSFrançois Tigeot GEM_BUG_ON(tail >= ring->size); 544*a85cb24fSFrançois Tigeot } 545*a85cb24fSFrançois Tigeot 546*a85cb24fSFrançois Tigeot static inline unsigned int 547*a85cb24fSFrançois Tigeot intel_ring_set_tail(struct intel_ring *ring, unsigned int tail) 548*a85cb24fSFrançois Tigeot { 549*a85cb24fSFrançois Tigeot /* Whilst writes to the tail are strictly order, there is no 550*a85cb24fSFrançois Tigeot * serialisation between readers and the writers. The tail may be 551*a85cb24fSFrançois Tigeot * read by i915_gem_request_retire() just as it is being updated 552*a85cb24fSFrançois Tigeot * by execlists, as although the breadcrumb is complete, the context 553*a85cb24fSFrançois Tigeot * switch hasn't been seen. 554*a85cb24fSFrançois Tigeot */ 555*a85cb24fSFrançois Tigeot assert_ring_tail_valid(ring, tail); 556*a85cb24fSFrançois Tigeot ring->tail = tail; 557*a85cb24fSFrançois Tigeot return tail; 558*a85cb24fSFrançois Tigeot } 5599edbd4a0SFrançois Tigeot 5604be47400SFrançois Tigeot void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno); 561e3adcf8fSFrançois Tigeot 56287df8fc6SFrançois Tigeot void intel_engine_setup_common(struct intel_engine_cs *engine); 56387df8fc6SFrançois Tigeot int intel_engine_init_common(struct intel_engine_cs *engine); 5641e12ee3bSFrançois Tigeot int intel_engine_create_scratch(struct intel_engine_cs *engine, int size); 56571f41f3eSFrançois Tigeot void intel_engine_cleanup_common(struct intel_engine_cs *engine); 56671f41f3eSFrançois Tigeot 56787df8fc6SFrançois Tigeot int intel_init_render_ring_buffer(struct intel_engine_cs *engine); 56887df8fc6SFrançois Tigeot int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine); 56987df8fc6SFrançois Tigeot int intel_init_bsd2_ring_buffer(struct intel_engine_cs *engine); 57087df8fc6SFrançois Tigeot int intel_init_blt_ring_buffer(struct intel_engine_cs *engine); 57187df8fc6SFrançois Tigeot int intel_init_vebox_ring_buffer(struct intel_engine_cs *engine); 572e3adcf8fSFrançois Tigeot 57371f41f3eSFrançois Tigeot u64 intel_engine_get_active_head(struct intel_engine_cs *engine); 5741e12ee3bSFrançois Tigeot u64 intel_engine_get_last_batch_head(struct intel_engine_cs *engine); 5751e12ee3bSFrançois Tigeot 576303bf270SFrançois Tigeot static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine) 577303bf270SFrançois Tigeot { 578303bf270SFrançois Tigeot return intel_read_status_page(engine, I915_GEM_HWS_INDEX); 579303bf270SFrançois Tigeot } 580e3adcf8fSFrançois Tigeot 5814be47400SFrançois Tigeot static inline u32 intel_engine_last_submit(struct intel_engine_cs *engine) 5824be47400SFrançois Tigeot { 5834be47400SFrançois Tigeot /* We are only peeking at the tail of the submit queue (and not the 5844be47400SFrançois Tigeot * queue itself) in order to gain a hint as to the current active 5854be47400SFrançois Tigeot * state of the engine. Callers are not expected to be taking 5864be47400SFrançois Tigeot * engine->timeline->lock, nor are they expected to be concerned 5874be47400SFrançois Tigeot * wtih serialising this hint with anything, so document it as 5884be47400SFrançois Tigeot * a hint and nothing more. 5894be47400SFrançois Tigeot */ 590*a85cb24fSFrançois Tigeot return READ_ONCE(engine->timeline->seqno); 5914be47400SFrançois Tigeot } 5924be47400SFrançois Tigeot 5938621f407SFrançois Tigeot int init_workarounds_ring(struct intel_engine_cs *engine); 594*a85cb24fSFrançois Tigeot int intel_ring_workarounds_emit(struct drm_i915_gem_request *req); 5952c9916cdSFrançois Tigeot 5961e12ee3bSFrançois Tigeot void intel_engine_get_instdone(struct intel_engine_cs *engine, 5971e12ee3bSFrançois Tigeot struct intel_instdone *instdone); 5981e12ee3bSFrançois Tigeot 599a05eeebfSFrançois Tigeot /* 600a05eeebfSFrançois Tigeot * Arbitrary size for largest possible 'add request' sequence. The code paths 601a05eeebfSFrançois Tigeot * are complex and variable. Empirical measurement shows that the worst case 6021487f786SFrançois Tigeot * is BDW at 192 bytes (6 + 6 + 36 dwords), then ILK at 136 bytes. However, 6031487f786SFrançois Tigeot * we need to allocate double the largest single packet within that emission 6041487f786SFrançois Tigeot * to account for tail wraparound (so 6 + 6 + 72 dwords for BDW). 605a05eeebfSFrançois Tigeot */ 6061487f786SFrançois Tigeot #define MIN_SPACE_FOR_ADD_REQUEST 336 607a05eeebfSFrançois Tigeot 6081487f786SFrançois Tigeot static inline u32 intel_hws_seqno_address(struct intel_engine_cs *engine) 6091487f786SFrançois Tigeot { 6101e12ee3bSFrançois Tigeot return engine->status_page.ggtt_offset + I915_GEM_HWS_INDEX_ADDR; 6111487f786SFrançois Tigeot } 612f4e1c372SFrançois Tigeot 613303bf270SFrançois Tigeot /* intel_breadcrumbs.c -- user interrupt bottom-half for waiters */ 614303bf270SFrançois Tigeot int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine); 615303bf270SFrançois Tigeot 616*a85cb24fSFrançois Tigeot static inline void intel_wait_init(struct intel_wait *wait, 617*a85cb24fSFrançois Tigeot struct drm_i915_gem_request *rq) 618*a85cb24fSFrançois Tigeot { 619*a85cb24fSFrançois Tigeot wait->tsk = current; 620*a85cb24fSFrançois Tigeot wait->request = rq; 621*a85cb24fSFrançois Tigeot } 622*a85cb24fSFrançois Tigeot 623*a85cb24fSFrançois Tigeot static inline void intel_wait_init_for_seqno(struct intel_wait *wait, u32 seqno) 624303bf270SFrançois Tigeot { 625303bf270SFrançois Tigeot wait->tsk = current; 626303bf270SFrançois Tigeot wait->seqno = seqno; 627303bf270SFrançois Tigeot } 628303bf270SFrançois Tigeot 629*a85cb24fSFrançois Tigeot static inline bool intel_wait_has_seqno(const struct intel_wait *wait) 630*a85cb24fSFrançois Tigeot { 631*a85cb24fSFrançois Tigeot return wait->seqno; 632*a85cb24fSFrançois Tigeot } 633*a85cb24fSFrançois Tigeot 634*a85cb24fSFrançois Tigeot static inline bool 635*a85cb24fSFrançois Tigeot intel_wait_update_seqno(struct intel_wait *wait, u32 seqno) 636*a85cb24fSFrançois Tigeot { 637*a85cb24fSFrançois Tigeot wait->seqno = seqno; 638*a85cb24fSFrançois Tigeot return intel_wait_has_seqno(wait); 639*a85cb24fSFrançois Tigeot } 640*a85cb24fSFrançois Tigeot 641*a85cb24fSFrançois Tigeot static inline bool 642*a85cb24fSFrançois Tigeot intel_wait_update_request(struct intel_wait *wait, 643*a85cb24fSFrançois Tigeot const struct drm_i915_gem_request *rq) 644*a85cb24fSFrançois Tigeot { 645*a85cb24fSFrançois Tigeot return intel_wait_update_seqno(wait, i915_gem_request_global_seqno(rq)); 646*a85cb24fSFrançois Tigeot } 647*a85cb24fSFrançois Tigeot 648*a85cb24fSFrançois Tigeot static inline bool 649*a85cb24fSFrançois Tigeot intel_wait_check_seqno(const struct intel_wait *wait, u32 seqno) 650*a85cb24fSFrançois Tigeot { 651*a85cb24fSFrançois Tigeot return wait->seqno == seqno; 652*a85cb24fSFrançois Tigeot } 653*a85cb24fSFrançois Tigeot 654*a85cb24fSFrançois Tigeot static inline bool 655*a85cb24fSFrançois Tigeot intel_wait_check_request(const struct intel_wait *wait, 656*a85cb24fSFrançois Tigeot const struct drm_i915_gem_request *rq) 657*a85cb24fSFrançois Tigeot { 658*a85cb24fSFrançois Tigeot return intel_wait_check_seqno(wait, i915_gem_request_global_seqno(rq)); 659*a85cb24fSFrançois Tigeot } 660*a85cb24fSFrançois Tigeot 661303bf270SFrançois Tigeot static inline bool intel_wait_complete(const struct intel_wait *wait) 662303bf270SFrançois Tigeot { 663303bf270SFrançois Tigeot return RB_EMPTY_NODE(&wait->node); 664303bf270SFrançois Tigeot } 665303bf270SFrançois Tigeot 666303bf270SFrançois Tigeot bool intel_engine_add_wait(struct intel_engine_cs *engine, 667303bf270SFrançois Tigeot struct intel_wait *wait); 668303bf270SFrançois Tigeot void intel_engine_remove_wait(struct intel_engine_cs *engine, 669303bf270SFrançois Tigeot struct intel_wait *wait); 670303bf270SFrançois Tigeot void intel_engine_enable_signaling(struct drm_i915_gem_request *request); 671*a85cb24fSFrançois Tigeot void intel_engine_cancel_signaling(struct drm_i915_gem_request *request); 672303bf270SFrançois Tigeot 6731e12ee3bSFrançois Tigeot static inline bool intel_engine_has_waiter(const struct intel_engine_cs *engine) 674303bf270SFrançois Tigeot { 675*a85cb24fSFrançois Tigeot return READ_ONCE(engine->breadcrumbs.irq_wait); 676303bf270SFrançois Tigeot } 677303bf270SFrançois Tigeot 678*a85cb24fSFrançois Tigeot unsigned int intel_engine_wakeup(struct intel_engine_cs *engine); 679*a85cb24fSFrançois Tigeot #define ENGINE_WAKEUP_WAITER BIT(0) 680*a85cb24fSFrançois Tigeot #define ENGINE_WAKEUP_ASLEEP BIT(1) 6811e12ee3bSFrançois Tigeot 682*a85cb24fSFrançois Tigeot void __intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine); 683*a85cb24fSFrançois Tigeot void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine); 684303bf270SFrançois Tigeot 6851e12ee3bSFrançois Tigeot void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine); 686303bf270SFrançois Tigeot void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine); 687*a85cb24fSFrançois Tigeot bool intel_breadcrumbs_busy(struct intel_engine_cs *engine); 688*a85cb24fSFrançois Tigeot 689*a85cb24fSFrançois Tigeot static inline u32 *gen8_emit_pipe_control(u32 *batch, u32 flags, u32 offset) 690*a85cb24fSFrançois Tigeot { 691*a85cb24fSFrançois Tigeot memset(batch, 0, 6 * sizeof(u32)); 692*a85cb24fSFrançois Tigeot 693*a85cb24fSFrançois Tigeot batch[0] = GFX_OP_PIPE_CONTROL(6); 694*a85cb24fSFrançois Tigeot batch[1] = flags; 695*a85cb24fSFrançois Tigeot batch[2] = offset; 696*a85cb24fSFrançois Tigeot 697*a85cb24fSFrançois Tigeot return batch + 6; 698*a85cb24fSFrançois Tigeot } 699*a85cb24fSFrançois Tigeot 700*a85cb24fSFrançois Tigeot bool intel_engine_is_idle(struct intel_engine_cs *engine); 701*a85cb24fSFrançois Tigeot bool intel_engines_are_idle(struct drm_i915_private *dev_priv); 702*a85cb24fSFrançois Tigeot 703*a85cb24fSFrançois Tigeot void intel_engines_reset_default_submission(struct drm_i915_private *i915); 70471f41f3eSFrançois Tigeot 705e3adcf8fSFrançois Tigeot #endif /* _INTEL_RINGBUFFER_H_ */ 706