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 stream->oa_buffer.bo = bo;
918
919 stream->oa_buffer.bounce = kmalloc(stream->oa_buffer.format->size, GFP_KERNEL);
920 if (!stream->oa_buffer.bounce) {
921 xe_bo_unpin_map_no_vm(stream->oa_buffer.bo);
922 return -ENOMEM;
923 }
924
925 return 0;
926 }
927
928 static struct xe_oa_config_bo *
__xe_oa_alloc_config_buffer(struct xe_oa_stream * stream,struct xe_oa_config * oa_config)929 __xe_oa_alloc_config_buffer(struct xe_oa_stream *stream, struct xe_oa_config *oa_config)
930 {
931 struct xe_oa_config_bo *oa_bo;
932 size_t config_length;
933 struct xe_bb *bb;
934
935 oa_bo = kzalloc_obj(*oa_bo);
936 if (!oa_bo)
937 return ERR_PTR(-ENOMEM);
938
939 config_length = num_lri_dwords(oa_config->regs_len);
940 config_length = ALIGN(sizeof(u32) * config_length, XE_PAGE_SIZE) / sizeof(u32);
941
942 bb = xe_bb_new(stream->gt, config_length, false);
943 if (IS_ERR(bb))
944 goto err_free;
945
946 write_cs_mi_lri(bb, oa_config->regs, oa_config->regs_len);
947
948 oa_bo->bb = bb;
949 oa_bo->oa_config = xe_oa_config_get(oa_config);
950 llist_add(&oa_bo->node, &stream->oa_config_bos);
951
952 return oa_bo;
953 err_free:
954 kfree(oa_bo);
955 return ERR_CAST(bb);
956 }
957
958 static struct xe_oa_config_bo *
xe_oa_alloc_config_buffer(struct xe_oa_stream * stream,struct xe_oa_config * oa_config)959 xe_oa_alloc_config_buffer(struct xe_oa_stream *stream, struct xe_oa_config *oa_config)
960 {
961 struct xe_oa_config_bo *oa_bo;
962
963 /* Look for the buffer in the already allocated BOs attached to the stream */
964 llist_for_each_entry(oa_bo, stream->oa_config_bos.first, node) {
965 if (oa_bo->oa_config == oa_config &&
966 memcmp(oa_bo->oa_config->uuid, oa_config->uuid,
967 sizeof(oa_config->uuid)) == 0)
968 goto out;
969 }
970
971 oa_bo = __xe_oa_alloc_config_buffer(stream, oa_config);
972 out:
973 return oa_bo;
974 }
975
xe_oa_update_last_fence(struct xe_oa_stream * stream,struct dma_fence * fence)976 static void xe_oa_update_last_fence(struct xe_oa_stream *stream, struct dma_fence *fence)
977 {
978 dma_fence_put(stream->last_fence);
979 stream->last_fence = dma_fence_get(fence);
980 }
981
xe_oa_fence_work_fn(struct work_struct * w)982 static void xe_oa_fence_work_fn(struct work_struct *w)
983 {
984 struct xe_oa_fence *ofence = container_of(w, typeof(*ofence), work.work);
985
986 /* Signal fence to indicate new OA configuration is active */
987 dma_fence_signal(&ofence->base);
988 dma_fence_put(&ofence->base);
989 }
990
xe_oa_config_cb(struct dma_fence * fence,struct dma_fence_cb * cb)991 static void xe_oa_config_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
992 {
993 /* Additional empirical delay needed for NOA programming after registers are written */
994 #define NOA_PROGRAM_ADDITIONAL_DELAY_US 500
995
996 struct xe_oa_fence *ofence = container_of(cb, typeof(*ofence), cb);
997
998 INIT_DELAYED_WORK(&ofence->work, xe_oa_fence_work_fn);
999 queue_delayed_work(system_dfl_wq, &ofence->work,
1000 usecs_to_jiffies(NOA_PROGRAM_ADDITIONAL_DELAY_US));
1001 dma_fence_put(fence);
1002 }
1003
xe_oa_get_driver_name(struct dma_fence * fence)1004 static const char *xe_oa_get_driver_name(struct dma_fence *fence)
1005 {
1006 return "xe_oa";
1007 }
1008
xe_oa_get_timeline_name(struct dma_fence * fence)1009 static const char *xe_oa_get_timeline_name(struct dma_fence *fence)
1010 {
1011 return "unbound";
1012 }
1013
1014 static const struct dma_fence_ops xe_oa_fence_ops = {
1015 .get_driver_name = xe_oa_get_driver_name,
1016 .get_timeline_name = xe_oa_get_timeline_name,
1017 };
1018
xe_oa_emit_oa_config(struct xe_oa_stream * stream,struct xe_oa_config * config)1019 static int xe_oa_emit_oa_config(struct xe_oa_stream *stream, struct xe_oa_config *config)
1020 {
1021 #define NOA_PROGRAM_ADDITIONAL_DELAY_US 500
1022 struct xe_oa_config_bo *oa_bo;
1023 struct xe_oa_fence *ofence;
1024 int i, err, num_signal = 0;
1025 struct dma_fence *fence;
1026
1027 ofence = kzalloc_obj(*ofence);
1028 if (!ofence) {
1029 err = -ENOMEM;
1030 goto exit;
1031 }
1032
1033 oa_bo = xe_oa_alloc_config_buffer(stream, config);
1034 if (IS_ERR(oa_bo)) {
1035 err = PTR_ERR(oa_bo);
1036 goto exit;
1037 }
1038
1039 /* Emit OA configuration batch */
1040 fence = xe_oa_submit_bb(stream, XE_OA_SUBMIT_ADD_DEPS, oa_bo->bb);
1041 if (IS_ERR(fence)) {
1042 err = PTR_ERR(fence);
1043 goto exit;
1044 }
1045
1046 /* Point of no return: initialize and set fence to signal */
1047 spin_lock_init(&ofence->lock);
1048 dma_fence_init(&ofence->base, &xe_oa_fence_ops, &ofence->lock, 0, 0);
1049
1050 for (i = 0; i < stream->num_syncs; i++) {
1051 if (stream->syncs[i].flags & DRM_XE_SYNC_FLAG_SIGNAL)
1052 num_signal++;
1053 xe_sync_entry_signal(&stream->syncs[i], &ofence->base);
1054 }
1055
1056 /* Additional dma_fence_get in case we dma_fence_wait */
1057 if (!num_signal)
1058 dma_fence_get(&ofence->base);
1059
1060 /* Update last fence too before adding callback */
1061 xe_oa_update_last_fence(stream, fence);
1062
1063 /* Add job fence callback to schedule work to signal ofence->base */
1064 err = dma_fence_add_callback(fence, &ofence->cb, xe_oa_config_cb);
1065 xe_gt_assert(stream->gt, !err || err == -ENOENT);
1066 if (err == -ENOENT)
1067 xe_oa_config_cb(fence, &ofence->cb);
1068
1069 /* If nothing needs to be signaled we wait synchronously */
1070 if (!num_signal) {
1071 dma_fence_wait(&ofence->base, false);
1072 dma_fence_put(&ofence->base);
1073 }
1074
1075 /* Done with syncs */
1076 for (i = 0; i < stream->num_syncs; i++)
1077 xe_sync_entry_cleanup(&stream->syncs[i]);
1078 kfree(stream->syncs);
1079
1080 return 0;
1081 exit:
1082 kfree(ofence);
1083 return err;
1084 }
1085
oag_report_ctx_switches(const struct xe_oa_stream * stream)1086 static u32 oag_report_ctx_switches(const struct xe_oa_stream *stream)
1087 {
1088 /* If user didn't require OA reports, ask HW not to emit ctx switch reports */
1089 if (stream->sample)
1090 return REG_MASKED_FIELD_DISABLE(OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS);
1091 else
1092 return REG_MASKED_FIELD_ENABLE(OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS);
1093 }
1094
oag_buf_size_select(const struct xe_oa_stream * stream)1095 static u32 oag_buf_size_select(const struct xe_oa_stream *stream)
1096 {
1097 if (xe_bo_size(stream->oa_buffer.bo) > SZ_16M)
1098 return REG_MASKED_FIELD_ENABLE(OAG_OA_DEBUG_BUF_SIZE_SELECT);
1099 else
1100 return REG_MASKED_FIELD_DISABLE(OAG_OA_DEBUG_BUF_SIZE_SELECT);
1101 }
1102
xe_oa_enable_metric_set(struct xe_oa_stream * stream)1103 static int xe_oa_enable_metric_set(struct xe_oa_stream *stream)
1104 {
1105 struct xe_mmio *mmio = &stream->gt->mmio;
1106 u32 oa_debug, sqcnt1;
1107 int ret;
1108
1109 /*
1110 * EU NOA signals behave incorrectly if EU clock gating is enabled.
1111 * Disable thread stall DOP gating and EU DOP gating.
1112 */
1113 if (XE_GT_WA(stream->gt, 1508761755)) {
1114 xe_gt_mcr_multicast_write(stream->gt, ROW_CHICKEN,
1115 REG_MASKED_FIELD_ENABLE(STALL_DOP_GATING_DISABLE));
1116 xe_gt_mcr_multicast_write(stream->gt, ROW_CHICKEN2,
1117 REG_MASKED_FIELD_ENABLE(DISABLE_DOP_GATING));
1118 }
1119
1120 /* Disable clk ratio reports */
1121 oa_debug = OAG_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
1122 OAG_OA_DEBUG_INCLUDE_CLK_RATIO;
1123
1124 if (GRAPHICS_VER(stream->oa->xe) >= 20)
1125 oa_debug |=
1126 /* The three bits below are needed to get PEC counters running */
1127 OAG_OA_DEBUG_START_TRIGGER_SCOPE_CONTROL |
1128 OAG_OA_DEBUG_DISABLE_START_TRG_2_COUNT_QUAL |
1129 OAG_OA_DEBUG_DISABLE_START_TRG_1_COUNT_QUAL;
1130
1131 xe_mmio_write32(mmio, __oa_regs(stream)->oa_debug,
1132 REG_MASKED_FIELD_ENABLE(oa_debug) |
1133 oag_report_ctx_switches(stream) |
1134 oag_buf_size_select(stream) |
1135 oag_configure_mmio_trigger(stream, true));
1136
1137 xe_mmio_write32(mmio, __oa_regs(stream)->oa_ctx_ctrl,
1138 OAG_OAGLBCTXCTRL_COUNTER_RESUME |
1139 (stream->periodic ?
1140 OAG_OAGLBCTXCTRL_TIMER_ENABLE |
1141 REG_FIELD_PREP(OAG_OAGLBCTXCTRL_TIMER_PERIOD_MASK,
1142 stream->period_exponent) : 0));
1143
1144 /*
1145 * Initialize Super Queue Internal Cnt Register
1146 * Set PMON Enable in order to collect valid metrics
1147 * Enable bytes per clock reporting
1148 */
1149 sqcnt1 = SQCNT1_PMON_ENABLE |
1150 (HAS_OA_BPC_REPORTING(stream->oa->xe) ? SQCNT1_OABPC : 0);
1151 xe_mmio_rmw32(mmio, XELPMP_SQCNT1, 0, sqcnt1);
1152
1153 if ((stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAM ||
1154 stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAM_SAG) &&
1155 GRAPHICS_VER(stream->oa->xe) >= 30)
1156 xe_mmio_rmw32(mmio, OAM_COMPRESSION_T3_CONTROL, 0, OAM_LAT_MEASURE_ENABLE);
1157
1158 /* Configure OAR/OAC */
1159 if (stream->exec_q) {
1160 ret = xe_oa_configure_oa_context(stream, true);
1161 if (ret)
1162 return ret;
1163 }
1164
1165 return xe_oa_emit_oa_config(stream, stream->oa_config);
1166 }
1167
decode_oa_format(struct xe_oa * oa,u64 fmt,enum xe_oa_format_name * name)1168 static int decode_oa_format(struct xe_oa *oa, u64 fmt, enum xe_oa_format_name *name)
1169 {
1170 u32 counter_size = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SIZE, fmt);
1171 u32 counter_sel = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SEL, fmt);
1172 u32 bc_report = FIELD_GET(DRM_XE_OA_FORMAT_MASK_BC_REPORT, fmt);
1173 u32 type = FIELD_GET(DRM_XE_OA_FORMAT_MASK_FMT_TYPE, fmt);
1174 int idx;
1175
1176 for_each_set_bit(idx, oa->format_mask, __XE_OA_FORMAT_MAX) {
1177 const struct xe_oa_format *f = &oa->oa_formats[idx];
1178
1179 if (counter_size == f->counter_size && bc_report == f->bc_report &&
1180 type == f->type && counter_sel == f->counter_select) {
1181 *name = idx;
1182 return 0;
1183 }
1184 }
1185
1186 return -EINVAL;
1187 }
1188
xe_oa_lookup_oa_unit(struct xe_oa * oa,u32 oa_unit_id)1189 static struct xe_oa_unit *xe_oa_lookup_oa_unit(struct xe_oa *oa, u32 oa_unit_id)
1190 {
1191 struct xe_gt *gt;
1192 int gt_id, i;
1193
1194 for_each_gt(gt, oa->xe, gt_id) {
1195 for (i = 0; i < gt->oa.num_oa_units; i++) {
1196 struct xe_oa_unit *u = >->oa.oa_unit[i];
1197
1198 if (u->oa_unit_id == oa_unit_id)
1199 return u;
1200 }
1201 }
1202
1203 return NULL;
1204 }
1205
xe_oa_set_prop_oa_unit_id(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1206 static int xe_oa_set_prop_oa_unit_id(struct xe_oa *oa, u64 value,
1207 struct xe_oa_open_param *param)
1208 {
1209 param->oa_unit = xe_oa_lookup_oa_unit(oa, value);
1210 if (!param->oa_unit) {
1211 drm_dbg(&oa->xe->drm, "OA unit ID out of range %lld\n", value);
1212 return -EINVAL;
1213 }
1214 return 0;
1215 }
1216
xe_oa_set_prop_sample_oa(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1217 static int xe_oa_set_prop_sample_oa(struct xe_oa *oa, u64 value,
1218 struct xe_oa_open_param *param)
1219 {
1220 param->sample = value;
1221 return 0;
1222 }
1223
xe_oa_set_prop_metric_set(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1224 static int xe_oa_set_prop_metric_set(struct xe_oa *oa, u64 value,
1225 struct xe_oa_open_param *param)
1226 {
1227 param->metric_set = value;
1228 return 0;
1229 }
1230
xe_oa_set_prop_oa_format(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1231 static int xe_oa_set_prop_oa_format(struct xe_oa *oa, u64 value,
1232 struct xe_oa_open_param *param)
1233 {
1234 int ret = decode_oa_format(oa, value, ¶m->oa_format);
1235
1236 if (ret) {
1237 drm_dbg(&oa->xe->drm, "Unsupported OA report format %#llx\n", value);
1238 return ret;
1239 }
1240 return 0;
1241 }
1242
xe_oa_set_prop_oa_exponent(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1243 static int xe_oa_set_prop_oa_exponent(struct xe_oa *oa, u64 value,
1244 struct xe_oa_open_param *param)
1245 {
1246 #define OA_EXPONENT_MAX 31
1247
1248 if (value > OA_EXPONENT_MAX) {
1249 drm_dbg(&oa->xe->drm, "OA timer exponent too high (> %u)\n", OA_EXPONENT_MAX);
1250 return -EINVAL;
1251 }
1252 param->period_exponent = value;
1253 return 0;
1254 }
1255
xe_oa_set_prop_disabled(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1256 static int xe_oa_set_prop_disabled(struct xe_oa *oa, u64 value,
1257 struct xe_oa_open_param *param)
1258 {
1259 param->disabled = value;
1260 return 0;
1261 }
1262
xe_oa_set_prop_exec_queue_id(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1263 static int xe_oa_set_prop_exec_queue_id(struct xe_oa *oa, u64 value,
1264 struct xe_oa_open_param *param)
1265 {
1266 param->exec_queue_id = value;
1267 return 0;
1268 }
1269
xe_oa_set_prop_engine_instance(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1270 static int xe_oa_set_prop_engine_instance(struct xe_oa *oa, u64 value,
1271 struct xe_oa_open_param *param)
1272 {
1273 param->engine_instance = value;
1274 return 0;
1275 }
1276
xe_oa_set_no_preempt(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1277 static int xe_oa_set_no_preempt(struct xe_oa *oa, u64 value,
1278 struct xe_oa_open_param *param)
1279 {
1280 param->no_preempt = value;
1281 return 0;
1282 }
1283
xe_oa_set_prop_num_syncs(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1284 static int xe_oa_set_prop_num_syncs(struct xe_oa *oa, u64 value,
1285 struct xe_oa_open_param *param)
1286 {
1287 if (XE_IOCTL_DBG(oa->xe, value > DRM_XE_MAX_SYNCS))
1288 return -EINVAL;
1289
1290 param->num_syncs = value;
1291 return 0;
1292 }
1293
xe_oa_set_prop_syncs_user(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1294 static int xe_oa_set_prop_syncs_user(struct xe_oa *oa, u64 value,
1295 struct xe_oa_open_param *param)
1296 {
1297 param->syncs_user = u64_to_user_ptr(value);
1298 return 0;
1299 }
1300
xe_oa_set_prop_oa_buffer_size(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1301 static int xe_oa_set_prop_oa_buffer_size(struct xe_oa *oa, u64 value,
1302 struct xe_oa_open_param *param)
1303 {
1304 if (!is_power_of_2(value) || value < SZ_128K || value > SZ_128M) {
1305 drm_dbg(&oa->xe->drm, "OA buffer size invalid %llu\n", value);
1306 return -EINVAL;
1307 }
1308 param->oa_buffer_size = value;
1309 return 0;
1310 }
1311
xe_oa_set_prop_wait_num_reports(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1312 static int xe_oa_set_prop_wait_num_reports(struct xe_oa *oa, u64 value,
1313 struct xe_oa_open_param *param)
1314 {
1315 if (!value) {
1316 drm_dbg(&oa->xe->drm, "wait_num_reports %llu\n", value);
1317 return -EINVAL;
1318 }
1319 param->wait_num_reports = value;
1320 return 0;
1321 }
1322
xe_oa_set_prop_ret_inval(struct xe_oa * oa,u64 value,struct xe_oa_open_param * param)1323 static int xe_oa_set_prop_ret_inval(struct xe_oa *oa, u64 value,
1324 struct xe_oa_open_param *param)
1325 {
1326 return -EINVAL;
1327 }
1328
1329 typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value,
1330 struct xe_oa_open_param *param);
1331 static const xe_oa_set_property_fn xe_oa_set_property_funcs_open[] = {
1332 [DRM_XE_OA_PROPERTY_OA_UNIT_ID] = xe_oa_set_prop_oa_unit_id,
1333 [DRM_XE_OA_PROPERTY_SAMPLE_OA] = xe_oa_set_prop_sample_oa,
1334 [DRM_XE_OA_PROPERTY_OA_METRIC_SET] = xe_oa_set_prop_metric_set,
1335 [DRM_XE_OA_PROPERTY_OA_FORMAT] = xe_oa_set_prop_oa_format,
1336 [DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT] = xe_oa_set_prop_oa_exponent,
1337 [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_disabled,
1338 [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_exec_queue_id,
1339 [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_engine_instance,
1340 [DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_no_preempt,
1341 [DRM_XE_OA_PROPERTY_NUM_SYNCS] = xe_oa_set_prop_num_syncs,
1342 [DRM_XE_OA_PROPERTY_SYNCS] = xe_oa_set_prop_syncs_user,
1343 [DRM_XE_OA_PROPERTY_OA_BUFFER_SIZE] = xe_oa_set_prop_oa_buffer_size,
1344 [DRM_XE_OA_PROPERTY_WAIT_NUM_REPORTS] = xe_oa_set_prop_wait_num_reports,
1345 };
1346
1347 static const xe_oa_set_property_fn xe_oa_set_property_funcs_config[] = {
1348 [DRM_XE_OA_PROPERTY_OA_UNIT_ID] = xe_oa_set_prop_ret_inval,
1349 [DRM_XE_OA_PROPERTY_SAMPLE_OA] = xe_oa_set_prop_ret_inval,
1350 [DRM_XE_OA_PROPERTY_OA_METRIC_SET] = xe_oa_set_prop_metric_set,
1351 [DRM_XE_OA_PROPERTY_OA_FORMAT] = xe_oa_set_prop_ret_inval,
1352 [DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT] = xe_oa_set_prop_ret_inval,
1353 [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_ret_inval,
1354 [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_ret_inval,
1355 [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_ret_inval,
1356 [DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_prop_ret_inval,
1357 [DRM_XE_OA_PROPERTY_NUM_SYNCS] = xe_oa_set_prop_num_syncs,
1358 [DRM_XE_OA_PROPERTY_SYNCS] = xe_oa_set_prop_syncs_user,
1359 [DRM_XE_OA_PROPERTY_OA_BUFFER_SIZE] = xe_oa_set_prop_ret_inval,
1360 [DRM_XE_OA_PROPERTY_WAIT_NUM_REPORTS] = xe_oa_set_prop_ret_inval,
1361 };
1362
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)1363 static int xe_oa_user_ext_set_property(struct xe_oa *oa, enum xe_oa_user_extn_from from,
1364 u64 extension, struct xe_oa_open_param *param)
1365 {
1366 u64 __user *address = u64_to_user_ptr(extension);
1367 struct drm_xe_ext_set_property ext;
1368 int err;
1369 u32 idx;
1370
1371 err = copy_from_user(&ext, address, sizeof(ext));
1372 if (XE_IOCTL_DBG(oa->xe, err))
1373 return -EFAULT;
1374
1375 BUILD_BUG_ON(ARRAY_SIZE(xe_oa_set_property_funcs_open) !=
1376 ARRAY_SIZE(xe_oa_set_property_funcs_config));
1377
1378 if (XE_IOCTL_DBG(oa->xe, ext.property >= ARRAY_SIZE(xe_oa_set_property_funcs_open)) ||
1379 XE_IOCTL_DBG(oa->xe, !ext.property) || XE_IOCTL_DBG(oa->xe, ext.pad))
1380 return -EINVAL;
1381
1382 idx = array_index_nospec(ext.property, ARRAY_SIZE(xe_oa_set_property_funcs_open));
1383
1384 if (from == XE_OA_USER_EXTN_FROM_CONFIG)
1385 return xe_oa_set_property_funcs_config[idx](oa, ext.value, param);
1386 else
1387 return xe_oa_set_property_funcs_open[idx](oa, ext.value, param);
1388 }
1389
1390 typedef int (*xe_oa_user_extension_fn)(struct xe_oa *oa, enum xe_oa_user_extn_from from,
1391 u64 extension, struct xe_oa_open_param *param);
1392 static const xe_oa_user_extension_fn xe_oa_user_extension_funcs[] = {
1393 [DRM_XE_OA_EXTENSION_SET_PROPERTY] = xe_oa_user_ext_set_property,
1394 };
1395
1396 #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)1397 static int xe_oa_user_extensions(struct xe_oa *oa, enum xe_oa_user_extn_from from, u64 extension,
1398 int ext_number, struct xe_oa_open_param *param)
1399 {
1400 u64 __user *address = u64_to_user_ptr(extension);
1401 struct drm_xe_user_extension ext;
1402 int err;
1403 u32 idx;
1404
1405 if (XE_IOCTL_DBG(oa->xe, ext_number >= MAX_USER_EXTENSIONS))
1406 return -E2BIG;
1407
1408 err = copy_from_user(&ext, address, sizeof(ext));
1409 if (XE_IOCTL_DBG(oa->xe, err))
1410 return -EFAULT;
1411
1412 if (XE_IOCTL_DBG(oa->xe, ext.pad) ||
1413 XE_IOCTL_DBG(oa->xe, ext.name >= ARRAY_SIZE(xe_oa_user_extension_funcs)))
1414 return -EINVAL;
1415
1416 idx = array_index_nospec(ext.name, ARRAY_SIZE(xe_oa_user_extension_funcs));
1417 err = xe_oa_user_extension_funcs[idx](oa, from, extension, param);
1418 if (XE_IOCTL_DBG(oa->xe, err))
1419 return err;
1420
1421 if (ext.next_extension)
1422 return xe_oa_user_extensions(oa, from, ext.next_extension, ++ext_number, param);
1423
1424 return 0;
1425 }
1426
xe_oa_parse_syncs(struct xe_oa * oa,struct xe_oa_stream * stream,struct xe_oa_open_param * param)1427 static int xe_oa_parse_syncs(struct xe_oa *oa,
1428 struct xe_oa_stream *stream,
1429 struct xe_oa_open_param *param)
1430 {
1431 int ret, num_syncs, num_ufence = 0;
1432
1433 if (param->num_syncs && !param->syncs_user) {
1434 drm_dbg(&oa->xe->drm, "num_syncs specified without sync array\n");
1435 ret = -EINVAL;
1436 goto exit;
1437 }
1438
1439 if (param->num_syncs) {
1440 param->syncs = kzalloc_objs(*param->syncs, param->num_syncs);
1441 if (!param->syncs) {
1442 ret = -ENOMEM;
1443 goto exit;
1444 }
1445 }
1446
1447 for (num_syncs = 0; num_syncs < param->num_syncs; num_syncs++) {
1448 ret = xe_sync_entry_parse(oa->xe, param->xef, ¶m->syncs[num_syncs],
1449 ¶m->syncs_user[num_syncs],
1450 stream->ufence_syncobj,
1451 ++stream->ufence_timeline_value, 0);
1452 if (ret)
1453 goto err_syncs;
1454
1455 if (xe_sync_is_ufence(¶m->syncs[num_syncs]))
1456 num_ufence++;
1457 }
1458
1459 if (XE_IOCTL_DBG(oa->xe, num_ufence > 1)) {
1460 ret = -EINVAL;
1461 goto err_syncs;
1462 }
1463
1464 return 0;
1465
1466 err_syncs:
1467 while (num_syncs--)
1468 xe_sync_entry_cleanup(¶m->syncs[num_syncs]);
1469 kfree(param->syncs);
1470 exit:
1471 return ret;
1472 }
1473
xe_oa_stream_enable(struct xe_oa_stream * stream)1474 static void xe_oa_stream_enable(struct xe_oa_stream *stream)
1475 {
1476 stream->pollin = false;
1477
1478 xe_oa_enable(stream);
1479
1480 if (stream->sample)
1481 hrtimer_start(&stream->poll_check_timer,
1482 ns_to_ktime(stream->poll_period_ns),
1483 HRTIMER_MODE_REL_PINNED);
1484 }
1485
xe_oa_stream_disable(struct xe_oa_stream * stream)1486 static void xe_oa_stream_disable(struct xe_oa_stream *stream)
1487 {
1488 xe_oa_disable(stream);
1489
1490 if (stream->sample)
1491 hrtimer_cancel(&stream->poll_check_timer);
1492
1493 /* Update stream->oa_buffer.tail to allow any final reports to be read */
1494 if (xe_oa_buffer_check_unlocked(stream))
1495 wake_up(&stream->poll_wq);
1496 }
1497
xe_oa_enable_preempt_timeslice(struct xe_oa_stream * stream)1498 static int xe_oa_enable_preempt_timeslice(struct xe_oa_stream *stream)
1499 {
1500 struct xe_exec_queue *q = stream->exec_q;
1501 int ret1, ret2;
1502
1503 /* Best effort recovery: try to revert both to original, irrespective of error */
1504 ret1 = q->ops->set_timeslice(q, stream->hwe->eclass->sched_props.timeslice_us);
1505 ret2 = q->ops->set_preempt_timeout(q, stream->hwe->eclass->sched_props.preempt_timeout_us);
1506 if (ret1 || ret2)
1507 goto err;
1508 return 0;
1509 err:
1510 drm_dbg(&stream->oa->xe->drm, "%s failed ret1 %d ret2 %d\n", __func__, ret1, ret2);
1511 return ret1 ?: ret2;
1512 }
1513
xe_oa_disable_preempt_timeslice(struct xe_oa_stream * stream)1514 static int xe_oa_disable_preempt_timeslice(struct xe_oa_stream *stream)
1515 {
1516 struct xe_exec_queue *q = stream->exec_q;
1517 int ret;
1518
1519 /* Setting values to 0 will disable timeslice and preempt_timeout */
1520 ret = q->ops->set_timeslice(q, 0);
1521 if (ret)
1522 goto err;
1523
1524 ret = q->ops->set_preempt_timeout(q, 0);
1525 if (ret)
1526 goto err;
1527
1528 return 0;
1529 err:
1530 xe_oa_enable_preempt_timeslice(stream);
1531 drm_dbg(&stream->oa->xe->drm, "%s failed %d\n", __func__, ret);
1532 return ret;
1533 }
1534
xe_oa_enable_locked(struct xe_oa_stream * stream)1535 static int xe_oa_enable_locked(struct xe_oa_stream *stream)
1536 {
1537 if (stream->enabled)
1538 return 0;
1539
1540 if (stream->no_preempt) {
1541 int ret = xe_oa_disable_preempt_timeslice(stream);
1542
1543 if (ret)
1544 return ret;
1545 }
1546
1547 xe_oa_stream_enable(stream);
1548
1549 stream->enabled = true;
1550 return 0;
1551 }
1552
xe_oa_disable_locked(struct xe_oa_stream * stream)1553 static int xe_oa_disable_locked(struct xe_oa_stream *stream)
1554 {
1555 int ret = 0;
1556
1557 if (!stream->enabled)
1558 return 0;
1559
1560 xe_oa_stream_disable(stream);
1561
1562 if (stream->no_preempt)
1563 ret = xe_oa_enable_preempt_timeslice(stream);
1564
1565 stream->enabled = false;
1566 return ret;
1567 }
1568
xe_oa_config_locked(struct xe_oa_stream * stream,u64 arg)1569 static long xe_oa_config_locked(struct xe_oa_stream *stream, u64 arg)
1570 {
1571 struct xe_oa_open_param param = {};
1572 long ret = stream->oa_config->id;
1573 struct xe_oa_config *config;
1574 int err;
1575
1576 err = xe_oa_user_extensions(stream->oa, XE_OA_USER_EXTN_FROM_CONFIG, arg, 0, ¶m);
1577 if (err)
1578 return err;
1579
1580 config = xe_oa_get_oa_config(stream->oa, param.metric_set);
1581 if (!config)
1582 return -ENODEV;
1583
1584 param.xef = stream->xef;
1585 err = xe_oa_parse_syncs(stream->oa, stream, ¶m);
1586 if (err)
1587 goto err_config_put;
1588
1589 stream->num_syncs = param.num_syncs;
1590 stream->syncs = param.syncs;
1591
1592 err = xe_oa_emit_oa_config(stream, config);
1593 if (!err) {
1594 config = xchg(&stream->oa_config, config);
1595 drm_dbg(&stream->oa->xe->drm, "changed to oa config uuid=%s\n",
1596 stream->oa_config->uuid);
1597 } else {
1598 while (param.num_syncs--)
1599 xe_sync_entry_cleanup(¶m.syncs[param.num_syncs]);
1600 kfree(param.syncs);
1601 }
1602
1603 err_config_put:
1604 xe_oa_config_put(config);
1605
1606 return err ?: ret;
1607 }
1608
xe_oa_status_locked(struct xe_oa_stream * stream,unsigned long arg)1609 static long xe_oa_status_locked(struct xe_oa_stream *stream, unsigned long arg)
1610 {
1611 struct drm_xe_oa_stream_status status = {};
1612 void __user *uaddr = (void __user *)arg;
1613
1614 /* Map from register to uapi bits */
1615 if (stream->oa_status & OASTATUS_REPORT_LOST)
1616 status.oa_status |= DRM_XE_OASTATUS_REPORT_LOST;
1617 if (stream->oa_status & OASTATUS_BUFFER_OVERFLOW)
1618 status.oa_status |= DRM_XE_OASTATUS_BUFFER_OVERFLOW;
1619 if (stream->oa_status & OASTATUS_COUNTER_OVERFLOW)
1620 status.oa_status |= DRM_XE_OASTATUS_COUNTER_OVERFLOW;
1621 if (stream->oa_status & OASTATUS_MMIO_TRG_Q_FULL)
1622 status.oa_status |= DRM_XE_OASTATUS_MMIO_TRG_Q_FULL;
1623
1624 if (copy_to_user(uaddr, &status, sizeof(status)))
1625 return -EFAULT;
1626
1627 return 0;
1628 }
1629
xe_oa_info_locked(struct xe_oa_stream * stream,unsigned long arg)1630 static long xe_oa_info_locked(struct xe_oa_stream *stream, unsigned long arg)
1631 {
1632 struct drm_xe_oa_stream_info info = { .oa_buf_size = xe_bo_size(stream->oa_buffer.bo), };
1633 void __user *uaddr = (void __user *)arg;
1634
1635 if (copy_to_user(uaddr, &info, sizeof(info)))
1636 return -EFAULT;
1637
1638 return 0;
1639 }
1640
xe_oa_ioctl_locked(struct xe_oa_stream * stream,unsigned int cmd,unsigned long arg)1641 static long xe_oa_ioctl_locked(struct xe_oa_stream *stream,
1642 unsigned int cmd,
1643 unsigned long arg)
1644 {
1645 switch (cmd) {
1646 case DRM_XE_OBSERVATION_IOCTL_ENABLE:
1647 return xe_oa_enable_locked(stream);
1648 case DRM_XE_OBSERVATION_IOCTL_DISABLE:
1649 return xe_oa_disable_locked(stream);
1650 case DRM_XE_OBSERVATION_IOCTL_CONFIG:
1651 return xe_oa_config_locked(stream, arg);
1652 case DRM_XE_OBSERVATION_IOCTL_STATUS:
1653 return xe_oa_status_locked(stream, arg);
1654 case DRM_XE_OBSERVATION_IOCTL_INFO:
1655 return xe_oa_info_locked(stream, arg);
1656 }
1657
1658 return -EINVAL;
1659 }
1660
xe_oa_ioctl(struct file * file,unsigned int cmd,unsigned long arg)1661 static long xe_oa_ioctl(struct file *file,
1662 unsigned int cmd,
1663 unsigned long arg)
1664 {
1665 struct xe_oa_stream *stream = file->private_data;
1666 long ret;
1667
1668 mutex_lock(&stream->stream_lock);
1669 ret = xe_oa_ioctl_locked(stream, cmd, arg);
1670 mutex_unlock(&stream->stream_lock);
1671
1672 return ret;
1673 }
1674
xe_oa_destroy_locked(struct xe_oa_stream * stream)1675 static void xe_oa_destroy_locked(struct xe_oa_stream *stream)
1676 {
1677 if (stream->enabled)
1678 xe_oa_disable_locked(stream);
1679
1680 xe_oa_stream_destroy(stream);
1681
1682 if (stream->exec_q)
1683 xe_exec_queue_put(stream->exec_q);
1684
1685 drm_syncobj_put(stream->ufence_syncobj);
1686 kfree(stream);
1687 }
1688
xe_oa_release(struct inode * inode,struct file * file)1689 static int xe_oa_release(struct inode *inode, struct file *file)
1690 {
1691 struct xe_oa_stream *stream = file->private_data;
1692 struct xe_gt *gt = stream->gt;
1693
1694 xe_pm_runtime_get(gt_to_xe(gt));
1695 mutex_lock(>->oa.gt_lock);
1696 xe_oa_destroy_locked(stream);
1697 mutex_unlock(>->oa.gt_lock);
1698 xe_pm_runtime_put(gt_to_xe(gt));
1699
1700 /* Release the reference the OA stream kept on the driver */
1701 drm_dev_put(>_to_xe(gt)->drm);
1702
1703 return 0;
1704 }
1705
xe_oa_mmap(struct file * file,struct vm_area_struct * vma)1706 static int xe_oa_mmap(struct file *file, struct vm_area_struct *vma)
1707 {
1708 struct xe_oa_stream *stream = file->private_data;
1709 int ret = xe_observation_paranoid_check();
1710 struct xe_bo *bo = stream->oa_buffer.bo;
1711
1712 if (ret) {
1713 drm_dbg(&stream->oa->xe->drm, "Insufficient privilege to map OA buffer\n");
1714 return ret;
1715 }
1716
1717 /* Can mmap the entire OA buffer or nothing (no partial OA buffer mmaps) */
1718 if (vma->vm_end - vma->vm_start != xe_bo_size(bo)) {
1719 drm_dbg(&stream->oa->xe->drm, "Wrong mmap size, must be OA buffer size\n");
1720 return -EINVAL;
1721 }
1722
1723 /*
1724 * Only support VM_READ, enforce MAP_PRIVATE by checking for
1725 * VM_MAYSHARE, don't copy the vma on fork
1726 */
1727 if (vma->vm_flags & (VM_WRITE | VM_EXEC | VM_SHARED | VM_MAYSHARE)) {
1728 drm_dbg(&stream->oa->xe->drm, "mmap must be read only\n");
1729 return -EINVAL;
1730 }
1731 vm_flags_mod(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_DONTCOPY,
1732 VM_MAYWRITE | VM_MAYEXEC);
1733
1734 return drm_gem_mmap_obj(&bo->ttm.base, xe_bo_size(bo), vma);
1735 }
1736
1737 static const struct file_operations xe_oa_fops = {
1738 .owner = THIS_MODULE,
1739 .release = xe_oa_release,
1740 .poll = xe_oa_poll,
1741 .read = xe_oa_read,
1742 .unlocked_ioctl = xe_oa_ioctl,
1743 .mmap = xe_oa_mmap,
1744 };
1745
xe_oa_stream_init(struct xe_oa_stream * stream,struct xe_oa_open_param * param)1746 static int xe_oa_stream_init(struct xe_oa_stream *stream,
1747 struct xe_oa_open_param *param)
1748 {
1749 struct xe_gt *gt = param->hwe->gt;
1750 int ret;
1751
1752 stream->exec_q = param->exec_q;
1753 stream->poll_period_ns = DEFAULT_POLL_PERIOD_NS;
1754 stream->oa_unit = param->oa_unit;
1755 stream->hwe = param->hwe;
1756 stream->gt = stream->hwe->gt;
1757 stream->oa_buffer.format = &stream->oa->oa_formats[param->oa_format];
1758
1759 stream->sample = param->sample;
1760 stream->periodic = param->period_exponent >= 0;
1761 stream->period_exponent = param->period_exponent;
1762 stream->no_preempt = param->no_preempt;
1763 stream->wait_num_reports = param->wait_num_reports;
1764
1765 stream->xef = xe_file_get(param->xef);
1766 stream->num_syncs = param->num_syncs;
1767 stream->syncs = param->syncs;
1768
1769 /*
1770 * For Xe2+, when overrun mode is enabled, there are no partial reports at the end
1771 * of buffer, making the OA buffer effectively a non-power-of-2 size circular
1772 * buffer whose size, circ_size, is a multiple of the report size
1773 */
1774 if (GRAPHICS_VER(stream->oa->xe) >= 20 &&
1775 stream->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAG && stream->sample)
1776 stream->oa_buffer.circ_size =
1777 param->oa_buffer_size -
1778 param->oa_buffer_size % stream->oa_buffer.format->size;
1779 else
1780 stream->oa_buffer.circ_size = param->oa_buffer_size;
1781
1782 stream->oa_config = xe_oa_get_oa_config(stream->oa, param->metric_set);
1783 if (!stream->oa_config) {
1784 drm_dbg(&stream->oa->xe->drm, "Invalid OA config id=%i\n", param->metric_set);
1785 ret = -EINVAL;
1786 goto exit;
1787 }
1788
1789 /* Take runtime pm ref and forcewake to disable RC6 */
1790 xe_pm_runtime_get(stream->oa->xe);
1791 stream->fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
1792 if (!xe_force_wake_ref_has_domain(stream->fw_ref, XE_FORCEWAKE_ALL)) {
1793 ret = -ETIMEDOUT;
1794 goto err_fw_put;
1795 }
1796
1797 ret = xe_oa_alloc_oa_buffer(stream, param->oa_buffer_size);
1798 if (ret)
1799 goto err_fw_put;
1800
1801 stream->k_exec_q = xe_exec_queue_create(stream->oa->xe, NULL,
1802 BIT(stream->hwe->logical_instance), 1,
1803 stream->hwe, EXEC_QUEUE_FLAG_KERNEL, 0);
1804 if (IS_ERR(stream->k_exec_q)) {
1805 ret = PTR_ERR(stream->k_exec_q);
1806 drm_err(&stream->oa->xe->drm, "gt%d, hwe %s, xe_exec_queue_create failed=%d",
1807 stream->gt->info.id, stream->hwe->name, ret);
1808 goto err_free_oa_buf;
1809 }
1810
1811 ret = xe_oa_enable_metric_set(stream);
1812 if (ret) {
1813 drm_dbg(&stream->oa->xe->drm, "Unable to enable metric set\n");
1814 goto err_put_k_exec_q;
1815 }
1816
1817 drm_dbg(&stream->oa->xe->drm, "opening stream oa config uuid=%s\n",
1818 stream->oa_config->uuid);
1819
1820 WRITE_ONCE(stream->oa_unit->exclusive_stream, stream);
1821
1822 hrtimer_setup(&stream->poll_check_timer, xe_oa_poll_check_timer_cb, CLOCK_MONOTONIC,
1823 HRTIMER_MODE_REL);
1824 init_waitqueue_head(&stream->poll_wq);
1825
1826 spin_lock_init(&stream->oa_buffer.ptr_lock);
1827 mutex_init(&stream->stream_lock);
1828
1829 return 0;
1830
1831 err_put_k_exec_q:
1832 xe_oa_disable_metric_set(stream);
1833 xe_exec_queue_put(stream->k_exec_q);
1834 err_free_oa_buf:
1835 xe_oa_free_oa_buffer(stream);
1836 err_fw_put:
1837 xe_force_wake_put(gt_to_fw(gt), stream->fw_ref);
1838 xe_pm_runtime_put(stream->oa->xe);
1839 xe_oa_free_configs(stream);
1840 exit:
1841 xe_file_put(stream->xef);
1842 return ret;
1843 }
1844
xe_oa_stream_open_ioctl_locked(struct xe_oa * oa,struct xe_oa_open_param * param)1845 static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa,
1846 struct xe_oa_open_param *param)
1847 {
1848 struct xe_oa_stream *stream;
1849 struct drm_syncobj *ufence_syncobj;
1850 int stream_fd;
1851 int ret;
1852
1853 /* We currently only allow exclusive access */
1854 if (param->oa_unit->exclusive_stream) {
1855 drm_dbg(&oa->xe->drm, "OA unit already in use\n");
1856 ret = -EBUSY;
1857 goto exit;
1858 }
1859
1860 ret = drm_syncobj_create(&ufence_syncobj, DRM_SYNCOBJ_CREATE_SIGNALED,
1861 NULL);
1862 if (ret)
1863 goto exit;
1864
1865 stream = kzalloc_obj(*stream);
1866 if (!stream) {
1867 ret = -ENOMEM;
1868 goto err_syncobj;
1869 }
1870 stream->ufence_syncobj = ufence_syncobj;
1871 stream->oa = oa;
1872
1873 ret = xe_oa_parse_syncs(oa, stream, param);
1874 if (ret)
1875 goto err_free;
1876
1877 ret = xe_oa_stream_init(stream, param);
1878 if (ret) {
1879 while (param->num_syncs--)
1880 xe_sync_entry_cleanup(¶m->syncs[param->num_syncs]);
1881 kfree(param->syncs);
1882 goto err_free;
1883 }
1884
1885 if (!param->disabled) {
1886 ret = xe_oa_enable_locked(stream);
1887 if (ret)
1888 goto err_destroy;
1889 }
1890
1891 stream_fd = anon_inode_getfd("[xe_oa]", &xe_oa_fops, stream, 0);
1892 if (stream_fd < 0) {
1893 ret = stream_fd;
1894 goto err_disable;
1895 }
1896
1897 if (stream->sample)
1898 xe_reg_whitelist_oa_regs(stream->gt);
1899
1900 /* Hold a reference on the drm device till stream_fd is released */
1901 drm_dev_get(&stream->oa->xe->drm);
1902
1903 return stream_fd;
1904 err_disable:
1905 if (!param->disabled)
1906 xe_oa_disable_locked(stream);
1907 err_destroy:
1908 xe_oa_stream_destroy(stream);
1909 err_free:
1910 kfree(stream);
1911 err_syncobj:
1912 drm_syncobj_put(ufence_syncobj);
1913 exit:
1914 return ret;
1915 }
1916
1917 /**
1918 * xe_oa_timestamp_frequency - Return OA timestamp frequency
1919 * @gt: @xe_gt
1920 *
1921 * OA timestamp frequency = CS timestamp frequency in most platforms. On some
1922 * platforms OA unit ignores the CTC_SHIFT and the 2 timestamps differ. In such
1923 * cases, return the adjusted CS timestamp frequency to the user.
1924 */
xe_oa_timestamp_frequency(struct xe_gt * gt)1925 u32 xe_oa_timestamp_frequency(struct xe_gt *gt)
1926 {
1927 u32 reg, shift;
1928
1929 if (XE_GT_WA(gt, 18013179988) || XE_GT_WA(gt, 14015568240)) {
1930 xe_pm_runtime_get(gt_to_xe(gt));
1931 reg = xe_mmio_read32(>->mmio, RPM_CONFIG0);
1932 xe_pm_runtime_put(gt_to_xe(gt));
1933
1934 shift = REG_FIELD_GET(RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, reg);
1935 return gt->info.reference_clock << (3 - shift);
1936 } else {
1937 return gt->info.reference_clock;
1938 }
1939 }
1940
oa_exponent_to_ns(struct xe_gt * gt,int exponent)1941 static u64 oa_exponent_to_ns(struct xe_gt *gt, int exponent)
1942 {
1943 u64 nom = (2ULL << exponent) * NSEC_PER_SEC;
1944 u32 den = xe_oa_timestamp_frequency(gt);
1945
1946 return div_u64(nom + den - 1, den);
1947 }
1948
oa_unit_supports_oa_format(struct xe_oa * oa,struct xe_oa_open_param * param)1949 static bool oa_unit_supports_oa_format(struct xe_oa *oa, struct xe_oa_open_param *param)
1950 {
1951 const struct xe_oa_format *f = &oa->oa_formats[param->oa_format];
1952
1953 switch (param->oa_unit->type) {
1954 case DRM_XE_OA_UNIT_TYPE_OAG:
1955 return f->type == DRM_XE_OA_FMT_TYPE_OAG || f->type == DRM_XE_OA_FMT_TYPE_OAR ||
1956 f->type == DRM_XE_OA_FMT_TYPE_OAC || f->type == DRM_XE_OA_FMT_TYPE_PEC;
1957 case DRM_XE_OA_UNIT_TYPE_MERT:
1958 if (XE_DEVICE_WA(oa->xe, 14026746987))
1959 return param->oa_format == XE_OAM_FORMAT_MPEC8u32_B8_C8;
1960 fallthrough;
1961 case DRM_XE_OA_UNIT_TYPE_OAM:
1962 case DRM_XE_OA_UNIT_TYPE_OAM_SAG:
1963 return f->type == DRM_XE_OA_FMT_TYPE_OAM || f->type == DRM_XE_OA_FMT_TYPE_OAM_MPEC;
1964 default:
1965 return false;
1966 }
1967 }
1968
1969 /**
1970 * xe_oa_unit_id - Return OA unit ID for a hardware engine
1971 * @hwe: @xe_hw_engine
1972 *
1973 * Return OA unit ID for a hardware engine when available
1974 */
xe_oa_unit_id(struct xe_hw_engine * hwe)1975 u16 xe_oa_unit_id(struct xe_hw_engine *hwe)
1976 {
1977 return hwe->oa_unit && hwe->oa_unit->num_engines ?
1978 hwe->oa_unit->oa_unit_id : U16_MAX;
1979 }
1980
1981 /* 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)1982 static int xe_oa_assign_hwe(struct xe_oa *oa, struct xe_oa_open_param *param)
1983 {
1984 struct xe_hw_engine *hwe;
1985 enum xe_hw_engine_id id;
1986 int ret = 0;
1987
1988 /* When we have an exec_q, get hwe from the exec_q */
1989 if (param->exec_q) {
1990 param->hwe = xe_gt_hw_engine(param->exec_q->gt, param->exec_q->class,
1991 param->engine_instance, true);
1992 if (!param->hwe || param->hwe->oa_unit != param->oa_unit)
1993 goto err;
1994 goto out;
1995 }
1996
1997 /* Else just get the first hwe attached to the oa unit */
1998 for_each_hw_engine(hwe, param->oa_unit->gt, id) {
1999 if (hwe->oa_unit == param->oa_unit) {
2000 param->hwe = hwe;
2001 goto out;
2002 }
2003 }
2004
2005 /* If we still didn't find a hwe, just get one with a valid oa_unit from the same gt */
2006 for_each_hw_engine(hwe, param->oa_unit->gt, id) {
2007 if (!hwe->oa_unit)
2008 continue;
2009
2010 param->hwe = hwe;
2011 goto out;
2012 }
2013 err:
2014 drm_dbg(&oa->xe->drm, "Unable to find hwe (%d, %d) for OA unit ID %d\n",
2015 param->exec_q ? param->exec_q->class : -1,
2016 param->engine_instance, param->oa_unit->oa_unit_id);
2017 ret = -EINVAL;
2018 out:
2019 return ret;
2020 }
2021
2022 /**
2023 * xe_oa_stream_open_ioctl - Opens an OA stream
2024 * @dev: @drm_device
2025 * @data: pointer to struct @drm_xe_oa_config
2026 * @file: @drm_file
2027 *
2028 * The functions opens an OA stream. An OA stream, opened with specified
2029 * properties, enables OA counter samples to be collected, either
2030 * periodically (time based sampling), or on request (using OA queries)
2031 */
xe_oa_stream_open_ioctl(struct drm_device * dev,u64 data,struct drm_file * file)2032 int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *file)
2033 {
2034 struct xe_device *xe = to_xe_device(dev);
2035 struct xe_oa *oa = &xe->oa;
2036 struct xe_file *xef = to_xe_file(file);
2037 struct xe_oa_open_param param = {};
2038 const struct xe_oa_format *f;
2039 bool privileged_op = true;
2040 int ret;
2041
2042 if (!oa->xe) {
2043 drm_dbg(&xe->drm, "xe oa interface not available for this system\n");
2044 return -ENODEV;
2045 }
2046
2047 param.xef = xef;
2048 param.period_exponent = -1;
2049 ret = xe_oa_user_extensions(oa, XE_OA_USER_EXTN_FROM_OPEN, data, 0, ¶m);
2050 if (ret)
2051 return ret;
2052
2053 /* If not provided, OA unit defaults to OA unit 0 as per uapi */
2054 if (!param.oa_unit)
2055 param.oa_unit = &xe_root_mmio_gt(oa->xe)->oa.oa_unit[0];
2056
2057 if (param.exec_queue_id > 0) {
2058 /* An exec_queue is only needed for OAR/OAC functionality on OAG */
2059 if (XE_IOCTL_DBG(oa->xe, param.oa_unit->type != DRM_XE_OA_UNIT_TYPE_OAG))
2060 return -EINVAL;
2061
2062 param.exec_q = xe_exec_queue_lookup(xef, param.exec_queue_id);
2063 if (XE_IOCTL_DBG(oa->xe, !param.exec_q))
2064 return -ENOENT;
2065
2066 if (XE_IOCTL_DBG(oa->xe, param.exec_q->width > 1)) {
2067 ret = -EOPNOTSUPP;
2068 goto err_exec_q;
2069 }
2070 }
2071
2072 /*
2073 * Query based sampling (using MI_REPORT_PERF_COUNT) with OAR/OAC,
2074 * without global stream access, can be an unprivileged operation
2075 */
2076 if (param.exec_q && !param.sample)
2077 privileged_op = false;
2078
2079 if (param.no_preempt) {
2080 if (!param.exec_q) {
2081 drm_dbg(&oa->xe->drm, "Preemption disable without exec_q!\n");
2082 ret = -EINVAL;
2083 goto err_exec_q;
2084 }
2085 privileged_op = true;
2086 }
2087
2088 if (privileged_op) {
2089 ret = xe_observation_paranoid_check();
2090 if (ret) {
2091 drm_dbg(&oa->xe->drm, "Insufficient privileges to open xe OA stream\n");
2092 goto err_exec_q;
2093 }
2094 }
2095
2096 if (!param.exec_q && !param.sample) {
2097 drm_dbg(&oa->xe->drm, "Only OA report sampling supported\n");
2098 ret = -EINVAL;
2099 goto err_exec_q;
2100 }
2101
2102 ret = xe_oa_assign_hwe(oa, ¶m);
2103 if (ret)
2104 goto err_exec_q;
2105
2106 f = &oa->oa_formats[param.oa_format];
2107 if (!param.oa_format || !f->size || !oa_unit_supports_oa_format(oa, ¶m)) {
2108 drm_dbg(&oa->xe->drm, "Invalid OA format %d type %d size %d for class %d\n",
2109 param.oa_format, f->type, f->size, param.hwe->class);
2110 ret = -EINVAL;
2111 goto err_exec_q;
2112 }
2113
2114 if (param.period_exponent >= 0) {
2115 u64 oa_period, oa_freq_hz;
2116
2117 /* Requesting samples from OAG buffer is a privileged operation */
2118 if (!param.sample) {
2119 drm_dbg(&oa->xe->drm, "OA_EXPONENT specified without SAMPLE_OA\n");
2120 ret = -EINVAL;
2121 goto err_exec_q;
2122 }
2123 oa_period = oa_exponent_to_ns(param.hwe->gt, param.period_exponent);
2124 oa_freq_hz = div64_u64(NSEC_PER_SEC, oa_period);
2125 drm_dbg(&oa->xe->drm, "Using periodic sampling freq %lld Hz\n", oa_freq_hz);
2126 }
2127
2128 if (!param.oa_buffer_size)
2129 param.oa_buffer_size = DEFAULT_XE_OA_BUFFER_SIZE;
2130
2131 if (!param.wait_num_reports)
2132 param.wait_num_reports = 1;
2133 if (param.wait_num_reports > param.oa_buffer_size / f->size) {
2134 drm_dbg(&oa->xe->drm, "wait_num_reports %d\n", param.wait_num_reports);
2135 ret = -EINVAL;
2136 goto err_exec_q;
2137 }
2138
2139 mutex_lock(¶m.hwe->gt->oa.gt_lock);
2140 ret = xe_oa_stream_open_ioctl_locked(oa, ¶m);
2141 mutex_unlock(¶m.hwe->gt->oa.gt_lock);
2142 if (ret < 0)
2143 goto err_exec_q;
2144
2145 return ret;
2146
2147 err_exec_q:
2148 if (param.exec_q)
2149 xe_exec_queue_put(param.exec_q);
2150 return ret;
2151 }
2152
xe_oa_is_valid_flex_addr(struct xe_oa * oa,u32 addr)2153 static bool xe_oa_is_valid_flex_addr(struct xe_oa *oa, u32 addr)
2154 {
2155 static const struct xe_reg flex_eu_regs[] = {
2156 EU_PERF_CNTL0,
2157 EU_PERF_CNTL1,
2158 EU_PERF_CNTL2,
2159 EU_PERF_CNTL3,
2160 EU_PERF_CNTL4,
2161 EU_PERF_CNTL5,
2162 EU_PERF_CNTL6,
2163 };
2164 int i;
2165
2166 for (i = 0; i < ARRAY_SIZE(flex_eu_regs); i++) {
2167 if (flex_eu_regs[i].addr == addr)
2168 return true;
2169 }
2170 return false;
2171 }
2172
xe_oa_reg_in_range_table(u32 addr,const struct xe_mmio_range * table)2173 static bool xe_oa_reg_in_range_table(u32 addr, const struct xe_mmio_range *table)
2174 {
2175 while (table->start && table->end) {
2176 if (addr >= table->start && addr <= table->end)
2177 return true;
2178
2179 table++;
2180 }
2181
2182 return false;
2183 }
2184
2185 static const struct xe_mmio_range xehp_oa_b_counters[] = {
2186 { .start = 0xdc48, .end = 0xdc48 }, /* OAA_ENABLE_REG */
2187 { .start = 0xdd00, .end = 0xdd48 }, /* OAG_LCE0_0 - OAA_LENABLE_REG */
2188 {}
2189 };
2190
2191 static const struct xe_mmio_range gen12_oa_b_counters[] = {
2192 { .start = 0x2b2c, .end = 0x2b2c }, /* OAG_OA_PESS */
2193 { .start = 0xd900, .end = 0xd91c }, /* OAG_OASTARTTRIG[1-8] */
2194 { .start = 0xd920, .end = 0xd93c }, /* OAG_OAREPORTTRIG1[1-8] */
2195 { .start = 0xd940, .end = 0xd97c }, /* OAG_CEC[0-7][0-1] */
2196 { .start = 0xdc00, .end = 0xdc3c }, /* OAG_SCEC[0-7][0-1] */
2197 { .start = 0xdc40, .end = 0xdc40 }, /* OAG_SPCTR_CNF */
2198 { .start = 0xdc44, .end = 0xdc44 }, /* OAA_DBG_REG */
2199 {}
2200 };
2201
2202 static const struct xe_mmio_range mtl_oam_b_counters[] = {
2203 { .start = 0x393000, .end = 0x39301c }, /* OAM_STARTTRIG1[1-8] */
2204 { .start = 0x393020, .end = 0x39303c }, /* OAM_REPORTTRIG1[1-8] */
2205 { .start = 0x393040, .end = 0x39307c }, /* OAM_CEC[0-7][0-1] */
2206 { .start = 0x393200, .end = 0x39323C }, /* MPES[0-7] */
2207 {}
2208 };
2209
2210 static const struct xe_mmio_range xe2_oa_b_counters[] = {
2211 { .start = 0x393200, .end = 0x39323C }, /* MPES_0_MPES_SAG - MPES_7_UPPER_MPES_SAG */
2212 { .start = 0x394200, .end = 0x39423C }, /* MPES_0_MPES_SCMI0 - MPES_7_UPPER_MPES_SCMI0 */
2213 { .start = 0x394A00, .end = 0x394A3C }, /* MPES_0_MPES_SCMI1 - MPES_7_UPPER_MPES_SCMI1 */
2214 {},
2215 };
2216
xe_oa_is_valid_b_counter_addr(struct xe_oa * oa,u32 addr)2217 static bool xe_oa_is_valid_b_counter_addr(struct xe_oa *oa, u32 addr)
2218 {
2219 return xe_oa_reg_in_range_table(addr, xehp_oa_b_counters) ||
2220 xe_oa_reg_in_range_table(addr, gen12_oa_b_counters) ||
2221 xe_oa_reg_in_range_table(addr, mtl_oam_b_counters) ||
2222 (GRAPHICS_VER(oa->xe) >= 20 &&
2223 xe_oa_reg_in_range_table(addr, xe2_oa_b_counters));
2224 }
2225
2226 static const struct xe_mmio_range mtl_oa_mux_regs[] = {
2227 { .start = 0x0d00, .end = 0x0d04 }, /* RPM_CONFIG[0-1] */
2228 { .start = 0x0d0c, .end = 0x0d2c }, /* NOA_CONFIG[0-8] */
2229 { .start = 0x9840, .end = 0x9840 }, /* GDT_CHICKEN_BITS */
2230 { .start = 0x9884, .end = 0x9888 }, /* NOA_WRITE */
2231 { .start = 0x38d100, .end = 0x38d114}, /* VISACTL */
2232 {}
2233 };
2234
2235 static const struct xe_mmio_range gen12_oa_mux_regs[] = {
2236 { .start = 0x0d00, .end = 0x0d04 }, /* RPM_CONFIG[0-1] */
2237 { .start = 0x0d0c, .end = 0x0d2c }, /* NOA_CONFIG[0-8] */
2238 { .start = 0x9840, .end = 0x9840 }, /* GDT_CHICKEN_BITS */
2239 { .start = 0x9884, .end = 0x9888 }, /* NOA_WRITE */
2240 { .start = 0x20cc, .end = 0x20cc }, /* WAIT_FOR_RC6_EXIT */
2241 {}
2242 };
2243
2244 static const struct xe_mmio_range xe2_oa_mux_regs[] = {
2245 { .start = 0x5194, .end = 0x5194 }, /* SYS_MEM_LAT_MEASURE_MERTF_GRP_3D */
2246 { .start = 0x8704, .end = 0x8704 }, /* LMEM_LAT_MEASURE_MCFG_GRP */
2247 { .start = 0xB01C, .end = 0xB01C }, /* LNCF_MISC_CONFIG_REGISTER0 */
2248 { .start = 0xB1BC, .end = 0xB1BC }, /* L3_BANK_LAT_MEASURE_LBCF_GFX */
2249 { .start = 0xD0E0, .end = 0xD0F4 }, /* VISACTL */
2250 { .start = 0xE18C, .end = 0xE18C }, /* SAMPLER_MODE */
2251 { .start = 0xE590, .end = 0xE590 }, /* TDL_LSC_LAT_MEASURE_TDL_GFX */
2252 { .start = 0x13000, .end = 0x137FC }, /* PES_0_PESL0 - PES_63_UPPER_PESL3 */
2253 { .start = 0x145194, .end = 0x145194 }, /* SYS_MEM_LAT_MEASURE */
2254 { .start = 0x145340, .end = 0x14537C }, /* MERTSS_PES_0 - MERTSS_PES_7 */
2255 {},
2256 };
2257
xe_oa_is_valid_mux_addr(struct xe_oa * oa,u32 addr)2258 static bool xe_oa_is_valid_mux_addr(struct xe_oa *oa, u32 addr)
2259 {
2260 if (GRAPHICS_VER(oa->xe) >= 20)
2261 return xe_oa_reg_in_range_table(addr, xe2_oa_mux_regs);
2262 else if (GRAPHICS_VERx100(oa->xe) >= 1270)
2263 return xe_oa_reg_in_range_table(addr, mtl_oa_mux_regs);
2264 else
2265 return xe_oa_reg_in_range_table(addr, gen12_oa_mux_regs);
2266 }
2267
xe_oa_is_valid_config_reg(struct xe_oa * oa,u32 addr,u32 val)2268 static bool xe_oa_is_valid_config_reg(struct xe_oa *oa, u32 addr, u32 val)
2269 {
2270 if (XE_DEVICE_WA(oa->xe, 14026779378) &&
2271 addr == SYS_MEM_LAT_MEASURE.addr && val & SYS_MEM_LAT_MEASURE_EN)
2272 return false;
2273
2274 return xe_oa_is_valid_flex_addr(oa, addr) ||
2275 xe_oa_is_valid_b_counter_addr(oa, addr) ||
2276 xe_oa_is_valid_mux_addr(oa, addr);
2277 }
2278
2279 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)2280 xe_oa_alloc_regs(struct xe_oa *oa, bool (*is_valid)(struct xe_oa *oa, u32 addr, u32 val),
2281 u32 __user *regs, u32 n_regs)
2282 {
2283 struct xe_oa_reg *oa_regs;
2284 int err;
2285 u32 i;
2286
2287 oa_regs = kmalloc_objs(*oa_regs, n_regs);
2288 if (!oa_regs)
2289 return ERR_PTR(-ENOMEM);
2290
2291 for (i = 0; i < n_regs; i++) {
2292 u32 addr, value;
2293
2294 err = get_user(addr, regs);
2295 if (err)
2296 goto addr_err;
2297
2298 err = get_user(value, regs + 1);
2299 if (err)
2300 goto addr_err;
2301
2302 if (!is_valid(oa, addr, value)) {
2303 drm_dbg(&oa->xe->drm, "Invalid oa_reg addr/value: %#x %#x\n", addr, value);
2304 err = -EINVAL;
2305 goto addr_err;
2306 }
2307
2308 oa_regs[i].addr = XE_REG(addr);
2309 oa_regs[i].value = value;
2310
2311 regs += 2;
2312 }
2313
2314 return oa_regs;
2315
2316 addr_err:
2317 kfree(oa_regs);
2318 return ERR_PTR(err);
2319 }
2320 ALLOW_ERROR_INJECTION(xe_oa_alloc_regs, ERRNO);
2321
show_dynamic_id(struct kobject * kobj,struct kobj_attribute * attr,char * buf)2322 static ssize_t show_dynamic_id(struct kobject *kobj,
2323 struct kobj_attribute *attr,
2324 char *buf)
2325 {
2326 struct xe_oa_config *oa_config =
2327 container_of(attr, typeof(*oa_config), sysfs_metric_id);
2328
2329 return sysfs_emit(buf, "%d\n", oa_config->id);
2330 }
2331
create_dynamic_oa_sysfs_entry(struct xe_oa * oa,struct xe_oa_config * oa_config)2332 static int create_dynamic_oa_sysfs_entry(struct xe_oa *oa,
2333 struct xe_oa_config *oa_config)
2334 {
2335 sysfs_attr_init(&oa_config->sysfs_metric_id.attr);
2336 oa_config->sysfs_metric_id.attr.name = "id";
2337 oa_config->sysfs_metric_id.attr.mode = 0444;
2338 oa_config->sysfs_metric_id.show = show_dynamic_id;
2339 oa_config->sysfs_metric_id.store = NULL;
2340
2341 oa_config->attrs[0] = &oa_config->sysfs_metric_id.attr;
2342 oa_config->attrs[1] = NULL;
2343
2344 oa_config->sysfs_metric.name = oa_config->uuid;
2345 oa_config->sysfs_metric.attrs = oa_config->attrs;
2346
2347 return sysfs_create_group(oa->metrics_kobj, &oa_config->sysfs_metric);
2348 }
2349
2350 /**
2351 * xe_oa_add_config_ioctl - Adds one OA config
2352 * @dev: @drm_device
2353 * @data: pointer to struct @drm_xe_oa_config
2354 * @file: @drm_file
2355 *
2356 * The functions adds an OA config to the set of OA configs maintained in
2357 * the kernel. The config determines which OA metrics are collected for an
2358 * OA stream.
2359 */
xe_oa_add_config_ioctl(struct drm_device * dev,u64 data,struct drm_file * file)2360 int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file)
2361 {
2362 struct xe_device *xe = to_xe_device(dev);
2363 struct xe_oa *oa = &xe->oa;
2364 struct drm_xe_oa_config param;
2365 struct drm_xe_oa_config *arg = ¶m;
2366 struct xe_oa_config *oa_config, *tmp;
2367 struct xe_oa_reg *regs;
2368 int err, id;
2369
2370 if (!oa->xe) {
2371 drm_dbg(&xe->drm, "xe oa interface not available for this system\n");
2372 return -ENODEV;
2373 }
2374
2375 err = xe_observation_paranoid_check();
2376 if (err) {
2377 drm_dbg(&oa->xe->drm, "Insufficient privileges to add xe OA config\n");
2378 return err;
2379 }
2380
2381 err = copy_from_user(¶m, u64_to_user_ptr(data), sizeof(param));
2382 if (XE_IOCTL_DBG(oa->xe, err))
2383 return -EFAULT;
2384
2385 if (XE_IOCTL_DBG(oa->xe, arg->extensions) ||
2386 XE_IOCTL_DBG(oa->xe, !arg->regs_ptr) ||
2387 XE_IOCTL_DBG(oa->xe, !arg->n_regs))
2388 return -EINVAL;
2389
2390 oa_config = kzalloc_obj(*oa_config);
2391 if (!oa_config)
2392 return -ENOMEM;
2393
2394 oa_config->oa = oa;
2395 kref_init(&oa_config->ref);
2396
2397 if (!uuid_is_valid(arg->uuid)) {
2398 drm_dbg(&oa->xe->drm, "Invalid uuid format for OA config\n");
2399 err = -EINVAL;
2400 goto reg_err;
2401 }
2402
2403 /* Last character in oa_config->uuid will be 0 because oa_config is kzalloc */
2404 memcpy(oa_config->uuid, arg->uuid, sizeof(arg->uuid));
2405
2406 oa_config->regs_len = arg->n_regs;
2407 regs = xe_oa_alloc_regs(oa, xe_oa_is_valid_config_reg,
2408 u64_to_user_ptr(arg->regs_ptr),
2409 arg->n_regs);
2410 if (IS_ERR(regs)) {
2411 drm_dbg(&oa->xe->drm, "Failed to create OA config for mux_regs\n");
2412 err = PTR_ERR(regs);
2413 goto reg_err;
2414 }
2415 oa_config->regs = regs;
2416
2417 err = mutex_lock_interruptible(&oa->metrics_lock);
2418 if (err)
2419 goto reg_err;
2420
2421 /* We shouldn't have too many configs, so this iteration shouldn't be too costly */
2422 idr_for_each_entry(&oa->metrics_idr, tmp, id) {
2423 if (!strcmp(tmp->uuid, oa_config->uuid)) {
2424 drm_dbg(&oa->xe->drm, "OA config already exists with this uuid\n");
2425 err = -EADDRINUSE;
2426 goto sysfs_err;
2427 }
2428 }
2429
2430 err = create_dynamic_oa_sysfs_entry(oa, oa_config);
2431 if (err) {
2432 drm_dbg(&oa->xe->drm, "Failed to create sysfs entry for OA config\n");
2433 goto sysfs_err;
2434 }
2435
2436 oa_config->id = idr_alloc(&oa->metrics_idr, oa_config, 1, 0, GFP_KERNEL);
2437 if (oa_config->id < 0) {
2438 drm_dbg(&oa->xe->drm, "Failed to create sysfs entry for OA config\n");
2439 err = oa_config->id;
2440 goto sysfs_err;
2441 }
2442
2443 id = oa_config->id;
2444
2445 drm_dbg(&oa->xe->drm, "Added config %s id=%i\n", oa_config->uuid, id);
2446
2447 mutex_unlock(&oa->metrics_lock);
2448
2449 return id;
2450
2451 sysfs_err:
2452 mutex_unlock(&oa->metrics_lock);
2453 reg_err:
2454 xe_oa_config_put(oa_config);
2455 drm_dbg(&oa->xe->drm, "Failed to add new OA config\n");
2456 return err;
2457 }
2458
2459 /**
2460 * xe_oa_remove_config_ioctl - Removes one OA config
2461 * @dev: @drm_device
2462 * @data: pointer to struct @drm_xe_observation_param
2463 * @file: @drm_file
2464 */
xe_oa_remove_config_ioctl(struct drm_device * dev,u64 data,struct drm_file * file)2465 int xe_oa_remove_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file)
2466 {
2467 struct xe_device *xe = to_xe_device(dev);
2468 struct xe_oa *oa = &xe->oa;
2469 struct xe_oa_config *oa_config;
2470 u64 arg, *ptr = u64_to_user_ptr(data);
2471 int ret;
2472
2473 if (!oa->xe) {
2474 drm_dbg(&xe->drm, "xe oa interface not available for this system\n");
2475 return -ENODEV;
2476 }
2477
2478 ret = xe_observation_paranoid_check();
2479 if (ret) {
2480 drm_dbg(&oa->xe->drm, "Insufficient privileges to remove xe OA config\n");
2481 return ret;
2482 }
2483
2484 ret = get_user(arg, ptr);
2485 if (XE_IOCTL_DBG(oa->xe, ret))
2486 return ret;
2487
2488 ret = mutex_lock_interruptible(&oa->metrics_lock);
2489 if (ret)
2490 return ret;
2491
2492 oa_config = idr_find(&oa->metrics_idr, arg);
2493 if (!oa_config) {
2494 drm_dbg(&oa->xe->drm, "Failed to remove unknown OA config\n");
2495 ret = -ENOENT;
2496 goto err_unlock;
2497 }
2498
2499 WARN_ON(arg != oa_config->id);
2500
2501 sysfs_remove_group(oa->metrics_kobj, &oa_config->sysfs_metric);
2502 idr_remove(&oa->metrics_idr, arg);
2503
2504 mutex_unlock(&oa->metrics_lock);
2505
2506 drm_dbg(&oa->xe->drm, "Removed config %s id=%i\n", oa_config->uuid, oa_config->id);
2507
2508 xe_oa_config_put(oa_config);
2509
2510 return 0;
2511
2512 err_unlock:
2513 mutex_unlock(&oa->metrics_lock);
2514 return ret;
2515 }
2516
xe_oa_unregister(void * arg)2517 static void xe_oa_unregister(void *arg)
2518 {
2519 struct xe_oa *oa = arg;
2520
2521 if (!oa->metrics_kobj)
2522 return;
2523
2524 kobject_put(oa->metrics_kobj);
2525 oa->metrics_kobj = NULL;
2526 }
2527
2528 /**
2529 * xe_oa_register - Xe OA registration
2530 * @xe: @xe_device
2531 *
2532 * Exposes the metrics sysfs directory upon completion of module initialization
2533 */
xe_oa_register(struct xe_device * xe)2534 int xe_oa_register(struct xe_device *xe)
2535 {
2536 struct xe_oa *oa = &xe->oa;
2537
2538 if (!oa->xe)
2539 return 0;
2540
2541 oa->metrics_kobj = kobject_create_and_add("metrics",
2542 &xe->drm.primary->kdev->kobj);
2543 if (!oa->metrics_kobj)
2544 return -ENOMEM;
2545
2546 return devm_add_action_or_reset(xe->drm.dev, xe_oa_unregister, oa);
2547 }
2548
num_oa_units_per_gt(struct xe_gt * gt)2549 static u32 num_oa_units_per_gt(struct xe_gt *gt)
2550 {
2551 if (xe_gt_is_main_type(gt) || GRAPHICS_VER(gt_to_xe(gt)) < 20)
2552 /*
2553 * Mert OA unit belongs to the SoC, not a gt, so should be accessed using
2554 * xe_root_tile_mmio(). However, for all known platforms this is the same as
2555 * accessing via xe_root_mmio_gt()->mmio.
2556 */
2557 return xe_device_has_mert(gt_to_xe(gt)) ? 2 : 1;
2558 else if (!IS_DGFX(gt_to_xe(gt)))
2559 return XE_OAM_UNIT_SCMI_0 + 1; /* SAG + SCMI_0 */
2560 else
2561 return XE_OAM_UNIT_SCMI_1 + 1; /* SAG + SCMI_0 + SCMI_1 */
2562 }
2563
__hwe_oam_unit(struct xe_hw_engine * hwe)2564 static u32 __hwe_oam_unit(struct xe_hw_engine *hwe)
2565 {
2566 if (GRAPHICS_VERx100(gt_to_xe(hwe->gt)) < 1270)
2567 return XE_OA_UNIT_INVALID;
2568
2569 xe_gt_WARN_ON(hwe->gt, xe_gt_is_main_type(hwe->gt));
2570
2571 if (GRAPHICS_VER(gt_to_xe(hwe->gt)) < 20)
2572 return 0;
2573 /*
2574 * XE_OAM_UNIT_SAG has only GSCCS attached to it, but only on some platforms. Also
2575 * GSCCS cannot be used to submit batches to program the OAM unit. Therefore we don't
2576 * assign an OA unit to GSCCS. This means that XE_OAM_UNIT_SAG is exposed as an OA
2577 * unit without attached engines. Fused off engines can also result in oa_unit's with
2578 * num_engines == 0. OA streams can be opened on all OA units.
2579 */
2580 else if (hwe->engine_id == XE_HW_ENGINE_GSCCS0)
2581 return XE_OA_UNIT_INVALID;
2582 else if (!IS_DGFX(gt_to_xe(hwe->gt)))
2583 return XE_OAM_UNIT_SCMI_0;
2584 else if (hwe->class == XE_ENGINE_CLASS_VIDEO_DECODE)
2585 return (hwe->instance / 2 & 0x1) + 1;
2586 else if (hwe->class == XE_ENGINE_CLASS_VIDEO_ENHANCE)
2587 return (hwe->instance & 0x1) + 1;
2588
2589 return XE_OA_UNIT_INVALID;
2590 }
2591
__hwe_oa_unit(struct xe_hw_engine * hwe)2592 static u32 __hwe_oa_unit(struct xe_hw_engine *hwe)
2593 {
2594 switch (hwe->class) {
2595 case XE_ENGINE_CLASS_RENDER:
2596 case XE_ENGINE_CLASS_COMPUTE:
2597 return 0;
2598
2599 case XE_ENGINE_CLASS_VIDEO_DECODE:
2600 case XE_ENGINE_CLASS_VIDEO_ENHANCE:
2601 case XE_ENGINE_CLASS_OTHER:
2602 return __hwe_oam_unit(hwe);
2603
2604 default:
2605 return XE_OA_UNIT_INVALID;
2606 }
2607 }
2608
__oam_regs(u32 base)2609 static struct xe_oa_regs __oam_regs(u32 base)
2610 {
2611 return (struct xe_oa_regs) {
2612 .base = base,
2613 .oa_head_ptr = OAM_HEAD_POINTER(base),
2614 .oa_tail_ptr = OAM_TAIL_POINTER(base),
2615 .oa_buffer = OAM_BUFFER(base),
2616 .oa_ctx_ctrl = OAM_CONTEXT_CONTROL(base),
2617 .oa_ctrl = OAM_CONTROL(base),
2618 .oa_debug = OAM_DEBUG(base),
2619 .oa_status = OAM_STATUS(base),
2620 .oa_mmio_trg = OAM_MMIO_TRG(base),
2621 .oa_ctrl_counter_select_mask = OAM_CONTROL_COUNTER_SEL_MASK,
2622 };
2623 }
2624
__oag_regs(void)2625 static struct xe_oa_regs __oag_regs(void)
2626 {
2627 return (struct xe_oa_regs) {
2628 .base = 0,
2629 .oa_head_ptr = OAG_OAHEADPTR,
2630 .oa_tail_ptr = OAG_OATAILPTR,
2631 .oa_buffer = OAG_OABUFFER,
2632 .oa_ctx_ctrl = OAG_OAGLBCTXCTRL,
2633 .oa_ctrl = OAG_OACONTROL,
2634 .oa_debug = OAG_OA_DEBUG,
2635 .oa_status = OAG_OASTATUS,
2636 .oa_mmio_trg = OAG_MMIOTRIGGER,
2637 .oa_ctrl_counter_select_mask = OAG_OACONTROL_OA_COUNTER_SEL_MASK,
2638 };
2639 }
2640
__oamert_regs(void)2641 static struct xe_oa_regs __oamert_regs(void)
2642 {
2643 return (struct xe_oa_regs) {
2644 .base = 0,
2645 .oa_head_ptr = OAMERT_HEAD_POINTER,
2646 .oa_tail_ptr = OAMERT_TAIL_POINTER,
2647 .oa_buffer = OAMERT_BUFFER,
2648 .oa_ctx_ctrl = OAMERT_CONTEXT_CONTROL,
2649 .oa_ctrl = OAMERT_CONTROL,
2650 .oa_debug = OAMERT_DEBUG,
2651 .oa_status = OAMERT_STATUS,
2652 .oa_mmio_trg = OAMERT_MMIO_TRG,
2653 .oa_ctrl_counter_select_mask = OAM_CONTROL_COUNTER_SEL_MASK,
2654 };
2655 }
2656
__xe_oa_init_oa_units(struct xe_gt * gt)2657 static void __xe_oa_init_oa_units(struct xe_gt *gt)
2658 {
2659 const u32 oam_base_addr[] = {
2660 [XE_OAM_UNIT_SAG] = XE_OAM_SAG_BASE,
2661 [XE_OAM_UNIT_SCMI_0] = XE_OAM_SCMI_0_BASE,
2662 [XE_OAM_UNIT_SCMI_1] = XE_OAM_SCMI_1_BASE,
2663 };
2664 int i, num_units = gt->oa.num_oa_units;
2665
2666 for (i = 0; i < num_units; i++) {
2667 struct xe_oa_unit *u = >->oa.oa_unit[i];
2668
2669 if (xe_gt_is_main_type(gt)) {
2670 if (!i) {
2671 u->regs = __oag_regs();
2672 u->type = DRM_XE_OA_UNIT_TYPE_OAG;
2673 } else {
2674 xe_gt_assert(gt, xe_device_has_mert(gt_to_xe(gt)));
2675 xe_gt_assert(gt, gt == xe_root_mmio_gt(gt_to_xe(gt)));
2676 u->regs = __oamert_regs();
2677 u->type = DRM_XE_OA_UNIT_TYPE_MERT;
2678 }
2679 } else {
2680 xe_gt_assert(gt, GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270);
2681 u->regs = __oam_regs(oam_base_addr[i]);
2682 u->type = i == XE_OAM_UNIT_SAG && GRAPHICS_VER(gt_to_xe(gt)) >= 20 ?
2683 DRM_XE_OA_UNIT_TYPE_OAM_SAG : DRM_XE_OA_UNIT_TYPE_OAM;
2684 }
2685
2686 u->gt = gt;
2687
2688 xe_mmio_write32(>->mmio, u->regs.oa_ctrl, 0);
2689
2690 /* Ensure MMIO trigger remains disabled till there is a stream */
2691 xe_mmio_write32(>->mmio, u->regs.oa_debug,
2692 oag_configure_mmio_trigger(NULL, false));
2693
2694 /* Set oa_unit_ids now to ensure ids remain contiguous */
2695 u->oa_unit_id = gt_to_xe(gt)->oa.oa_unit_ids++;
2696 }
2697 }
2698
xe_oa_init_gt(struct xe_gt * gt)2699 static int xe_oa_init_gt(struct xe_gt *gt)
2700 {
2701 u32 num_oa_units = num_oa_units_per_gt(gt);
2702 struct xe_hw_engine *hwe;
2703 enum xe_hw_engine_id id;
2704 struct xe_oa_unit *u;
2705
2706 u = drmm_kcalloc(>_to_xe(gt)->drm, num_oa_units, sizeof(*u), GFP_KERNEL);
2707 if (!u)
2708 return -ENOMEM;
2709
2710 for_each_hw_engine(hwe, gt, id) {
2711 u32 index = __hwe_oa_unit(hwe);
2712
2713 hwe->oa_unit = NULL;
2714 if (index < num_oa_units) {
2715 u[index].num_engines++;
2716 hwe->oa_unit = &u[index];
2717 }
2718 }
2719
2720 gt->oa.num_oa_units = num_oa_units;
2721 gt->oa.oa_unit = u;
2722
2723 __xe_oa_init_oa_units(gt);
2724
2725 return drmm_mutex_init(>_to_xe(gt)->drm, >->oa.gt_lock);
2726 }
2727
xe_oa_print_gt_oa_units(struct xe_gt * gt)2728 static void xe_oa_print_gt_oa_units(struct xe_gt *gt)
2729 {
2730 enum xe_hw_engine_id hwe_id;
2731 struct xe_hw_engine *hwe;
2732 struct xe_oa_unit *u;
2733 char buf[256];
2734 int i, n;
2735
2736 for (i = 0; i < gt->oa.num_oa_units; i++) {
2737 u = >->oa.oa_unit[i];
2738 buf[0] = '\0';
2739 n = 0;
2740
2741 for_each_hw_engine(hwe, gt, hwe_id)
2742 if (xe_oa_unit_id(hwe) == u->oa_unit_id)
2743 n += scnprintf(buf + n, sizeof(buf) - n, "%s ", hwe->name);
2744
2745 xe_gt_dbg(gt, "oa_unit %d, type %d, Engines: %s\n", u->oa_unit_id, u->type, buf);
2746 }
2747 }
2748
xe_oa_print_oa_units(struct xe_oa * oa)2749 static void xe_oa_print_oa_units(struct xe_oa *oa)
2750 {
2751 struct xe_gt *gt;
2752 int gt_id;
2753
2754 for_each_gt(gt, oa->xe, gt_id)
2755 xe_oa_print_gt_oa_units(gt);
2756 }
2757
xe_oa_init_oa_units(struct xe_oa * oa)2758 static int xe_oa_init_oa_units(struct xe_oa *oa)
2759 {
2760 struct xe_gt *gt;
2761 int i, ret;
2762
2763 /* Needed for OAM implementation here */
2764 BUILD_BUG_ON(XE_OAM_UNIT_SAG != 0);
2765 BUILD_BUG_ON(XE_OAM_UNIT_SCMI_0 != 1);
2766 BUILD_BUG_ON(XE_OAM_UNIT_SCMI_1 != 2);
2767
2768 for_each_gt(gt, oa->xe, i) {
2769 ret = xe_oa_init_gt(gt);
2770 if (ret)
2771 return ret;
2772 }
2773
2774 xe_oa_print_oa_units(oa);
2775
2776 return 0;
2777 }
2778
oa_format_add(struct xe_oa * oa,enum xe_oa_format_name format)2779 static void oa_format_add(struct xe_oa *oa, enum xe_oa_format_name format)
2780 {
2781 __set_bit(format, oa->format_mask);
2782 }
2783
xe_oa_init_supported_formats(struct xe_oa * oa)2784 static void xe_oa_init_supported_formats(struct xe_oa *oa)
2785 {
2786 if (GRAPHICS_VER(oa->xe) >= 20) {
2787 /* Xe2+ */
2788 oa_format_add(oa, XE_OAM_FORMAT_MPEC8u64_B8_C8);
2789 oa_format_add(oa, XE_OAM_FORMAT_MPEC8u32_B8_C8);
2790 oa_format_add(oa, XE_OA_FORMAT_PEC64u64);
2791 oa_format_add(oa, XE_OA_FORMAT_PEC64u64_B8_C8);
2792 oa_format_add(oa, XE_OA_FORMAT_PEC64u32);
2793 oa_format_add(oa, XE_OA_FORMAT_PEC32u64_G1);
2794 oa_format_add(oa, XE_OA_FORMAT_PEC32u32_G1);
2795 oa_format_add(oa, XE_OA_FORMAT_PEC32u64_G2);
2796 oa_format_add(oa, XE_OA_FORMAT_PEC32u32_G2);
2797 oa_format_add(oa, XE_OA_FORMAT_PEC36u64_G1_32_G2_4);
2798 oa_format_add(oa, XE_OA_FORMAT_PEC36u64_G1_4_G2_32);
2799 } else if (GRAPHICS_VERx100(oa->xe) >= 1270) {
2800 /* XE_METEORLAKE */
2801 oa_format_add(oa, XE_OAR_FORMAT_A32u40_A4u32_B8_C8);
2802 oa_format_add(oa, XE_OA_FORMAT_A24u40_A14u32_B8_C8);
2803 oa_format_add(oa, XE_OAC_FORMAT_A24u64_B8_C8);
2804 oa_format_add(oa, XE_OAC_FORMAT_A22u32_R2u32_B8_C8);
2805 oa_format_add(oa, XE_OAM_FORMAT_MPEC8u64_B8_C8);
2806 oa_format_add(oa, XE_OAM_FORMAT_MPEC8u32_B8_C8);
2807 } else if (GRAPHICS_VERx100(oa->xe) >= 1255) {
2808 /* XE_DG2, XE_PVC */
2809 oa_format_add(oa, XE_OAR_FORMAT_A32u40_A4u32_B8_C8);
2810 oa_format_add(oa, XE_OA_FORMAT_A24u40_A14u32_B8_C8);
2811 oa_format_add(oa, XE_OAC_FORMAT_A24u64_B8_C8);
2812 oa_format_add(oa, XE_OAC_FORMAT_A22u32_R2u32_B8_C8);
2813 } else {
2814 /* Gen12+ */
2815 xe_assert(oa->xe, GRAPHICS_VER(oa->xe) >= 12);
2816 oa_format_add(oa, XE_OA_FORMAT_A12);
2817 oa_format_add(oa, XE_OA_FORMAT_A12_B8_C8);
2818 oa_format_add(oa, XE_OA_FORMAT_A32u40_A4u32_B8_C8);
2819 oa_format_add(oa, XE_OA_FORMAT_C4_B8);
2820 }
2821 }
2822
destroy_config(int id,void * p,void * data)2823 static int destroy_config(int id, void *p, void *data)
2824 {
2825 xe_oa_config_put(p);
2826
2827 return 0;
2828 }
2829
xe_oa_fini(void * arg)2830 static void xe_oa_fini(void *arg)
2831 {
2832 struct xe_device *xe = arg;
2833 struct xe_oa *oa = &xe->oa;
2834
2835 if (!oa->xe)
2836 return;
2837
2838 idr_for_each(&oa->metrics_idr, destroy_config, oa);
2839 idr_destroy(&oa->metrics_idr);
2840
2841 oa->xe = NULL;
2842 }
2843
2844 /**
2845 * xe_oa_init - OA initialization during device probe
2846 * @xe: @xe_device
2847 *
2848 * Return: 0 on success or a negative error code on failure
2849 */
xe_oa_init(struct xe_device * xe)2850 int xe_oa_init(struct xe_device *xe)
2851 {
2852 struct xe_oa *oa = &xe->oa;
2853 int ret;
2854
2855 /* Support OA only with GuC submission and Gen12+ */
2856 if (!xe_device_uc_enabled(xe) || GRAPHICS_VER(xe) < 12)
2857 return 0;
2858
2859 if (IS_SRIOV_VF(xe))
2860 return 0;
2861
2862 oa->xe = xe;
2863 oa->oa_formats = oa_formats;
2864
2865 ret = drmm_mutex_init(&oa->xe->drm, &oa->metrics_lock);
2866 if (ret)
2867 goto exit;
2868
2869 idr_init_base(&oa->metrics_idr, 1);
2870
2871 ret = xe_oa_init_oa_units(oa);
2872 if (ret) {
2873 drm_err(&xe->drm, "OA initialization failed (%pe)\n", ERR_PTR(ret));
2874 goto exit;
2875 }
2876
2877 xe_oa_init_supported_formats(oa);
2878
2879 return devm_add_action_or_reset(xe->drm.dev, xe_oa_fini, xe);
2880
2881 exit:
2882 oa->xe = NULL;
2883 return ret;
2884 }
2885