1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright © 2023-2024 Intel Corporation
4 */
5
6 #include <linux/anon_inodes.h>
7 #include <linux/delay.h>
8 #include <linux/nospec.h>
9 #include <linux/poll.h>
10
11 #include <drm/drm_drv.h>
12 #include <drm/drm_gem.h>
13 #include <drm/drm_managed.h>
14 #include <drm/drm_syncobj.h>
15 #include <uapi/drm/xe_drm.h>
16
17 #include <generated/xe_wa_oob.h>
18 #include <generated/xe_device_wa_oob.h>
19
20 #include "abi/guc_actions_slpc_abi.h"
21 #include "instructions/xe_mi_commands.h"
22 #include "regs/xe_engine_regs.h"
23 #include "regs/xe_gt_regs.h"
24 #include "regs/xe_oa_regs.h"
25 #include "xe_assert.h"
26 #include "xe_bb.h"
27 #include "xe_bo.h"
28 #include "xe_device.h"
29 #include "xe_exec_queue.h"
30 #include "xe_force_wake.h"
31 #include "xe_gt.h"
32 #include "xe_gt_mcr.h"
33 #include "xe_gt_printk.h"
34 #include "xe_guc_rc.h"
35 #include "xe_macros.h"
36 #include "xe_mmio.h"
37 #include "xe_oa.h"
38 #include "xe_observation.h"
39 #include "xe_pm.h"
40 #include "xe_reg_whitelist.h"
41 #include "xe_sched_job.h"
42 #include "xe_sriov.h"
43 #include "xe_sync.h"
44 #include "xe_wa.h"
45
46 #define DEFAULT_POLL_FREQUENCY_HZ 200
47 #define DEFAULT_POLL_PERIOD_NS (NSEC_PER_SEC / DEFAULT_POLL_FREQUENCY_HZ)
48 #define XE_OA_UNIT_INVALID U32_MAX
49
50 enum xe_oam_unit_type {
51 XE_OAM_UNIT_SAG,
52 XE_OAM_UNIT_SCMI_0,
53 XE_OAM_UNIT_SCMI_1,
54 };
55
56 enum xe_oa_submit_deps {
57 XE_OA_SUBMIT_NO_DEPS,
58 XE_OA_SUBMIT_ADD_DEPS,
59 };
60
61 enum xe_oa_user_extn_from {
62 XE_OA_USER_EXTN_FROM_OPEN,
63 XE_OA_USER_EXTN_FROM_CONFIG,
64 };
65
66 struct xe_oa_reg {
67 struct xe_reg addr;
68 u32 value;
69 };
70
71 struct xe_oa_config {
72 struct xe_oa *oa;
73
74 char uuid[UUID_STRING_LEN + 1];
75 int id;
76
77 const struct xe_oa_reg *regs;
78 u32 regs_len;
79
80 struct attribute_group sysfs_metric;
81 struct attribute *attrs[2];
82 struct kobj_attribute sysfs_metric_id;
83
84 struct kref ref;
85 struct rcu_head rcu;
86 };
87
88 struct xe_oa_open_param {
89 struct xe_file *xef;
90 struct xe_oa_unit *oa_unit;
91 bool sample;
92 u32 metric_set;
93 enum xe_oa_format_name oa_format;
94 int period_exponent;
95 bool disabled;
96 int exec_queue_id;
97 int engine_instance;
98 struct xe_exec_queue *exec_q;
99 struct xe_hw_engine *hwe;
100 bool no_preempt;
101 struct drm_xe_sync __user *syncs_user;
102 int num_syncs;
103 struct xe_sync_entry *syncs;
104 size_t oa_buffer_size;
105 int wait_num_reports;
106 };
107
108 struct xe_oa_config_bo {
109 struct llist_node node;
110
111 struct xe_oa_config *oa_config;
112 struct xe_bb *bb;
113 };
114
115 struct xe_oa_fence {
116 /* @base: dma fence base */
117 struct dma_fence base;
118 /* @lock: lock for the fence */
119 spinlock_t lock;
120 /* @work: work to signal @base */
121 struct delayed_work work;
122 /* @cb: callback to schedule @work */
123 struct dma_fence_cb cb;
124 };
125
126 #define DRM_FMT(x) DRM_XE_OA_FMT_TYPE_##x
127
128 static const struct xe_oa_format oa_formats[] = {
129 [XE_OA_FORMAT_C4_B8] = { 7, 64, DRM_FMT(OAG) },
130 [XE_OA_FORMAT_A12] = { 0, 64, DRM_FMT(OAG) },
131 [XE_OA_FORMAT_A12_B8_C8] = { 2, 128, DRM_FMT(OAG) },
132 [XE_OA_FORMAT_A32u40_A4u32_B8_C8] = { 5, 256, DRM_FMT(OAG) },
133 [XE_OAR_FORMAT_A32u40_A4u32_B8_C8] = { 5, 256, DRM_FMT(OAR) },
134 [XE_OA_FORMAT_A24u40_A14u32_B8_C8] = { 5, 256, DRM_FMT(OAG) },
135 [XE_OAC_FORMAT_A24u64_B8_C8] = { 1, 320, DRM_FMT(OAC), HDR_64_BIT },
136 [XE_OAC_FORMAT_A22u32_R2u32_B8_C8] = { 2, 192, DRM_FMT(OAC), HDR_64_BIT },
137 [XE_OAM_FORMAT_MPEC8u64_B8_C8] = { 1, 192, DRM_FMT(OAM_MPEC), HDR_64_BIT },
138 [XE_OAM_FORMAT_MPEC8u32_B8_C8] = { 2, 128, DRM_FMT(OAM_MPEC), HDR_64_BIT },
139 [XE_OA_FORMAT_PEC64u64] = { 1, 576, DRM_FMT(PEC), HDR_64_BIT, 1, 0 },
140 [XE_OA_FORMAT_PEC64u64_B8_C8] = { 1, 640, DRM_FMT(PEC), HDR_64_BIT, 1, 1 },
141 [XE_OA_FORMAT_PEC64u32] = { 1, 320, DRM_FMT(PEC), HDR_64_BIT },
142 [XE_OA_FORMAT_PEC32u64_G1] = { 5, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 },
143 [XE_OA_FORMAT_PEC32u32_G1] = { 5, 192, DRM_FMT(PEC), HDR_64_BIT },
144 [XE_OA_FORMAT_PEC32u64_G2] = { 6, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 },
145 [XE_OA_FORMAT_PEC32u32_G2] = { 6, 192, DRM_FMT(PEC), HDR_64_BIT },
146 [XE_OA_FORMAT_PEC36u64_G1_32_G2_4] = { 3, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 },
147 [XE_OA_FORMAT_PEC36u64_G1_4_G2_32] = { 4, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 },
148 };
149
xe_oa_circ_diff(struct xe_oa_stream * stream,u32 tail,u32 head)150 static u32 xe_oa_circ_diff(struct xe_oa_stream *stream, u32 tail, u32 head)
151 {
152 return tail >= head ? tail - head :
153 tail + stream->oa_buffer.circ_size - head;
154 }
155
xe_oa_circ_incr(struct xe_oa_stream * stream,u32 ptr,u32 n)156 static u32 xe_oa_circ_incr(struct xe_oa_stream *stream, u32 ptr, u32 n)
157 {
158 return ptr + n >= stream->oa_buffer.circ_size ?
159 ptr + n - stream->oa_buffer.circ_size : ptr + n;
160 }
161
xe_oa_config_release(struct kref * ref)162 static void xe_oa_config_release(struct kref *ref)
163 {
164 struct xe_oa_config *oa_config =
165 container_of(ref, typeof(*oa_config), ref);
166
167 kfree(oa_config->regs);
168
169 kfree_rcu(oa_config, rcu);
170 }
171
xe_oa_config_put(struct xe_oa_config * oa_config)172 static void xe_oa_config_put(struct xe_oa_config *oa_config)
173 {
174 if (!oa_config)
175 return;
176
177 kref_put(&oa_config->ref, xe_oa_config_release);
178 }
179
xe_oa_config_get(struct xe_oa_config * oa_config)180 static struct xe_oa_config *xe_oa_config_get(struct xe_oa_config *oa_config)
181 {
182 return kref_get_unless_zero(&oa_config->ref) ? oa_config : NULL;
183 }
184
xe_oa_get_oa_config(struct xe_oa * oa,int metrics_set)185 static struct xe_oa_config *xe_oa_get_oa_config(struct xe_oa *oa, int metrics_set)
186 {
187 struct xe_oa_config *oa_config;
188
189 rcu_read_lock();
190 oa_config = idr_find(&oa->metrics_idr, metrics_set);
191 if (oa_config)
192 oa_config = xe_oa_config_get(oa_config);
193 rcu_read_unlock();
194
195 return oa_config;
196 }
197
free_oa_config_bo(struct xe_oa_config_bo * oa_bo,struct dma_fence * last_fence)198 static void free_oa_config_bo(struct xe_oa_config_bo *oa_bo, struct dma_fence *last_fence)
199 {
200 xe_oa_config_put(oa_bo->oa_config);
201 xe_bb_free(oa_bo->bb, last_fence);
202 kfree(oa_bo);
203 }
204
__oa_regs(struct xe_oa_stream * stream)205 static const struct xe_oa_regs *__oa_regs(struct xe_oa_stream *stream)
206 {
207 return &stream->oa_unit->regs;
208 }
209
xe_oa_hw_tail_read(struct xe_oa_stream * stream)210 static u32 xe_oa_hw_tail_read(struct xe_oa_stream *stream)
211 {
212 return xe_mmio_read32(&stream->gt->mmio, __oa_regs(stream)->oa_tail_ptr) &
213 OAG_OATAILPTR_MASK;
214 }
215
216 #define oa_report_header_64bit(__s) \
217 ((__s)->oa_buffer.format->header == HDR_64_BIT)
218
oa_report_id(struct xe_oa_stream * stream,u32 report_offset)219 static u64 oa_report_id(struct xe_oa_stream *stream, u32 report_offset)
220 {
221 struct iosys_map *map = &stream->oa_buffer.bo->vmap;
222
223 return oa_report_header_64bit(stream) ?
224 xe_map_rd(stream->oa->xe, map, report_offset, u64) :
225 xe_map_rd(stream->oa->xe, map, report_offset, u32);
226 }
227
oa_report_id_clear(struct xe_oa_stream * stream,u32 report_offset)228 static void oa_report_id_clear(struct xe_oa_stream *stream, u32 report_offset)
229 {
230 struct iosys_map *map = &stream->oa_buffer.bo->vmap;
231
232 oa_report_header_64bit(stream) ?
233 xe_map_wr(stream->oa->xe, map, report_offset, u64, 0) :
234 xe_map_wr(stream->oa->xe, map, report_offset, u32, 0);
235 }
236
oa_timestamp(struct xe_oa_stream * stream,u32 report_offset)237 static u64 oa_timestamp(struct xe_oa_stream *stream, u32 report_offset)
238 {
239 struct iosys_map *map = &stream->oa_buffer.bo->vmap;
240
241 return oa_report_header_64bit(stream) ?
242 xe_map_rd(stream->oa->xe, map, report_offset + 8, u64) :
243 xe_map_rd(stream->oa->xe, map, report_offset + 4, u32);
244 }
245
oa_timestamp_clear(struct xe_oa_stream * stream,u32 report_offset)246 static void oa_timestamp_clear(struct xe_oa_stream *stream, u32 report_offset)
247 {
248 struct iosys_map *map = &stream->oa_buffer.bo->vmap;
249
250 oa_report_header_64bit(stream) ?
251 xe_map_wr(stream->oa->xe, map, report_offset + 8, u64, 0) :
252 xe_map_wr(stream->oa->xe, map, report_offset + 4, u32, 0);
253 }
254
mert_wa_14026633728(struct xe_oa_stream * s)255 static bool mert_wa_14026633728(struct xe_oa_stream *s)
256 {
257 return s->oa_unit->type == DRM_XE_OA_UNIT_TYPE_MERT && XE_DEVICE_WA(s->oa->xe, 14026633728);
258 }
259
xe_oa_buffer_check_unlocked(struct xe_oa_stream * stream)260 static bool xe_oa_buffer_check_unlocked(struct xe_oa_stream *stream)
261 {
262 u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo);
263 u32 tail, hw_tail, partial_report_size, available;
264 int report_size = stream->oa_buffer.format->size;
265 unsigned long flags;
266
267 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
268
269 hw_tail = xe_oa_hw_tail_read(stream);
270 hw_tail -= gtt_offset;
271
272 /*
273 * The tail pointer increases in 64 byte (cacheline size), not in report_size
274 * increments. Also report size may not be a power of 2. Compute potential
275 * partially landed report in OA buffer.
276 */
277 partial_report_size = xe_oa_circ_diff(stream, hw_tail, stream->oa_buffer.tail);
278 partial_report_size %= report_size;
279
280 /* Subtract partial amount off the tail */
281 hw_tail = xe_oa_circ_diff(stream, hw_tail, partial_report_size);
282
283 tail = hw_tail;
284
285 /*
286 * Walk the stream backward until we find a report with report id and timestamp
287 * not 0. We can't tell whether a report has fully landed in memory before the
288 * report id and timestamp of the following report have landed.
289 *
290 * This is assuming that the writes of the OA unit land in memory in the order
291 * they were written. If not : (╯°□°)╯︵ ┻━┻
292 */
293 while (xe_oa_circ_diff(stream, tail, stream->oa_buffer.tail) >= report_size) {
294 if (oa_report_id(stream, tail) || oa_timestamp(stream, tail))
295 break;
296
297 tail = xe_oa_circ_diff(stream, tail, report_size);
298 }
299
300 if (xe_oa_circ_diff(stream, hw_tail, tail) > report_size)
301 drm_dbg(&stream->oa->xe->drm,
302 "unlanded report(s) head=0x%x tail=0x%x hw_tail=0x%x\n",
303 stream->oa_buffer.head, tail, hw_tail);
304
305 stream->oa_buffer.tail = tail;
306
307 available = xe_oa_circ_diff(stream, stream->oa_buffer.tail, stream->oa_buffer.head);
308 stream->pollin = available >= stream->wait_num_reports * report_size;
309
310 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
311
312 return stream->pollin;
313 }
314
xe_oa_poll_check_timer_cb(struct hrtimer * hrtimer)315 static enum hrtimer_restart xe_oa_poll_check_timer_cb(struct hrtimer *hrtimer)
316 {
317 struct xe_oa_stream *stream =
318 container_of(hrtimer, typeof(*stream), poll_check_timer);
319
320 if (xe_oa_buffer_check_unlocked(stream))
321 wake_up(&stream->poll_wq);
322
323 hrtimer_forward_now(hrtimer, ns_to_ktime(stream->poll_period_ns));
324
325 return HRTIMER_RESTART;
326 }
327
328 static unsigned long
xe_oa_copy_to_user(struct xe_oa_stream * stream,void __user * dst,u32 report_offset,u32 len)329 xe_oa_copy_to_user(struct xe_oa_stream *stream, void __user *dst, u32 report_offset, u32 len)
330 {
331 xe_assert(stream->oa->xe, len <= stream->oa_buffer.format->size);
332
333 xe_map_memcpy_from(stream->oa->xe, stream->oa_buffer.bounce,
334 &stream->oa_buffer.bo->vmap, report_offset, len);
335 return copy_to_user(dst, stream->oa_buffer.bounce, len);
336 }
337
xe_oa_append_report(struct xe_oa_stream * stream,char __user * buf,size_t count,size_t * offset,u32 report_offset)338 static int xe_oa_append_report(struct xe_oa_stream *stream, char __user *buf,
339 size_t count, size_t *offset, u32 report_offset)
340 {
341 int report_size = stream->oa_buffer.format->size;
342 int report_size_partial;
343
344 if ((count - *offset) < report_size)
345 return -ENOSPC;
346
347 buf += *offset;
348
349 report_size_partial = stream->oa_buffer.circ_size - report_offset;
350
351 if (report_size_partial < report_size) {
352 if (xe_oa_copy_to_user(stream, buf, report_offset, report_size_partial))
353 return -EFAULT;
354 buf += report_size_partial;
355
356 if (xe_oa_copy_to_user(stream, buf, 0, report_size - report_size_partial))
357 return -EFAULT;
358 } else if (xe_oa_copy_to_user(stream, buf, report_offset, report_size)) {
359 return -EFAULT;
360 }
361
362 *offset += report_size;
363
364 return 0;
365 }
366
xe_oa_append_reports(struct xe_oa_stream * stream,char __user * buf,size_t count,size_t * offset)367 static int xe_oa_append_reports(struct xe_oa_stream *stream, char __user *buf,
368 size_t count, size_t *offset)
369 {
370 int report_size = stream->oa_buffer.format->size;
371 u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo);
372 size_t start_offset = *offset;
373 unsigned long flags;
374 u32 head, tail;
375 int ret = 0;
376
377 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
378 head = stream->oa_buffer.head;
379 tail = stream->oa_buffer.tail;
380 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
381
382 xe_assert(stream->oa->xe,
383 head < stream->oa_buffer.circ_size && tail < stream->oa_buffer.circ_size);
384
385 for (; xe_oa_circ_diff(stream, tail, head);
386 head = xe_oa_circ_incr(stream, head, report_size)) {
387 ret = xe_oa_append_report(stream, buf, count, offset, head);
388 if (ret)
389 break;
390
391 if (!(stream->oa_buffer.circ_size % report_size)) {
392 /* Clear out report id and timestamp to detect unlanded reports */
393 oa_report_id_clear(stream, head);
394 oa_timestamp_clear(stream, head);
395 } else {
396 struct iosys_map *map = &stream->oa_buffer.bo->vmap;
397 u32 part = stream->oa_buffer.circ_size - head;
398
399 /* Zero out the entire report */
400 if (report_size <= part) {
401 xe_map_memset(stream->oa->xe, map, head, 0, report_size);
402 } else {
403 xe_map_memset(stream->oa->xe, map, head, 0, part);
404 xe_map_memset(stream->oa->xe, map, 0, 0, report_size - part);
405 }
406 }
407 }
408
409 if (start_offset != *offset) {
410 struct xe_reg oaheadptr = __oa_regs(stream)->oa_head_ptr;
411
412 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
413 xe_mmio_write32(&stream->gt->mmio, oaheadptr,
414 (head + gtt_offset) & OAG_OAHEADPTR_MASK);
415 stream->oa_buffer.head = head;
416 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
417 }
418
419 return ret;
420 }
421
xe_oa_init_oa_buffer(struct xe_oa_stream * stream)422 static void xe_oa_init_oa_buffer(struct xe_oa_stream *stream)
423 {
424 u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo);
425 int size_exponent = __ffs(xe_bo_size(stream->oa_buffer.bo));
426 u32 oa_buf = gtt_offset | OAG_OABUFFER_MEMORY_SELECT;
427 struct xe_mmio *mmio = &stream->gt->mmio;
428 unsigned long flags;
429
430 /*
431 * If oa buffer size is more than 16MB (exponent greater than 24), the
432 * oa buffer size field is multiplied by 8 in xe_oa_enable_metric_set.
433 */
434 oa_buf |= REG_FIELD_PREP(OABUFFER_SIZE_MASK,
435 size_exponent > 24 ? size_exponent - 20 : size_exponent - 17);
436
437 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
438
439 xe_mmio_write32(mmio, __oa_regs(stream)->oa_status, 0);
440 xe_mmio_write32(mmio, __oa_regs(stream)->oa_head_ptr,
441 gtt_offset & OAG_OAHEADPTR_MASK);
442 stream->oa_buffer.head = 0;
443 /*
444 * PRM says: "This MMIO must be set before the OATAILPTR register and after the
445 * OAHEADPTR register. This is to enable proper functionality of the overflow bit".
446 */
447 xe_mmio_write32(mmio, __oa_regs(stream)->oa_buffer, oa_buf);
448 xe_mmio_write32(mmio, __oa_regs(stream)->oa_tail_ptr,
449 gtt_offset & OAG_OATAILPTR_MASK);
450
451 /* Mark that we need updated tail pointer to read from */
452 stream->oa_buffer.tail = 0;
453
454 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
455
456 /* Zero out the OA buffer since we rely on zero report id and timestamp fields */
457 xe_map_memset(stream->oa->xe, &stream->oa_buffer.bo->vmap, 0, 0,
458 xe_bo_size(stream->oa_buffer.bo));
459 }
460
__format_to_oactrl(const struct xe_oa_format * format,int counter_sel_mask)461 static u32 __format_to_oactrl(const struct xe_oa_format *format, int counter_sel_mask)
462 {
463 return ((format->counter_select << (ffs(counter_sel_mask) - 1)) & counter_sel_mask) |
464 REG_FIELD_PREP(OA_OACONTROL_REPORT_BC_MASK, format->bc_report) |
465 REG_FIELD_PREP(OA_OACONTROL_COUNTER_SIZE_MASK, format->counter_size);
466 }
467
__oa_ccs_select(struct xe_oa_stream * stream)468 static u32 __oa_ccs_select(struct xe_oa_stream *stream)
469 {
470 u32 val;
471
472 if (stream->hwe->class != XE_ENGINE_CLASS_COMPUTE)
473 return 0;
474
475 val = REG_FIELD_PREP(OAG_OACONTROL_OA_CCS_SELECT_MASK, stream->hwe->instance);
476 xe_assert(stream->oa->xe,
477 REG_FIELD_GET(OAG_OACONTROL_OA_CCS_SELECT_MASK, val) == stream->hwe->instance);
478 return val;
479 }
480
__oactrl_used_bits(struct xe_oa_stream * stream)481 static u32 __oactrl_used_bits(struct xe_oa_stream *stream)
482 {
483 return stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAG ?
484 OAG_OACONTROL_USED_BITS : OAM_OACONTROL_USED_BITS;
485 }
486
xe_oa_enable(struct xe_oa_stream * stream)487 static void xe_oa_enable(struct xe_oa_stream *stream)
488 {
489 const struct xe_oa_format *format = stream->oa_buffer.format;
490 const struct xe_oa_regs *regs;
491 u32 val;
492
493 /*
494 * BSpec: 46822: Bit 0. Even if stream->sample is 0, for OAR to function, the OA
495 * buffer must be correctly initialized
496 */
497 xe_oa_init_oa_buffer(stream);
498
499 regs = __oa_regs(stream);
500 val = __format_to_oactrl(format, regs->oa_ctrl_counter_select_mask) |
501 __oa_ccs_select(stream) | OAG_OACONTROL_OA_COUNTER_ENABLE;
502
503 if (GRAPHICS_VER(stream->oa->xe) >= 20 &&
504 stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAG)
505 val |= OAG_OACONTROL_OA_PES_DISAG_EN;
506
507 xe_mmio_rmw32(&stream->gt->mmio, regs->oa_ctrl, __oactrl_used_bits(stream), val);
508 }
509
xe_oa_disable(struct xe_oa_stream * stream)510 static void xe_oa_disable(struct xe_oa_stream *stream)
511 {
512 struct xe_mmio *mmio = &stream->gt->mmio;
513
514 xe_mmio_rmw32(mmio, __oa_regs(stream)->oa_ctrl, __oactrl_used_bits(stream), 0);
515 if (xe_mmio_wait32(mmio, __oa_regs(stream)->oa_ctrl,
516 OAG_OACONTROL_OA_COUNTER_ENABLE, 0, 50000, NULL, false))
517 drm_err(&stream->oa->xe->drm,
518 "wait for OA to be disabled timed out\n");
519
520 if (GRAPHICS_VERx100(stream->oa->xe) <= 1270 && GRAPHICS_VERx100(stream->oa->xe) != 1260) {
521 /* <= XE_METEORLAKE except XE_PVC */
522 xe_mmio_write32(mmio, OA_TLB_INV_CR, 1);
523 if (xe_mmio_wait32(mmio, OA_TLB_INV_CR, 1, 0, 50000, NULL, false))
524 drm_err(&stream->oa->xe->drm,
525 "wait for OA tlb invalidate timed out\n");
526 }
527 }
528
xe_oa_wait_unlocked(struct xe_oa_stream * stream)529 static int xe_oa_wait_unlocked(struct xe_oa_stream *stream)
530 {
531 /* We might wait indefinitely if periodic sampling is not enabled */
532 if (!stream->periodic)
533 return -EINVAL;
534
535 return wait_event_interruptible(stream->poll_wq,
536 xe_oa_buffer_check_unlocked(stream));
537 }
538
539 #define OASTATUS_RELEVANT_BITS (OASTATUS_MMIO_TRG_Q_FULL | OASTATUS_COUNTER_OVERFLOW | \
540 OASTATUS_BUFFER_OVERFLOW | OASTATUS_REPORT_LOST)
541
__xe_oa_read(struct xe_oa_stream * stream,char __user * buf,size_t count,size_t * offset)542 static int __xe_oa_read(struct xe_oa_stream *stream, char __user *buf,
543 size_t count, size_t *offset)
544 {
545 /* Only clear our bits to avoid side-effects */
546 stream->oa_status = xe_mmio_rmw32(&stream->gt->mmio, __oa_regs(stream)->oa_status,
547 OASTATUS_RELEVANT_BITS, 0);
548 /*
549 * Signal to userspace that there is non-zero OA status to read via
550 * @DRM_XE_OBSERVATION_IOCTL_STATUS observation stream fd ioctl
551 */
552 if (stream->oa_status & OASTATUS_RELEVANT_BITS)
553 return -EIO;
554
555 return xe_oa_append_reports(stream, buf, count, offset);
556 }
557
xe_oa_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)558 static ssize_t xe_oa_read(struct file *file, char __user *buf,
559 size_t count, loff_t *ppos)
560 {
561 struct xe_oa_stream *stream = file->private_data;
562 size_t offset = 0;
563 int ret;
564
565 if (!stream->sample)
566 return -EINVAL;
567
568 if (!(file->f_flags & O_NONBLOCK)) {
569 do {
570 ret = xe_oa_wait_unlocked(stream);
571 if (ret)
572 return ret;
573
574 mutex_lock(&stream->stream_lock);
575 ret = __xe_oa_read(stream, buf, count, &offset);
576 mutex_unlock(&stream->stream_lock);
577 } while (!offset && !ret);
578 } else {
579 xe_oa_buffer_check_unlocked(stream);
580 mutex_lock(&stream->stream_lock);
581 ret = __xe_oa_read(stream, buf, count, &offset);
582 mutex_unlock(&stream->stream_lock);
583 }
584
585 /*
586 * Typically we clear pollin here in order to wait for the new hrtimer callback
587 * before unblocking. The exception to this is if __xe_oa_read returns -ENOSPC,
588 * which means that more OA data is available than could fit in the user provided
589 * buffer. In this case we want the next poll() call to not block.
590 *
591 * Also in case of -EIO, we have already waited for data before returning
592 * -EIO, so need to wait again
593 */
594 if (ret != -ENOSPC && ret != -EIO)
595 stream->pollin = false;
596
597 /* Possible values for ret are 0, -EFAULT, -ENOSPC, -EIO, -EINVAL, ... */
598 return offset ?: (ret ?: -EAGAIN);
599 }
600
xe_oa_poll_locked(struct xe_oa_stream * stream,struct file * file,poll_table * wait)601 static __poll_t xe_oa_poll_locked(struct xe_oa_stream *stream,
602 struct file *file, poll_table *wait)
603 {
604 __poll_t events = 0;
605
606 poll_wait(file, &stream->poll_wq, wait);
607
608 /*
609 * We don't explicitly check whether there's something to read here since this
610 * path may be hot depending on what else userspace is polling, or on the timeout
611 * in use. We rely on hrtimer xe_oa_poll_check_timer_cb to notify us when there
612 * are samples to read
613 */
614 if (stream->pollin)
615 events |= EPOLLIN;
616
617 return events;
618 }
619
xe_oa_poll(struct file * file,poll_table * wait)620 static __poll_t xe_oa_poll(struct file *file, poll_table *wait)
621 {
622 struct xe_oa_stream *stream = file->private_data;
623 __poll_t ret;
624
625 mutex_lock(&stream->stream_lock);
626 ret = xe_oa_poll_locked(stream, file, wait);
627 mutex_unlock(&stream->stream_lock);
628
629 return ret;
630 }
631
xe_oa_lock_vma(struct xe_exec_queue * q)632 static void xe_oa_lock_vma(struct xe_exec_queue *q)
633 {
634 if (q->vm) {
635 down_read(&q->vm->lock);
636 xe_vm_lock(q->vm, false);
637 }
638 }
639
xe_oa_unlock_vma(struct xe_exec_queue * q)640 static void xe_oa_unlock_vma(struct xe_exec_queue *q)
641 {
642 if (q->vm) {
643 xe_vm_unlock(q->vm);
644 up_read(&q->vm->lock);
645 }
646 }
647
xe_oa_submit_bb(struct xe_oa_stream * stream,enum xe_oa_submit_deps deps,struct xe_bb * bb)648 static struct dma_fence *xe_oa_submit_bb(struct xe_oa_stream *stream, enum xe_oa_submit_deps deps,
649 struct xe_bb *bb)
650 {
651 struct xe_exec_queue *q = stream->exec_q ?: stream->k_exec_q;
652 struct xe_sched_job *job;
653 struct dma_fence *fence;
654 int err = 0;
655
656 xe_oa_lock_vma(q);
657
658 job = xe_bb_create_job(q, bb);
659 if (IS_ERR(job)) {
660 err = PTR_ERR(job);
661 goto exit;
662 }
663 job->ggtt = true;
664
665 if (deps == XE_OA_SUBMIT_ADD_DEPS) {
666 for (int i = 0; i < stream->num_syncs && !err; i++)
667 err = xe_sync_entry_add_deps(&stream->syncs[i], job);
668 if (err) {
669 drm_dbg(&stream->oa->xe->drm, "xe_sync_entry_add_deps err %d\n", err);
670 goto err_put_job;
671 }
672 }
673
674 xe_sched_job_arm(job);
675 fence = dma_fence_get(&job->drm.s_fence->finished);
676 xe_sched_job_push(job);
677
678 xe_oa_unlock_vma(q);
679
680 return fence;
681 err_put_job:
682 xe_sched_job_put(job);
683 exit:
684 xe_oa_unlock_vma(q);
685 return ERR_PTR(err);
686 }
687
write_cs_mi_lri(struct xe_bb * bb,const struct xe_oa_reg * reg_data,u32 n_regs)688 static void write_cs_mi_lri(struct xe_bb *bb, const struct xe_oa_reg *reg_data, u32 n_regs)
689 {
690 u32 i;
691
692 #define MI_LOAD_REGISTER_IMM_MAX_REGS (126)
693
694 for (i = 0; i < n_regs; i++) {
695 if ((i % MI_LOAD_REGISTER_IMM_MAX_REGS) == 0) {
696 u32 n_lri = min_t(u32, n_regs - i,
697 MI_LOAD_REGISTER_IMM_MAX_REGS);
698
699 bb->cs[bb->len++] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(n_lri);
700 }
701 bb->cs[bb->len++] = reg_data[i].addr.addr;
702 bb->cs[bb->len++] = reg_data[i].value;
703 }
704 }
705
num_lri_dwords(int num_regs)706 static int num_lri_dwords(int num_regs)
707 {
708 int count = 0;
709
710 if (num_regs > 0) {
711 count += DIV_ROUND_UP(num_regs, MI_LOAD_REGISTER_IMM_MAX_REGS);
712 count += num_regs * 2;
713 }
714
715 return count;
716 }
717
xe_oa_free_oa_buffer(struct xe_oa_stream * stream)718 static void xe_oa_free_oa_buffer(struct xe_oa_stream *stream)
719 {
720 xe_bo_unpin_map_no_vm(stream->oa_buffer.bo);
721 kfree(stream->oa_buffer.bounce);
722 }
723
xe_oa_free_configs(struct xe_oa_stream * stream)724 static void xe_oa_free_configs(struct xe_oa_stream *stream)
725 {
726 struct xe_oa_config_bo *oa_bo, *tmp;
727
728 xe_oa_config_put(stream->oa_config);
729 llist_for_each_entry_safe(oa_bo, tmp, stream->oa_config_bos.first, node)
730 free_oa_config_bo(oa_bo, stream->last_fence);
731 dma_fence_put(stream->last_fence);
732 }
733
xe_oa_load_with_lri(struct xe_oa_stream * stream,struct xe_oa_reg * reg_lri,u32 count)734 static int xe_oa_load_with_lri(struct xe_oa_stream *stream, struct xe_oa_reg *reg_lri, u32 count)
735 {
736 struct dma_fence *fence;
737 struct xe_bb *bb;
738 int err;
739
740 bb = xe_bb_new(stream->gt, 2 * count + 1, false);
741 if (IS_ERR(bb)) {
742 err = PTR_ERR(bb);
743 goto exit;
744 }
745
746 write_cs_mi_lri(bb, reg_lri, count);
747
748 fence = xe_oa_submit_bb(stream, XE_OA_SUBMIT_NO_DEPS, bb);
749 if (IS_ERR(fence)) {
750 err = PTR_ERR(fence);
751 goto free_bb;
752 }
753 xe_bb_free(bb, fence);
754 dma_fence_put(fence);
755
756 return 0;
757 free_bb:
758 xe_bb_free(bb, NULL);
759 exit:
760 return err;
761 }
762
xe_oa_configure_oar_context(struct xe_oa_stream * stream,bool enable)763 static int xe_oa_configure_oar_context(struct xe_oa_stream *stream, bool enable)
764 {
765 const struct xe_oa_format *format = stream->oa_buffer.format;
766 u32 oacontrol = __format_to_oactrl(format, OAR_OACONTROL_COUNTER_SEL_MASK) |
767 (enable ? OAR_OACONTROL_COUNTER_ENABLE : 0);
768
769 struct xe_oa_reg reg_lri[] = {
770 {
771 OACTXCONTROL(stream->hwe->mmio_base),
772 enable ? OA_COUNTER_RESUME : 0,
773 },
774 {
775 OAR_OACONTROL,
776 oacontrol,
777 },
778 {
779 RING_CONTEXT_CONTROL(stream->hwe->mmio_base),
780 enable ?
781 REG_MASKED_FIELD_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE) :
782 REG_MASKED_FIELD_DISABLE(CTX_CTRL_OAC_CONTEXT_ENABLE)
783 },
784 };
785
786 return xe_oa_load_with_lri(stream, reg_lri, ARRAY_SIZE(reg_lri));
787 }
788
xe_oa_configure_oac_context(struct xe_oa_stream * stream,bool enable)789 static int xe_oa_configure_oac_context(struct xe_oa_stream *stream, bool enable)
790 {
791 const struct xe_oa_format *format = stream->oa_buffer.format;
792 u32 oacontrol = __format_to_oactrl(format, OAR_OACONTROL_COUNTER_SEL_MASK) |
793 (enable ? OAR_OACONTROL_COUNTER_ENABLE : 0);
794 struct xe_oa_reg reg_lri[] = {
795 {
796 OACTXCONTROL(stream->hwe->mmio_base),
797 enable ? OA_COUNTER_RESUME : 0,
798 },
799 {
800 OAC_OACONTROL,
801 oacontrol
802 },
803 {
804 RING_CONTEXT_CONTROL(stream->hwe->mmio_base),
805 enable ?
806 REG_MASKED_FIELD_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE | CTX_CTRL_RUN_ALONE) :
807 REG_MASKED_FIELD_DISABLE(CTX_CTRL_OAC_CONTEXT_ENABLE | CTX_CTRL_RUN_ALONE),
808 },
809 };
810
811 /* Set ccs select to enable programming of OAC_OACONTROL */
812 xe_mmio_write32(&stream->gt->mmio, __oa_regs(stream)->oa_ctrl,
813 __oa_ccs_select(stream));
814
815 return xe_oa_load_with_lri(stream, reg_lri, ARRAY_SIZE(reg_lri));
816 }
817
xe_oa_configure_oa_context(struct xe_oa_stream * stream,bool enable)818 static int xe_oa_configure_oa_context(struct xe_oa_stream *stream, bool enable)
819 {
820 switch (stream->hwe->class) {
821 case XE_ENGINE_CLASS_RENDER:
822 return xe_oa_configure_oar_context(stream, enable);
823 case XE_ENGINE_CLASS_COMPUTE:
824 return xe_oa_configure_oac_context(stream, enable);
825 default:
826 /* Video engines do not support MI_REPORT_PERF_COUNT */
827 return 0;
828 }
829 }
830
831 #define HAS_OA_BPC_REPORTING(xe) (GRAPHICS_VERx100(xe) >= 1255)
832
oag_configure_mmio_trigger(const struct xe_oa_stream * stream,bool enable)833 static u32 oag_configure_mmio_trigger(const struct xe_oa_stream *stream, bool enable)
834 {
835 if (enable && stream && stream->sample)
836 return REG_MASKED_FIELD_DISABLE(OAG_OA_DEBUG_DISABLE_MMIO_TRG);
837 else
838 return REG_MASKED_FIELD_ENABLE(OAG_OA_DEBUG_DISABLE_MMIO_TRG);
839 }
840
xe_oa_disable_metric_set(struct xe_oa_stream * stream)841 static void xe_oa_disable_metric_set(struct xe_oa_stream *stream)
842 {
843 struct xe_mmio *mmio = &stream->gt->mmio;
844 u32 sqcnt1;
845
846 /* Enable thread stall DOP gating and EU DOP gating. */
847 if (XE_GT_WA(stream->gt, 1508761755)) {
848 xe_gt_mcr_multicast_write(stream->gt, ROW_CHICKEN,
849 REG_MASKED_FIELD_DISABLE(STALL_DOP_GATING_DISABLE));
850 xe_gt_mcr_multicast_write(stream->gt, ROW_CHICKEN2,
851 REG_MASKED_FIELD_DISABLE(DISABLE_DOP_GATING));
852 }
853
854 xe_mmio_write32(mmio, __oa_regs(stream)->oa_debug,
855 oag_configure_mmio_trigger(stream, false));
856
857 /* disable the context save/restore or OAR counters */
858 if (stream->exec_q)
859 xe_oa_configure_oa_context(stream, false);
860
861 /* Make sure we disable noa to save power. */
862 if (GT_VER(stream->gt) < 35)
863 xe_mmio_rmw32(mmio, RPM_CONFIG1, GT_NOA_ENABLE, 0);
864
865 sqcnt1 = SQCNT1_PMON_ENABLE |
866 (HAS_OA_BPC_REPORTING(stream->oa->xe) ? SQCNT1_OABPC : 0);
867
868 /* Reset PMON Enable to save power. */
869 xe_mmio_rmw32(mmio, XELPMP_SQCNT1, sqcnt1, 0);
870
871 if ((stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAM ||
872 stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAM_SAG) &&
873 GRAPHICS_VER(stream->oa->xe) >= 30)
874 xe_mmio_rmw32(mmio, OAM_COMPRESSION_T3_CONTROL, OAM_LAT_MEASURE_ENABLE, 0);
875 }
876
xe_oa_stream_destroy(struct xe_oa_stream * stream)877 static void xe_oa_stream_destroy(struct xe_oa_stream *stream)
878 {
879 struct xe_oa_unit *u = stream->oa_unit;
880 struct xe_gt *gt = stream->hwe->gt;
881
882 if (WARN_ON(stream != u->exclusive_stream))
883 return;
884
885 WRITE_ONCE(u->exclusive_stream, NULL);
886
887 mutex_destroy(&stream->stream_lock);
888
889 if (stream->sample)
890 xe_reg_dewhitelist_oa_regs(stream->gt);
891
892 xe_oa_disable_metric_set(stream);
893 xe_exec_queue_put(stream->k_exec_q);
894
895 xe_oa_free_oa_buffer(stream);
896
897 xe_force_wake_put(gt_to_fw(gt), stream->fw_ref);
898 xe_pm_runtime_put(stream->oa->xe);
899
900 xe_oa_free_configs(stream);
901 xe_file_put(stream->xef);
902 }
903
xe_oa_alloc_oa_buffer(struct xe_oa_stream * stream,size_t size)904 static int xe_oa_alloc_oa_buffer(struct xe_oa_stream *stream, size_t size)
905 {
906 u32 vram = mert_wa_14026633728(stream) ?
907 XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(stream->oa->xe)) :
908 XE_BO_FLAG_SYSTEM;
909 struct xe_bo *bo;
910
911 bo = xe_bo_create_pin_map_novm(stream->oa->xe, stream->gt->tile,
912 size, ttm_bo_type_kernel,
913 vram | XE_BO_FLAG_GGTT, false);
914 if (IS_ERR(bo))
915 return PTR_ERR(bo);
916
917 /*
918 * ttm_bo_type_kernel BOs are not zeroed on allocation, so the buffer can
919 * hold stale data from previously freed pages. Since the OA buffer is
920 * mmap'able by userspace, clear it here to avoid leaking kernel memory.
921 */
922 xe_map_memset(stream->oa->xe, &bo->vmap, 0, 0, xe_bo_size(bo));
923
924 stream->oa_buffer.bo = bo;
925
926 stream->oa_buffer.bounce = kmalloc(stream->oa_buffer.format->size, GFP_KERNEL);
927 if (!stream->oa_buffer.bounce) {
928 xe_bo_unpin_map_no_vm(stream->oa_buffer.bo);
929 return -ENOMEM;
930 }
931
932 return 0;
933 }
934
935 static struct xe_oa_config_bo *
__xe_oa_alloc_config_buffer(struct xe_oa_stream * stream,struct xe_oa_config * oa_config)936 __xe_oa_alloc_config_buffer(struct xe_oa_stream *stream, struct xe_oa_config *oa_config)
937 {
938 struct xe_oa_config_bo *oa_bo;
939 size_t config_length;
940 struct xe_bb *bb;
941
942 oa_bo = kzalloc_obj(*oa_bo);
943 if (!oa_bo)
944 return ERR_PTR(-ENOMEM);
945
946 config_length = num_lri_dwords(oa_config->regs_len);
947 config_length = ALIGN(sizeof(u32) * config_length, XE_PAGE_SIZE) / sizeof(u32);
948
949 bb = xe_bb_new(stream->gt, config_length, false);
950 if (IS_ERR(bb))
951 goto err_free;
952
953 write_cs_mi_lri(bb, oa_config->regs, oa_config->regs_len);
954
955 oa_bo->bb = bb;
956 oa_bo->oa_config = xe_oa_config_get(oa_config);
957 llist_add(&oa_bo->node, &stream->oa_config_bos);
958
959 return oa_bo;
960 err_free:
961 kfree(oa_bo);
962 return ERR_CAST(bb);
963 }
964
965 static struct xe_oa_config_bo *
xe_oa_alloc_config_buffer(struct xe_oa_stream * stream,struct xe_oa_config * oa_config)966 xe_oa_alloc_config_buffer(struct xe_oa_stream *stream, struct xe_oa_config *oa_config)
967 {
968 struct xe_oa_config_bo *oa_bo;
969
970 /* Look for the buffer in the already allocated BOs attached to the stream */
971 llist_for_each_entry(oa_bo, stream->oa_config_bos.first, node) {
972 if (oa_bo->oa_config == oa_config &&
973 memcmp(oa_bo->oa_config->uuid, oa_config->uuid,
974 sizeof(oa_config->uuid)) == 0)
975 goto out;
976 }
977
978 oa_bo = __xe_oa_alloc_config_buffer(stream, oa_config);
979 out:
980 return oa_bo;
981 }
982
xe_oa_update_last_fence(struct xe_oa_stream * stream,struct dma_fence * fence)983 static void xe_oa_update_last_fence(struct xe_oa_stream *stream, struct dma_fence *fence)
984 {
985 dma_fence_put(stream->last_fence);
986 stream->last_fence = dma_fence_get(fence);
987 }
988
xe_oa_fence_work_fn(struct work_struct * w)989 static void xe_oa_fence_work_fn(struct work_struct *w)
990 {
991 struct xe_oa_fence *ofence = container_of(w, typeof(*ofence), work.work);
992
993 /* Signal fence to indicate new OA configuration is active */
994 dma_fence_signal(&ofence->base);
995 dma_fence_put(&ofence->base);
996 }
997
xe_oa_config_cb(struct dma_fence * fence,struct dma_fence_cb * cb)998 static void xe_oa_config_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
999 {
1000 /* Additional empirical delay needed for NOA programming after registers are written */
1001 #define NOA_PROGRAM_ADDITIONAL_DELAY_US 500
1002
1003 struct xe_oa_fence *ofence = container_of(cb, typeof(*ofence), cb);
1004
1005 INIT_DELAYED_WORK(&ofence->work, xe_oa_fence_work_fn);
1006 queue_delayed_work(system_dfl_wq, &ofence->work,
1007 usecs_to_jiffies(NOA_PROGRAM_ADDITIONAL_DELAY_US));
1008 dma_fence_put(fence);
1009 }
1010
xe_oa_get_driver_name(struct dma_fence * fence)1011 static const char *xe_oa_get_driver_name(struct dma_fence *fence)
1012 {
1013 return "xe_oa";
1014 }
1015
xe_oa_get_timeline_name(struct dma_fence * fence)1016 static const char *xe_oa_get_timeline_name(struct dma_fence *fence)
1017 {
1018 return "unbound";
1019 }
1020
1021 static const struct dma_fence_ops xe_oa_fence_ops = {
1022 .get_driver_name = xe_oa_get_driver_name,
1023 .get_timeline_name = xe_oa_get_timeline_name,
1024 };
1025
xe_oa_emit_oa_config(struct xe_oa_stream * stream,struct xe_oa_config * config)1026 static int xe_oa_emit_oa_config(struct xe_oa_stream *stream, struct xe_oa_config *config)
1027 {
1028 #define NOA_PROGRAM_ADDITIONAL_DELAY_US 500
1029 struct xe_oa_config_bo *oa_bo;
1030 struct xe_oa_fence *ofence;
1031 int i, err, num_signal = 0;
1032 struct dma_fence *fence;
1033
1034 ofence = kzalloc_obj(*ofence);
1035 if (!ofence) {
1036 err = -ENOMEM;
1037 goto exit;
1038 }
1039
1040 oa_bo = xe_oa_alloc_config_buffer(stream, config);
1041 if (IS_ERR(oa_bo)) {
1042 err = PTR_ERR(oa_bo);
1043 goto exit;
1044 }
1045
1046 /* Emit OA configuration batch */
1047 fence = xe_oa_submit_bb(stream, XE_OA_SUBMIT_ADD_DEPS, oa_bo->bb);
1048 if (IS_ERR(fence)) {
1049 err = PTR_ERR(fence);
1050 goto exit;
1051 }
1052
1053 /* Point of no return: initialize and set fence to signal */
1054 spin_lock_init(&ofence->lock);
1055 dma_fence_init(&ofence->base, &xe_oa_fence_ops, &ofence->lock, 0, 0);
1056
1057 for (i = 0; i < stream->num_syncs; i++) {
1058 if (stream->syncs[i].flags & DRM_XE_SYNC_FLAG_SIGNAL)
1059 num_signal++;
1060 xe_sync_entry_signal(&stream->syncs[i], &ofence->base);
1061 }
1062
1063 /* Additional dma_fence_get in case we dma_fence_wait */
1064 if (!num_signal)
1065 dma_fence_get(&ofence->base);
1066
1067 /* Update last fence too before adding callback */
1068 xe_oa_update_last_fence(stream, fence);
1069
1070 /* Add job fence callback to schedule work to signal ofence->base */
1071 err = dma_fence_add_callback(fence, &ofence->cb, xe_oa_config_cb);
1072 xe_gt_assert(stream->gt, !err || err == -ENOENT);
1073 if (err == -ENOENT)
1074 xe_oa_config_cb(fence, &ofence->cb);
1075
1076 /* If nothing needs to be signaled we wait synchronously */
1077 if (!num_signal) {
1078 dma_fence_wait(&ofence->base, false);
1079 dma_fence_put(&ofence->base);
1080 }
1081
1082 /* Done with syncs */
1083 for (i = 0; i < stream->num_syncs; i++)
1084 xe_sync_entry_cleanup(&stream->syncs[i]);
1085 kfree(stream->syncs);
1086
1087 return 0;
1088 exit:
1089 kfree(ofence);
1090 return err;
1091 }
1092
oag_report_ctx_switches(const struct xe_oa_stream * stream)1093 static u32 oag_report_ctx_switches(const struct xe_oa_stream *stream)
1094 {
1095 /* If user didn't require OA reports, ask HW not to emit ctx switch reports */
1096 if (stream->sample)
1097 return REG_MASKED_FIELD_DISABLE(OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS);
1098 else
1099 return REG_MASKED_FIELD_ENABLE(OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS);
1100 }
1101
oag_buf_size_select(const struct xe_oa_stream * stream)1102 static u32 oag_buf_size_select(const struct xe_oa_stream *stream)
1103 {
1104 if (xe_bo_size(stream->oa_buffer.bo) > SZ_16M)
1105 return REG_MASKED_FIELD_ENABLE(OAG_OA_DEBUG_BUF_SIZE_SELECT);
1106 else
1107 return REG_MASKED_FIELD_DISABLE(OAG_OA_DEBUG_BUF_SIZE_SELECT);
1108 }
1109
xe_oa_enable_metric_set(struct xe_oa_stream * stream)1110 static int xe_oa_enable_metric_set(struct xe_oa_stream *stream)
1111 {
1112 struct xe_mmio *mmio = &stream->gt->mmio;
1113 u32 oa_debug, sqcnt1;
1114 int ret;
1115
1116 /*
1117 * EU NOA signals behave incorrectly if EU clock gating is enabled.
1118 * Disable thread stall DOP gating and EU DOP gating.
1119 */
1120 if (XE_GT_WA(stream->gt, 1508761755)) {
1121 xe_gt_mcr_multicast_write(stream->gt, ROW_CHICKEN,
1122 REG_MASKED_FIELD_ENABLE(STALL_DOP_GATING_DISABLE));
1123 xe_gt_mcr_multicast_write(stream->gt, ROW_CHICKEN2,
1124 REG_MASKED_FIELD_ENABLE(DISABLE_DOP_GATING));
1125 }
1126
1127 /* Disable clk ratio reports */
1128 oa_debug = OAG_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
1129 OAG_OA_DEBUG_INCLUDE_CLK_RATIO;
1130
1131 if (GRAPHICS_VER(stream->oa->xe) >= 20)
1132 oa_debug |=
1133 /* The three bits below are needed to get PEC counters running */
1134 OAG_OA_DEBUG_START_TRIGGER_SCOPE_CONTROL |
1135 OAG_OA_DEBUG_DISABLE_START_TRG_2_COUNT_QUAL |
1136 OAG_OA_DEBUG_DISABLE_START_TRG_1_COUNT_QUAL;
1137
1138 xe_mmio_write32(mmio, __oa_regs(stream)->oa_debug,
1139 REG_MASKED_FIELD_ENABLE(oa_debug) |
1140 oag_report_ctx_switches(stream) |
1141 oag_buf_size_select(stream) |
1142 oag_configure_mmio_trigger(stream, true));
1143
1144 xe_mmio_write32(mmio, __oa_regs(stream)->oa_ctx_ctrl,
1145 OAG_OAGLBCTXCTRL_COUNTER_RESUME |
1146 (stream->periodic ?
1147 OAG_OAGLBCTXCTRL_TIMER_ENABLE |
1148 REG_FIELD_PREP(OAG_OAGLBCTXCTRL_TIMER_PERIOD_MASK,
1149 stream->period_exponent) : 0));
1150
1151 /*
1152 * Initialize Super Queue Internal Cnt Register
1153 * Set PMON Enable in order to collect valid metrics
1154 * Enable bytes per clock reporting
1155 */
1156 sqcnt1 = SQCNT1_PMON_ENABLE |
1157 (HAS_OA_BPC_REPORTING(stream->oa->xe) ? SQCNT1_OABPC : 0);
1158 xe_mmio_rmw32(mmio, XELPMP_SQCNT1, 0, sqcnt1);
1159
1160 if ((stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAM ||
1161 stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAM_SAG) &&
1162 GRAPHICS_VER(stream->oa->xe) >= 30)
1163 xe_mmio_rmw32(mmio, OAM_COMPRESSION_T3_CONTROL, 0, OAM_LAT_MEASURE_ENABLE);
1164
1165 /* Configure OAR/OAC */
1166 if (stream->exec_q) {
1167 ret = xe_oa_configure_oa_context(stream, true);
1168 if (ret)
1169 return ret;
1170 }
1171
1172 return xe_oa_emit_oa_config(stream, stream->oa_config);
1173 }
1174
decode_oa_format(struct xe_oa * oa,u64 fmt,enum xe_oa_format_name * name)1175 static int decode_oa_format(struct xe_oa *oa, u64 fmt, enum xe_oa_format_name *name)
1176 {
1177 u32 counter_size = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SIZE, fmt);
1178 u32 counter_sel = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SEL, fmt);
1179 u32 bc_report = FIELD_GET(DRM_XE_OA_FORMAT_MASK_BC_REPORT, fmt);
1180 u32 type = FIELD_GET(DRM_XE_OA_FORMAT_MASK_FMT_TYPE, fmt);
1181 int idx;
1182
1183 for_each_set_bit(idx, oa->format_mask, __XE_OA_FORMAT_MAX) {
1184 const struct xe_oa_format *f = &oa->oa_formats[idx];
1185
1186 if (counter_size == f->counter_size && bc_report == f->bc_report &&
1187 type == f->type && counter_sel == f->counter_select) {
1188 *name = idx;
1189 return 0;
1190 }
1191 }
1192
1193 return -EINVAL;
1194 }
1195
xe_oa_lookup_oa_unit(struct xe_oa * oa,u32 oa_unit_id)1196 static struct xe_oa_unit *xe_oa_lookup_oa_unit(struct xe_oa *oa, u32 oa_unit_id)
1197 {
1198 struct xe_gt *gt;
1199 int gt_id, i;
1200
1201 for_each_gt(gt, oa->xe, gt_id) {
1202 for (i = 0; i < gt->oa.num_oa_units; i++) {
1203 struct xe_oa_unit *u = >->oa.oa_unit[i];
1204
1205 if (u->oa_unit_id == oa_unit_id)
1206 return u;
1207 }
1208 }
1209
1210 return NULL;
1211 }
1212
xe_oa_set_prop_oa_unit_id(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1213 static int xe_oa_set_prop_oa_unit_id(struct xe_oa *oa, u64 value,
1214 struct xe_oa_open_param *param)
1215 {
1216 param->oa_unit = xe_oa_lookup_oa_unit(oa, value);
1217 if (!param->oa_unit) {
1218 drm_dbg(&oa->xe->drm, "OA unit ID out of range %lld\n", value);
1219 return -EINVAL;
1220 }
1221 return 0;
1222 }
1223
xe_oa_set_prop_sample_oa(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1224 static int xe_oa_set_prop_sample_oa(struct xe_oa *oa, u64 value,
1225 struct xe_oa_open_param *param)
1226 {
1227 param->sample = value;
1228 return 0;
1229 }
1230
xe_oa_set_prop_metric_set(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1231 static int xe_oa_set_prop_metric_set(struct xe_oa *oa, u64 value,
1232 struct xe_oa_open_param *param)
1233 {
1234 param->metric_set = value;
1235 return 0;
1236 }
1237
xe_oa_set_prop_oa_format(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1238 static int xe_oa_set_prop_oa_format(struct xe_oa *oa, u64 value,
1239 struct xe_oa_open_param *param)
1240 {
1241 int ret = decode_oa_format(oa, value, ¶m->oa_format);
1242
1243 if (ret) {
1244 drm_dbg(&oa->xe->drm, "Unsupported OA report format %#llx\n", value);
1245 return ret;
1246 }
1247 return 0;
1248 }
1249
xe_oa_set_prop_oa_exponent(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1250 static int xe_oa_set_prop_oa_exponent(struct xe_oa *oa, u64 value,
1251 struct xe_oa_open_param *param)
1252 {
1253 #define OA_EXPONENT_MAX 31
1254
1255 if (value > OA_EXPONENT_MAX) {
1256 drm_dbg(&oa->xe->drm, "OA timer exponent too high (> %u)\n", OA_EXPONENT_MAX);
1257 return -EINVAL;
1258 }
1259 param->period_exponent = value;
1260 return 0;
1261 }
1262
xe_oa_set_prop_disabled(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1263 static int xe_oa_set_prop_disabled(struct xe_oa *oa, u64 value,
1264 struct xe_oa_open_param *param)
1265 {
1266 param->disabled = value;
1267 return 0;
1268 }
1269
xe_oa_set_prop_exec_queue_id(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1270 static int xe_oa_set_prop_exec_queue_id(struct xe_oa *oa, u64 value,
1271 struct xe_oa_open_param *param)
1272 {
1273 param->exec_queue_id = value;
1274 return 0;
1275 }
1276
xe_oa_set_prop_engine_instance(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1277 static int xe_oa_set_prop_engine_instance(struct xe_oa *oa, u64 value,
1278 struct xe_oa_open_param *param)
1279 {
1280 param->engine_instance = value;
1281 return 0;
1282 }
1283
xe_oa_set_no_preempt(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1284 static int xe_oa_set_no_preempt(struct xe_oa *oa, u64 value,
1285 struct xe_oa_open_param *param)
1286 {
1287 param->no_preempt = value;
1288 return 0;
1289 }
1290
xe_oa_set_prop_num_syncs(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1291 static int xe_oa_set_prop_num_syncs(struct xe_oa *oa, u64 value,
1292 struct xe_oa_open_param *param)
1293 {
1294 if (XE_IOCTL_DBG(oa->xe, value > DRM_XE_MAX_SYNCS))
1295 return -EINVAL;
1296
1297 param->num_syncs = value;
1298 return 0;
1299 }
1300
xe_oa_set_prop_syncs_user(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1301 static int xe_oa_set_prop_syncs_user(struct xe_oa *oa, u64 value,
1302 struct xe_oa_open_param *param)
1303 {
1304 param->syncs_user = u64_to_user_ptr(value);
1305 return 0;
1306 }
1307
xe_oa_set_prop_oa_buffer_size(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1308 static int xe_oa_set_prop_oa_buffer_size(struct xe_oa *oa, u64 value,
1309 struct xe_oa_open_param *param)
1310 {
1311 if (!is_power_of_2(value) || value < SZ_128K || value > SZ_128M) {
1312 drm_dbg(&oa->xe->drm, "OA buffer size invalid %llu\n", value);
1313 return -EINVAL;
1314 }
1315 param->oa_buffer_size = value;
1316 return 0;
1317 }
1318
xe_oa_set_prop_wait_num_reports(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1319 static int xe_oa_set_prop_wait_num_reports(struct xe_oa *oa, u64 value,
1320 struct xe_oa_open_param *param)
1321 {
1322 if (!value) {
1323 drm_dbg(&oa->xe->drm, "wait_num_reports %llu\n", value);
1324 return -EINVAL;
1325 }
1326 param->wait_num_reports = value;
1327 return 0;
1328 }
1329
xe_oa_set_prop_ret_inval(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1330 static int xe_oa_set_prop_ret_inval(struct xe_oa *oa, u64 value,
1331 struct xe_oa_open_param *param)
1332 {
1333 return -EINVAL;
1334 }
1335
1336 typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value,
1337 struct xe_oa_open_param *param);
1338 static const xe_oa_set_property_fn xe_oa_set_property_funcs_open[] = {
1339 [DRM_XE_OA_PROPERTY_OA_UNIT_ID] = xe_oa_set_prop_oa_unit_id,
1340 [DRM_XE_OA_PROPERTY_SAMPLE_OA] = xe_oa_set_prop_sample_oa,
1341 [DRM_XE_OA_PROPERTY_OA_METRIC_SET] = xe_oa_set_prop_metric_set,
1342 [DRM_XE_OA_PROPERTY_OA_FORMAT] = xe_oa_set_prop_oa_format,
1343 [DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT] = xe_oa_set_prop_oa_exponent,
1344 [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_disabled,
1345 [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_exec_queue_id,
1346 [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_engine_instance,
1347 [DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_no_preempt,
1348 [DRM_XE_OA_PROPERTY_NUM_SYNCS] = xe_oa_set_prop_num_syncs,
1349 [DRM_XE_OA_PROPERTY_SYNCS] = xe_oa_set_prop_syncs_user,
1350 [DRM_XE_OA_PROPERTY_OA_BUFFER_SIZE] = xe_oa_set_prop_oa_buffer_size,
1351 [DRM_XE_OA_PROPERTY_WAIT_NUM_REPORTS] = xe_oa_set_prop_wait_num_reports,
1352 };
1353
1354 static const xe_oa_set_property_fn xe_oa_set_property_funcs_config[] = {
1355 [DRM_XE_OA_PROPERTY_OA_UNIT_ID] = xe_oa_set_prop_ret_inval,
1356 [DRM_XE_OA_PROPERTY_SAMPLE_OA] = xe_oa_set_prop_ret_inval,
1357 [DRM_XE_OA_PROPERTY_OA_METRIC_SET] = xe_oa_set_prop_metric_set,
1358 [DRM_XE_OA_PROPERTY_OA_FORMAT] = xe_oa_set_prop_ret_inval,
1359 [DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT] = xe_oa_set_prop_ret_inval,
1360 [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_ret_inval,
1361 [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_ret_inval,
1362 [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_ret_inval,
1363 [DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_prop_ret_inval,
1364 [DRM_XE_OA_PROPERTY_NUM_SYNCS] = xe_oa_set_prop_num_syncs,
1365 [DRM_XE_OA_PROPERTY_SYNCS] = xe_oa_set_prop_syncs_user,
1366 [DRM_XE_OA_PROPERTY_OA_BUFFER_SIZE] = xe_oa_set_prop_ret_inval,
1367 [DRM_XE_OA_PROPERTY_WAIT_NUM_REPORTS] = xe_oa_set_prop_ret_inval,
1368 };
1369
xe_oa_user_ext_set_property(struct xe_oa * oa,enum xe_oa_user_extn_from from,u64 extension,struct xe_oa_open_param * param)1370 static int xe_oa_user_ext_set_property(struct xe_oa *oa, enum xe_oa_user_extn_from from,
1371 u64 extension, struct xe_oa_open_param *param)
1372 {
1373 u64 __user *address = u64_to_user_ptr(extension);
1374 struct drm_xe_ext_set_property ext;
1375 int err;
1376 u32 idx;
1377
1378 err = copy_from_user(&ext, address, sizeof(ext));
1379 if (XE_IOCTL_DBG(oa->xe, err))
1380 return -EFAULT;
1381
1382 BUILD_BUG_ON(ARRAY_SIZE(xe_oa_set_property_funcs_open) !=
1383 ARRAY_SIZE(xe_oa_set_property_funcs_config));
1384
1385 if (XE_IOCTL_DBG(oa->xe, ext.property >= ARRAY_SIZE(xe_oa_set_property_funcs_open)) ||
1386 XE_IOCTL_DBG(oa->xe, !ext.property) || XE_IOCTL_DBG(oa->xe, ext.pad))
1387 return -EINVAL;
1388
1389 idx = array_index_nospec(ext.property, ARRAY_SIZE(xe_oa_set_property_funcs_open));
1390
1391 if (from == XE_OA_USER_EXTN_FROM_CONFIG)
1392 return xe_oa_set_property_funcs_config[idx](oa, ext.value, param);
1393 else
1394 return xe_oa_set_property_funcs_open[idx](oa, ext.value, param);
1395 }
1396
1397 typedef int (*xe_oa_user_extension_fn)(struct xe_oa *oa, enum xe_oa_user_extn_from from,
1398 u64 extension, struct xe_oa_open_param *param);
1399 static const xe_oa_user_extension_fn xe_oa_user_extension_funcs[] = {
1400 [DRM_XE_OA_EXTENSION_SET_PROPERTY] = xe_oa_user_ext_set_property,
1401 };
1402
1403 #define MAX_USER_EXTENSIONS 16
xe_oa_user_extensions(struct xe_oa * oa,enum xe_oa_user_extn_from from,u64 extension,int ext_number,struct xe_oa_open_param * param)1404 static int xe_oa_user_extensions(struct xe_oa *oa, enum xe_oa_user_extn_from from, u64 extension,
1405 int ext_number, struct xe_oa_open_param *param)
1406 {
1407 u64 __user *address = u64_to_user_ptr(extension);
1408 struct drm_xe_user_extension ext;
1409 int err;
1410 u32 idx;
1411
1412 if (XE_IOCTL_DBG(oa->xe, ext_number >= MAX_USER_EXTENSIONS))
1413 return -E2BIG;
1414
1415 err = copy_from_user(&ext, address, sizeof(ext));
1416 if (XE_IOCTL_DBG(oa->xe, err))
1417 return -EFAULT;
1418
1419 if (XE_IOCTL_DBG(oa->xe, ext.pad) ||
1420 XE_IOCTL_DBG(oa->xe, ext.name >= ARRAY_SIZE(xe_oa_user_extension_funcs)))
1421 return -EINVAL;
1422
1423 idx = array_index_nospec(ext.name, ARRAY_SIZE(xe_oa_user_extension_funcs));
1424 err = xe_oa_user_extension_funcs[idx](oa, from, extension, param);
1425 if (XE_IOCTL_DBG(oa->xe, err))
1426 return err;
1427
1428 if (ext.next_extension)
1429 return xe_oa_user_extensions(oa, from, ext.next_extension, ++ext_number, param);
1430
1431 return 0;
1432 }
1433
xe_oa_parse_syncs(struct xe_oa * oa,struct xe_oa_stream * stream,struct xe_oa_open_param * param)1434 static int xe_oa_parse_syncs(struct xe_oa *oa,
1435 struct xe_oa_stream *stream,
1436 struct xe_oa_open_param *param)
1437 {
1438 int ret, num_syncs, num_ufence = 0;
1439
1440 if (param->num_syncs && !param->syncs_user) {
1441 drm_dbg(&oa->xe->drm, "num_syncs specified without sync array\n");
1442 ret = -EINVAL;
1443 goto exit;
1444 }
1445
1446 if (param->num_syncs) {
1447 param->syncs = kzalloc_objs(*param->syncs, param->num_syncs);
1448 if (!param->syncs) {
1449 ret = -ENOMEM;
1450 goto exit;
1451 }
1452 }
1453
1454 for (num_syncs = 0; num_syncs < param->num_syncs; num_syncs++) {
1455 ret = xe_sync_entry_parse(oa->xe, param->xef, ¶m->syncs[num_syncs],
1456 ¶m->syncs_user[num_syncs],
1457 stream->ufence_syncobj,
1458 ++stream->ufence_timeline_value, 0);
1459 if (ret)
1460 goto err_syncs;
1461
1462 if (xe_sync_is_ufence(¶m->syncs[num_syncs]))
1463 num_ufence++;
1464 }
1465
1466 if (XE_IOCTL_DBG(oa->xe, num_ufence > 1)) {
1467 ret = -EINVAL;
1468 goto err_syncs;
1469 }
1470
1471 return 0;
1472
1473 err_syncs:
1474 while (num_syncs--)
1475 xe_sync_entry_cleanup(¶m->syncs[num_syncs]);
1476 kfree(param->syncs);
1477 exit:
1478 return ret;
1479 }
1480
xe_oa_stream_enable(struct xe_oa_stream * stream)1481 static void xe_oa_stream_enable(struct xe_oa_stream *stream)
1482 {
1483 stream->pollin = false;
1484
1485 xe_oa_enable(stream);
1486
1487 if (stream->sample)
1488 hrtimer_start(&stream->poll_check_timer,
1489 ns_to_ktime(stream->poll_period_ns),
1490 HRTIMER_MODE_REL_PINNED);
1491 }
1492
xe_oa_stream_disable(struct xe_oa_stream * stream)1493 static void xe_oa_stream_disable(struct xe_oa_stream *stream)
1494 {
1495 xe_oa_disable(stream);
1496
1497 if (stream->sample)
1498 hrtimer_cancel(&stream->poll_check_timer);
1499
1500 /* Update stream->oa_buffer.tail to allow any final reports to be read */
1501 if (xe_oa_buffer_check_unlocked(stream))
1502 wake_up(&stream->poll_wq);
1503 }
1504
xe_oa_enable_preempt_timeslice(struct xe_oa_stream * stream)1505 static int xe_oa_enable_preempt_timeslice(struct xe_oa_stream *stream)
1506 {
1507 struct xe_exec_queue *q = stream->exec_q;
1508 int ret1, ret2;
1509
1510 /* Best effort recovery: try to revert both to original, irrespective of error */
1511 ret1 = q->ops->set_timeslice(q, stream->hwe->eclass->sched_props.timeslice_us);
1512 ret2 = q->ops->set_preempt_timeout(q, stream->hwe->eclass->sched_props.preempt_timeout_us);
1513 if (ret1 || ret2)
1514 goto err;
1515 return 0;
1516 err:
1517 drm_dbg(&stream->oa->xe->drm, "%s failed ret1 %d ret2 %d\n", __func__, ret1, ret2);
1518 return ret1 ?: ret2;
1519 }
1520
xe_oa_disable_preempt_timeslice(struct xe_oa_stream * stream)1521 static int xe_oa_disable_preempt_timeslice(struct xe_oa_stream *stream)
1522 {
1523 struct xe_exec_queue *q = stream->exec_q;
1524 int ret;
1525
1526 /* Setting values to 0 will disable timeslice and preempt_timeout */
1527 ret = q->ops->set_timeslice(q, 0);
1528 if (ret)
1529 goto err;
1530
1531 ret = q->ops->set_preempt_timeout(q, 0);
1532 if (ret)
1533 goto err;
1534
1535 return 0;
1536 err:
1537 xe_oa_enable_preempt_timeslice(stream);
1538 drm_dbg(&stream->oa->xe->drm, "%s failed %d\n", __func__, ret);
1539 return ret;
1540 }
1541
xe_oa_enable_locked(struct xe_oa_stream * stream)1542 static int xe_oa_enable_locked(struct xe_oa_stream *stream)
1543 {
1544 if (stream->enabled)
1545 return 0;
1546
1547 if (stream->no_preempt) {
1548 int ret = xe_oa_disable_preempt_timeslice(stream);
1549
1550 if (ret)
1551 return ret;
1552 }
1553
1554 xe_oa_stream_enable(stream);
1555
1556 stream->enabled = true;
1557 return 0;
1558 }
1559
xe_oa_disable_locked(struct xe_oa_stream * stream)1560 static int xe_oa_disable_locked(struct xe_oa_stream *stream)
1561 {
1562 int ret = 0;
1563
1564 if (!stream->enabled)
1565 return 0;
1566
1567 xe_oa_stream_disable(stream);
1568
1569 if (stream->no_preempt)
1570 ret = xe_oa_enable_preempt_timeslice(stream);
1571
1572 stream->enabled = false;
1573 return ret;
1574 }
1575
xe_oa_config_locked(struct xe_oa_stream * stream,u64 arg)1576 static long xe_oa_config_locked(struct xe_oa_stream *stream, u64 arg)
1577 {
1578 struct xe_oa_open_param param = {};
1579 long ret = stream->oa_config->id;
1580 struct xe_oa_config *config;
1581 int err;
1582
1583 err = xe_oa_user_extensions(stream->oa, XE_OA_USER_EXTN_FROM_CONFIG, arg, 0, ¶m);
1584 if (err)
1585 return err;
1586
1587 config = xe_oa_get_oa_config(stream->oa, param.metric_set);
1588 if (!config)
1589 return -ENODEV;
1590
1591 param.xef = stream->xef;
1592 err = xe_oa_parse_syncs(stream->oa, stream, ¶m);
1593 if (err)
1594 goto err_config_put;
1595
1596 stream->num_syncs = param.num_syncs;
1597 stream->syncs = param.syncs;
1598
1599 err = xe_oa_emit_oa_config(stream, config);
1600 if (!err) {
1601 config = xchg(&stream->oa_config, config);
1602 drm_dbg(&stream->oa->xe->drm, "changed to oa config uuid=%s\n",
1603 stream->oa_config->uuid);
1604 } else {
1605 while (param.num_syncs--)
1606 xe_sync_entry_cleanup(¶m.syncs[param.num_syncs]);
1607 kfree(param.syncs);
1608 }
1609
1610 err_config_put:
1611 xe_oa_config_put(config);
1612
1613 return err ?: ret;
1614 }
1615
xe_oa_status_locked(struct xe_oa_stream * stream,unsigned long arg)1616 static long xe_oa_status_locked(struct xe_oa_stream *stream, unsigned long arg)
1617 {
1618 struct drm_xe_oa_stream_status status = {};
1619 void __user *uaddr = (void __user *)arg;
1620
1621 /* Map from register to uapi bits */
1622 if (stream->oa_status & OASTATUS_REPORT_LOST)
1623 status.oa_status |= DRM_XE_OASTATUS_REPORT_LOST;
1624 if (stream->oa_status & OASTATUS_BUFFER_OVERFLOW)
1625 status.oa_status |= DRM_XE_OASTATUS_BUFFER_OVERFLOW;
1626 if (stream->oa_status & OASTATUS_COUNTER_OVERFLOW)
1627 status.oa_status |= DRM_XE_OASTATUS_COUNTER_OVERFLOW;
1628 if (stream->oa_status & OASTATUS_MMIO_TRG_Q_FULL)
1629 status.oa_status |= DRM_XE_OASTATUS_MMIO_TRG_Q_FULL;
1630
1631 if (copy_to_user(uaddr, &status, sizeof(status)))
1632 return -EFAULT;
1633
1634 return 0;
1635 }
1636
xe_oa_info_locked(struct xe_oa_stream * stream,unsigned long arg)1637 static long xe_oa_info_locked(struct xe_oa_stream *stream, unsigned long arg)
1638 {
1639 struct drm_xe_oa_stream_info info = { .oa_buf_size = xe_bo_size(stream->oa_buffer.bo), };
1640 void __user *uaddr = (void __user *)arg;
1641
1642 if (copy_to_user(uaddr, &info, sizeof(info)))
1643 return -EFAULT;
1644
1645 return 0;
1646 }
1647
xe_oa_ioctl_locked(struct xe_oa_stream * stream,unsigned int cmd,unsigned long arg)1648 static long xe_oa_ioctl_locked(struct xe_oa_stream *stream,
1649 unsigned int cmd,
1650 unsigned long arg)
1651 {
1652 switch (cmd) {
1653 case DRM_XE_OBSERVATION_IOCTL_ENABLE:
1654 return xe_oa_enable_locked(stream);
1655 case DRM_XE_OBSERVATION_IOCTL_DISABLE:
1656 return xe_oa_disable_locked(stream);
1657 case DRM_XE_OBSERVATION_IOCTL_CONFIG:
1658 return xe_oa_config_locked(stream, arg);
1659 case DRM_XE_OBSERVATION_IOCTL_STATUS:
1660 return xe_oa_status_locked(stream, arg);
1661 case DRM_XE_OBSERVATION_IOCTL_INFO:
1662 return xe_oa_info_locked(stream, arg);
1663 }
1664
1665 return -EINVAL;
1666 }
1667
xe_oa_ioctl(struct file * file,unsigned int cmd,unsigned long arg)1668 static long xe_oa_ioctl(struct file *file,
1669 unsigned int cmd,
1670 unsigned long arg)
1671 {
1672 struct xe_oa_stream *stream = file->private_data;
1673 long ret;
1674
1675 mutex_lock(&stream->stream_lock);
1676 ret = xe_oa_ioctl_locked(stream, cmd, arg);
1677 mutex_unlock(&stream->stream_lock);
1678
1679 return ret;
1680 }
1681
xe_oa_destroy_locked(struct xe_oa_stream * stream)1682 static void xe_oa_destroy_locked(struct xe_oa_stream *stream)
1683 {
1684 if (stream->enabled)
1685 xe_oa_disable_locked(stream);
1686
1687 xe_oa_stream_destroy(stream);
1688
1689 if (stream->exec_q)
1690 xe_exec_queue_put(stream->exec_q);
1691
1692 drm_syncobj_put(stream->ufence_syncobj);
1693 kfree(stream);
1694 }
1695
xe_oa_release(struct inode * inode,struct file * file)1696 static int xe_oa_release(struct inode *inode, struct file *file)
1697 {
1698 struct xe_oa_stream *stream = file->private_data;
1699 struct xe_gt *gt = stream->gt;
1700
1701 xe_pm_runtime_get(gt_to_xe(gt));
1702 mutex_lock(>->oa.gt_lock);
1703 xe_oa_destroy_locked(stream);
1704 mutex_unlock(>->oa.gt_lock);
1705 xe_pm_runtime_put(gt_to_xe(gt));
1706
1707 /* Release the reference the OA stream kept on the driver */
1708 drm_dev_put(>_to_xe(gt)->drm);
1709
1710 return 0;
1711 }
1712
xe_oa_mmap(struct file * file,struct vm_area_struct * vma)1713 static int xe_oa_mmap(struct file *file, struct vm_area_struct *vma)
1714 {
1715 struct xe_oa_stream *stream = file->private_data;
1716 int ret = xe_observation_paranoid_check();
1717 struct xe_bo *bo = stream->oa_buffer.bo;
1718
1719 if (ret) {
1720 drm_dbg(&stream->oa->xe->drm, "Insufficient privilege to map OA buffer\n");
1721 return ret;
1722 }
1723
1724 /* Can mmap the entire OA buffer or nothing (no partial OA buffer mmaps) */
1725 if (vma->vm_end - vma->vm_start != xe_bo_size(bo)) {
1726 drm_dbg(&stream->oa->xe->drm, "Wrong mmap size, must be OA buffer size\n");
1727 return -EINVAL;
1728 }
1729
1730 /*
1731 * Only support VM_READ, enforce MAP_PRIVATE by checking for
1732 * VM_MAYSHARE, don't copy the vma on fork
1733 */
1734 if (vma->vm_flags & (VM_WRITE | VM_EXEC | VM_SHARED | VM_MAYSHARE)) {
1735 drm_dbg(&stream->oa->xe->drm, "mmap must be read only\n");
1736 return -EINVAL;
1737 }
1738 vm_flags_mod(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_DONTCOPY,
1739 VM_MAYWRITE | VM_MAYEXEC);
1740
1741 return drm_gem_mmap_obj(&bo->ttm.base, xe_bo_size(bo), vma);
1742 }
1743
1744 static const struct file_operations xe_oa_fops = {
1745 .owner = THIS_MODULE,
1746 .release = xe_oa_release,
1747 .poll = xe_oa_poll,
1748 .read = xe_oa_read,
1749 .unlocked_ioctl = xe_oa_ioctl,
1750 .mmap = xe_oa_mmap,
1751 };
1752
xe_oa_stream_init(struct xe_oa_stream * stream,struct xe_oa_open_param * param)1753 static int xe_oa_stream_init(struct xe_oa_stream *stream,
1754 struct xe_oa_open_param *param)
1755 {
1756 struct xe_gt *gt = param->hwe->gt;
1757 int ret;
1758
1759 stream->exec_q = param->exec_q;
1760 stream->poll_period_ns = DEFAULT_POLL_PERIOD_NS;
1761 stream->oa_unit = param->oa_unit;
1762 stream->hwe = param->hwe;
1763 stream->gt = stream->hwe->gt;
1764 stream->oa_buffer.format = &stream->oa->oa_formats[param->oa_format];
1765
1766 stream->sample = param->sample;
1767 stream->periodic = param->period_exponent >= 0;
1768 stream->period_exponent = param->period_exponent;
1769 stream->no_preempt = param->no_preempt;
1770 stream->wait_num_reports = param->wait_num_reports;
1771
1772 stream->xef = xe_file_get(param->xef);
1773 stream->num_syncs = param->num_syncs;
1774 stream->syncs = param->syncs;
1775
1776 /*
1777 * For Xe2+, when overrun mode is enabled, there are no partial reports at the end
1778 * of buffer, making the OA buffer effectively a non-power-of-2 size circular
1779 * buffer whose size, circ_size, is a multiple of the report size
1780 */
1781 if (GRAPHICS_VER(stream->oa->xe) >= 20 &&
1782 stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAG && stream->sample)
1783 stream->oa_buffer.circ_size =
1784 param->oa_buffer_size -
1785 param->oa_buffer_size % stream->oa_buffer.format->size;
1786 else
1787 stream->oa_buffer.circ_size = param->oa_buffer_size;
1788
1789 stream->oa_config = xe_oa_get_oa_config(stream->oa, param->metric_set);
1790 if (!stream->oa_config) {
1791 drm_dbg(&stream->oa->xe->drm, "Invalid OA config id=%i\n", param->metric_set);
1792 ret = -EINVAL;
1793 goto exit;
1794 }
1795
1796 /* Take runtime pm ref and forcewake to disable RC6 */
1797 xe_pm_runtime_get(stream->oa->xe);
1798 stream->fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
1799 if (!xe_force_wake_ref_has_domain(stream->fw_ref, XE_FORCEWAKE_ALL)) {
1800 ret = -ETIMEDOUT;
1801 goto err_fw_put;
1802 }
1803
1804 ret = xe_oa_alloc_oa_buffer(stream, param->oa_buffer_size);
1805 if (ret)
1806 goto err_fw_put;
1807
1808 stream->k_exec_q = xe_exec_queue_create(stream->oa->xe, NULL,
1809 BIT(stream->hwe->logical_instance), 1,
1810 stream->hwe, EXEC_QUEUE_FLAG_KERNEL, 0);
1811 if (IS_ERR(stream->k_exec_q)) {
1812 ret = PTR_ERR(stream->k_exec_q);
1813 drm_err(&stream->oa->xe->drm, "gt%d, hwe %s, xe_exec_queue_create failed=%d",
1814 stream->gt->info.id, stream->hwe->name, ret);
1815 goto err_free_oa_buf;
1816 }
1817
1818 ret = xe_oa_enable_metric_set(stream);
1819 if (ret) {
1820 drm_dbg(&stream->oa->xe->drm, "Unable to enable metric set\n");
1821 goto err_put_k_exec_q;
1822 }
1823
1824 drm_dbg(&stream->oa->xe->drm, "opening stream oa config uuid=%s\n",
1825 stream->oa_config->uuid);
1826
1827 WRITE_ONCE(stream->oa_unit->exclusive_stream, stream);
1828
1829 hrtimer_setup(&stream->poll_check_timer, xe_oa_poll_check_timer_cb, CLOCK_MONOTONIC,
1830 HRTIMER_MODE_REL);
1831 init_waitqueue_head(&stream->poll_wq);
1832
1833 spin_lock_init(&stream->oa_buffer.ptr_lock);
1834 mutex_init(&stream->stream_lock);
1835
1836 return 0;
1837
1838 err_put_k_exec_q:
1839 xe_oa_disable_metric_set(stream);
1840 xe_exec_queue_put(stream->k_exec_q);
1841 err_free_oa_buf:
1842 xe_oa_free_oa_buffer(stream);
1843 err_fw_put:
1844 xe_force_wake_put(gt_to_fw(gt), stream->fw_ref);
1845 xe_pm_runtime_put(stream->oa->xe);
1846 xe_oa_free_configs(stream);
1847 exit:
1848 xe_file_put(stream->xef);
1849 return ret;
1850 }
1851
xe_oa_stream_open_ioctl_locked(struct xe_oa * oa,struct xe_oa_open_param * param)1852 static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa,
1853 struct xe_oa_open_param *param)
1854 {
1855 struct xe_oa_stream *stream;
1856 struct drm_syncobj *ufence_syncobj;
1857 int stream_fd;
1858 int ret;
1859
1860 /* We currently only allow exclusive access */
1861 if (param->oa_unit->exclusive_stream) {
1862 drm_dbg(&oa->xe->drm, "OA unit already in use\n");
1863 ret = -EBUSY;
1864 goto exit;
1865 }
1866
1867 ret = drm_syncobj_create(&ufence_syncobj, DRM_SYNCOBJ_CREATE_SIGNALED,
1868 NULL);
1869 if (ret)
1870 goto exit;
1871
1872 stream = kzalloc_obj(*stream);
1873 if (!stream) {
1874 ret = -ENOMEM;
1875 goto err_syncobj;
1876 }
1877 stream->ufence_syncobj = ufence_syncobj;
1878 stream->oa = oa;
1879
1880 ret = xe_oa_parse_syncs(oa, stream, param);
1881 if (ret)
1882 goto err_free;
1883
1884 ret = xe_oa_stream_init(stream, param);
1885 if (ret) {
1886 while (param->num_syncs--)
1887 xe_sync_entry_cleanup(¶m->syncs[param->num_syncs]);
1888 kfree(param->syncs);
1889 goto err_free;
1890 }
1891
1892 if (!param->disabled) {
1893 ret = xe_oa_enable_locked(stream);
1894 if (ret)
1895 goto err_destroy;
1896 }
1897
1898 stream_fd = anon_inode_getfd("[xe_oa]", &xe_oa_fops, stream, 0);
1899 if (stream_fd < 0) {
1900 ret = stream_fd;
1901 goto err_disable;
1902 }
1903
1904 if (stream->sample)
1905 xe_reg_whitelist_oa_regs(stream->gt);
1906
1907 /* Hold a reference on the drm device till stream_fd is released */
1908 drm_dev_get(&stream->oa->xe->drm);
1909
1910 return stream_fd;
1911 err_disable:
1912 if (!param->disabled)
1913 xe_oa_disable_locked(stream);
1914 err_destroy:
1915 xe_oa_stream_destroy(stream);
1916 err_free:
1917 kfree(stream);
1918 err_syncobj:
1919 drm_syncobj_put(ufence_syncobj);
1920 exit:
1921 return ret;
1922 }
1923
1924 /**
1925 * xe_oa_timestamp_frequency - Return OA timestamp frequency
1926 * @gt: @xe_gt
1927 *
1928 * OA timestamp frequency = CS timestamp frequency in most platforms. On some
1929 * platforms OA unit ignores the CTC_SHIFT and the 2 timestamps differ. In such
1930 * cases, return the adjusted CS timestamp frequency to the user.
1931 */
xe_oa_timestamp_frequency(struct xe_gt * gt)1932 u32 xe_oa_timestamp_frequency(struct xe_gt *gt)
1933 {
1934 u32 reg, shift;
1935
1936 if (XE_GT_WA(gt, 18013179988) || XE_GT_WA(gt, 14015568240)) {
1937 xe_pm_runtime_get(gt_to_xe(gt));
1938 reg = xe_mmio_read32(>->mmio, RPM_CONFIG0);
1939 xe_pm_runtime_put(gt_to_xe(gt));
1940
1941 shift = REG_FIELD_GET(RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, reg);
1942 return gt->info.reference_clock << (3 - shift);
1943 } else {
1944 return gt->info.reference_clock;
1945 }
1946 }
1947
oa_exponent_to_ns(struct xe_gt * gt,int exponent)1948 static u64 oa_exponent_to_ns(struct xe_gt *gt, int exponent)
1949 {
1950 u64 nom = (2ULL << exponent) * NSEC_PER_SEC;
1951 u32 den = xe_oa_timestamp_frequency(gt);
1952
1953 return div_u64(nom + den - 1, den);
1954 }
1955
oa_unit_supports_oa_format(struct xe_oa * oa,struct xe_oa_open_param * param)1956 static bool oa_unit_supports_oa_format(struct xe_oa *oa, struct xe_oa_open_param *param)
1957 {
1958 const struct xe_oa_format *f = &oa->oa_formats[param->oa_format];
1959
1960 switch (param->oa_unit->type) {
1961 case DRM_XE_OA_UNIT_TYPE_OAG:
1962 return f->type == DRM_XE_OA_FMT_TYPE_OAG || f->type == DRM_XE_OA_FMT_TYPE_OAR ||
1963 f->type == DRM_XE_OA_FMT_TYPE_OAC || f->type == DRM_XE_OA_FMT_TYPE_PEC;
1964 case DRM_XE_OA_UNIT_TYPE_MERT:
1965 if (XE_DEVICE_WA(oa->xe, 14026746987))
1966 return param->oa_format == XE_OAM_FORMAT_MPEC8u32_B8_C8;
1967 fallthrough;
1968 case DRM_XE_OA_UNIT_TYPE_OAM:
1969 case DRM_XE_OA_UNIT_TYPE_OAM_SAG:
1970 return f->type == DRM_XE_OA_FMT_TYPE_OAM || f->type == DRM_XE_OA_FMT_TYPE_OAM_MPEC;
1971 default:
1972 return false;
1973 }
1974 }
1975
1976 /**
1977 * xe_oa_unit_id - Return OA unit ID for a hardware engine
1978 * @hwe: @xe_hw_engine
1979 *
1980 * Return OA unit ID for a hardware engine when available
1981 */
xe_oa_unit_id(struct xe_hw_engine * hwe)1982 u16 xe_oa_unit_id(struct xe_hw_engine *hwe)
1983 {
1984 return hwe->oa_unit && hwe->oa_unit->num_engines ?
1985 hwe->oa_unit->oa_unit_id : U16_MAX;
1986 }
1987
1988 /* A hwe must be assigned to stream/oa_unit for batch submissions */
xe_oa_assign_hwe(struct xe_oa * oa,struct xe_oa_open_param * param)1989 static int xe_oa_assign_hwe(struct xe_oa *oa, struct xe_oa_open_param *param)
1990 {
1991 struct xe_hw_engine *hwe;
1992 enum xe_hw_engine_id id;
1993 int ret = 0;
1994
1995 /* When we have an exec_q, get hwe from the exec_q */
1996 if (param->exec_q) {
1997 param->hwe = xe_gt_hw_engine(param->exec_q->gt, param->exec_q->class,
1998 param->engine_instance, true);
1999 if (!param->hwe || param->hwe->oa_unit != param->oa_unit)
2000 goto err;
2001 goto out;
2002 }
2003
2004 /* Else just get the first hwe attached to the oa unit */
2005 for_each_hw_engine(hwe, param->oa_unit->gt, id) {
2006 if (hwe->oa_unit == param->oa_unit) {
2007 param->hwe = hwe;
2008 goto out;
2009 }
2010 }
2011
2012 /* If we still didn't find a hwe, just get one with a valid oa_unit from the same gt */
2013 for_each_hw_engine(hwe, param->oa_unit->gt, id) {
2014 if (!hwe->oa_unit)
2015 continue;
2016
2017 param->hwe = hwe;
2018 goto out;
2019 }
2020 err:
2021 drm_dbg(&oa->xe->drm, "Unable to find hwe (%d, %d) for OA unit ID %d\n",
2022 param->exec_q ? param->exec_q->class : -1,
2023 param->engine_instance, param->oa_unit->oa_unit_id);
2024 ret = -EINVAL;
2025 out:
2026 return ret;
2027 }
2028
2029 /**
2030 * xe_oa_stream_open_ioctl - Opens an OA stream
2031 * @dev: @drm_device
2032 * @data: pointer to struct @drm_xe_oa_config
2033 * @file: @drm_file
2034 *
2035 * The functions opens an OA stream. An OA stream, opened with specified
2036 * properties, enables OA counter samples to be collected, either
2037 * periodically (time based sampling), or on request (using OA queries)
2038 */
xe_oa_stream_open_ioctl(struct drm_device * dev,u64 data,struct drm_file * file)2039 int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *file)
2040 {
2041 struct xe_device *xe = to_xe_device(dev);
2042 struct xe_oa *oa = &xe->oa;
2043 struct xe_file *xef = to_xe_file(file);
2044 struct xe_oa_open_param param = {};
2045 const struct xe_oa_format *f;
2046 bool privileged_op = true;
2047 int ret;
2048
2049 if (!oa->xe) {
2050 drm_dbg(&xe->drm, "xe oa interface not available for this system\n");
2051 return -ENODEV;
2052 }
2053
2054 param.xef = xef;
2055 param.period_exponent = -1;
2056 ret = xe_oa_user_extensions(oa, XE_OA_USER_EXTN_FROM_OPEN, data, 0, ¶m);
2057 if (ret)
2058 return ret;
2059
2060 /* If not provided, OA unit defaults to OA unit 0 as per uapi */
2061 if (!param.oa_unit)
2062 param.oa_unit = &xe_root_mmio_gt(oa->xe)->oa.oa_unit[0];
2063
2064 if (param.exec_queue_id > 0) {
2065 /* An exec_queue is only needed for OAR/OAC functionality on OAG */
2066 if (XE_IOCTL_DBG(oa->xe, param.oa_unit->type != DRM_XE_OA_UNIT_TYPE_OAG))
2067 return -EINVAL;
2068
2069 param.exec_q = xe_exec_queue_lookup(xef, param.exec_queue_id);
2070 if (XE_IOCTL_DBG(oa->xe, !param.exec_q))
2071 return -ENOENT;
2072
2073 if (XE_IOCTL_DBG(oa->xe, param.exec_q->width > 1)) {
2074 ret = -EOPNOTSUPP;
2075 goto err_exec_q;
2076 }
2077 }
2078
2079 /*
2080 * Query based sampling (using MI_REPORT_PERF_COUNT) with OAR/OAC,
2081 * without global stream access, can be an unprivileged operation
2082 */
2083 if (param.exec_q && !param.sample)
2084 privileged_op = false;
2085
2086 if (param.no_preempt) {
2087 if (!param.exec_q) {
2088 drm_dbg(&oa->xe->drm, "Preemption disable without exec_q!\n");
2089 ret = -EINVAL;
2090 goto err_exec_q;
2091 }
2092 privileged_op = true;
2093 }
2094
2095 if (privileged_op) {
2096 ret = xe_observation_paranoid_check();
2097 if (ret) {
2098 drm_dbg(&oa->xe->drm, "Insufficient privileges to open xe OA stream\n");
2099 goto err_exec_q;
2100 }
2101 }
2102
2103 if (!param.exec_q && !param.sample) {
2104 drm_dbg(&oa->xe->drm, "Only OA report sampling supported\n");
2105 ret = -EINVAL;
2106 goto err_exec_q;
2107 }
2108
2109 ret = xe_oa_assign_hwe(oa, ¶m);
2110 if (ret)
2111 goto err_exec_q;
2112
2113 f = &oa->oa_formats[param.oa_format];
2114 if (!param.oa_format || !f->size || !oa_unit_supports_oa_format(oa, ¶m)) {
2115 drm_dbg(&oa->xe->drm, "Invalid OA format %d type %d size %d for class %d\n",
2116 param.oa_format, f->type, f->size, param.hwe->class);
2117 ret = -EINVAL;
2118 goto err_exec_q;
2119 }
2120
2121 if (param.period_exponent >= 0) {
2122 u64 oa_period, oa_freq_hz;
2123
2124 /* Requesting samples from OAG buffer is a privileged operation */
2125 if (!param.sample) {
2126 drm_dbg(&oa->xe->drm, "OA_EXPONENT specified without SAMPLE_OA\n");
2127 ret = -EINVAL;
2128 goto err_exec_q;
2129 }
2130 oa_period = oa_exponent_to_ns(param.hwe->gt, param.period_exponent);
2131 oa_freq_hz = div64_u64(NSEC_PER_SEC, oa_period);
2132 drm_dbg(&oa->xe->drm, "Using periodic sampling freq %lld Hz\n", oa_freq_hz);
2133 }
2134
2135 if (!param.oa_buffer_size)
2136 param.oa_buffer_size = DEFAULT_XE_OA_BUFFER_SIZE;
2137
2138 if (!param.wait_num_reports)
2139 param.wait_num_reports = 1;
2140 if (param.wait_num_reports > param.oa_buffer_size / f->size) {
2141 drm_dbg(&oa->xe->drm, "wait_num_reports %d\n", param.wait_num_reports);
2142 ret = -EINVAL;
2143 goto err_exec_q;
2144 }
2145
2146 mutex_lock(¶m.hwe->gt->oa.gt_lock);
2147 ret = xe_oa_stream_open_ioctl_locked(oa, ¶m);
2148 mutex_unlock(¶m.hwe->gt->oa.gt_lock);
2149 if (ret < 0)
2150 goto err_exec_q;
2151
2152 return ret;
2153
2154 err_exec_q:
2155 if (param.exec_q)
2156 xe_exec_queue_put(param.exec_q);
2157 return ret;
2158 }
2159
xe_oa_is_valid_flex_addr(struct xe_oa * oa,u32 addr)2160 static bool xe_oa_is_valid_flex_addr(struct xe_oa *oa, u32 addr)
2161 {
2162 static const struct xe_reg flex_eu_regs[] = {
2163 EU_PERF_CNTL0,
2164 EU_PERF_CNTL1,
2165 EU_PERF_CNTL2,
2166 EU_PERF_CNTL3,
2167 EU_PERF_CNTL4,
2168 EU_PERF_CNTL5,
2169 EU_PERF_CNTL6,
2170 };
2171 int i;
2172
2173 for (i = 0; i < ARRAY_SIZE(flex_eu_regs); i++) {
2174 if (flex_eu_regs[i].addr == addr)
2175 return true;
2176 }
2177 return false;
2178 }
2179
xe_oa_reg_in_range_table(u32 addr,const struct xe_mmio_range * table)2180 static bool xe_oa_reg_in_range_table(u32 addr, const struct xe_mmio_range *table)
2181 {
2182 while (table->start && table->end) {
2183 if (addr >= table->start && addr <= table->end)
2184 return true;
2185
2186 table++;
2187 }
2188
2189 return false;
2190 }
2191
2192 static const struct xe_mmio_range xehp_oa_b_counters[] = {
2193 { .start = 0xdc48, .end = 0xdc48 }, /* OAA_ENABLE_REG */
2194 { .start = 0xdd00, .end = 0xdd48 }, /* OAG_LCE0_0 - OAA_LENABLE_REG */
2195 {}
2196 };
2197
2198 static const struct xe_mmio_range gen12_oa_b_counters[] = {
2199 { .start = 0x2b2c, .end = 0x2b2c }, /* OAG_OA_PESS */
2200 { .start = 0xd900, .end = 0xd91c }, /* OAG_OASTARTTRIG[1-8] */
2201 { .start = 0xd920, .end = 0xd93c }, /* OAG_OAREPORTTRIG1[1-8] */
2202 { .start = 0xd940, .end = 0xd97c }, /* OAG_CEC[0-7][0-1] */
2203 { .start = 0xdc00, .end = 0xdc3c }, /* OAG_SCEC[0-7][0-1] */
2204 { .start = 0xdc40, .end = 0xdc40 }, /* OAG_SPCTR_CNF */
2205 { .start = 0xdc44, .end = 0xdc44 }, /* OAA_DBG_REG */
2206 {}
2207 };
2208
2209 static const struct xe_mmio_range mtl_oam_b_counters[] = {
2210 { .start = 0x393000, .end = 0x39301c }, /* OAM_STARTTRIG1[1-8] */
2211 { .start = 0x393020, .end = 0x39303c }, /* OAM_REPORTTRIG1[1-8] */
2212 { .start = 0x393040, .end = 0x39307c }, /* OAM_CEC[0-7][0-1] */
2213 { .start = 0x393200, .end = 0x39323C }, /* MPES[0-7] */
2214 {}
2215 };
2216
2217 static const struct xe_mmio_range xe2_oa_b_counters[] = {
2218 { .start = 0x393200, .end = 0x39323C }, /* MPES_0_MPES_SAG - MPES_7_UPPER_MPES_SAG */
2219 { .start = 0x394200, .end = 0x39423C }, /* MPES_0_MPES_SCMI0 - MPES_7_UPPER_MPES_SCMI0 */
2220 { .start = 0x394A00, .end = 0x394A3C }, /* MPES_0_MPES_SCMI1 - MPES_7_UPPER_MPES_SCMI1 */
2221 {},
2222 };
2223
xe_oa_is_valid_b_counter_addr(struct xe_oa * oa,u32 addr)2224 static bool xe_oa_is_valid_b_counter_addr(struct xe_oa *oa, u32 addr)
2225 {
2226 return xe_oa_reg_in_range_table(addr, xehp_oa_b_counters) ||
2227 xe_oa_reg_in_range_table(addr, gen12_oa_b_counters) ||
2228 xe_oa_reg_in_range_table(addr, mtl_oam_b_counters) ||
2229 (GRAPHICS_VER(oa->xe) >= 20 &&
2230 xe_oa_reg_in_range_table(addr, xe2_oa_b_counters));
2231 }
2232
2233 static const struct xe_mmio_range mtl_oa_mux_regs[] = {
2234 { .start = 0x0d00, .end = 0x0d04 }, /* RPM_CONFIG[0-1] */
2235 { .start = 0x0d0c, .end = 0x0d2c }, /* NOA_CONFIG[0-8] */
2236 { .start = 0x9840, .end = 0x9840 }, /* GDT_CHICKEN_BITS */
2237 { .start = 0x9884, .end = 0x9888 }, /* NOA_WRITE */
2238 { .start = 0x38d100, .end = 0x38d114}, /* VISACTL */
2239 {}
2240 };
2241
2242 static const struct xe_mmio_range gen12_oa_mux_regs[] = {
2243 { .start = 0x0d00, .end = 0x0d04 }, /* RPM_CONFIG[0-1] */
2244 { .start = 0x0d0c, .end = 0x0d2c }, /* NOA_CONFIG[0-8] */
2245 { .start = 0x9840, .end = 0x9840 }, /* GDT_CHICKEN_BITS */
2246 { .start = 0x9884, .end = 0x9888 }, /* NOA_WRITE */
2247 { .start = 0x20cc, .end = 0x20cc }, /* WAIT_FOR_RC6_EXIT */
2248 {}
2249 };
2250
2251 static const struct xe_mmio_range xe2_oa_mux_regs[] = {
2252 { .start = 0x5194, .end = 0x5194 }, /* SYS_MEM_LAT_MEASURE_MERTF_GRP_3D */
2253 { .start = 0x8704, .end = 0x8704 }, /* LMEM_LAT_MEASURE_MCFG_GRP */
2254 { .start = 0xB01C, .end = 0xB01C }, /* LNCF_MISC_CONFIG_REGISTER0 */
2255 { .start = 0xB1BC, .end = 0xB1BC }, /* L3_BANK_LAT_MEASURE_LBCF_GFX */
2256 { .start = 0xD0E0, .end = 0xD0F4 }, /* VISACTL */
2257 { .start = 0xE18C, .end = 0xE18C }, /* SAMPLER_MODE */
2258 { .start = 0xE590, .end = 0xE590 }, /* TDL_LSC_LAT_MEASURE_TDL_GFX */
2259 { .start = 0x13000, .end = 0x137FC }, /* PES_0_PESL0 - PES_63_UPPER_PESL3 */
2260 { .start = 0x145194, .end = 0x145194 }, /* SYS_MEM_LAT_MEASURE */
2261 { .start = 0x145340, .end = 0x14537C }, /* MERTSS_PES_0 - MERTSS_PES_7 */
2262 {},
2263 };
2264
xe_oa_is_valid_mux_addr(struct xe_oa * oa,u32 addr)2265 static bool xe_oa_is_valid_mux_addr(struct xe_oa *oa, u32 addr)
2266 {
2267 if (GRAPHICS_VER(oa->xe) >= 20)
2268 return xe_oa_reg_in_range_table(addr, xe2_oa_mux_regs);
2269 else if (GRAPHICS_VERx100(oa->xe) >= 1270)
2270 return xe_oa_reg_in_range_table(addr, mtl_oa_mux_regs);
2271 else
2272 return xe_oa_reg_in_range_table(addr, gen12_oa_mux_regs);
2273 }
2274
xe_oa_is_valid_config_reg(struct xe_oa * oa,u32 addr,u32 val)2275 static bool xe_oa_is_valid_config_reg(struct xe_oa *oa, u32 addr, u32 val)
2276 {
2277 if (XE_DEVICE_WA(oa->xe, 14026779378) &&
2278 addr == SYS_MEM_LAT_MEASURE.addr && val & SYS_MEM_LAT_MEASURE_EN)
2279 return false;
2280
2281 return xe_oa_is_valid_flex_addr(oa, addr) ||
2282 xe_oa_is_valid_b_counter_addr(oa, addr) ||
2283 xe_oa_is_valid_mux_addr(oa, addr);
2284 }
2285
2286 static struct xe_oa_reg *
xe_oa_alloc_regs(struct xe_oa * oa,bool (* is_valid)(struct xe_oa * oa,u32 addr,u32 val),u32 __user * regs,u32 n_regs)2287 xe_oa_alloc_regs(struct xe_oa *oa, bool (*is_valid)(struct xe_oa *oa, u32 addr, u32 val),
2288 u32 __user *regs, u32 n_regs)
2289 {
2290 struct xe_oa_reg *oa_regs;
2291 int err;
2292 u32 i;
2293
2294 oa_regs = kmalloc_objs(*oa_regs, n_regs);
2295 if (!oa_regs)
2296 return ERR_PTR(-ENOMEM);
2297
2298 for (i = 0; i < n_regs; i++) {
2299 u32 addr, value;
2300
2301 err = get_user(addr, regs);
2302 if (err)
2303 goto addr_err;
2304
2305 err = get_user(value, regs + 1);
2306 if (err)
2307 goto addr_err;
2308
2309 if (!is_valid(oa, addr, value)) {
2310 drm_dbg(&oa->xe->drm, "Invalid oa_reg addr/value: %#x %#x\n", addr, value);
2311 err = -EINVAL;
2312 goto addr_err;
2313 }
2314
2315 oa_regs[i].addr = XE_REG(addr);
2316 oa_regs[i].value = value;
2317
2318 regs += 2;
2319 }
2320
2321 return oa_regs;
2322
2323 addr_err:
2324 kfree(oa_regs);
2325 return ERR_PTR(err);
2326 }
2327 ALLOW_ERROR_INJECTION(xe_oa_alloc_regs, ERRNO);
2328
show_dynamic_id(struct kobject * kobj,struct kobj_attribute * attr,char * buf)2329 static ssize_t show_dynamic_id(struct kobject *kobj,
2330 struct kobj_attribute *attr,
2331 char *buf)
2332 {
2333 struct xe_oa_config *oa_config =
2334 container_of(attr, typeof(*oa_config), sysfs_metric_id);
2335
2336 return sysfs_emit(buf, "%d\n", oa_config->id);
2337 }
2338
create_dynamic_oa_sysfs_entry(struct xe_oa * oa,struct xe_oa_config * oa_config)2339 static int create_dynamic_oa_sysfs_entry(struct xe_oa *oa,
2340 struct xe_oa_config *oa_config)
2341 {
2342 sysfs_attr_init(&oa_config->sysfs_metric_id.attr);
2343 oa_config->sysfs_metric_id.attr.name = "id";
2344 oa_config->sysfs_metric_id.attr.mode = 0444;
2345 oa_config->sysfs_metric_id.show = show_dynamic_id;
2346 oa_config->sysfs_metric_id.store = NULL;
2347
2348 oa_config->attrs[0] = &oa_config->sysfs_metric_id.attr;
2349 oa_config->attrs[1] = NULL;
2350
2351 oa_config->sysfs_metric.name = oa_config->uuid;
2352 oa_config->sysfs_metric.attrs = oa_config->attrs;
2353
2354 return sysfs_create_group(oa->metrics_kobj, &oa_config->sysfs_metric);
2355 }
2356
2357 /**
2358 * xe_oa_add_config_ioctl - Adds one OA config
2359 * @dev: @drm_device
2360 * @data: pointer to struct @drm_xe_oa_config
2361 * @file: @drm_file
2362 *
2363 * The functions adds an OA config to the set of OA configs maintained in
2364 * the kernel. The config determines which OA metrics are collected for an
2365 * OA stream.
2366 */
xe_oa_add_config_ioctl(struct drm_device * dev,u64 data,struct drm_file * file)2367 int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file)
2368 {
2369 struct xe_device *xe = to_xe_device(dev);
2370 struct xe_oa *oa = &xe->oa;
2371 struct drm_xe_oa_config param;
2372 struct drm_xe_oa_config *arg = ¶m;
2373 struct xe_oa_config *oa_config, *tmp;
2374 struct xe_oa_reg *regs;
2375 int err, id;
2376
2377 if (!oa->xe) {
2378 drm_dbg(&xe->drm, "xe oa interface not available for this system\n");
2379 return -ENODEV;
2380 }
2381
2382 err = xe_observation_paranoid_check();
2383 if (err) {
2384 drm_dbg(&oa->xe->drm, "Insufficient privileges to add xe OA config\n");
2385 return err;
2386 }
2387
2388 err = copy_from_user(¶m, u64_to_user_ptr(data), sizeof(param));
2389 if (XE_IOCTL_DBG(oa->xe, err))
2390 return -EFAULT;
2391
2392 if (XE_IOCTL_DBG(oa->xe, arg->extensions) ||
2393 XE_IOCTL_DBG(oa->xe, !arg->regs_ptr) ||
2394 XE_IOCTL_DBG(oa->xe, !arg->n_regs))
2395 return -EINVAL;
2396
2397 oa_config = kzalloc_obj(*oa_config);
2398 if (!oa_config)
2399 return -ENOMEM;
2400
2401 oa_config->oa = oa;
2402 kref_init(&oa_config->ref);
2403
2404 if (!uuid_is_valid(arg->uuid)) {
2405 drm_dbg(&oa->xe->drm, "Invalid uuid format for OA config\n");
2406 err = -EINVAL;
2407 goto reg_err;
2408 }
2409
2410 /* Last character in oa_config->uuid will be 0 because oa_config is kzalloc */
2411 memcpy(oa_config->uuid, arg->uuid, sizeof(arg->uuid));
2412
2413 oa_config->regs_len = arg->n_regs;
2414 regs = xe_oa_alloc_regs(oa, xe_oa_is_valid_config_reg,
2415 u64_to_user_ptr(arg->regs_ptr),
2416 arg->n_regs);
2417 if (IS_ERR(regs)) {
2418 drm_dbg(&oa->xe->drm, "Failed to create OA config for mux_regs\n");
2419 err = PTR_ERR(regs);
2420 goto reg_err;
2421 }
2422 oa_config->regs = regs;
2423
2424 err = mutex_lock_interruptible(&oa->metrics_lock);
2425 if (err)
2426 goto reg_err;
2427
2428 /* We shouldn't have too many configs, so this iteration shouldn't be too costly */
2429 idr_for_each_entry(&oa->metrics_idr, tmp, id) {
2430 if (!strcmp(tmp->uuid, oa_config->uuid)) {
2431 drm_dbg(&oa->xe->drm, "OA config already exists with this uuid\n");
2432 err = -EADDRINUSE;
2433 goto sysfs_err;
2434 }
2435 }
2436
2437 err = create_dynamic_oa_sysfs_entry(oa, oa_config);
2438 if (err) {
2439 drm_dbg(&oa->xe->drm, "Failed to create sysfs entry for OA config\n");
2440 goto sysfs_err;
2441 }
2442
2443 oa_config->id = idr_alloc(&oa->metrics_idr, oa_config, 1, 0, GFP_KERNEL);
2444 if (oa_config->id < 0) {
2445 drm_dbg(&oa->xe->drm, "Failed to allocate id for OA config\n");
2446 err = oa_config->id;
2447 goto id_alloc_err;
2448 }
2449
2450 id = oa_config->id;
2451
2452 drm_dbg(&oa->xe->drm, "Added config %s id=%i\n", oa_config->uuid, id);
2453
2454 mutex_unlock(&oa->metrics_lock);
2455
2456 return id;
2457
2458 id_alloc_err:
2459 sysfs_remove_group(oa->metrics_kobj, &oa_config->sysfs_metric);
2460 sysfs_err:
2461 mutex_unlock(&oa->metrics_lock);
2462 reg_err:
2463 xe_oa_config_put(oa_config);
2464 drm_dbg(&oa->xe->drm, "Failed to add new OA config\n");
2465 return err;
2466 }
2467
2468 /**
2469 * xe_oa_remove_config_ioctl - Removes one OA config
2470 * @dev: @drm_device
2471 * @data: pointer to struct @drm_xe_observation_param
2472 * @file: @drm_file
2473 */
xe_oa_remove_config_ioctl(struct drm_device * dev,u64 data,struct drm_file * file)2474 int xe_oa_remove_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file)
2475 {
2476 struct xe_device *xe = to_xe_device(dev);
2477 struct xe_oa *oa = &xe->oa;
2478 struct xe_oa_config *oa_config;
2479 u64 arg, *ptr = u64_to_user_ptr(data);
2480 int ret;
2481
2482 if (!oa->xe) {
2483 drm_dbg(&xe->drm, "xe oa interface not available for this system\n");
2484 return -ENODEV;
2485 }
2486
2487 ret = xe_observation_paranoid_check();
2488 if (ret) {
2489 drm_dbg(&oa->xe->drm, "Insufficient privileges to remove xe OA config\n");
2490 return ret;
2491 }
2492
2493 ret = get_user(arg, ptr);
2494 if (XE_IOCTL_DBG(oa->xe, ret))
2495 return ret;
2496
2497 ret = mutex_lock_interruptible(&oa->metrics_lock);
2498 if (ret)
2499 return ret;
2500
2501 oa_config = idr_find(&oa->metrics_idr, arg);
2502 if (!oa_config) {
2503 drm_dbg(&oa->xe->drm, "Failed to remove unknown OA config\n");
2504 ret = -ENOENT;
2505 goto err_unlock;
2506 }
2507
2508 WARN_ON(arg != oa_config->id);
2509
2510 sysfs_remove_group(oa->metrics_kobj, &oa_config->sysfs_metric);
2511 idr_remove(&oa->metrics_idr, arg);
2512
2513 mutex_unlock(&oa->metrics_lock);
2514
2515 drm_dbg(&oa->xe->drm, "Removed config %s id=%i\n", oa_config->uuid, oa_config->id);
2516
2517 xe_oa_config_put(oa_config);
2518
2519 return 0;
2520
2521 err_unlock:
2522 mutex_unlock(&oa->metrics_lock);
2523 return ret;
2524 }
2525
xe_oa_unregister(void * arg)2526 static void xe_oa_unregister(void *arg)
2527 {
2528 struct xe_oa *oa = arg;
2529
2530 if (!oa->metrics_kobj)
2531 return;
2532
2533 kobject_put(oa->metrics_kobj);
2534 oa->metrics_kobj = NULL;
2535 }
2536
2537 /**
2538 * xe_oa_register - Xe OA registration
2539 * @xe: @xe_device
2540 *
2541 * Exposes the metrics sysfs directory upon completion of module initialization
2542 */
xe_oa_register(struct xe_device * xe)2543 int xe_oa_register(struct xe_device *xe)
2544 {
2545 struct xe_oa *oa = &xe->oa;
2546
2547 if (!oa->xe)
2548 return 0;
2549
2550 oa->metrics_kobj = kobject_create_and_add("metrics",
2551 &xe->drm.primary->kdev->kobj);
2552 if (!oa->metrics_kobj)
2553 return -ENOMEM;
2554
2555 return devm_add_action_or_reset(xe->drm.dev, xe_oa_unregister, oa);
2556 }
2557
num_oa_units_per_gt(struct xe_gt * gt)2558 static u32 num_oa_units_per_gt(struct xe_gt *gt)
2559 {
2560 if (xe_gt_is_main_type(gt) || GRAPHICS_VER(gt_to_xe(gt)) < 20)
2561 /*
2562 * Mert OA unit belongs to the SoC, not a gt, so should be accessed using
2563 * xe_root_tile_mmio(). However, for all known platforms this is the same as
2564 * accessing via xe_root_mmio_gt()->mmio.
2565 */
2566 return xe_device_has_mert(gt_to_xe(gt)) ? 2 : 1;
2567 else if (!IS_DGFX(gt_to_xe(gt)))
2568 return XE_OAM_UNIT_SCMI_0 + 1; /* SAG + SCMI_0 */
2569 else
2570 return XE_OAM_UNIT_SCMI_1 + 1; /* SAG + SCMI_0 + SCMI_1 */
2571 }
2572
__hwe_oam_unit(struct xe_hw_engine * hwe)2573 static u32 __hwe_oam_unit(struct xe_hw_engine *hwe)
2574 {
2575 if (GRAPHICS_VERx100(gt_to_xe(hwe->gt)) < 1270)
2576 return XE_OA_UNIT_INVALID;
2577
2578 xe_gt_WARN_ON(hwe->gt, xe_gt_is_main_type(hwe->gt));
2579
2580 if (GRAPHICS_VER(gt_to_xe(hwe->gt)) < 20)
2581 return 0;
2582 /*
2583 * XE_OAM_UNIT_SAG has only GSCCS attached to it, but only on some platforms. Also
2584 * GSCCS cannot be used to submit batches to program the OAM unit. Therefore we don't
2585 * assign an OA unit to GSCCS. This means that XE_OAM_UNIT_SAG is exposed as an OA
2586 * unit without attached engines. Fused off engines can also result in oa_unit's with
2587 * num_engines == 0. OA streams can be opened on all OA units.
2588 */
2589 else if (hwe->engine_id == XE_HW_ENGINE_GSCCS0)
2590 return XE_OA_UNIT_INVALID;
2591 else if (!IS_DGFX(gt_to_xe(hwe->gt)))
2592 return XE_OAM_UNIT_SCMI_0;
2593 else if (hwe->class == XE_ENGINE_CLASS_VIDEO_DECODE)
2594 return (hwe->instance / 2 & 0x1) + 1;
2595 else if (hwe->class == XE_ENGINE_CLASS_VIDEO_ENHANCE)
2596 return (hwe->instance & 0x1) + 1;
2597
2598 return XE_OA_UNIT_INVALID;
2599 }
2600
__hwe_oa_unit(struct xe_hw_engine * hwe)2601 static u32 __hwe_oa_unit(struct xe_hw_engine *hwe)
2602 {
2603 switch (hwe->class) {
2604 case XE_ENGINE_CLASS_RENDER:
2605 case XE_ENGINE_CLASS_COMPUTE:
2606 return 0;
2607
2608 case XE_ENGINE_CLASS_VIDEO_DECODE:
2609 case XE_ENGINE_CLASS_VIDEO_ENHANCE:
2610 case XE_ENGINE_CLASS_OTHER:
2611 return __hwe_oam_unit(hwe);
2612
2613 default:
2614 return XE_OA_UNIT_INVALID;
2615 }
2616 }
2617
__oam_regs(u32 base)2618 static struct xe_oa_regs __oam_regs(u32 base)
2619 {
2620 return (struct xe_oa_regs) {
2621 .base = base,
2622 .oa_head_ptr = OAM_HEAD_POINTER(base),
2623 .oa_tail_ptr = OAM_TAIL_POINTER(base),
2624 .oa_buffer = OAM_BUFFER(base),
2625 .oa_ctx_ctrl = OAM_CONTEXT_CONTROL(base),
2626 .oa_ctrl = OAM_CONTROL(base),
2627 .oa_debug = OAM_DEBUG(base),
2628 .oa_status = OAM_STATUS(base),
2629 .oa_mmio_trg = OAM_MMIO_TRG(base),
2630 .oa_ctrl_counter_select_mask = OAM_CONTROL_COUNTER_SEL_MASK,
2631 };
2632 }
2633
__oag_regs(void)2634 static struct xe_oa_regs __oag_regs(void)
2635 {
2636 return (struct xe_oa_regs) {
2637 .base = 0,
2638 .oa_head_ptr = OAG_OAHEADPTR,
2639 .oa_tail_ptr = OAG_OATAILPTR,
2640 .oa_buffer = OAG_OABUFFER,
2641 .oa_ctx_ctrl = OAG_OAGLBCTXCTRL,
2642 .oa_ctrl = OAG_OACONTROL,
2643 .oa_debug = OAG_OA_DEBUG,
2644 .oa_status = OAG_OASTATUS,
2645 .oa_mmio_trg = OAG_MMIOTRIGGER,
2646 .oa_ctrl_counter_select_mask = OAG_OACONTROL_OA_COUNTER_SEL_MASK,
2647 };
2648 }
2649
__oamert_regs(void)2650 static struct xe_oa_regs __oamert_regs(void)
2651 {
2652 return (struct xe_oa_regs) {
2653 .base = 0,
2654 .oa_head_ptr = OAMERT_HEAD_POINTER,
2655 .oa_tail_ptr = OAMERT_TAIL_POINTER,
2656 .oa_buffer = OAMERT_BUFFER,
2657 .oa_ctx_ctrl = OAMERT_CONTEXT_CONTROL,
2658 .oa_ctrl = OAMERT_CONTROL,
2659 .oa_debug = OAMERT_DEBUG,
2660 .oa_status = OAMERT_STATUS,
2661 .oa_mmio_trg = OAMERT_MMIO_TRG,
2662 .oa_ctrl_counter_select_mask = OAM_CONTROL_COUNTER_SEL_MASK,
2663 };
2664 }
2665
__xe_oa_init_oa_units(struct xe_gt * gt)2666 static void __xe_oa_init_oa_units(struct xe_gt *gt)
2667 {
2668 const u32 oam_base_addr[] = {
2669 [XE_OAM_UNIT_SAG] = XE_OAM_SAG_BASE,
2670 [XE_OAM_UNIT_SCMI_0] = XE_OAM_SCMI_0_BASE,
2671 [XE_OAM_UNIT_SCMI_1] = XE_OAM_SCMI_1_BASE,
2672 };
2673 int i, num_units = gt->oa.num_oa_units;
2674
2675 for (i = 0; i < num_units; i++) {
2676 struct xe_oa_unit *u = >->oa.oa_unit[i];
2677
2678 if (xe_gt_is_main_type(gt)) {
2679 if (!i) {
2680 u->regs = __oag_regs();
2681 u->type = DRM_XE_OA_UNIT_TYPE_OAG;
2682 } else {
2683 xe_gt_assert(gt, xe_device_has_mert(gt_to_xe(gt)));
2684 xe_gt_assert(gt, gt == xe_root_mmio_gt(gt_to_xe(gt)));
2685 u->regs = __oamert_regs();
2686 u->type = DRM_XE_OA_UNIT_TYPE_MERT;
2687 }
2688 } else {
2689 xe_gt_assert(gt, GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270);
2690 u->regs = __oam_regs(oam_base_addr[i]);
2691 u->type = i == XE_OAM_UNIT_SAG && GRAPHICS_VER(gt_to_xe(gt)) >= 20 ?
2692 DRM_XE_OA_UNIT_TYPE_OAM_SAG : DRM_XE_OA_UNIT_TYPE_OAM;
2693 }
2694
2695 u->gt = gt;
2696
2697 xe_mmio_write32(>->mmio, u->regs.oa_ctrl, 0);
2698
2699 /* Ensure MMIO trigger remains disabled till there is a stream */
2700 xe_mmio_write32(>->mmio, u->regs.oa_debug,
2701 oag_configure_mmio_trigger(NULL, false));
2702
2703 /* Set oa_unit_ids now to ensure ids remain contiguous */
2704 u->oa_unit_id = gt_to_xe(gt)->oa.oa_unit_ids++;
2705 }
2706 }
2707
xe_oa_init_gt(struct xe_gt * gt)2708 static int xe_oa_init_gt(struct xe_gt *gt)
2709 {
2710 u32 num_oa_units = num_oa_units_per_gt(gt);
2711 struct xe_hw_engine *hwe;
2712 enum xe_hw_engine_id id;
2713 struct xe_oa_unit *u;
2714
2715 u = drmm_kcalloc(>_to_xe(gt)->drm, num_oa_units, sizeof(*u), GFP_KERNEL);
2716 if (!u)
2717 return -ENOMEM;
2718
2719 for_each_hw_engine(hwe, gt, id) {
2720 u32 index = __hwe_oa_unit(hwe);
2721
2722 hwe->oa_unit = NULL;
2723 if (index < num_oa_units) {
2724 u[index].num_engines++;
2725 hwe->oa_unit = &u[index];
2726 }
2727 }
2728
2729 gt->oa.num_oa_units = num_oa_units;
2730 gt->oa.oa_unit = u;
2731
2732 __xe_oa_init_oa_units(gt);
2733
2734 return drmm_mutex_init(>_to_xe(gt)->drm, >->oa.gt_lock);
2735 }
2736
xe_oa_print_gt_oa_units(struct xe_gt * gt)2737 static void xe_oa_print_gt_oa_units(struct xe_gt *gt)
2738 {
2739 enum xe_hw_engine_id hwe_id;
2740 struct xe_hw_engine *hwe;
2741 struct xe_oa_unit *u;
2742 char buf[256];
2743 int i, n;
2744
2745 for (i = 0; i < gt->oa.num_oa_units; i++) {
2746 u = >->oa.oa_unit[i];
2747 buf[0] = '\0';
2748 n = 0;
2749
2750 for_each_hw_engine(hwe, gt, hwe_id)
2751 if (xe_oa_unit_id(hwe) == u->oa_unit_id)
2752 n += scnprintf(buf + n, sizeof(buf) - n, "%s ", hwe->name);
2753
2754 xe_gt_dbg(gt, "oa_unit %d, type %d, Engines: %s\n", u->oa_unit_id, u->type, buf);
2755 }
2756 }
2757
xe_oa_print_oa_units(struct xe_oa * oa)2758 static void xe_oa_print_oa_units(struct xe_oa *oa)
2759 {
2760 struct xe_gt *gt;
2761 int gt_id;
2762
2763 for_each_gt(gt, oa->xe, gt_id)
2764 xe_oa_print_gt_oa_units(gt);
2765 }
2766
xe_oa_init_oa_units(struct xe_oa * oa)2767 static int xe_oa_init_oa_units(struct xe_oa *oa)
2768 {
2769 struct xe_gt *gt;
2770 int i, ret;
2771
2772 /* Needed for OAM implementation here */
2773 BUILD_BUG_ON(XE_OAM_UNIT_SAG != 0);
2774 BUILD_BUG_ON(XE_OAM_UNIT_SCMI_0 != 1);
2775 BUILD_BUG_ON(XE_OAM_UNIT_SCMI_1 != 2);
2776
2777 for_each_gt(gt, oa->xe, i) {
2778 ret = xe_oa_init_gt(gt);
2779 if (ret)
2780 return ret;
2781 }
2782
2783 xe_oa_print_oa_units(oa);
2784
2785 return 0;
2786 }
2787
oa_format_add(struct xe_oa * oa,enum xe_oa_format_name format)2788 static void oa_format_add(struct xe_oa *oa, enum xe_oa_format_name format)
2789 {
2790 __set_bit(format, oa->format_mask);
2791 }
2792
xe_oa_init_supported_formats(struct xe_oa * oa)2793 static void xe_oa_init_supported_formats(struct xe_oa *oa)
2794 {
2795 if (GRAPHICS_VER(oa->xe) >= 20) {
2796 /* Xe2+ */
2797 oa_format_add(oa, XE_OAM_FORMAT_MPEC8u64_B8_C8);
2798 oa_format_add(oa, XE_OAM_FORMAT_MPEC8u32_B8_C8);
2799 oa_format_add(oa, XE_OA_FORMAT_PEC64u64);
2800 oa_format_add(oa, XE_OA_FORMAT_PEC64u64_B8_C8);
2801 oa_format_add(oa, XE_OA_FORMAT_PEC64u32);
2802 oa_format_add(oa, XE_OA_FORMAT_PEC32u64_G1);
2803 oa_format_add(oa, XE_OA_FORMAT_PEC32u32_G1);
2804 oa_format_add(oa, XE_OA_FORMAT_PEC32u64_G2);
2805 oa_format_add(oa, XE_OA_FORMAT_PEC32u32_G2);
2806 oa_format_add(oa, XE_OA_FORMAT_PEC36u64_G1_32_G2_4);
2807 oa_format_add(oa, XE_OA_FORMAT_PEC36u64_G1_4_G2_32);
2808 } else if (GRAPHICS_VERx100(oa->xe) >= 1270) {
2809 /* XE_METEORLAKE */
2810 oa_format_add(oa, XE_OAR_FORMAT_A32u40_A4u32_B8_C8);
2811 oa_format_add(oa, XE_OA_FORMAT_A24u40_A14u32_B8_C8);
2812 oa_format_add(oa, XE_OAC_FORMAT_A24u64_B8_C8);
2813 oa_format_add(oa, XE_OAC_FORMAT_A22u32_R2u32_B8_C8);
2814 oa_format_add(oa, XE_OAM_FORMAT_MPEC8u64_B8_C8);
2815 oa_format_add(oa, XE_OAM_FORMAT_MPEC8u32_B8_C8);
2816 } else if (GRAPHICS_VERx100(oa->xe) >= 1255) {
2817 /* XE_DG2, XE_PVC */
2818 oa_format_add(oa, XE_OAR_FORMAT_A32u40_A4u32_B8_C8);
2819 oa_format_add(oa, XE_OA_FORMAT_A24u40_A14u32_B8_C8);
2820 oa_format_add(oa, XE_OAC_FORMAT_A24u64_B8_C8);
2821 oa_format_add(oa, XE_OAC_FORMAT_A22u32_R2u32_B8_C8);
2822 } else {
2823 /* Gen12+ */
2824 xe_assert(oa->xe, GRAPHICS_VER(oa->xe) >= 12);
2825 oa_format_add(oa, XE_OA_FORMAT_A12);
2826 oa_format_add(oa, XE_OA_FORMAT_A12_B8_C8);
2827 oa_format_add(oa, XE_OA_FORMAT_A32u40_A4u32_B8_C8);
2828 oa_format_add(oa, XE_OA_FORMAT_C4_B8);
2829 }
2830 }
2831
destroy_config(int id,void * p,void * data)2832 static int destroy_config(int id, void *p, void *data)
2833 {
2834 xe_oa_config_put(p);
2835
2836 return 0;
2837 }
2838
xe_oa_fini(void * arg)2839 static void xe_oa_fini(void *arg)
2840 {
2841 struct xe_device *xe = arg;
2842 struct xe_oa *oa = &xe->oa;
2843
2844 if (!oa->xe)
2845 return;
2846
2847 idr_for_each(&oa->metrics_idr, destroy_config, oa);
2848 idr_destroy(&oa->metrics_idr);
2849
2850 oa->xe = NULL;
2851 }
2852
2853 /**
2854 * xe_oa_init - OA initialization during device probe
2855 * @xe: @xe_device
2856 *
2857 * Return: 0 on success or a negative error code on failure
2858 */
xe_oa_init(struct xe_device * xe)2859 int xe_oa_init(struct xe_device *xe)
2860 {
2861 struct xe_oa *oa = &xe->oa;
2862 int ret;
2863
2864 /* Support OA only with GuC submission and Gen12+ */
2865 if (!xe_device_uc_enabled(xe) || GRAPHICS_VER(xe) < 12)
2866 return 0;
2867
2868 if (IS_SRIOV_VF(xe))
2869 return 0;
2870
2871 oa->xe = xe;
2872 oa->oa_formats = oa_formats;
2873
2874 ret = drmm_mutex_init(&oa->xe->drm, &oa->metrics_lock);
2875 if (ret)
2876 goto exit;
2877
2878 idr_init_base(&oa->metrics_idr, 1);
2879
2880 ret = xe_oa_init_oa_units(oa);
2881 if (ret) {
2882 drm_err(&xe->drm, "OA initialization failed (%pe)\n", ERR_PTR(ret));
2883 goto exit;
2884 }
2885
2886 xe_oa_init_supported_formats(oa);
2887
2888 return devm_add_action_or_reset(xe->drm.dev, xe_oa_fini, xe);
2889
2890 exit:
2891 oa->xe = NULL;
2892 return ret;
2893 }
2894