1 /*
2  * Copyright 2021 Valve Corporation
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * on the rights to use, copy, modify, merge, publish, distribute, sub
9  * license, and/or sell copies of the Software, and to permit persons to whom
10  * the Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22  * USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #ifndef AC_SPM_H
26 #define AC_SPM_H
27 
28 #include <stdint.h>
29 
30 #include "ac_perfcounter.h"
31 
32 #define AC_SPM_MAX_COUNTER_PER_BLOCK 16
33 #define AC_SPM_GLOBAL_TIMESTAMP_COUNTERS 4 /* in unit of 16-bit counters*/
34 #define AC_SPM_NUM_COUNTER_PER_MUXSEL 16 /* 16 16-bit counters per muxsel */
35 #define AC_SPM_MUXSEL_LINE_SIZE ((AC_SPM_NUM_COUNTER_PER_MUXSEL * 2) / 4) /* in dwords */
36 #define AC_SPM_NUM_PERF_SEL 4
37 
38 enum ac_spm_segment_type {
39    AC_SPM_SEGMENT_TYPE_SE0,
40    AC_SPM_SEGMENT_TYPE_SE1,
41    AC_SPM_SEGMENT_TYPE_SE2,
42    AC_SPM_SEGMENT_TYPE_SE3,
43    AC_SPM_SEGMENT_TYPE_GLOBAL,
44    AC_SPM_SEGMENT_TYPE_COUNT,
45 };
46 
47 struct ac_spm_counter_create_info {
48    enum ac_pc_gpu_block gpu_block;
49    uint32_t instance;
50    uint32_t event_id;
51 };
52 
53 struct ac_spm_muxsel {
54    uint16_t counter      : 6;
55    uint16_t block        : 4;
56    uint16_t shader_array : 1; /* 0: SA0, 1: SA1 */
57    uint16_t instance     : 5;
58 };
59 
60 struct ac_spm_muxsel_line {
61    struct ac_spm_muxsel muxsel[AC_SPM_NUM_COUNTER_PER_MUXSEL];
62 };
63 
64 struct ac_spm_counter_info {
65    /* General info. */
66    enum ac_pc_gpu_block gpu_block;
67    uint32_t instance;
68    uint32_t event_id;
69 
70    /* Muxsel info. */
71    enum ac_spm_segment_type segment_type;
72    bool is_even;
73    struct ac_spm_muxsel muxsel;
74 
75    /* Output info. */
76    uint64_t offset;
77 };
78 
79 struct ac_spm_counter_select {
80    uint8_t active; /* mask of used 16-bit counters. */
81    uint32_t sel0;
82    uint32_t sel1;
83 };
84 
85 struct ac_spm_block_select {
86    const struct ac_pc_block *b;
87    uint32_t grbm_gfx_index;
88 
89    uint32_t num_counters;
90    struct ac_spm_counter_select counters[AC_SPM_MAX_COUNTER_PER_BLOCK];
91 };
92 
93 struct ac_spm_trace_data {
94    /* struct radeon_winsys_bo or struct pb_buffer */
95    void *bo;
96    void *ptr;
97    uint32_t buffer_size;
98    uint16_t sample_interval;
99 
100    /* Enabled counters. */
101    unsigned num_counters;
102    struct ac_spm_counter_info *counters;
103 
104    /* Block/counters selection. */
105    uint32_t num_block_sel;
106    struct ac_spm_block_select *block_sel;
107    uint32_t num_used_sq_block_sel;
108    struct ac_spm_block_select sq_block_sel[16];
109 
110    /* Muxsel lines. */
111    unsigned num_muxsel_lines[AC_SPM_SEGMENT_TYPE_COUNT];
112    struct ac_spm_muxsel_line *muxsel_lines[AC_SPM_SEGMENT_TYPE_COUNT];
113 };
114 
115 bool ac_init_spm(const struct radeon_info *info,
116                  const struct ac_perfcounters *pc,
117                  unsigned num_counters,
118                  const struct ac_spm_counter_create_info *counters,
119                  struct ac_spm_trace_data *spm_trace);
120 void ac_destroy_spm(struct ac_spm_trace_data *spm_trace);
121 
122 uint32_t ac_spm_get_sample_size(const struct ac_spm_trace_data *spm_trace);
123 uint32_t ac_spm_get_num_samples(const struct ac_spm_trace_data *spm_trace);
124 
125 #endif
126