This source file includes following definitions.
- free_oa_config
- put_oa_config
- get_oa_config
- gen8_oa_hw_tail_read
- gen7_oa_hw_tail_read
- oa_buffer_check_unlocked
- append_oa_status
- append_oa_sample
- gen8_append_oa_reports
- gen8_oa_read
- gen7_append_oa_reports
- gen7_oa_read
- i915_oa_wait_unlocked
- i915_oa_poll_wait
- i915_oa_read
- oa_pin_context
- oa_get_render_ctx_id
- oa_put_render_ctx_id
- free_oa_buffer
- i915_oa_stream_destroy
- gen7_init_oa_buffer
- gen8_init_oa_buffer
- alloc_oa_buffer
- config_oa_regs
- delay_after_mux
- hsw_enable_metric_set
- hsw_disable_metric_set
- oa_config_flex_reg
- gen8_update_reg_state_unlocked
- gen8_store_flex
- gen8_load_flex
- gen8_modify_context
- gen8_modify_self
- gen8_configure_context
- gen8_configure_all_contexts
- gen8_enable_metric_set
- gen8_disable_metric_set
- gen10_disable_metric_set
- gen7_oa_enable
- gen8_oa_enable
- i915_oa_stream_enable
- gen7_oa_disable
- gen8_oa_disable
- i915_oa_stream_disable
- i915_oa_stream_init
- i915_oa_init_reg_state
- i915_perf_read_locked
- i915_perf_read
- oa_poll_check_timer_cb
- i915_perf_poll_locked
- i915_perf_poll
- i915_perf_enable_locked
- i915_perf_disable_locked
- i915_perf_ioctl_locked
- i915_perf_ioctl
- i915_perf_destroy_locked
- i915_perf_release
- i915_perf_open_ioctl_locked
- oa_exponent_to_ns
- read_properties_unlocked
- i915_perf_open_ioctl
- i915_perf_register
- i915_perf_unregister
- gen8_is_valid_flex_addr
- gen7_is_valid_b_counter_addr
- gen7_is_valid_mux_addr
- gen8_is_valid_mux_addr
- gen10_is_valid_mux_addr
- hsw_is_valid_mux_addr
- chv_is_valid_mux_addr
- mask_reg_value
- alloc_oa_regs
- show_dynamic_id
- create_dynamic_oa_sysfs_entry
- i915_perf_add_config_ioctl
- i915_perf_remove_config_ioctl
- i915_perf_init
- destroy_config
- i915_perf_fini
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194 #include <linux/anon_inodes.h>
195 #include <linux/sizes.h>
196 #include <linux/uuid.h>
197
198 #include "gem/i915_gem_context.h"
199 #include "gem/i915_gem_pm.h"
200 #include "gt/intel_lrc_reg.h"
201
202 #include "i915_drv.h"
203 #include "i915_perf.h"
204 #include "oa/i915_oa_hsw.h"
205 #include "oa/i915_oa_bdw.h"
206 #include "oa/i915_oa_chv.h"
207 #include "oa/i915_oa_sklgt2.h"
208 #include "oa/i915_oa_sklgt3.h"
209 #include "oa/i915_oa_sklgt4.h"
210 #include "oa/i915_oa_bxt.h"
211 #include "oa/i915_oa_kblgt2.h"
212 #include "oa/i915_oa_kblgt3.h"
213 #include "oa/i915_oa_glk.h"
214 #include "oa/i915_oa_cflgt2.h"
215 #include "oa/i915_oa_cflgt3.h"
216 #include "oa/i915_oa_cnl.h"
217 #include "oa/i915_oa_icl.h"
218
219
220
221
222
223 #define OA_BUFFER_SIZE SZ_16M
224
225 #define OA_TAKEN(tail, head) ((tail - head) & (OA_BUFFER_SIZE - 1))
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268 #define OA_TAIL_MARGIN_NSEC 100000ULL
269 #define INVALID_TAIL_PTR 0xffffffff
270
271
272
273
274 #define POLL_FREQUENCY 200
275 #define POLL_PERIOD (NSEC_PER_SEC / POLL_FREQUENCY)
276
277
278 static u32 i915_perf_stream_paranoid = true;
279
280
281
282
283
284
285
286
287
288 #define OA_EXPONENT_MAX 31
289
290 #define INVALID_CTX_ID 0xffffffff
291
292
293 #define OAREPORT_REASON_MASK 0x3f
294 #define OAREPORT_REASON_SHIFT 19
295 #define OAREPORT_REASON_TIMER (1<<0)
296 #define OAREPORT_REASON_CTX_SWITCH (1<<3)
297 #define OAREPORT_REASON_CLK_RATIO (1<<5)
298
299
300
301
302
303
304
305
306
307 static int oa_sample_rate_hard_limit;
308
309
310
311
312
313
314
315 static u32 i915_oa_max_sample_rate = 100000;
316
317
318
319
320
321 static const struct i915_oa_format hsw_oa_formats[I915_OA_FORMAT_MAX] = {
322 [I915_OA_FORMAT_A13] = { 0, 64 },
323 [I915_OA_FORMAT_A29] = { 1, 128 },
324 [I915_OA_FORMAT_A13_B8_C8] = { 2, 128 },
325
326 [I915_OA_FORMAT_B4_C8] = { 4, 64 },
327 [I915_OA_FORMAT_A45_B8_C8] = { 5, 256 },
328 [I915_OA_FORMAT_B4_C8_A16] = { 6, 128 },
329 [I915_OA_FORMAT_C4_B8] = { 7, 64 },
330 };
331
332 static const struct i915_oa_format gen8_plus_oa_formats[I915_OA_FORMAT_MAX] = {
333 [I915_OA_FORMAT_A12] = { 0, 64 },
334 [I915_OA_FORMAT_A12_B8_C8] = { 2, 128 },
335 [I915_OA_FORMAT_A32u40_A4u32_B8_C8] = { 5, 256 },
336 [I915_OA_FORMAT_C4_B8] = { 7, 64 },
337 };
338
339 #define SAMPLE_OA_REPORT (1<<0)
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355 struct perf_open_properties {
356 u32 sample_flags;
357
358 u64 single_context:1;
359 u64 ctx_handle;
360
361
362 int metrics_set;
363 int oa_format;
364 bool oa_periodic;
365 int oa_period_exponent;
366 };
367
368 static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer);
369
370 static void free_oa_config(struct drm_i915_private *dev_priv,
371 struct i915_oa_config *oa_config)
372 {
373 if (!PTR_ERR(oa_config->flex_regs))
374 kfree(oa_config->flex_regs);
375 if (!PTR_ERR(oa_config->b_counter_regs))
376 kfree(oa_config->b_counter_regs);
377 if (!PTR_ERR(oa_config->mux_regs))
378 kfree(oa_config->mux_regs);
379 kfree(oa_config);
380 }
381
382 static void put_oa_config(struct drm_i915_private *dev_priv,
383 struct i915_oa_config *oa_config)
384 {
385 if (!atomic_dec_and_test(&oa_config->ref_count))
386 return;
387
388 free_oa_config(dev_priv, oa_config);
389 }
390
391 static int get_oa_config(struct drm_i915_private *dev_priv,
392 int metrics_set,
393 struct i915_oa_config **out_config)
394 {
395 int ret;
396
397 if (metrics_set == 1) {
398 *out_config = &dev_priv->perf.test_config;
399 atomic_inc(&dev_priv->perf.test_config.ref_count);
400 return 0;
401 }
402
403 ret = mutex_lock_interruptible(&dev_priv->perf.metrics_lock);
404 if (ret)
405 return ret;
406
407 *out_config = idr_find(&dev_priv->perf.metrics_idr, metrics_set);
408 if (!*out_config)
409 ret = -EINVAL;
410 else
411 atomic_inc(&(*out_config)->ref_count);
412
413 mutex_unlock(&dev_priv->perf.metrics_lock);
414
415 return ret;
416 }
417
418 static u32 gen8_oa_hw_tail_read(struct i915_perf_stream *stream)
419 {
420 struct drm_i915_private *dev_priv = stream->dev_priv;
421
422 return I915_READ(GEN8_OATAILPTR) & GEN8_OATAILPTR_MASK;
423 }
424
425 static u32 gen7_oa_hw_tail_read(struct i915_perf_stream *stream)
426 {
427 struct drm_i915_private *dev_priv = stream->dev_priv;
428 u32 oastatus1 = I915_READ(GEN7_OASTATUS1);
429
430 return oastatus1 & GEN7_OASTATUS1_TAIL_MASK;
431 }
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457 static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
458 {
459 struct drm_i915_private *dev_priv = stream->dev_priv;
460 int report_size = stream->oa_buffer.format_size;
461 unsigned long flags;
462 unsigned int aged_idx;
463 u32 head, hw_tail, aged_tail, aging_tail;
464 u64 now;
465
466
467
468
469
470 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
471
472
473
474
475
476 head = stream->oa_buffer.head;
477
478 aged_idx = stream->oa_buffer.aged_tail_idx;
479 aged_tail = stream->oa_buffer.tails[aged_idx].offset;
480 aging_tail = stream->oa_buffer.tails[!aged_idx].offset;
481
482 hw_tail = dev_priv->perf.ops.oa_hw_tail_read(stream);
483
484
485
486
487 hw_tail &= ~(report_size - 1);
488
489 now = ktime_get_mono_fast_ns();
490
491
492
493
494
495
496
497
498
499
500
501 if (aging_tail != INVALID_TAIL_PTR &&
502 ((now - stream->oa_buffer.aging_timestamp) >
503 OA_TAIL_MARGIN_NSEC)) {
504
505 aged_idx ^= 1;
506 stream->oa_buffer.aged_tail_idx = aged_idx;
507
508 aged_tail = aging_tail;
509
510
511 stream->oa_buffer.tails[!aged_idx].offset = INVALID_TAIL_PTR;
512 aging_tail = INVALID_TAIL_PTR;
513 }
514
515
516
517
518
519
520
521
522
523 if (aging_tail == INVALID_TAIL_PTR &&
524 (aged_tail == INVALID_TAIL_PTR ||
525 OA_TAKEN(hw_tail, aged_tail) >= report_size)) {
526 struct i915_vma *vma = stream->oa_buffer.vma;
527 u32 gtt_offset = i915_ggtt_offset(vma);
528
529
530
531
532
533 if (hw_tail >= gtt_offset &&
534 hw_tail < (gtt_offset + OA_BUFFER_SIZE)) {
535 stream->oa_buffer.tails[!aged_idx].offset =
536 aging_tail = hw_tail;
537 stream->oa_buffer.aging_timestamp = now;
538 } else {
539 DRM_ERROR("Ignoring spurious out of range OA buffer tail pointer = %u\n",
540 hw_tail);
541 }
542 }
543
544 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
545
546 return aged_tail == INVALID_TAIL_PTR ?
547 false : OA_TAKEN(aged_tail, head) >= report_size;
548 }
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565 static int append_oa_status(struct i915_perf_stream *stream,
566 char __user *buf,
567 size_t count,
568 size_t *offset,
569 enum drm_i915_perf_record_type type)
570 {
571 struct drm_i915_perf_record_header header = { type, 0, sizeof(header) };
572
573 if ((count - *offset) < header.size)
574 return -ENOSPC;
575
576 if (copy_to_user(buf + *offset, &header, sizeof(header)))
577 return -EFAULT;
578
579 (*offset) += header.size;
580
581 return 0;
582 }
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601 static int append_oa_sample(struct i915_perf_stream *stream,
602 char __user *buf,
603 size_t count,
604 size_t *offset,
605 const u8 *report)
606 {
607 int report_size = stream->oa_buffer.format_size;
608 struct drm_i915_perf_record_header header;
609 u32 sample_flags = stream->sample_flags;
610
611 header.type = DRM_I915_PERF_RECORD_SAMPLE;
612 header.pad = 0;
613 header.size = stream->sample_size;
614
615 if ((count - *offset) < header.size)
616 return -ENOSPC;
617
618 buf += *offset;
619 if (copy_to_user(buf, &header, sizeof(header)))
620 return -EFAULT;
621 buf += sizeof(header);
622
623 if (sample_flags & SAMPLE_OA_REPORT) {
624 if (copy_to_user(buf, report, report_size))
625 return -EFAULT;
626 }
627
628 (*offset) += header.size;
629
630 return 0;
631 }
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653 static int gen8_append_oa_reports(struct i915_perf_stream *stream,
654 char __user *buf,
655 size_t count,
656 size_t *offset)
657 {
658 struct drm_i915_private *dev_priv = stream->dev_priv;
659 int report_size = stream->oa_buffer.format_size;
660 u8 *oa_buf_base = stream->oa_buffer.vaddr;
661 u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
662 u32 mask = (OA_BUFFER_SIZE - 1);
663 size_t start_offset = *offset;
664 unsigned long flags;
665 unsigned int aged_tail_idx;
666 u32 head, tail;
667 u32 taken;
668 int ret = 0;
669
670 if (WARN_ON(!stream->enabled))
671 return -EIO;
672
673 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
674
675 head = stream->oa_buffer.head;
676 aged_tail_idx = stream->oa_buffer.aged_tail_idx;
677 tail = stream->oa_buffer.tails[aged_tail_idx].offset;
678
679 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
680
681
682
683
684
685 if (tail == INVALID_TAIL_PTR)
686 return -EAGAIN;
687
688
689
690
691
692 head -= gtt_offset;
693 tail -= gtt_offset;
694
695
696
697
698
699
700
701
702 if (WARN_ONCE(head > OA_BUFFER_SIZE || head % report_size ||
703 tail > OA_BUFFER_SIZE || tail % report_size,
704 "Inconsistent OA buffer pointers: head = %u, tail = %u\n",
705 head, tail))
706 return -EIO;
707
708
709 for (;
710 (taken = OA_TAKEN(tail, head));
711 head = (head + report_size) & mask) {
712 u8 *report = oa_buf_base + head;
713 u32 *report32 = (void *)report;
714 u32 ctx_id;
715 u32 reason;
716
717
718
719
720
721
722
723
724
725
726 if (WARN_ON((OA_BUFFER_SIZE - head) < report_size)) {
727 DRM_ERROR("Spurious OA head ptr: non-integral report offset\n");
728 break;
729 }
730
731
732
733
734
735
736
737
738
739
740 reason = ((report32[0] >> OAREPORT_REASON_SHIFT) &
741 OAREPORT_REASON_MASK);
742 if (reason == 0) {
743 if (__ratelimit(&dev_priv->perf.spurious_report_rs))
744 DRM_NOTE("Skipping spurious, invalid OA report\n");
745 continue;
746 }
747
748 ctx_id = report32[2] & stream->specific_ctx_id_mask;
749
750
751
752
753
754
755
756
757
758 if (!(report32[0] & dev_priv->perf.gen8_valid_ctx_bit))
759 ctx_id = report32[2] = INVALID_CTX_ID;
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792 if (!dev_priv->perf.exclusive_stream->ctx ||
793 stream->specific_ctx_id == ctx_id ||
794 stream->oa_buffer.last_ctx_id == stream->specific_ctx_id ||
795 reason & OAREPORT_REASON_CTX_SWITCH) {
796
797
798
799
800
801 if (dev_priv->perf.exclusive_stream->ctx &&
802 stream->specific_ctx_id != ctx_id) {
803 report32[2] = INVALID_CTX_ID;
804 }
805
806 ret = append_oa_sample(stream, buf, count, offset,
807 report);
808 if (ret)
809 break;
810
811 stream->oa_buffer.last_ctx_id = ctx_id;
812 }
813
814
815
816
817
818
819
820
821 report32[0] = 0;
822 }
823
824 if (start_offset != *offset) {
825 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
826
827
828
829
830
831 head += gtt_offset;
832
833 I915_WRITE(GEN8_OAHEADPTR, head & GEN8_OAHEADPTR_MASK);
834 stream->oa_buffer.head = head;
835
836 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
837 }
838
839 return ret;
840 }
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862 static int gen8_oa_read(struct i915_perf_stream *stream,
863 char __user *buf,
864 size_t count,
865 size_t *offset)
866 {
867 struct drm_i915_private *dev_priv = stream->dev_priv;
868 u32 oastatus;
869 int ret;
870
871 if (WARN_ON(!stream->oa_buffer.vaddr))
872 return -EIO;
873
874 oastatus = I915_READ(GEN8_OASTATUS);
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890 if (oastatus & GEN8_OASTATUS_OABUFFER_OVERFLOW) {
891 ret = append_oa_status(stream, buf, count, offset,
892 DRM_I915_PERF_RECORD_OA_BUFFER_LOST);
893 if (ret)
894 return ret;
895
896 DRM_DEBUG("OA buffer overflow (exponent = %d): force restart\n",
897 stream->period_exponent);
898
899 dev_priv->perf.ops.oa_disable(stream);
900 dev_priv->perf.ops.oa_enable(stream);
901
902
903
904
905
906 oastatus = I915_READ(GEN8_OASTATUS);
907 }
908
909 if (oastatus & GEN8_OASTATUS_REPORT_LOST) {
910 ret = append_oa_status(stream, buf, count, offset,
911 DRM_I915_PERF_RECORD_OA_REPORT_LOST);
912 if (ret)
913 return ret;
914 I915_WRITE(GEN8_OASTATUS,
915 oastatus & ~GEN8_OASTATUS_REPORT_LOST);
916 }
917
918 return gen8_append_oa_reports(stream, buf, count, offset);
919 }
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941 static int gen7_append_oa_reports(struct i915_perf_stream *stream,
942 char __user *buf,
943 size_t count,
944 size_t *offset)
945 {
946 struct drm_i915_private *dev_priv = stream->dev_priv;
947 int report_size = stream->oa_buffer.format_size;
948 u8 *oa_buf_base = stream->oa_buffer.vaddr;
949 u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
950 u32 mask = (OA_BUFFER_SIZE - 1);
951 size_t start_offset = *offset;
952 unsigned long flags;
953 unsigned int aged_tail_idx;
954 u32 head, tail;
955 u32 taken;
956 int ret = 0;
957
958 if (WARN_ON(!stream->enabled))
959 return -EIO;
960
961 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
962
963 head = stream->oa_buffer.head;
964 aged_tail_idx = stream->oa_buffer.aged_tail_idx;
965 tail = stream->oa_buffer.tails[aged_tail_idx].offset;
966
967 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
968
969
970
971
972 if (tail == INVALID_TAIL_PTR)
973 return -EAGAIN;
974
975
976
977
978 head -= gtt_offset;
979 tail -= gtt_offset;
980
981
982
983
984
985
986
987 if (WARN_ONCE(head > OA_BUFFER_SIZE || head % report_size ||
988 tail > OA_BUFFER_SIZE || tail % report_size,
989 "Inconsistent OA buffer pointers: head = %u, tail = %u\n",
990 head, tail))
991 return -EIO;
992
993
994 for (;
995 (taken = OA_TAKEN(tail, head));
996 head = (head + report_size) & mask) {
997 u8 *report = oa_buf_base + head;
998 u32 *report32 = (void *)report;
999
1000
1001
1002
1003
1004
1005
1006
1007
1008 if (WARN_ON((OA_BUFFER_SIZE - head) < report_size)) {
1009 DRM_ERROR("Spurious OA head ptr: non-integral report offset\n");
1010 break;
1011 }
1012
1013
1014
1015
1016
1017
1018
1019 if (report32[0] == 0) {
1020 if (__ratelimit(&dev_priv->perf.spurious_report_rs))
1021 DRM_NOTE("Skipping spurious, invalid OA report\n");
1022 continue;
1023 }
1024
1025 ret = append_oa_sample(stream, buf, count, offset, report);
1026 if (ret)
1027 break;
1028
1029
1030
1031
1032
1033
1034
1035 report32[0] = 0;
1036 }
1037
1038 if (start_offset != *offset) {
1039 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
1040
1041
1042
1043
1044 head += gtt_offset;
1045
1046 I915_WRITE(GEN7_OASTATUS2,
1047 ((head & GEN7_OASTATUS2_HEAD_MASK) |
1048 GEN7_OASTATUS2_MEM_SELECT_GGTT));
1049 stream->oa_buffer.head = head;
1050
1051 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
1052 }
1053
1054 return ret;
1055 }
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073 static int gen7_oa_read(struct i915_perf_stream *stream,
1074 char __user *buf,
1075 size_t count,
1076 size_t *offset)
1077 {
1078 struct drm_i915_private *dev_priv = stream->dev_priv;
1079 u32 oastatus1;
1080 int ret;
1081
1082 if (WARN_ON(!stream->oa_buffer.vaddr))
1083 return -EIO;
1084
1085 oastatus1 = I915_READ(GEN7_OASTATUS1);
1086
1087
1088
1089
1090
1091
1092 oastatus1 &= ~dev_priv->perf.gen7_latched_oastatus1;
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114 if (unlikely(oastatus1 & GEN7_OASTATUS1_OABUFFER_OVERFLOW)) {
1115 ret = append_oa_status(stream, buf, count, offset,
1116 DRM_I915_PERF_RECORD_OA_BUFFER_LOST);
1117 if (ret)
1118 return ret;
1119
1120 DRM_DEBUG("OA buffer overflow (exponent = %d): force restart\n",
1121 stream->period_exponent);
1122
1123 dev_priv->perf.ops.oa_disable(stream);
1124 dev_priv->perf.ops.oa_enable(stream);
1125
1126 oastatus1 = I915_READ(GEN7_OASTATUS1);
1127 }
1128
1129 if (unlikely(oastatus1 & GEN7_OASTATUS1_REPORT_LOST)) {
1130 ret = append_oa_status(stream, buf, count, offset,
1131 DRM_I915_PERF_RECORD_OA_REPORT_LOST);
1132 if (ret)
1133 return ret;
1134 dev_priv->perf.gen7_latched_oastatus1 |=
1135 GEN7_OASTATUS1_REPORT_LOST;
1136 }
1137
1138 return gen7_append_oa_reports(stream, buf, count, offset);
1139 }
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 static int i915_oa_wait_unlocked(struct i915_perf_stream *stream)
1156 {
1157
1158 if (!stream->periodic)
1159 return -EIO;
1160
1161 return wait_event_interruptible(stream->poll_wq,
1162 oa_buffer_check_unlocked(stream));
1163 }
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175 static void i915_oa_poll_wait(struct i915_perf_stream *stream,
1176 struct file *file,
1177 poll_table *wait)
1178 {
1179 poll_wait(file, &stream->poll_wq, wait);
1180 }
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194 static int i915_oa_read(struct i915_perf_stream *stream,
1195 char __user *buf,
1196 size_t count,
1197 size_t *offset)
1198 {
1199 struct drm_i915_private *dev_priv = stream->dev_priv;
1200
1201 return dev_priv->perf.ops.read(stream, buf, count, offset);
1202 }
1203
1204 static struct intel_context *oa_pin_context(struct i915_perf_stream *stream)
1205 {
1206 struct i915_gem_engines_iter it;
1207 struct drm_i915_private *i915 = stream->dev_priv;
1208 struct i915_gem_context *ctx = stream->ctx;
1209 struct intel_context *ce;
1210 int err;
1211
1212 err = i915_mutex_lock_interruptible(&i915->drm);
1213 if (err)
1214 return ERR_PTR(err);
1215
1216 for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
1217 if (ce->engine->class != RENDER_CLASS)
1218 continue;
1219
1220
1221
1222
1223
1224 err = intel_context_pin(ce);
1225 if (err == 0) {
1226 stream->pinned_ctx = ce;
1227 break;
1228 }
1229 }
1230 i915_gem_context_unlock_engines(ctx);
1231
1232 mutex_unlock(&i915->drm.struct_mutex);
1233 if (err)
1234 return ERR_PTR(err);
1235
1236 return stream->pinned_ctx;
1237 }
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249 static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
1250 {
1251 struct drm_i915_private *i915 = stream->dev_priv;
1252 struct intel_context *ce;
1253
1254 ce = oa_pin_context(stream);
1255 if (IS_ERR(ce))
1256 return PTR_ERR(ce);
1257
1258 switch (INTEL_GEN(i915)) {
1259 case 7: {
1260
1261
1262
1263
1264 stream->specific_ctx_id = i915_ggtt_offset(ce->state);
1265 stream->specific_ctx_id_mask = 0;
1266 break;
1267 }
1268
1269 case 8:
1270 case 9:
1271 case 10:
1272 if (USES_GUC_SUBMISSION(i915)) {
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283 stream->specific_ctx_id =
1284 lower_32_bits(ce->lrc_desc) >> 12;
1285
1286
1287
1288
1289
1290 stream->specific_ctx_id_mask =
1291 (1U << (GEN8_CTX_ID_WIDTH - 1)) - 1;
1292 } else {
1293 stream->specific_ctx_id_mask =
1294 (1U << GEN8_CTX_ID_WIDTH) - 1;
1295 stream->specific_ctx_id =
1296 upper_32_bits(ce->lrc_desc);
1297 stream->specific_ctx_id &=
1298 stream->specific_ctx_id_mask;
1299 }
1300 break;
1301
1302 case 11: {
1303 stream->specific_ctx_id_mask =
1304 ((1U << GEN11_SW_CTX_ID_WIDTH) - 1) << (GEN11_SW_CTX_ID_SHIFT - 32) |
1305 ((1U << GEN11_ENGINE_INSTANCE_WIDTH) - 1) << (GEN11_ENGINE_INSTANCE_SHIFT - 32) |
1306 ((1 << GEN11_ENGINE_CLASS_WIDTH) - 1) << (GEN11_ENGINE_CLASS_SHIFT - 32);
1307 stream->specific_ctx_id = upper_32_bits(ce->lrc_desc);
1308 stream->specific_ctx_id &=
1309 stream->specific_ctx_id_mask;
1310 break;
1311 }
1312
1313 default:
1314 MISSING_CASE(INTEL_GEN(i915));
1315 }
1316
1317 DRM_DEBUG_DRIVER("filtering on ctx_id=0x%x ctx_id_mask=0x%x\n",
1318 stream->specific_ctx_id,
1319 stream->specific_ctx_id_mask);
1320
1321 return 0;
1322 }
1323
1324
1325
1326
1327
1328
1329
1330
1331 static void oa_put_render_ctx_id(struct i915_perf_stream *stream)
1332 {
1333 struct drm_i915_private *dev_priv = stream->dev_priv;
1334 struct intel_context *ce;
1335
1336 stream->specific_ctx_id = INVALID_CTX_ID;
1337 stream->specific_ctx_id_mask = 0;
1338
1339 ce = fetch_and_zero(&stream->pinned_ctx);
1340 if (ce) {
1341 mutex_lock(&dev_priv->drm.struct_mutex);
1342 intel_context_unpin(ce);
1343 mutex_unlock(&dev_priv->drm.struct_mutex);
1344 }
1345 }
1346
1347 static void
1348 free_oa_buffer(struct i915_perf_stream *stream)
1349 {
1350 struct drm_i915_private *i915 = stream->dev_priv;
1351
1352 mutex_lock(&i915->drm.struct_mutex);
1353
1354 i915_vma_unpin_and_release(&stream->oa_buffer.vma,
1355 I915_VMA_RELEASE_MAP);
1356
1357 mutex_unlock(&i915->drm.struct_mutex);
1358
1359 stream->oa_buffer.vaddr = NULL;
1360 }
1361
1362 static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
1363 {
1364 struct drm_i915_private *dev_priv = stream->dev_priv;
1365
1366 BUG_ON(stream != dev_priv->perf.exclusive_stream);
1367
1368
1369
1370
1371
1372 mutex_lock(&dev_priv->drm.struct_mutex);
1373 dev_priv->perf.exclusive_stream = NULL;
1374 dev_priv->perf.ops.disable_metric_set(stream);
1375 mutex_unlock(&dev_priv->drm.struct_mutex);
1376
1377 free_oa_buffer(stream);
1378
1379 intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
1380 intel_runtime_pm_put(&dev_priv->runtime_pm, stream->wakeref);
1381
1382 if (stream->ctx)
1383 oa_put_render_ctx_id(stream);
1384
1385 put_oa_config(dev_priv, stream->oa_config);
1386
1387 if (dev_priv->perf.spurious_report_rs.missed) {
1388 DRM_NOTE("%d spurious OA report notices suppressed due to ratelimiting\n",
1389 dev_priv->perf.spurious_report_rs.missed);
1390 }
1391 }
1392
1393 static void gen7_init_oa_buffer(struct i915_perf_stream *stream)
1394 {
1395 struct drm_i915_private *dev_priv = stream->dev_priv;
1396 u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
1397 unsigned long flags;
1398
1399 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
1400
1401
1402
1403
1404 I915_WRITE(GEN7_OASTATUS2,
1405 gtt_offset | GEN7_OASTATUS2_MEM_SELECT_GGTT);
1406 stream->oa_buffer.head = gtt_offset;
1407
1408 I915_WRITE(GEN7_OABUFFER, gtt_offset);
1409
1410 I915_WRITE(GEN7_OASTATUS1, gtt_offset | OABUFFER_SIZE_16M);
1411
1412
1413 stream->oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
1414 stream->oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
1415
1416 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
1417
1418
1419
1420
1421
1422 dev_priv->perf.gen7_latched_oastatus1 = 0;
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 memset(stream->oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
1436
1437
1438
1439
1440 stream->pollin = false;
1441 }
1442
1443 static void gen8_init_oa_buffer(struct i915_perf_stream *stream)
1444 {
1445 struct drm_i915_private *dev_priv = stream->dev_priv;
1446 u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
1447 unsigned long flags;
1448
1449 spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
1450
1451 I915_WRITE(GEN8_OASTATUS, 0);
1452 I915_WRITE(GEN8_OAHEADPTR, gtt_offset);
1453 stream->oa_buffer.head = gtt_offset;
1454
1455 I915_WRITE(GEN8_OABUFFER_UDW, 0);
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465 I915_WRITE(GEN8_OABUFFER, gtt_offset |
1466 OABUFFER_SIZE_16M | GEN8_OABUFFER_MEM_SELECT_GGTT);
1467 I915_WRITE(GEN8_OATAILPTR, gtt_offset & GEN8_OATAILPTR_MASK);
1468
1469
1470 stream->oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
1471 stream->oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
1472
1473
1474
1475
1476
1477
1478 stream->oa_buffer.last_ctx_id = INVALID_CTX_ID;
1479
1480 spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494 memset(stream->oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
1495
1496
1497
1498
1499
1500 stream->pollin = false;
1501 }
1502
1503 static int alloc_oa_buffer(struct i915_perf_stream *stream)
1504 {
1505 struct drm_i915_gem_object *bo;
1506 struct drm_i915_private *dev_priv = stream->dev_priv;
1507 struct i915_vma *vma;
1508 int ret;
1509
1510 if (WARN_ON(stream->oa_buffer.vma))
1511 return -ENODEV;
1512
1513 ret = i915_mutex_lock_interruptible(&dev_priv->drm);
1514 if (ret)
1515 return ret;
1516
1517 BUILD_BUG_ON_NOT_POWER_OF_2(OA_BUFFER_SIZE);
1518 BUILD_BUG_ON(OA_BUFFER_SIZE < SZ_128K || OA_BUFFER_SIZE > SZ_16M);
1519
1520 bo = i915_gem_object_create_shmem(dev_priv, OA_BUFFER_SIZE);
1521 if (IS_ERR(bo)) {
1522 DRM_ERROR("Failed to allocate OA buffer\n");
1523 ret = PTR_ERR(bo);
1524 goto unlock;
1525 }
1526
1527 i915_gem_object_set_cache_coherency(bo, I915_CACHE_LLC);
1528
1529
1530 vma = i915_gem_object_ggtt_pin(bo, NULL, 0, SZ_16M, 0);
1531 if (IS_ERR(vma)) {
1532 ret = PTR_ERR(vma);
1533 goto err_unref;
1534 }
1535 stream->oa_buffer.vma = vma;
1536
1537 stream->oa_buffer.vaddr =
1538 i915_gem_object_pin_map(bo, I915_MAP_WB);
1539 if (IS_ERR(stream->oa_buffer.vaddr)) {
1540 ret = PTR_ERR(stream->oa_buffer.vaddr);
1541 goto err_unpin;
1542 }
1543
1544 DRM_DEBUG_DRIVER("OA Buffer initialized, gtt offset = 0x%x, vaddr = %p\n",
1545 i915_ggtt_offset(stream->oa_buffer.vma),
1546 stream->oa_buffer.vaddr);
1547
1548 goto unlock;
1549
1550 err_unpin:
1551 __i915_vma_unpin(vma);
1552
1553 err_unref:
1554 i915_gem_object_put(bo);
1555
1556 stream->oa_buffer.vaddr = NULL;
1557 stream->oa_buffer.vma = NULL;
1558
1559 unlock:
1560 mutex_unlock(&dev_priv->drm.struct_mutex);
1561 return ret;
1562 }
1563
1564 static void config_oa_regs(struct drm_i915_private *dev_priv,
1565 const struct i915_oa_reg *regs,
1566 u32 n_regs)
1567 {
1568 u32 i;
1569
1570 for (i = 0; i < n_regs; i++) {
1571 const struct i915_oa_reg *reg = regs + i;
1572
1573 I915_WRITE(reg->addr, reg->value);
1574 }
1575 }
1576
1577 static void delay_after_mux(void)
1578 {
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601 usleep_range(15000, 20000);
1602 }
1603
1604 static int hsw_enable_metric_set(struct i915_perf_stream *stream)
1605 {
1606 struct drm_i915_private *dev_priv = stream->dev_priv;
1607 const struct i915_oa_config *oa_config = stream->oa_config;
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619 I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
1620 ~GEN7_DOP_CLOCK_GATE_ENABLE));
1621 I915_WRITE(GEN6_UCGCTL1, (I915_READ(GEN6_UCGCTL1) |
1622 GEN6_CSUNIT_CLOCK_GATE_DISABLE));
1623
1624 config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
1625 delay_after_mux();
1626
1627 config_oa_regs(dev_priv, oa_config->b_counter_regs,
1628 oa_config->b_counter_regs_len);
1629
1630 return 0;
1631 }
1632
1633 static void hsw_disable_metric_set(struct i915_perf_stream *stream)
1634 {
1635 struct drm_i915_private *dev_priv = stream->dev_priv;
1636
1637 I915_WRITE(GEN6_UCGCTL1, (I915_READ(GEN6_UCGCTL1) &
1638 ~GEN6_CSUNIT_CLOCK_GATE_DISABLE));
1639 I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) |
1640 GEN7_DOP_CLOCK_GATE_ENABLE));
1641
1642 I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) &
1643 ~GT_NOA_ENABLE));
1644 }
1645
1646 static u32 oa_config_flex_reg(const struct i915_oa_config *oa_config,
1647 i915_reg_t reg)
1648 {
1649 u32 mmio = i915_mmio_reg_offset(reg);
1650 int i;
1651
1652
1653
1654
1655
1656
1657 if (!oa_config)
1658 return 0;
1659
1660 for (i = 0; i < oa_config->flex_regs_len; i++) {
1661 if (i915_mmio_reg_offset(oa_config->flex_regs[i].addr) == mmio)
1662 return oa_config->flex_regs[i].value;
1663 }
1664
1665 return 0;
1666 }
1667
1668
1669
1670
1671
1672
1673
1674 static void
1675 gen8_update_reg_state_unlocked(struct i915_perf_stream *stream,
1676 struct intel_context *ce,
1677 u32 *reg_state,
1678 const struct i915_oa_config *oa_config)
1679 {
1680 struct drm_i915_private *i915 = ce->engine->i915;
1681 u32 ctx_oactxctrl = i915->perf.ctx_oactxctrl_offset;
1682 u32 ctx_flexeu0 = i915->perf.ctx_flexeu0_offset;
1683
1684 i915_reg_t flex_regs[] = {
1685 EU_PERF_CNTL0,
1686 EU_PERF_CNTL1,
1687 EU_PERF_CNTL2,
1688 EU_PERF_CNTL3,
1689 EU_PERF_CNTL4,
1690 EU_PERF_CNTL5,
1691 EU_PERF_CNTL6,
1692 };
1693 int i;
1694
1695 CTX_REG(reg_state, ctx_oactxctrl, GEN8_OACTXCONTROL,
1696 (stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
1697 (stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
1698 GEN8_OA_COUNTER_RESUME);
1699
1700 for (i = 0; i < ARRAY_SIZE(flex_regs); i++) {
1701 CTX_REG(reg_state, ctx_flexeu0 + i * 2, flex_regs[i],
1702 oa_config_flex_reg(oa_config, flex_regs[i]));
1703 }
1704
1705 CTX_REG(reg_state,
1706 CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE,
1707 intel_sseu_make_rpcs(i915, &ce->sseu));
1708 }
1709
1710 struct flex {
1711 i915_reg_t reg;
1712 u32 offset;
1713 u32 value;
1714 };
1715
1716 static int
1717 gen8_store_flex(struct i915_request *rq,
1718 struct intel_context *ce,
1719 const struct flex *flex, unsigned int count)
1720 {
1721 u32 offset;
1722 u32 *cs;
1723
1724 cs = intel_ring_begin(rq, 4 * count);
1725 if (IS_ERR(cs))
1726 return PTR_ERR(cs);
1727
1728 offset = i915_ggtt_offset(ce->state) + LRC_STATE_PN * PAGE_SIZE;
1729 do {
1730 *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
1731 *cs++ = offset + (flex->offset + 1) * sizeof(u32);
1732 *cs++ = 0;
1733 *cs++ = flex->value;
1734 } while (flex++, --count);
1735
1736 intel_ring_advance(rq, cs);
1737
1738 return 0;
1739 }
1740
1741 static int
1742 gen8_load_flex(struct i915_request *rq,
1743 struct intel_context *ce,
1744 const struct flex *flex, unsigned int count)
1745 {
1746 u32 *cs;
1747
1748 GEM_BUG_ON(!count || count > 63);
1749
1750 cs = intel_ring_begin(rq, 2 * count + 2);
1751 if (IS_ERR(cs))
1752 return PTR_ERR(cs);
1753
1754 *cs++ = MI_LOAD_REGISTER_IMM(count);
1755 do {
1756 *cs++ = i915_mmio_reg_offset(flex->reg);
1757 *cs++ = flex->value;
1758 } while (flex++, --count);
1759 *cs++ = MI_NOOP;
1760
1761 intel_ring_advance(rq, cs);
1762
1763 return 0;
1764 }
1765
1766 static int gen8_modify_context(struct intel_context *ce,
1767 const struct flex *flex, unsigned int count)
1768 {
1769 struct i915_request *rq;
1770 int err;
1771
1772 lockdep_assert_held(&ce->pin_mutex);
1773
1774 rq = i915_request_create(ce->engine->kernel_context);
1775 if (IS_ERR(rq))
1776 return PTR_ERR(rq);
1777
1778
1779 err = intel_context_prepare_remote_request(ce, rq);
1780 if (err == 0)
1781 err = gen8_store_flex(rq, ce, flex, count);
1782
1783 i915_request_add(rq);
1784 return err;
1785 }
1786
1787 static int gen8_modify_self(struct intel_context *ce,
1788 const struct flex *flex, unsigned int count)
1789 {
1790 struct i915_request *rq;
1791 int err;
1792
1793 rq = i915_request_create(ce);
1794 if (IS_ERR(rq))
1795 return PTR_ERR(rq);
1796
1797 err = gen8_load_flex(rq, ce, flex, count);
1798
1799 i915_request_add(rq);
1800 return err;
1801 }
1802
1803 static int gen8_configure_context(struct i915_gem_context *ctx,
1804 struct flex *flex, unsigned int count)
1805 {
1806 struct i915_gem_engines_iter it;
1807 struct intel_context *ce;
1808 int err = 0;
1809
1810 for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
1811 GEM_BUG_ON(ce == ce->engine->kernel_context);
1812
1813 if (ce->engine->class != RENDER_CLASS)
1814 continue;
1815
1816 err = intel_context_lock_pinned(ce);
1817 if (err)
1818 break;
1819
1820 flex->value = intel_sseu_make_rpcs(ctx->i915, &ce->sseu);
1821
1822
1823 if (intel_context_is_pinned(ce))
1824 err = gen8_modify_context(ce, flex, count);
1825
1826 intel_context_unlock_pinned(ce);
1827 if (err)
1828 break;
1829 }
1830 i915_gem_context_unlock_engines(ctx);
1831
1832 return err;
1833 }
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859 static int gen8_configure_all_contexts(struct i915_perf_stream *stream,
1860 const struct i915_oa_config *oa_config)
1861 {
1862 struct drm_i915_private *i915 = stream->dev_priv;
1863
1864 const u32 ctx_flexeu0 = i915->perf.ctx_flexeu0_offset;
1865 #define ctx_flexeuN(N) (ctx_flexeu0 + 2 * (N))
1866 struct flex regs[] = {
1867 {
1868 GEN8_R_PWR_CLK_STATE,
1869 CTX_R_PWR_CLK_STATE,
1870 },
1871 {
1872 GEN8_OACTXCONTROL,
1873 i915->perf.ctx_oactxctrl_offset,
1874 ((stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
1875 (stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
1876 GEN8_OA_COUNTER_RESUME)
1877 },
1878 { EU_PERF_CNTL0, ctx_flexeuN(0) },
1879 { EU_PERF_CNTL1, ctx_flexeuN(1) },
1880 { EU_PERF_CNTL2, ctx_flexeuN(2) },
1881 { EU_PERF_CNTL3, ctx_flexeuN(3) },
1882 { EU_PERF_CNTL4, ctx_flexeuN(4) },
1883 { EU_PERF_CNTL5, ctx_flexeuN(5) },
1884 { EU_PERF_CNTL6, ctx_flexeuN(6) },
1885 };
1886 #undef ctx_flexeuN
1887 struct intel_engine_cs *engine;
1888 struct i915_gem_context *ctx;
1889 int i;
1890
1891 for (i = 2; i < ARRAY_SIZE(regs); i++)
1892 regs[i].value = oa_config_flex_reg(oa_config, regs[i].reg);
1893
1894 lockdep_assert_held(&i915->drm.struct_mutex);
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912 list_for_each_entry(ctx, &i915->contexts.list, link) {
1913 int err;
1914
1915 if (ctx == i915->kernel_context)
1916 continue;
1917
1918 err = gen8_configure_context(ctx, regs, ARRAY_SIZE(regs));
1919 if (err)
1920 return err;
1921 }
1922
1923
1924
1925
1926
1927
1928 for_each_uabi_engine(engine, i915) {
1929 struct intel_context *ce = engine->kernel_context;
1930 int err;
1931
1932 if (engine->class != RENDER_CLASS)
1933 continue;
1934
1935 regs[0].value = intel_sseu_make_rpcs(i915, &ce->sseu);
1936
1937 err = gen8_modify_self(ce, regs, ARRAY_SIZE(regs));
1938 if (err)
1939 return err;
1940 }
1941
1942 return 0;
1943 }
1944
1945 static int gen8_enable_metric_set(struct i915_perf_stream *stream)
1946 {
1947 struct drm_i915_private *dev_priv = stream->dev_priv;
1948 const struct i915_oa_config *oa_config = stream->oa_config;
1949 int ret;
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974 if (IS_GEN_RANGE(dev_priv, 9, 11)) {
1975 I915_WRITE(GEN8_OA_DEBUG,
1976 _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
1977 GEN9_OA_DEBUG_INCLUDE_CLK_RATIO));
1978 }
1979
1980
1981
1982
1983
1984
1985 ret = gen8_configure_all_contexts(stream, oa_config);
1986 if (ret)
1987 return ret;
1988
1989 config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
1990 delay_after_mux();
1991
1992 config_oa_regs(dev_priv, oa_config->b_counter_regs,
1993 oa_config->b_counter_regs_len);
1994
1995 return 0;
1996 }
1997
1998 static void gen8_disable_metric_set(struct i915_perf_stream *stream)
1999 {
2000 struct drm_i915_private *dev_priv = stream->dev_priv;
2001
2002
2003 gen8_configure_all_contexts(stream, NULL);
2004
2005 I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) &
2006 ~GT_NOA_ENABLE));
2007 }
2008
2009 static void gen10_disable_metric_set(struct i915_perf_stream *stream)
2010 {
2011 struct drm_i915_private *dev_priv = stream->dev_priv;
2012
2013
2014 gen8_configure_all_contexts(stream, NULL);
2015
2016
2017 I915_WRITE(RPM_CONFIG1,
2018 I915_READ(RPM_CONFIG1) & ~GEN10_GT_NOA_ENABLE);
2019 }
2020
2021 static void gen7_oa_enable(struct i915_perf_stream *stream)
2022 {
2023 struct drm_i915_private *dev_priv = stream->dev_priv;
2024 struct i915_gem_context *ctx = stream->ctx;
2025 u32 ctx_id = stream->specific_ctx_id;
2026 bool periodic = stream->periodic;
2027 u32 period_exponent = stream->period_exponent;
2028 u32 report_format = stream->oa_buffer.format;
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039 gen7_init_oa_buffer(stream);
2040
2041 I915_WRITE(GEN7_OACONTROL,
2042 (ctx_id & GEN7_OACONTROL_CTX_MASK) |
2043 (period_exponent <<
2044 GEN7_OACONTROL_TIMER_PERIOD_SHIFT) |
2045 (periodic ? GEN7_OACONTROL_TIMER_ENABLE : 0) |
2046 (report_format << GEN7_OACONTROL_FORMAT_SHIFT) |
2047 (ctx ? GEN7_OACONTROL_PER_CTX_ENABLE : 0) |
2048 GEN7_OACONTROL_ENABLE);
2049 }
2050
2051 static void gen8_oa_enable(struct i915_perf_stream *stream)
2052 {
2053 struct drm_i915_private *dev_priv = stream->dev_priv;
2054 u32 report_format = stream->oa_buffer.format;
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065 gen8_init_oa_buffer(stream);
2066
2067
2068
2069
2070
2071
2072 I915_WRITE(GEN8_OACONTROL, (report_format <<
2073 GEN8_OA_REPORT_FORMAT_SHIFT) |
2074 GEN8_OA_COUNTER_ENABLE);
2075 }
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086 static void i915_oa_stream_enable(struct i915_perf_stream *stream)
2087 {
2088 struct drm_i915_private *dev_priv = stream->dev_priv;
2089
2090 dev_priv->perf.ops.oa_enable(stream);
2091
2092 if (stream->periodic)
2093 hrtimer_start(&stream->poll_check_timer,
2094 ns_to_ktime(POLL_PERIOD),
2095 HRTIMER_MODE_REL_PINNED);
2096 }
2097
2098 static void gen7_oa_disable(struct i915_perf_stream *stream)
2099 {
2100 struct intel_uncore *uncore = &stream->dev_priv->uncore;
2101
2102 intel_uncore_write(uncore, GEN7_OACONTROL, 0);
2103 if (intel_wait_for_register(uncore,
2104 GEN7_OACONTROL, GEN7_OACONTROL_ENABLE, 0,
2105 50))
2106 DRM_ERROR("wait for OA to be disabled timed out\n");
2107 }
2108
2109 static void gen8_oa_disable(struct i915_perf_stream *stream)
2110 {
2111 struct intel_uncore *uncore = &stream->dev_priv->uncore;
2112
2113 intel_uncore_write(uncore, GEN8_OACONTROL, 0);
2114 if (intel_wait_for_register(uncore,
2115 GEN8_OACONTROL, GEN8_OA_COUNTER_ENABLE, 0,
2116 50))
2117 DRM_ERROR("wait for OA to be disabled timed out\n");
2118 }
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128 static void i915_oa_stream_disable(struct i915_perf_stream *stream)
2129 {
2130 struct drm_i915_private *dev_priv = stream->dev_priv;
2131
2132 dev_priv->perf.ops.oa_disable(stream);
2133
2134 if (stream->periodic)
2135 hrtimer_cancel(&stream->poll_check_timer);
2136 }
2137
2138 static const struct i915_perf_stream_ops i915_oa_stream_ops = {
2139 .destroy = i915_oa_stream_destroy,
2140 .enable = i915_oa_stream_enable,
2141 .disable = i915_oa_stream_disable,
2142 .wait_unlocked = i915_oa_wait_unlocked,
2143 .poll_wait = i915_oa_poll_wait,
2144 .read = i915_oa_read,
2145 };
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165 static int i915_oa_stream_init(struct i915_perf_stream *stream,
2166 struct drm_i915_perf_open_param *param,
2167 struct perf_open_properties *props)
2168 {
2169 struct drm_i915_private *dev_priv = stream->dev_priv;
2170 int format_size;
2171 int ret;
2172
2173
2174
2175
2176
2177 if (!dev_priv->perf.metrics_kobj) {
2178 DRM_DEBUG("OA metrics weren't advertised via sysfs\n");
2179 return -EINVAL;
2180 }
2181
2182 if (!(props->sample_flags & SAMPLE_OA_REPORT)) {
2183 DRM_DEBUG("Only OA report sampling supported\n");
2184 return -EINVAL;
2185 }
2186
2187 if (!dev_priv->perf.ops.enable_metric_set) {
2188 DRM_DEBUG("OA unit not supported\n");
2189 return -ENODEV;
2190 }
2191
2192
2193
2194
2195
2196 if (dev_priv->perf.exclusive_stream) {
2197 DRM_DEBUG("OA unit already in use\n");
2198 return -EBUSY;
2199 }
2200
2201 if (!props->oa_format) {
2202 DRM_DEBUG("OA report format not specified\n");
2203 return -EINVAL;
2204 }
2205
2206 stream->sample_size = sizeof(struct drm_i915_perf_record_header);
2207
2208 format_size = dev_priv->perf.oa_formats[props->oa_format].size;
2209
2210 stream->sample_flags |= SAMPLE_OA_REPORT;
2211 stream->sample_size += format_size;
2212
2213 stream->oa_buffer.format_size = format_size;
2214 if (WARN_ON(stream->oa_buffer.format_size == 0))
2215 return -EINVAL;
2216
2217 stream->oa_buffer.format =
2218 dev_priv->perf.oa_formats[props->oa_format].format;
2219
2220 stream->periodic = props->oa_periodic;
2221 if (stream->periodic)
2222 stream->period_exponent = props->oa_period_exponent;
2223
2224 if (stream->ctx) {
2225 ret = oa_get_render_ctx_id(stream);
2226 if (ret) {
2227 DRM_DEBUG("Invalid context id to filter with\n");
2228 return ret;
2229 }
2230 }
2231
2232 ret = get_oa_config(dev_priv, props->metrics_set, &stream->oa_config);
2233 if (ret) {
2234 DRM_DEBUG("Invalid OA config id=%i\n", props->metrics_set);
2235 goto err_config;
2236 }
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250 stream->wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
2251 intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
2252
2253 ret = alloc_oa_buffer(stream);
2254 if (ret)
2255 goto err_oa_buf_alloc;
2256
2257 ret = i915_mutex_lock_interruptible(&dev_priv->drm);
2258 if (ret)
2259 goto err_lock;
2260
2261 stream->ops = &i915_oa_stream_ops;
2262 dev_priv->perf.exclusive_stream = stream;
2263
2264 ret = dev_priv->perf.ops.enable_metric_set(stream);
2265 if (ret) {
2266 DRM_DEBUG("Unable to enable metric set\n");
2267 goto err_enable;
2268 }
2269
2270 mutex_unlock(&dev_priv->drm.struct_mutex);
2271
2272 hrtimer_init(&stream->poll_check_timer,
2273 CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2274 stream->poll_check_timer.function = oa_poll_check_timer_cb;
2275 init_waitqueue_head(&stream->poll_wq);
2276 spin_lock_init(&stream->oa_buffer.ptr_lock);
2277
2278 return 0;
2279
2280 err_enable:
2281 dev_priv->perf.exclusive_stream = NULL;
2282 dev_priv->perf.ops.disable_metric_set(stream);
2283 mutex_unlock(&dev_priv->drm.struct_mutex);
2284
2285 err_lock:
2286 free_oa_buffer(stream);
2287
2288 err_oa_buf_alloc:
2289 put_oa_config(dev_priv, stream->oa_config);
2290
2291 intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
2292 intel_runtime_pm_put(&dev_priv->runtime_pm, stream->wakeref);
2293
2294 err_config:
2295 if (stream->ctx)
2296 oa_put_render_ctx_id(stream);
2297
2298 return ret;
2299 }
2300
2301 void i915_oa_init_reg_state(struct intel_engine_cs *engine,
2302 struct intel_context *ce,
2303 u32 *regs)
2304 {
2305 struct i915_perf_stream *stream;
2306
2307 if (engine->class != RENDER_CLASS)
2308 return;
2309
2310 stream = engine->i915->perf.exclusive_stream;
2311 if (stream)
2312 gen8_update_reg_state_unlocked(stream, ce, regs, stream->oa_config);
2313 }
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340 static ssize_t i915_perf_read_locked(struct i915_perf_stream *stream,
2341 struct file *file,
2342 char __user *buf,
2343 size_t count,
2344 loff_t *ppos)
2345 {
2346
2347
2348
2349
2350
2351
2352 size_t offset = 0;
2353 int ret = stream->ops->read(stream, buf, count, &offset);
2354
2355 return offset ?: (ret ?: -EAGAIN);
2356 }
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376 static ssize_t i915_perf_read(struct file *file,
2377 char __user *buf,
2378 size_t count,
2379 loff_t *ppos)
2380 {
2381 struct i915_perf_stream *stream = file->private_data;
2382 struct drm_i915_private *dev_priv = stream->dev_priv;
2383 ssize_t ret;
2384
2385
2386
2387
2388
2389 if (!stream->enabled)
2390 return -EIO;
2391
2392 if (!(file->f_flags & O_NONBLOCK)) {
2393
2394
2395
2396
2397
2398
2399
2400 do {
2401 ret = stream->ops->wait_unlocked(stream);
2402 if (ret)
2403 return ret;
2404
2405 mutex_lock(&dev_priv->perf.lock);
2406 ret = i915_perf_read_locked(stream, file,
2407 buf, count, ppos);
2408 mutex_unlock(&dev_priv->perf.lock);
2409 } while (ret == -EAGAIN);
2410 } else {
2411 mutex_lock(&dev_priv->perf.lock);
2412 ret = i915_perf_read_locked(stream, file, buf, count, ppos);
2413 mutex_unlock(&dev_priv->perf.lock);
2414 }
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424 if (ret >= 0 || ret == -EAGAIN) {
2425
2426
2427
2428 stream->pollin = false;
2429 }
2430
2431 return ret;
2432 }
2433
2434 static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer)
2435 {
2436 struct i915_perf_stream *stream =
2437 container_of(hrtimer, typeof(*stream), poll_check_timer);
2438
2439 if (oa_buffer_check_unlocked(stream)) {
2440 stream->pollin = true;
2441 wake_up(&stream->poll_wq);
2442 }
2443
2444 hrtimer_forward_now(hrtimer, ns_to_ktime(POLL_PERIOD));
2445
2446 return HRTIMER_RESTART;
2447 }
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465 static __poll_t i915_perf_poll_locked(struct drm_i915_private *dev_priv,
2466 struct i915_perf_stream *stream,
2467 struct file *file,
2468 poll_table *wait)
2469 {
2470 __poll_t events = 0;
2471
2472 stream->ops->poll_wait(stream, file, wait);
2473
2474
2475
2476
2477
2478
2479
2480 if (stream->pollin)
2481 events |= EPOLLIN;
2482
2483 return events;
2484 }
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499 static __poll_t i915_perf_poll(struct file *file, poll_table *wait)
2500 {
2501 struct i915_perf_stream *stream = file->private_data;
2502 struct drm_i915_private *dev_priv = stream->dev_priv;
2503 __poll_t ret;
2504
2505 mutex_lock(&dev_priv->perf.lock);
2506 ret = i915_perf_poll_locked(dev_priv, stream, file, wait);
2507 mutex_unlock(&dev_priv->perf.lock);
2508
2509 return ret;
2510 }
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522 static void i915_perf_enable_locked(struct i915_perf_stream *stream)
2523 {
2524 if (stream->enabled)
2525 return;
2526
2527
2528 stream->enabled = true;
2529
2530 if (stream->ops->enable)
2531 stream->ops->enable(stream);
2532 }
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548 static void i915_perf_disable_locked(struct i915_perf_stream *stream)
2549 {
2550 if (!stream->enabled)
2551 return;
2552
2553
2554 stream->enabled = false;
2555
2556 if (stream->ops->disable)
2557 stream->ops->disable(stream);
2558 }
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572 static long i915_perf_ioctl_locked(struct i915_perf_stream *stream,
2573 unsigned int cmd,
2574 unsigned long arg)
2575 {
2576 switch (cmd) {
2577 case I915_PERF_IOCTL_ENABLE:
2578 i915_perf_enable_locked(stream);
2579 return 0;
2580 case I915_PERF_IOCTL_DISABLE:
2581 i915_perf_disable_locked(stream);
2582 return 0;
2583 }
2584
2585 return -EINVAL;
2586 }
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599 static long i915_perf_ioctl(struct file *file,
2600 unsigned int cmd,
2601 unsigned long arg)
2602 {
2603 struct i915_perf_stream *stream = file->private_data;
2604 struct drm_i915_private *dev_priv = stream->dev_priv;
2605 long ret;
2606
2607 mutex_lock(&dev_priv->perf.lock);
2608 ret = i915_perf_ioctl_locked(stream, cmd, arg);
2609 mutex_unlock(&dev_priv->perf.lock);
2610
2611 return ret;
2612 }
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624 static void i915_perf_destroy_locked(struct i915_perf_stream *stream)
2625 {
2626 if (stream->enabled)
2627 i915_perf_disable_locked(stream);
2628
2629 if (stream->ops->destroy)
2630 stream->ops->destroy(stream);
2631
2632 list_del(&stream->link);
2633
2634 if (stream->ctx)
2635 i915_gem_context_put(stream->ctx);
2636
2637 kfree(stream);
2638 }
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651 static int i915_perf_release(struct inode *inode, struct file *file)
2652 {
2653 struct i915_perf_stream *stream = file->private_data;
2654 struct drm_i915_private *dev_priv = stream->dev_priv;
2655
2656 mutex_lock(&dev_priv->perf.lock);
2657 i915_perf_destroy_locked(stream);
2658 mutex_unlock(&dev_priv->perf.lock);
2659
2660
2661 drm_dev_put(&dev_priv->drm);
2662
2663 return 0;
2664 }
2665
2666
2667 static const struct file_operations fops = {
2668 .owner = THIS_MODULE,
2669 .llseek = no_llseek,
2670 .release = i915_perf_release,
2671 .poll = i915_perf_poll,
2672 .read = i915_perf_read,
2673 .unlocked_ioctl = i915_perf_ioctl,
2674
2675
2676
2677 .compat_ioctl = i915_perf_ioctl,
2678 };
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705 static int
2706 i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv,
2707 struct drm_i915_perf_open_param *param,
2708 struct perf_open_properties *props,
2709 struct drm_file *file)
2710 {
2711 struct i915_gem_context *specific_ctx = NULL;
2712 struct i915_perf_stream *stream = NULL;
2713 unsigned long f_flags = 0;
2714 bool privileged_op = true;
2715 int stream_fd;
2716 int ret;
2717
2718 if (props->single_context) {
2719 u32 ctx_handle = props->ctx_handle;
2720 struct drm_i915_file_private *file_priv = file->driver_priv;
2721
2722 specific_ctx = i915_gem_context_lookup(file_priv, ctx_handle);
2723 if (!specific_ctx) {
2724 DRM_DEBUG("Failed to look up context with ID %u for opening perf stream\n",
2725 ctx_handle);
2726 ret = -ENOENT;
2727 goto err;
2728 }
2729 }
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745 if (IS_HASWELL(dev_priv) && specific_ctx)
2746 privileged_op = false;
2747
2748
2749
2750
2751
2752
2753 if (privileged_op &&
2754 i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) {
2755 DRM_DEBUG("Insufficient privileges to open system-wide i915 perf stream\n");
2756 ret = -EACCES;
2757 goto err_ctx;
2758 }
2759
2760 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
2761 if (!stream) {
2762 ret = -ENOMEM;
2763 goto err_ctx;
2764 }
2765
2766 stream->dev_priv = dev_priv;
2767 stream->ctx = specific_ctx;
2768
2769 ret = i915_oa_stream_init(stream, param, props);
2770 if (ret)
2771 goto err_alloc;
2772
2773
2774
2775
2776
2777 if (WARN_ON(stream->sample_flags != props->sample_flags)) {
2778 ret = -ENODEV;
2779 goto err_flags;
2780 }
2781
2782 list_add(&stream->link, &dev_priv->perf.streams);
2783
2784 if (param->flags & I915_PERF_FLAG_FD_CLOEXEC)
2785 f_flags |= O_CLOEXEC;
2786 if (param->flags & I915_PERF_FLAG_FD_NONBLOCK)
2787 f_flags |= O_NONBLOCK;
2788
2789 stream_fd = anon_inode_getfd("[i915_perf]", &fops, stream, f_flags);
2790 if (stream_fd < 0) {
2791 ret = stream_fd;
2792 goto err_open;
2793 }
2794
2795 if (!(param->flags & I915_PERF_FLAG_DISABLED))
2796 i915_perf_enable_locked(stream);
2797
2798
2799
2800
2801 drm_dev_get(&dev_priv->drm);
2802
2803 return stream_fd;
2804
2805 err_open:
2806 list_del(&stream->link);
2807 err_flags:
2808 if (stream->ops->destroy)
2809 stream->ops->destroy(stream);
2810 err_alloc:
2811 kfree(stream);
2812 err_ctx:
2813 if (specific_ctx)
2814 i915_gem_context_put(specific_ctx);
2815 err:
2816 return ret;
2817 }
2818
2819 static u64 oa_exponent_to_ns(struct drm_i915_private *dev_priv, int exponent)
2820 {
2821 return div64_u64(1000000000ULL * (2ULL << exponent),
2822 1000ULL * RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz);
2823 }
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840 static int read_properties_unlocked(struct drm_i915_private *dev_priv,
2841 u64 __user *uprops,
2842 u32 n_props,
2843 struct perf_open_properties *props)
2844 {
2845 u64 __user *uprop = uprops;
2846 u32 i;
2847
2848 memset(props, 0, sizeof(struct perf_open_properties));
2849
2850 if (!n_props) {
2851 DRM_DEBUG("No i915 perf properties given\n");
2852 return -EINVAL;
2853 }
2854
2855
2856
2857
2858
2859
2860
2861 if (n_props >= DRM_I915_PERF_PROP_MAX) {
2862 DRM_DEBUG("More i915 perf properties specified than exist\n");
2863 return -EINVAL;
2864 }
2865
2866 for (i = 0; i < n_props; i++) {
2867 u64 oa_period, oa_freq_hz;
2868 u64 id, value;
2869 int ret;
2870
2871 ret = get_user(id, uprop);
2872 if (ret)
2873 return ret;
2874
2875 ret = get_user(value, uprop + 1);
2876 if (ret)
2877 return ret;
2878
2879 if (id == 0 || id >= DRM_I915_PERF_PROP_MAX) {
2880 DRM_DEBUG("Unknown i915 perf property ID\n");
2881 return -EINVAL;
2882 }
2883
2884 switch ((enum drm_i915_perf_property_id)id) {
2885 case DRM_I915_PERF_PROP_CTX_HANDLE:
2886 props->single_context = 1;
2887 props->ctx_handle = value;
2888 break;
2889 case DRM_I915_PERF_PROP_SAMPLE_OA:
2890 if (value)
2891 props->sample_flags |= SAMPLE_OA_REPORT;
2892 break;
2893 case DRM_I915_PERF_PROP_OA_METRICS_SET:
2894 if (value == 0) {
2895 DRM_DEBUG("Unknown OA metric set ID\n");
2896 return -EINVAL;
2897 }
2898 props->metrics_set = value;
2899 break;
2900 case DRM_I915_PERF_PROP_OA_FORMAT:
2901 if (value == 0 || value >= I915_OA_FORMAT_MAX) {
2902 DRM_DEBUG("Out-of-range OA report format %llu\n",
2903 value);
2904 return -EINVAL;
2905 }
2906 if (!dev_priv->perf.oa_formats[value].size) {
2907 DRM_DEBUG("Unsupported OA report format %llu\n",
2908 value);
2909 return -EINVAL;
2910 }
2911 props->oa_format = value;
2912 break;
2913 case DRM_I915_PERF_PROP_OA_EXPONENT:
2914 if (value > OA_EXPONENT_MAX) {
2915 DRM_DEBUG("OA timer exponent too high (> %u)\n",
2916 OA_EXPONENT_MAX);
2917 return -EINVAL;
2918 }
2919
2920
2921
2922
2923
2924
2925
2926 BUILD_BUG_ON(sizeof(oa_period) != 8);
2927 oa_period = oa_exponent_to_ns(dev_priv, value);
2928
2929
2930
2931
2932
2933
2934
2935 if (oa_period <= NSEC_PER_SEC) {
2936 u64 tmp = NSEC_PER_SEC;
2937 do_div(tmp, oa_period);
2938 oa_freq_hz = tmp;
2939 } else
2940 oa_freq_hz = 0;
2941
2942 if (oa_freq_hz > i915_oa_max_sample_rate &&
2943 !capable(CAP_SYS_ADMIN)) {
2944 DRM_DEBUG("OA exponent would exceed the max sampling frequency (sysctl dev.i915.oa_max_sample_rate) %uHz without root privileges\n",
2945 i915_oa_max_sample_rate);
2946 return -EACCES;
2947 }
2948
2949 props->oa_periodic = true;
2950 props->oa_period_exponent = value;
2951 break;
2952 case DRM_I915_PERF_PROP_MAX:
2953 MISSING_CASE(id);
2954 return -EINVAL;
2955 }
2956
2957 uprop += 2;
2958 }
2959
2960 return 0;
2961 }
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987 int i915_perf_open_ioctl(struct drm_device *dev, void *data,
2988 struct drm_file *file)
2989 {
2990 struct drm_i915_private *dev_priv = dev->dev_private;
2991 struct drm_i915_perf_open_param *param = data;
2992 struct perf_open_properties props;
2993 u32 known_open_flags;
2994 int ret;
2995
2996 if (!dev_priv->perf.initialized) {
2997 DRM_DEBUG("i915 perf interface not available for this system\n");
2998 return -ENOTSUPP;
2999 }
3000
3001 known_open_flags = I915_PERF_FLAG_FD_CLOEXEC |
3002 I915_PERF_FLAG_FD_NONBLOCK |
3003 I915_PERF_FLAG_DISABLED;
3004 if (param->flags & ~known_open_flags) {
3005 DRM_DEBUG("Unknown drm_i915_perf_open_param flag\n");
3006 return -EINVAL;
3007 }
3008
3009 ret = read_properties_unlocked(dev_priv,
3010 u64_to_user_ptr(param->properties_ptr),
3011 param->num_properties,
3012 &props);
3013 if (ret)
3014 return ret;
3015
3016 mutex_lock(&dev_priv->perf.lock);
3017 ret = i915_perf_open_ioctl_locked(dev_priv, param, &props, file);
3018 mutex_unlock(&dev_priv->perf.lock);
3019
3020 return ret;
3021 }
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031 void i915_perf_register(struct drm_i915_private *dev_priv)
3032 {
3033 int ret;
3034
3035 if (!dev_priv->perf.initialized)
3036 return;
3037
3038
3039
3040
3041
3042 mutex_lock(&dev_priv->perf.lock);
3043
3044 dev_priv->perf.metrics_kobj =
3045 kobject_create_and_add("metrics",
3046 &dev_priv->drm.primary->kdev->kobj);
3047 if (!dev_priv->perf.metrics_kobj)
3048 goto exit;
3049
3050 sysfs_attr_init(&dev_priv->perf.test_config.sysfs_metric_id.attr);
3051
3052 if (INTEL_GEN(dev_priv) >= 11) {
3053 i915_perf_load_test_config_icl(dev_priv);
3054 } else if (IS_CANNONLAKE(dev_priv)) {
3055 i915_perf_load_test_config_cnl(dev_priv);
3056 } else if (IS_COFFEELAKE(dev_priv)) {
3057 if (IS_CFL_GT2(dev_priv))
3058 i915_perf_load_test_config_cflgt2(dev_priv);
3059 if (IS_CFL_GT3(dev_priv))
3060 i915_perf_load_test_config_cflgt3(dev_priv);
3061 } else if (IS_GEMINILAKE(dev_priv)) {
3062 i915_perf_load_test_config_glk(dev_priv);
3063 } else if (IS_KABYLAKE(dev_priv)) {
3064 if (IS_KBL_GT2(dev_priv))
3065 i915_perf_load_test_config_kblgt2(dev_priv);
3066 else if (IS_KBL_GT3(dev_priv))
3067 i915_perf_load_test_config_kblgt3(dev_priv);
3068 } else if (IS_BROXTON(dev_priv)) {
3069 i915_perf_load_test_config_bxt(dev_priv);
3070 } else if (IS_SKYLAKE(dev_priv)) {
3071 if (IS_SKL_GT2(dev_priv))
3072 i915_perf_load_test_config_sklgt2(dev_priv);
3073 else if (IS_SKL_GT3(dev_priv))
3074 i915_perf_load_test_config_sklgt3(dev_priv);
3075 else if (IS_SKL_GT4(dev_priv))
3076 i915_perf_load_test_config_sklgt4(dev_priv);
3077 } else if (IS_CHERRYVIEW(dev_priv)) {
3078 i915_perf_load_test_config_chv(dev_priv);
3079 } else if (IS_BROADWELL(dev_priv)) {
3080 i915_perf_load_test_config_bdw(dev_priv);
3081 } else if (IS_HASWELL(dev_priv)) {
3082 i915_perf_load_test_config_hsw(dev_priv);
3083 }
3084
3085 if (dev_priv->perf.test_config.id == 0)
3086 goto sysfs_error;
3087
3088 ret = sysfs_create_group(dev_priv->perf.metrics_kobj,
3089 &dev_priv->perf.test_config.sysfs_metric);
3090 if (ret)
3091 goto sysfs_error;
3092
3093 atomic_set(&dev_priv->perf.test_config.ref_count, 1);
3094
3095 goto exit;
3096
3097 sysfs_error:
3098 kobject_put(dev_priv->perf.metrics_kobj);
3099 dev_priv->perf.metrics_kobj = NULL;
3100
3101 exit:
3102 mutex_unlock(&dev_priv->perf.lock);
3103 }
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114 void i915_perf_unregister(struct drm_i915_private *dev_priv)
3115 {
3116 if (!dev_priv->perf.metrics_kobj)
3117 return;
3118
3119 sysfs_remove_group(dev_priv->perf.metrics_kobj,
3120 &dev_priv->perf.test_config.sysfs_metric);
3121
3122 kobject_put(dev_priv->perf.metrics_kobj);
3123 dev_priv->perf.metrics_kobj = NULL;
3124 }
3125
3126 static bool gen8_is_valid_flex_addr(struct drm_i915_private *dev_priv, u32 addr)
3127 {
3128 static const i915_reg_t flex_eu_regs[] = {
3129 EU_PERF_CNTL0,
3130 EU_PERF_CNTL1,
3131 EU_PERF_CNTL2,
3132 EU_PERF_CNTL3,
3133 EU_PERF_CNTL4,
3134 EU_PERF_CNTL5,
3135 EU_PERF_CNTL6,
3136 };
3137 int i;
3138
3139 for (i = 0; i < ARRAY_SIZE(flex_eu_regs); i++) {
3140 if (i915_mmio_reg_offset(flex_eu_regs[i]) == addr)
3141 return true;
3142 }
3143 return false;
3144 }
3145
3146 static bool gen7_is_valid_b_counter_addr(struct drm_i915_private *dev_priv, u32 addr)
3147 {
3148 return (addr >= i915_mmio_reg_offset(OASTARTTRIG1) &&
3149 addr <= i915_mmio_reg_offset(OASTARTTRIG8)) ||
3150 (addr >= i915_mmio_reg_offset(OAREPORTTRIG1) &&
3151 addr <= i915_mmio_reg_offset(OAREPORTTRIG8)) ||
3152 (addr >= i915_mmio_reg_offset(OACEC0_0) &&
3153 addr <= i915_mmio_reg_offset(OACEC7_1));
3154 }
3155
3156 static bool gen7_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
3157 {
3158 return addr == i915_mmio_reg_offset(HALF_SLICE_CHICKEN2) ||
3159 (addr >= i915_mmio_reg_offset(MICRO_BP0_0) &&
3160 addr <= i915_mmio_reg_offset(NOA_WRITE)) ||
3161 (addr >= i915_mmio_reg_offset(OA_PERFCNT1_LO) &&
3162 addr <= i915_mmio_reg_offset(OA_PERFCNT2_HI)) ||
3163 (addr >= i915_mmio_reg_offset(OA_PERFMATRIX_LO) &&
3164 addr <= i915_mmio_reg_offset(OA_PERFMATRIX_HI));
3165 }
3166
3167 static bool gen8_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
3168 {
3169 return gen7_is_valid_mux_addr(dev_priv, addr) ||
3170 addr == i915_mmio_reg_offset(WAIT_FOR_RC6_EXIT) ||
3171 (addr >= i915_mmio_reg_offset(RPM_CONFIG0) &&
3172 addr <= i915_mmio_reg_offset(NOA_CONFIG(8)));
3173 }
3174
3175 static bool gen10_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
3176 {
3177 return gen8_is_valid_mux_addr(dev_priv, addr) ||
3178 addr == i915_mmio_reg_offset(GEN10_NOA_WRITE_HIGH) ||
3179 (addr >= i915_mmio_reg_offset(OA_PERFCNT3_LO) &&
3180 addr <= i915_mmio_reg_offset(OA_PERFCNT4_HI));
3181 }
3182
3183 static bool hsw_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
3184 {
3185 return gen7_is_valid_mux_addr(dev_priv, addr) ||
3186 (addr >= 0x25100 && addr <= 0x2FF90) ||
3187 (addr >= i915_mmio_reg_offset(HSW_MBVID2_NOA0) &&
3188 addr <= i915_mmio_reg_offset(HSW_MBVID2_NOA9)) ||
3189 addr == i915_mmio_reg_offset(HSW_MBVID2_MISR0);
3190 }
3191
3192 static bool chv_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
3193 {
3194 return gen7_is_valid_mux_addr(dev_priv, addr) ||
3195 (addr >= 0x182300 && addr <= 0x1823A4);
3196 }
3197
3198 static u32 mask_reg_value(u32 reg, u32 val)
3199 {
3200
3201
3202
3203
3204 if (i915_mmio_reg_offset(HALF_SLICE_CHICKEN2) == reg)
3205 val = val & ~_MASKED_BIT_ENABLE(GEN8_ST_PO_DISABLE);
3206
3207
3208
3209
3210
3211 if (i915_mmio_reg_offset(WAIT_FOR_RC6_EXIT) == reg)
3212 val = val & ~_MASKED_BIT_ENABLE(HSW_WAIT_FOR_RC6_EXIT_ENABLE);
3213
3214 return val;
3215 }
3216
3217 static struct i915_oa_reg *alloc_oa_regs(struct drm_i915_private *dev_priv,
3218 bool (*is_valid)(struct drm_i915_private *dev_priv, u32 addr),
3219 u32 __user *regs,
3220 u32 n_regs)
3221 {
3222 struct i915_oa_reg *oa_regs;
3223 int err;
3224 u32 i;
3225
3226 if (!n_regs)
3227 return NULL;
3228
3229 if (!access_ok(regs, n_regs * sizeof(u32) * 2))
3230 return ERR_PTR(-EFAULT);
3231
3232
3233 GEM_BUG_ON(!is_valid);
3234 if (!is_valid)
3235 return ERR_PTR(-EINVAL);
3236
3237 oa_regs = kmalloc_array(n_regs, sizeof(*oa_regs), GFP_KERNEL);
3238 if (!oa_regs)
3239 return ERR_PTR(-ENOMEM);
3240
3241 for (i = 0; i < n_regs; i++) {
3242 u32 addr, value;
3243
3244 err = get_user(addr, regs);
3245 if (err)
3246 goto addr_err;
3247
3248 if (!is_valid(dev_priv, addr)) {
3249 DRM_DEBUG("Invalid oa_reg address: %X\n", addr);
3250 err = -EINVAL;
3251 goto addr_err;
3252 }
3253
3254 err = get_user(value, regs + 1);
3255 if (err)
3256 goto addr_err;
3257
3258 oa_regs[i].addr = _MMIO(addr);
3259 oa_regs[i].value = mask_reg_value(addr, value);
3260
3261 regs += 2;
3262 }
3263
3264 return oa_regs;
3265
3266 addr_err:
3267 kfree(oa_regs);
3268 return ERR_PTR(err);
3269 }
3270
3271 static ssize_t show_dynamic_id(struct device *dev,
3272 struct device_attribute *attr,
3273 char *buf)
3274 {
3275 struct i915_oa_config *oa_config =
3276 container_of(attr, typeof(*oa_config), sysfs_metric_id);
3277
3278 return sprintf(buf, "%d\n", oa_config->id);
3279 }
3280
3281 static int create_dynamic_oa_sysfs_entry(struct drm_i915_private *dev_priv,
3282 struct i915_oa_config *oa_config)
3283 {
3284 sysfs_attr_init(&oa_config->sysfs_metric_id.attr);
3285 oa_config->sysfs_metric_id.attr.name = "id";
3286 oa_config->sysfs_metric_id.attr.mode = S_IRUGO;
3287 oa_config->sysfs_metric_id.show = show_dynamic_id;
3288 oa_config->sysfs_metric_id.store = NULL;
3289
3290 oa_config->attrs[0] = &oa_config->sysfs_metric_id.attr;
3291 oa_config->attrs[1] = NULL;
3292
3293 oa_config->sysfs_metric.name = oa_config->uuid;
3294 oa_config->sysfs_metric.attrs = oa_config->attrs;
3295
3296 return sysfs_create_group(dev_priv->perf.metrics_kobj,
3297 &oa_config->sysfs_metric);
3298 }
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313 int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
3314 struct drm_file *file)
3315 {
3316 struct drm_i915_private *dev_priv = dev->dev_private;
3317 struct drm_i915_perf_oa_config *args = data;
3318 struct i915_oa_config *oa_config, *tmp;
3319 int err, id;
3320
3321 if (!dev_priv->perf.initialized) {
3322 DRM_DEBUG("i915 perf interface not available for this system\n");
3323 return -ENOTSUPP;
3324 }
3325
3326 if (!dev_priv->perf.metrics_kobj) {
3327 DRM_DEBUG("OA metrics weren't advertised via sysfs\n");
3328 return -EINVAL;
3329 }
3330
3331 if (i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) {
3332 DRM_DEBUG("Insufficient privileges to add i915 OA config\n");
3333 return -EACCES;
3334 }
3335
3336 if ((!args->mux_regs_ptr || !args->n_mux_regs) &&
3337 (!args->boolean_regs_ptr || !args->n_boolean_regs) &&
3338 (!args->flex_regs_ptr || !args->n_flex_regs)) {
3339 DRM_DEBUG("No OA registers given\n");
3340 return -EINVAL;
3341 }
3342
3343 oa_config = kzalloc(sizeof(*oa_config), GFP_KERNEL);
3344 if (!oa_config) {
3345 DRM_DEBUG("Failed to allocate memory for the OA config\n");
3346 return -ENOMEM;
3347 }
3348
3349 atomic_set(&oa_config->ref_count, 1);
3350
3351 if (!uuid_is_valid(args->uuid)) {
3352 DRM_DEBUG("Invalid uuid format for OA config\n");
3353 err = -EINVAL;
3354 goto reg_err;
3355 }
3356
3357
3358
3359
3360 memcpy(oa_config->uuid, args->uuid, sizeof(args->uuid));
3361
3362 oa_config->mux_regs_len = args->n_mux_regs;
3363 oa_config->mux_regs =
3364 alloc_oa_regs(dev_priv,
3365 dev_priv->perf.ops.is_valid_mux_reg,
3366 u64_to_user_ptr(args->mux_regs_ptr),
3367 args->n_mux_regs);
3368
3369 if (IS_ERR(oa_config->mux_regs)) {
3370 DRM_DEBUG("Failed to create OA config for mux_regs\n");
3371 err = PTR_ERR(oa_config->mux_regs);
3372 goto reg_err;
3373 }
3374
3375 oa_config->b_counter_regs_len = args->n_boolean_regs;
3376 oa_config->b_counter_regs =
3377 alloc_oa_regs(dev_priv,
3378 dev_priv->perf.ops.is_valid_b_counter_reg,
3379 u64_to_user_ptr(args->boolean_regs_ptr),
3380 args->n_boolean_regs);
3381
3382 if (IS_ERR(oa_config->b_counter_regs)) {
3383 DRM_DEBUG("Failed to create OA config for b_counter_regs\n");
3384 err = PTR_ERR(oa_config->b_counter_regs);
3385 goto reg_err;
3386 }
3387
3388 if (INTEL_GEN(dev_priv) < 8) {
3389 if (args->n_flex_regs != 0) {
3390 err = -EINVAL;
3391 goto reg_err;
3392 }
3393 } else {
3394 oa_config->flex_regs_len = args->n_flex_regs;
3395 oa_config->flex_regs =
3396 alloc_oa_regs(dev_priv,
3397 dev_priv->perf.ops.is_valid_flex_reg,
3398 u64_to_user_ptr(args->flex_regs_ptr),
3399 args->n_flex_regs);
3400
3401 if (IS_ERR(oa_config->flex_regs)) {
3402 DRM_DEBUG("Failed to create OA config for flex_regs\n");
3403 err = PTR_ERR(oa_config->flex_regs);
3404 goto reg_err;
3405 }
3406 }
3407
3408 err = mutex_lock_interruptible(&dev_priv->perf.metrics_lock);
3409 if (err)
3410 goto reg_err;
3411
3412
3413
3414
3415 idr_for_each_entry(&dev_priv->perf.metrics_idr, tmp, id) {
3416 if (!strcmp(tmp->uuid, oa_config->uuid)) {
3417 DRM_DEBUG("OA config already exists with this uuid\n");
3418 err = -EADDRINUSE;
3419 goto sysfs_err;
3420 }
3421 }
3422
3423 err = create_dynamic_oa_sysfs_entry(dev_priv, oa_config);
3424 if (err) {
3425 DRM_DEBUG("Failed to create sysfs entry for OA config\n");
3426 goto sysfs_err;
3427 }
3428
3429
3430 oa_config->id = idr_alloc(&dev_priv->perf.metrics_idr,
3431 oa_config, 2,
3432 0, GFP_KERNEL);
3433 if (oa_config->id < 0) {
3434 DRM_DEBUG("Failed to create sysfs entry for OA config\n");
3435 err = oa_config->id;
3436 goto sysfs_err;
3437 }
3438
3439 mutex_unlock(&dev_priv->perf.metrics_lock);
3440
3441 DRM_DEBUG("Added config %s id=%i\n", oa_config->uuid, oa_config->id);
3442
3443 return oa_config->id;
3444
3445 sysfs_err:
3446 mutex_unlock(&dev_priv->perf.metrics_lock);
3447 reg_err:
3448 put_oa_config(dev_priv, oa_config);
3449 DRM_DEBUG("Failed to add new OA config\n");
3450 return err;
3451 }
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464 int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
3465 struct drm_file *file)
3466 {
3467 struct drm_i915_private *dev_priv = dev->dev_private;
3468 u64 *arg = data;
3469 struct i915_oa_config *oa_config;
3470 int ret;
3471
3472 if (!dev_priv->perf.initialized) {
3473 DRM_DEBUG("i915 perf interface not available for this system\n");
3474 return -ENOTSUPP;
3475 }
3476
3477 if (i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) {
3478 DRM_DEBUG("Insufficient privileges to remove i915 OA config\n");
3479 return -EACCES;
3480 }
3481
3482 ret = mutex_lock_interruptible(&dev_priv->perf.metrics_lock);
3483 if (ret)
3484 goto lock_err;
3485
3486 oa_config = idr_find(&dev_priv->perf.metrics_idr, *arg);
3487 if (!oa_config) {
3488 DRM_DEBUG("Failed to remove unknown OA config\n");
3489 ret = -ENOENT;
3490 goto config_err;
3491 }
3492
3493 GEM_BUG_ON(*arg != oa_config->id);
3494
3495 sysfs_remove_group(dev_priv->perf.metrics_kobj,
3496 &oa_config->sysfs_metric);
3497
3498 idr_remove(&dev_priv->perf.metrics_idr, *arg);
3499
3500 DRM_DEBUG("Removed config %s id=%i\n", oa_config->uuid, oa_config->id);
3501
3502 put_oa_config(dev_priv, oa_config);
3503
3504 config_err:
3505 mutex_unlock(&dev_priv->perf.metrics_lock);
3506 lock_err:
3507 return ret;
3508 }
3509
3510 static struct ctl_table oa_table[] = {
3511 {
3512 .procname = "perf_stream_paranoid",
3513 .data = &i915_perf_stream_paranoid,
3514 .maxlen = sizeof(i915_perf_stream_paranoid),
3515 .mode = 0644,
3516 .proc_handler = proc_dointvec_minmax,
3517 .extra1 = SYSCTL_ZERO,
3518 .extra2 = SYSCTL_ONE,
3519 },
3520 {
3521 .procname = "oa_max_sample_rate",
3522 .data = &i915_oa_max_sample_rate,
3523 .maxlen = sizeof(i915_oa_max_sample_rate),
3524 .mode = 0644,
3525 .proc_handler = proc_dointvec_minmax,
3526 .extra1 = SYSCTL_ZERO,
3527 .extra2 = &oa_sample_rate_hard_limit,
3528 },
3529 {}
3530 };
3531
3532 static struct ctl_table i915_root[] = {
3533 {
3534 .procname = "i915",
3535 .maxlen = 0,
3536 .mode = 0555,
3537 .child = oa_table,
3538 },
3539 {}
3540 };
3541
3542 static struct ctl_table dev_root[] = {
3543 {
3544 .procname = "dev",
3545 .maxlen = 0,
3546 .mode = 0555,
3547 .child = i915_root,
3548 },
3549 {}
3550 };
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561 void i915_perf_init(struct drm_i915_private *dev_priv)
3562 {
3563 if (IS_HASWELL(dev_priv)) {
3564 dev_priv->perf.ops.is_valid_b_counter_reg =
3565 gen7_is_valid_b_counter_addr;
3566 dev_priv->perf.ops.is_valid_mux_reg =
3567 hsw_is_valid_mux_addr;
3568 dev_priv->perf.ops.is_valid_flex_reg = NULL;
3569 dev_priv->perf.ops.enable_metric_set = hsw_enable_metric_set;
3570 dev_priv->perf.ops.disable_metric_set = hsw_disable_metric_set;
3571 dev_priv->perf.ops.oa_enable = gen7_oa_enable;
3572 dev_priv->perf.ops.oa_disable = gen7_oa_disable;
3573 dev_priv->perf.ops.read = gen7_oa_read;
3574 dev_priv->perf.ops.oa_hw_tail_read =
3575 gen7_oa_hw_tail_read;
3576
3577 dev_priv->perf.oa_formats = hsw_oa_formats;
3578 } else if (HAS_LOGICAL_RING_CONTEXTS(dev_priv)) {
3579
3580
3581
3582
3583
3584
3585 dev_priv->perf.oa_formats = gen8_plus_oa_formats;
3586
3587 dev_priv->perf.ops.oa_enable = gen8_oa_enable;
3588 dev_priv->perf.ops.oa_disable = gen8_oa_disable;
3589 dev_priv->perf.ops.read = gen8_oa_read;
3590 dev_priv->perf.ops.oa_hw_tail_read = gen8_oa_hw_tail_read;
3591
3592 if (IS_GEN_RANGE(dev_priv, 8, 9)) {
3593 dev_priv->perf.ops.is_valid_b_counter_reg =
3594 gen7_is_valid_b_counter_addr;
3595 dev_priv->perf.ops.is_valid_mux_reg =
3596 gen8_is_valid_mux_addr;
3597 dev_priv->perf.ops.is_valid_flex_reg =
3598 gen8_is_valid_flex_addr;
3599
3600 if (IS_CHERRYVIEW(dev_priv)) {
3601 dev_priv->perf.ops.is_valid_mux_reg =
3602 chv_is_valid_mux_addr;
3603 }
3604
3605 dev_priv->perf.ops.enable_metric_set = gen8_enable_metric_set;
3606 dev_priv->perf.ops.disable_metric_set = gen8_disable_metric_set;
3607
3608 if (IS_GEN(dev_priv, 8)) {
3609 dev_priv->perf.ctx_oactxctrl_offset = 0x120;
3610 dev_priv->perf.ctx_flexeu0_offset = 0x2ce;
3611
3612 dev_priv->perf.gen8_valid_ctx_bit = BIT(25);
3613 } else {
3614 dev_priv->perf.ctx_oactxctrl_offset = 0x128;
3615 dev_priv->perf.ctx_flexeu0_offset = 0x3de;
3616
3617 dev_priv->perf.gen8_valid_ctx_bit = BIT(16);
3618 }
3619 } else if (IS_GEN_RANGE(dev_priv, 10, 11)) {
3620 dev_priv->perf.ops.is_valid_b_counter_reg =
3621 gen7_is_valid_b_counter_addr;
3622 dev_priv->perf.ops.is_valid_mux_reg =
3623 gen10_is_valid_mux_addr;
3624 dev_priv->perf.ops.is_valid_flex_reg =
3625 gen8_is_valid_flex_addr;
3626
3627 dev_priv->perf.ops.enable_metric_set = gen8_enable_metric_set;
3628 dev_priv->perf.ops.disable_metric_set = gen10_disable_metric_set;
3629
3630 if (IS_GEN(dev_priv, 10)) {
3631 dev_priv->perf.ctx_oactxctrl_offset = 0x128;
3632 dev_priv->perf.ctx_flexeu0_offset = 0x3de;
3633 } else {
3634 dev_priv->perf.ctx_oactxctrl_offset = 0x124;
3635 dev_priv->perf.ctx_flexeu0_offset = 0x78e;
3636 }
3637 dev_priv->perf.gen8_valid_ctx_bit = BIT(16);
3638 }
3639 }
3640
3641 if (dev_priv->perf.ops.enable_metric_set) {
3642 INIT_LIST_HEAD(&dev_priv->perf.streams);
3643 mutex_init(&dev_priv->perf.lock);
3644
3645 oa_sample_rate_hard_limit = 1000 *
3646 (RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz / 2);
3647 dev_priv->perf.sysctl_header = register_sysctl_table(dev_root);
3648
3649 mutex_init(&dev_priv->perf.metrics_lock);
3650 idr_init(&dev_priv->perf.metrics_idr);
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662 ratelimit_state_init(&dev_priv->perf.spurious_report_rs,
3663 5 * HZ, 10);
3664
3665
3666
3667
3668 ratelimit_set_flags(&dev_priv->perf.spurious_report_rs,
3669 RATELIMIT_MSG_ON_RELEASE);
3670
3671 dev_priv->perf.initialized = true;
3672 }
3673 }
3674
3675 static int destroy_config(int id, void *p, void *data)
3676 {
3677 struct drm_i915_private *dev_priv = data;
3678 struct i915_oa_config *oa_config = p;
3679
3680 put_oa_config(dev_priv, oa_config);
3681
3682 return 0;
3683 }
3684
3685
3686
3687
3688
3689 void i915_perf_fini(struct drm_i915_private *dev_priv)
3690 {
3691 if (!dev_priv->perf.initialized)
3692 return;
3693
3694 idr_for_each(&dev_priv->perf.metrics_idr, destroy_config, dev_priv);
3695 idr_destroy(&dev_priv->perf.metrics_idr);
3696
3697 unregister_sysctl_table(dev_priv->perf.sysctl_header);
3698
3699 memset(&dev_priv->perf.ops, 0, sizeof(dev_priv->perf.ops));
3700
3701 dev_priv->perf.initialized = false;
3702 }