]>
Commit | Line | Data |
---|---|---|
39e2f501 CW |
1 | /* |
2 | * SPDX-License-Identifier: MIT | |
3 | * | |
4 | * Copyright © 2019 Intel Corporation | |
5 | */ | |
6 | ||
7 | #ifndef __INTEL_ENGINE_TYPES__ | |
8 | #define __INTEL_ENGINE_TYPES__ | |
9 | ||
b81e4d9b | 10 | #include <linux/average.h> |
39e2f501 CW |
11 | #include <linux/hashtable.h> |
12 | #include <linux/irq_work.h> | |
65baf0ef | 13 | #include <linux/kref.h> |
39e2f501 | 14 | #include <linux/list.h> |
ce476c80 | 15 | #include <linux/llist.h> |
750e76b4 | 16 | #include <linux/rbtree.h> |
8ee36e04 | 17 | #include <linux/timer.h> |
39e2f501 | 18 | #include <linux/types.h> |
058179e7 | 19 | #include <linux/workqueue.h> |
39e2f501 | 20 | |
3a891a62 | 21 | #include "i915_gem.h" |
112ed2d3 | 22 | #include "i915_pmu.h" |
8b74594a | 23 | #include "i915_priolist_types.h" |
3a891a62 | 24 | #include "i915_selftest.h" |
b40d7378 | 25 | #include "intel_engine_pool_types.h" |
09407579 | 26 | #include "intel_sseu.h" |
b40d7378 | 27 | #include "intel_timeline_types.h" |
79ffac85 | 28 | #include "intel_wakeref.h" |
39e2f501 CW |
29 | #include "intel_workarounds_types.h" |
30 | ||
3d7b3039 DCS |
31 | /* Legacy HW Engine ID */ |
32 | ||
33 | #define RCS0_HW 0 | |
34 | #define VCS0_HW 1 | |
35 | #define BCS0_HW 2 | |
36 | #define VECS0_HW 3 | |
37 | #define VCS1_HW 4 | |
38 | #define VCS2_HW 6 | |
39 | #define VCS3_HW 7 | |
40 | #define VECS1_HW 12 | |
41 | ||
42 | /* Gen11+ HW Engine class + instance */ | |
43 | #define RENDER_CLASS 0 | |
44 | #define VIDEO_DECODE_CLASS 1 | |
45 | #define VIDEO_ENHANCEMENT_CLASS 2 | |
46 | #define COPY_ENGINE_CLASS 3 | |
47 | #define OTHER_CLASS 4 | |
48 | #define MAX_ENGINE_CLASS 4 | |
49 | #define MAX_ENGINE_INSTANCE 3 | |
50 | ||
39e2f501 CW |
51 | #define I915_MAX_SLICES 3 |
52 | #define I915_MAX_SUBSLICES 8 | |
53 | ||
54 | #define I915_CMD_HASH_ORDER 9 | |
55 | ||
3a891a62 | 56 | struct dma_fence; |
5e5d2e20 | 57 | struct drm_i915_gem_object; |
39e2f501 CW |
58 | struct drm_i915_reg_table; |
59 | struct i915_gem_context; | |
60 | struct i915_request; | |
61 | struct i915_sched_attr; | |
f937f561 | 62 | struct intel_gt; |
2871ea85 | 63 | struct intel_ring; |
baba6e57 | 64 | struct intel_uncore; |
39e2f501 | 65 | |
3a891a62 CW |
66 | typedef u8 intel_engine_mask_t; |
67 | #define ALL_ENGINES ((intel_engine_mask_t)~0ul) | |
68 | ||
39e2f501 CW |
69 | struct intel_hw_status_page { |
70 | struct i915_vma *vma; | |
71 | u32 *addr; | |
72 | }; | |
73 | ||
74 | struct intel_instdone { | |
75 | u32 instdone; | |
76 | /* The following exist only in the RCS engine */ | |
77 | u32 slice_common; | |
f7043102 | 78 | u32 slice_common_extra[2]; |
39e2f501 CW |
79 | u32 sampler[I915_MAX_SLICES][I915_MAX_SUBSLICES]; |
80 | u32 row[I915_MAX_SLICES][I915_MAX_SUBSLICES]; | |
81 | }; | |
82 | ||
39e2f501 CW |
83 | /* |
84 | * we use a single page to load ctx workarounds so all of these | |
85 | * values are referred in terms of dwords | |
86 | * | |
87 | * struct i915_wa_ctx_bb: | |
88 | * offset: specifies batch starting position, also helpful in case | |
89 | * if we want to have multiple batches at different offsets based on | |
90 | * some criteria. It is not a requirement at the moment but provides | |
91 | * an option for future use. | |
92 | * size: size of the batch in DWORDS | |
93 | */ | |
94 | struct i915_ctx_workarounds { | |
95 | struct i915_wa_ctx_bb { | |
96 | u32 offset; | |
97 | u32 size; | |
98 | } indirect_ctx, per_ctx; | |
99 | struct i915_vma *vma; | |
100 | }; | |
101 | ||
102 | #define I915_MAX_VCS 4 | |
103 | #define I915_MAX_VECS 2 | |
104 | ||
105 | /* | |
106 | * Engine IDs definitions. | |
107 | * Keep instances of the same type engine together. | |
108 | */ | |
109 | enum intel_engine_id { | |
110 | RCS0 = 0, | |
111 | BCS0, | |
112 | VCS0, | |
113 | VCS1, | |
114 | VCS2, | |
115 | VCS3, | |
116 | #define _VCS(n) (VCS0 + (n)) | |
117 | VECS0, | |
3a891a62 | 118 | VECS1, |
39e2f501 | 119 | #define _VECS(n) (VECS0 + (n)) |
3a891a62 | 120 | I915_NUM_ENGINES |
a50134b1 | 121 | #define INVALID_ENGINE ((enum intel_engine_id)-1) |
39e2f501 CW |
122 | }; |
123 | ||
b81e4d9b CW |
124 | /* A simple estimator for the round-trip latency of an engine */ |
125 | DECLARE_EWMA(_engine_latency, 6, 4) | |
126 | ||
39e2f501 CW |
127 | struct st_preempt_hang { |
128 | struct completion completion; | |
129 | unsigned int count; | |
39e2f501 CW |
130 | }; |
131 | ||
132 | /** | |
133 | * struct intel_engine_execlists - execlist submission queue and port state | |
134 | * | |
135 | * The struct intel_engine_execlists represents the combined logical state of | |
136 | * driver and the hardware state for execlist mode of submission. | |
137 | */ | |
138 | struct intel_engine_execlists { | |
139 | /** | |
140 | * @tasklet: softirq tasklet for bottom handler | |
141 | */ | |
142 | struct tasklet_struct tasklet; | |
143 | ||
8ee36e04 CW |
144 | /** |
145 | * @timer: kick the current context if its timeslice expires | |
146 | */ | |
147 | struct timer_list timer; | |
148 | ||
3a7a92ab CW |
149 | /** |
150 | * @preempt: reset the current context if it fails to give way | |
151 | */ | |
152 | struct timer_list preempt; | |
153 | ||
39e2f501 CW |
154 | /** |
155 | * @default_priolist: priority list for I915_PRIORITY_NORMAL | |
156 | */ | |
157 | struct i915_priolist default_priolist; | |
158 | ||
53b2622e CW |
159 | /** |
160 | * @ccid: identifier for contexts submitted to this engine | |
161 | */ | |
162 | u32 ccid; | |
163 | ||
220dcfc1 CW |
164 | /** |
165 | * @yield: CCID at the time of the last semaphore-wait interrupt. | |
166 | * | |
167 | * Instead of leaving a semaphore busy-spinning on an engine, we would | |
168 | * like to switch to another ready context, i.e. yielding the semaphore | |
169 | * timeslice. | |
170 | */ | |
171 | u32 yield; | |
172 | ||
70a76a9b CW |
173 | /** |
174 | * @error_interrupt: CS Master EIR | |
175 | * | |
176 | * The CS generates an interrupt when it detects an error. We capture | |
177 | * the first error interrupt, record the EIR and schedule the tasklet. | |
178 | * In the tasklet, we process the pending CS events to ensure we have | |
179 | * the guilty request, and then reset the engine. | |
180 | */ | |
181 | u32 error_interrupt; | |
182 | ||
39e2f501 CW |
183 | /** |
184 | * @no_priolist: priority lists disabled | |
185 | */ | |
186 | bool no_priolist; | |
187 | ||
188 | /** | |
189 | * @submit_reg: gen-specific execlist submission register | |
190 | * set to the ExecList Submission Port (elsp) register pre-Gen11 and to | |
191 | * the ExecList Submission Queue Contents register array for Gen11+ | |
192 | */ | |
193 | u32 __iomem *submit_reg; | |
194 | ||
195 | /** | |
196 | * @ctrl_reg: the enhanced execlists control register, used to load the | |
197 | * submit queue on the HW and to request preemptions to idle | |
198 | */ | |
199 | u32 __iomem *ctrl_reg; | |
200 | ||
22b7a426 CW |
201 | #define EXECLIST_MAX_PORTS 2 |
202 | /** | |
203 | * @active: the currently known context executing on HW | |
204 | */ | |
205 | struct i915_request * const *active; | |
39e2f501 | 206 | /** |
22b7a426 | 207 | * @inflight: the set of contexts submitted and acknowleged by HW |
39e2f501 | 208 | * |
22b7a426 CW |
209 | * The set of inflight contexts is managed by reading CS events |
210 | * from the HW. On a context-switch event (not preemption), we | |
211 | * know the HW has transitioned from port0 to port1, and we | |
212 | * advance our inflight/active tracking accordingly. | |
39e2f501 | 213 | */ |
22b7a426 | 214 | struct i915_request *inflight[EXECLIST_MAX_PORTS + 1 /* sentinel */]; |
39e2f501 | 215 | /** |
22b7a426 | 216 | * @pending: the next set of contexts submitted to ELSP |
39e2f501 | 217 | * |
22b7a426 CW |
218 | * We store the array of contexts that we submit to HW (via ELSP) and |
219 | * promote them to the inflight array once HW has signaled the | |
220 | * preemption or idle-to-active event. | |
39e2f501 | 221 | */ |
22b7a426 | 222 | struct i915_request *pending[EXECLIST_MAX_PORTS + 1]; |
39e2f501 CW |
223 | |
224 | /** | |
225 | * @port_mask: number of execlist ports - 1 | |
226 | */ | |
227 | unsigned int port_mask; | |
228 | ||
df403069 CW |
229 | /** |
230 | * @switch_priority_hint: Second context priority. | |
231 | * | |
232 | * We submit multiple contexts to the HW simultaneously and would | |
233 | * like to occasionally switch between them to emulate timeslicing. | |
234 | * To know when timeslicing is suitable, we track the priority of | |
235 | * the context submitted second. | |
236 | */ | |
237 | int switch_priority_hint; | |
238 | ||
39e2f501 CW |
239 | /** |
240 | * @queue_priority_hint: Highest pending priority. | |
241 | * | |
242 | * When we add requests into the queue, or adjust the priority of | |
243 | * executing requests, we compute the maximum priority of those | |
244 | * pending requests. We can then use this value to determine if | |
245 | * we need to preempt the executing requests to service the queue. | |
246 | * However, since the we may have recorded the priority of an inflight | |
247 | * request we wanted to preempt but since completed, at the time of | |
248 | * dequeuing the priority hint may no longer may match the highest | |
249 | * available request priority. | |
250 | */ | |
251 | int queue_priority_hint; | |
252 | ||
253 | /** | |
254 | * @queue: queue of requests, in priority lists | |
255 | */ | |
256 | struct rb_root_cached queue; | |
6d06779e | 257 | struct rb_root_cached virtual; |
39e2f501 CW |
258 | |
259 | /** | |
260 | * @csb_write: control register for Context Switch buffer | |
261 | * | |
262 | * Note this register may be either mmio or HWSP shadow. | |
263 | */ | |
264 | u32 *csb_write; | |
265 | ||
266 | /** | |
267 | * @csb_status: status array for Context Switch buffer | |
268 | * | |
269 | * Note these register may be either mmio or HWSP shadow. | |
270 | */ | |
271 | u32 *csb_status; | |
272 | ||
7d4c75d9 MK |
273 | /** |
274 | * @csb_size: context status buffer FIFO size | |
275 | */ | |
276 | u8 csb_size; | |
277 | ||
39e2f501 CW |
278 | /** |
279 | * @csb_head: context status buffer head | |
280 | */ | |
281 | u8 csb_head; | |
282 | ||
283 | I915_SELFTEST_DECLARE(struct st_preempt_hang preempt_hang;) | |
284 | }; | |
285 | ||
286 | #define INTEL_ENGINE_CS_MAX_NAME 8 | |
287 | ||
288 | struct intel_engine_cs { | |
289 | struct drm_i915_private *i915; | |
f937f561 | 290 | struct intel_gt *gt; |
baba6e57 | 291 | struct intel_uncore *uncore; |
39e2f501 CW |
292 | char name[INTEL_ENGINE_CS_MAX_NAME]; |
293 | ||
294 | enum intel_engine_id id; | |
f1c4d157 CW |
295 | enum intel_engine_id legacy_idx; |
296 | ||
39e2f501 CW |
297 | unsigned int hw_id; |
298 | unsigned int guc_id; | |
f1c4d157 | 299 | |
39e2f501 CW |
300 | intel_engine_mask_t mask; |
301 | ||
39e2f501 CW |
302 | u8 class; |
303 | u8 instance; | |
750e76b4 | 304 | |
0b3bd0cd TU |
305 | u16 uabi_class; |
306 | u16 uabi_instance; | |
750e76b4 | 307 | |
2935ed53 | 308 | u32 uabi_capabilities; |
39e2f501 CW |
309 | u32 context_size; |
310 | u32 mmio_base; | |
311 | ||
1bc6a601 | 312 | unsigned long context_tag; |
c5d3e39c | 313 | |
750e76b4 CW |
314 | struct rb_node uabi_node; |
315 | ||
09407579 CW |
316 | struct intel_sseu sseu; |
317 | ||
422d7df4 CW |
318 | struct { |
319 | spinlock_t lock; | |
320 | struct list_head requests; | |
32ff621f | 321 | struct list_head hold; /* ready requests, but on hold */ |
422d7df4 CW |
322 | } active; |
323 | ||
ce476c80 | 324 | struct llist_head barrier_tasks; |
39e2f501 | 325 | |
9dbfea98 | 326 | struct intel_context *kernel_context; /* pinned */ |
9dbfea98 | 327 | |
44d89409 CW |
328 | intel_engine_mask_t saturated; /* submitting semaphores too late? */ |
329 | ||
058179e7 CW |
330 | struct { |
331 | struct delayed_work work; | |
332 | struct i915_request *systole; | |
333 | } heartbeat; | |
334 | ||
79ffac85 CW |
335 | unsigned long serial; |
336 | ||
337 | unsigned long wakeref_serial; | |
338 | struct intel_wakeref wakeref; | |
39e2f501 CW |
339 | struct drm_i915_gem_object *default_state; |
340 | void *pinned_default_state; | |
341 | ||
75d0a7f3 CW |
342 | struct { |
343 | struct intel_ring *ring; | |
344 | struct intel_timeline *timeline; | |
345 | } legacy; | |
346 | ||
b81e4d9b CW |
347 | /* |
348 | * We track the average duration of the idle pulse on parking the | |
349 | * engine to keep an estimate of the how the fast the engine is | |
350 | * under ideal conditions. | |
351 | */ | |
352 | struct ewma__engine_latency latency; | |
353 | ||
39e2f501 CW |
354 | /* Rather than have every client wait upon all user interrupts, |
355 | * with the herd waking after every interrupt and each doing the | |
356 | * heavyweight seqno dance, we delegate the task (of being the | |
357 | * bottom-half of the user interrupt) to the first client. After | |
358 | * every interrupt, we wake up one client, who does the heavyweight | |
359 | * coherent seqno read and either goes back to sleep (if incomplete), | |
360 | * or wakes up all the completed clients in parallel, before then | |
361 | * transferring the bottom-half status to the next client in the queue. | |
362 | * | |
363 | * Compared to walking the entire list of waiters in a single dedicated | |
364 | * bottom-half, we reduce the latency of the first waiter by avoiding | |
365 | * a context switch, but incur additional coherent seqno reads when | |
366 | * following the chain of request breadcrumbs. Since it is most likely | |
367 | * that we have a single client waiting on each seqno, then reducing | |
368 | * the overhead of waking that client is much preferred. | |
369 | */ | |
370 | struct intel_breadcrumbs { | |
371 | spinlock_t irq_lock; | |
372 | struct list_head signalers; | |
373 | ||
374 | struct irq_work irq_work; /* for use from inside irq_lock */ | |
375 | ||
376 | unsigned int irq_enabled; | |
377 | ||
378 | bool irq_armed; | |
379 | } breadcrumbs; | |
380 | ||
381 | struct intel_engine_pmu { | |
382 | /** | |
383 | * @enable: Bitmask of enable sample events on this engine. | |
384 | * | |
385 | * Bits correspond to sample event types, for instance | |
386 | * I915_SAMPLE_QUEUED is bit 0 etc. | |
387 | */ | |
388 | u32 enable; | |
389 | /** | |
390 | * @enable_count: Reference count for the enabled samplers. | |
391 | * | |
392 | * Index number corresponds to @enum drm_i915_pmu_engine_sample. | |
393 | */ | |
394 | unsigned int enable_count[I915_ENGINE_SAMPLE_COUNT]; | |
395 | /** | |
396 | * @sample: Counter values for sampling events. | |
397 | * | |
398 | * Our internal timer stores the current counters in this field. | |
399 | * | |
400 | * Index number corresponds to @enum drm_i915_pmu_engine_sample. | |
401 | */ | |
402 | struct i915_pmu_sample sample[I915_ENGINE_SAMPLE_COUNT]; | |
403 | } pmu; | |
404 | ||
405 | /* | |
406 | * A pool of objects to use as shadow copies of client batch buffers | |
407 | * when the command parser is enabled. Prevents the client from | |
408 | * modifying the batch contents after software parsing. | |
409 | */ | |
b40d7378 | 410 | struct intel_engine_pool pool; |
39e2f501 CW |
411 | |
412 | struct intel_hw_status_page status_page; | |
413 | struct i915_ctx_workarounds wa_ctx; | |
414 | struct i915_wa_list ctx_wa_list; | |
415 | struct i915_wa_list wa_list; | |
416 | struct i915_wa_list whitelist; | |
417 | ||
418 | u32 irq_keep_mask; /* always keep these interrupts */ | |
419 | u32 irq_enable_mask; /* bitmask to enable ring interrupt */ | |
420 | void (*irq_enable)(struct intel_engine_cs *engine); | |
421 | void (*irq_disable)(struct intel_engine_cs *engine); | |
422 | ||
79ffac85 | 423 | int (*resume)(struct intel_engine_cs *engine); |
39e2f501 CW |
424 | |
425 | struct { | |
426 | void (*prepare)(struct intel_engine_cs *engine); | |
e26b6d43 CW |
427 | |
428 | void (*rewind)(struct intel_engine_cs *engine, bool stalled); | |
429 | void (*cancel)(struct intel_engine_cs *engine); | |
430 | ||
39e2f501 CW |
431 | void (*finish)(struct intel_engine_cs *engine); |
432 | } reset; | |
433 | ||
434 | void (*park)(struct intel_engine_cs *engine); | |
435 | void (*unpark)(struct intel_engine_cs *engine); | |
436 | ||
437 | void (*set_default_submission)(struct intel_engine_cs *engine); | |
438 | ||
4dc84b77 | 439 | const struct intel_context_ops *cops; |
39e2f501 CW |
440 | |
441 | int (*request_alloc)(struct i915_request *rq); | |
39e2f501 CW |
442 | |
443 | int (*emit_flush)(struct i915_request *request, u32 mode); | |
444 | #define EMIT_INVALIDATE BIT(0) | |
445 | #define EMIT_FLUSH BIT(1) | |
446 | #define EMIT_BARRIER (EMIT_INVALIDATE | EMIT_FLUSH) | |
447 | int (*emit_bb_start)(struct i915_request *rq, | |
448 | u64 offset, u32 length, | |
449 | unsigned int dispatch_flags); | |
450 | #define I915_DISPATCH_SECURE BIT(0) | |
451 | #define I915_DISPATCH_PINNED BIT(1) | |
452 | int (*emit_init_breadcrumb)(struct i915_request *rq); | |
453 | u32 *(*emit_fini_breadcrumb)(struct i915_request *rq, | |
454 | u32 *cs); | |
455 | unsigned int emit_fini_breadcrumb_dw; | |
456 | ||
457 | /* Pass the request to the hardware queue (e.g. directly into | |
458 | * the legacy ringbuffer or to the end of an execlist). | |
459 | * | |
460 | * This is called from an atomic context with irqs disabled; must | |
461 | * be irq safe. | |
462 | */ | |
463 | void (*submit_request)(struct i915_request *rq); | |
464 | ||
ee113690 CW |
465 | /* |
466 | * Called on signaling of a SUBMIT_FENCE, passing along the signaling | |
467 | * request down to the bonded pairs. | |
468 | */ | |
469 | void (*bond_execute)(struct i915_request *rq, | |
470 | struct dma_fence *signal); | |
471 | ||
39e2f501 CW |
472 | /* |
473 | * Call when the priority on a request has changed and it and its | |
474 | * dependencies may need rescheduling. Note the request itself may | |
475 | * not be ready to run! | |
476 | */ | |
477 | void (*schedule)(struct i915_request *request, | |
478 | const struct i915_sched_attr *attr); | |
479 | ||
e26b6d43 | 480 | void (*release)(struct intel_engine_cs *engine); |
39e2f501 CW |
481 | |
482 | struct intel_engine_execlists execlists; | |
483 | ||
4f88f874 CW |
484 | /* |
485 | * Keep track of completed timelines on this engine for early | |
486 | * retirement with the goal of quickly enabling powersaving as | |
487 | * soon as the engine is idle. | |
488 | */ | |
489 | struct intel_timeline *retire; | |
490 | struct work_struct retire_work; | |
491 | ||
39e2f501 CW |
492 | /* status_notifier: list of callbacks for context-switch changes */ |
493 | struct atomic_notifier_head context_status_notifier; | |
494 | ||
311a50e7 | 495 | #define I915_ENGINE_USING_CMD_PARSER BIT(0) |
39e2f501 CW |
496 | #define I915_ENGINE_SUPPORTS_STATS BIT(1) |
497 | #define I915_ENGINE_HAS_PREEMPTION BIT(2) | |
498 | #define I915_ENGINE_HAS_SEMAPHORES BIT(3) | |
fe5a7082 CW |
499 | #define I915_ENGINE_HAS_TIMESLICES BIT(4) |
500 | #define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(5) | |
501 | #define I915_ENGINE_IS_VIRTUAL BIT(6) | |
502 | #define I915_ENGINE_HAS_RELATIVE_MMIO BIT(7) | |
503 | #define I915_ENGINE_REQUIRES_CMD_PARSER BIT(8) | |
39e2f501 CW |
504 | unsigned int flags; |
505 | ||
506 | /* | |
507 | * Table of commands the command parser needs to know about | |
508 | * for this engine. | |
509 | */ | |
510 | DECLARE_HASHTABLE(cmd_hash, I915_CMD_HASH_ORDER); | |
511 | ||
512 | /* | |
513 | * Table of registers allowed in commands that read/write registers. | |
514 | */ | |
515 | const struct drm_i915_reg_table *reg_tables; | |
516 | int reg_table_count; | |
517 | ||
518 | /* | |
519 | * Returns the bitmask for the length field of the specified command. | |
520 | * Return 0 for an unrecognized/invalid command. | |
521 | * | |
522 | * If the command parser finds an entry for a command in the engine's | |
523 | * cmd_tables, it gets the command's length based on the table entry. | |
524 | * If not, it calls this function to determine the per-engine length | |
525 | * field encoding for the command (i.e. different opcode ranges use | |
526 | * certain bits to encode the command length in the header). | |
527 | */ | |
528 | u32 (*get_cmd_length_mask)(u32 cmd_header); | |
529 | ||
530 | struct { | |
531 | /** | |
532 | * @lock: Lock protecting the below fields. | |
533 | */ | |
534 | seqlock_t lock; | |
535 | /** | |
536 | * @enabled: Reference count indicating number of listeners. | |
537 | */ | |
538 | unsigned int enabled; | |
539 | /** | |
540 | * @active: Number of contexts currently scheduled in. | |
541 | */ | |
542 | unsigned int active; | |
543 | /** | |
544 | * @enabled_at: Timestamp when busy stats were enabled. | |
545 | */ | |
546 | ktime_t enabled_at; | |
547 | /** | |
548 | * @start: Timestamp of the last idle to active transition. | |
549 | * | |
550 | * Idle is defined as active == 0, active is active > 0. | |
551 | */ | |
552 | ktime_t start; | |
553 | /** | |
554 | * @total: Total time this engine was busy. | |
555 | * | |
556 | * Accumulated time not counting the most recent block in cases | |
557 | * where engine is currently busy (active > 0). | |
558 | */ | |
559 | ktime_t total; | |
560 | } stats; | |
a8c51ed2 CW |
561 | |
562 | struct { | |
058179e7 | 563 | unsigned long heartbeat_interval_ms; |
062444bb | 564 | unsigned long max_busywait_duration_ns; |
3a7a92ab | 565 | unsigned long preempt_timeout_ms; |
a8c51ed2 | 566 | unsigned long stop_timeout_ms; |
b79029b2 | 567 | unsigned long timeslice_duration_ms; |
a8c51ed2 | 568 | } props; |
39e2f501 CW |
569 | }; |
570 | ||
571 | static inline bool | |
311a50e7 | 572 | intel_engine_using_cmd_parser(const struct intel_engine_cs *engine) |
39e2f501 | 573 | { |
311a50e7 JB |
574 | return engine->flags & I915_ENGINE_USING_CMD_PARSER; |
575 | } | |
576 | ||
577 | static inline bool | |
578 | intel_engine_requires_cmd_parser(const struct intel_engine_cs *engine) | |
579 | { | |
580 | return engine->flags & I915_ENGINE_REQUIRES_CMD_PARSER; | |
39e2f501 CW |
581 | } |
582 | ||
583 | static inline bool | |
584 | intel_engine_supports_stats(const struct intel_engine_cs *engine) | |
585 | { | |
586 | return engine->flags & I915_ENGINE_SUPPORTS_STATS; | |
587 | } | |
588 | ||
589 | static inline bool | |
590 | intel_engine_has_preemption(const struct intel_engine_cs *engine) | |
591 | { | |
592 | return engine->flags & I915_ENGINE_HAS_PREEMPTION; | |
593 | } | |
594 | ||
595 | static inline bool | |
596 | intel_engine_has_semaphores(const struct intel_engine_cs *engine) | |
597 | { | |
598 | return engine->flags & I915_ENGINE_HAS_SEMAPHORES; | |
599 | } | |
600 | ||
fe5a7082 CW |
601 | static inline bool |
602 | intel_engine_has_timeslices(const struct intel_engine_cs *engine) | |
603 | { | |
604 | if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION)) | |
605 | return false; | |
606 | ||
607 | return engine->flags & I915_ENGINE_HAS_TIMESLICES; | |
608 | } | |
609 | ||
4c6ce5c9 CW |
610 | static inline bool |
611 | intel_engine_needs_breadcrumb_tasklet(const struct intel_engine_cs *engine) | |
612 | { | |
613 | return engine->flags & I915_ENGINE_NEEDS_BREADCRUMB_TASKLET; | |
614 | } | |
615 | ||
6d06779e CW |
616 | static inline bool |
617 | intel_engine_is_virtual(const struct intel_engine_cs *engine) | |
618 | { | |
619 | return engine->flags & I915_ENGINE_IS_VIRTUAL; | |
620 | } | |
621 | ||
cdb736fa MK |
622 | static inline bool |
623 | intel_engine_has_relative_mmio(const struct intel_engine_cs * const engine) | |
624 | { | |
625 | return engine->flags & I915_ENGINE_HAS_RELATIVE_MMIO; | |
626 | } | |
627 | ||
eaef5b3c SS |
628 | #define instdone_has_slice(dev_priv___, sseu___, slice___) \ |
629 | ((IS_GEN(dev_priv___, 7) ? 1 : ((sseu___)->slice_mask)) & BIT(slice___)) | |
630 | ||
631 | #define instdone_has_subslice(dev_priv__, sseu__, slice__, subslice__) \ | |
632 | (IS_GEN(dev_priv__, 7) ? (1 & BIT(subslice__)) : \ | |
633 | intel_sseu_has_subslice(sseu__, 0, subslice__)) | |
634 | ||
635 | #define for_each_instdone_slice_subslice(dev_priv_, sseu_, slice_, subslice_) \ | |
636 | for ((slice_) = 0, (subslice_) = 0; (slice_) < I915_MAX_SLICES; \ | |
637 | (subslice_) = ((subslice_) + 1) % I915_MAX_SUBSLICES, \ | |
638 | (slice_) += ((subslice_) == 0)) \ | |
639 | for_each_if((instdone_has_slice(dev_priv_, sseu_, slice_)) && \ | |
640 | (instdone_has_subslice(dev_priv_, sseu_, slice_, \ | |
641 | subslice_))) | |
39e2f501 | 642 | #endif /* __INTEL_ENGINE_TYPES_H__ */ |