1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2018 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include <dirent.h>
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
27*61046927SAndroid Build Coastguard Worker #include <sys/stat.h>
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker #if defined(MAJOR_IN_SYSMACROS)
30*61046927SAndroid Build Coastguard Worker #include <sys/sysmacros.h>
31*61046927SAndroid Build Coastguard Worker #elif defined(MAJOR_IN_MKDEV)
32*61046927SAndroid Build Coastguard Worker #include <sys/mkdev.h>
33*61046927SAndroid Build Coastguard Worker #endif
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
36*61046927SAndroid Build Coastguard Worker #include <unistd.h>
37*61046927SAndroid Build Coastguard Worker #include <errno.h>
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker #ifndef HAVE_DIRENT_D_TYPE
40*61046927SAndroid Build Coastguard Worker #include <limits.h> // PATH_MAX
41*61046927SAndroid Build Coastguard Worker #endif
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker #include "common/intel_gem.h"
44*61046927SAndroid Build Coastguard Worker #include "common/i915/intel_gem.h"
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker #include "dev/intel_debug.h"
47*61046927SAndroid Build Coastguard Worker #include "dev/intel_device_info.h"
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker #include "perf/i915/intel_perf.h"
50*61046927SAndroid Build Coastguard Worker #include "perf/xe/intel_perf.h"
51*61046927SAndroid Build Coastguard Worker #include "perf/intel_perf.h"
52*61046927SAndroid Build Coastguard Worker #include "perf/intel_perf_common.h"
53*61046927SAndroid Build Coastguard Worker #include "perf/intel_perf_regs.h"
54*61046927SAndroid Build Coastguard Worker #include "perf/intel_perf_mdapi.h"
55*61046927SAndroid Build Coastguard Worker #include "perf/intel_perf_metrics.h"
56*61046927SAndroid Build Coastguard Worker #include "perf/intel_perf_private.h"
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker #include "perf/i915/intel_perf.h"
59*61046927SAndroid Build Coastguard Worker #include "perf/xe/intel_perf.h"
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker #include "util/bitscan.h"
62*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
63*61046927SAndroid Build Coastguard Worker #include "util/mesa-sha1.h"
64*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
65*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker #define FILE_DEBUG_FLAG DEBUG_PERFMON
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker static bool
is_dir_or_link(const struct dirent * entry,const char * parent_dir)70*61046927SAndroid Build Coastguard Worker is_dir_or_link(const struct dirent *entry, const char *parent_dir)
71*61046927SAndroid Build Coastguard Worker {
72*61046927SAndroid Build Coastguard Worker #ifdef HAVE_DIRENT_D_TYPE
73*61046927SAndroid Build Coastguard Worker return entry->d_type == DT_DIR || entry->d_type == DT_LNK;
74*61046927SAndroid Build Coastguard Worker #else
75*61046927SAndroid Build Coastguard Worker struct stat st;
76*61046927SAndroid Build Coastguard Worker char path[PATH_MAX + 1];
77*61046927SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "%s/%s", parent_dir, entry->d_name);
78*61046927SAndroid Build Coastguard Worker lstat(path, &st);
79*61046927SAndroid Build Coastguard Worker return S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode);
80*61046927SAndroid Build Coastguard Worker #endif
81*61046927SAndroid Build Coastguard Worker }
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker static bool
get_sysfs_dev_dir(struct intel_perf_config * perf,int fd)84*61046927SAndroid Build Coastguard Worker get_sysfs_dev_dir(struct intel_perf_config *perf, int fd)
85*61046927SAndroid Build Coastguard Worker {
86*61046927SAndroid Build Coastguard Worker struct stat sb;
87*61046927SAndroid Build Coastguard Worker int min, maj;
88*61046927SAndroid Build Coastguard Worker DIR *drmdir;
89*61046927SAndroid Build Coastguard Worker struct dirent *drm_entry;
90*61046927SAndroid Build Coastguard Worker int len;
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker perf->sysfs_dev_dir[0] = '\0';
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker if (INTEL_DEBUG(DEBUG_NO_OACONFIG))
95*61046927SAndroid Build Coastguard Worker return true;
96*61046927SAndroid Build Coastguard Worker
97*61046927SAndroid Build Coastguard Worker if (fstat(fd, &sb)) {
98*61046927SAndroid Build Coastguard Worker DBG("Failed to stat DRM fd\n");
99*61046927SAndroid Build Coastguard Worker return false;
100*61046927SAndroid Build Coastguard Worker }
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker maj = major(sb.st_rdev);
103*61046927SAndroid Build Coastguard Worker min = minor(sb.st_rdev);
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker if (!S_ISCHR(sb.st_mode)) {
106*61046927SAndroid Build Coastguard Worker DBG("DRM fd is not a character device as expected\n");
107*61046927SAndroid Build Coastguard Worker return false;
108*61046927SAndroid Build Coastguard Worker }
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker len = snprintf(perf->sysfs_dev_dir,
111*61046927SAndroid Build Coastguard Worker sizeof(perf->sysfs_dev_dir),
112*61046927SAndroid Build Coastguard Worker "/sys/dev/char/%d:%d/device/drm", maj, min);
113*61046927SAndroid Build Coastguard Worker if (len < 0 || len >= sizeof(perf->sysfs_dev_dir)) {
114*61046927SAndroid Build Coastguard Worker DBG("Failed to concatenate sysfs path to drm device\n");
115*61046927SAndroid Build Coastguard Worker return false;
116*61046927SAndroid Build Coastguard Worker }
117*61046927SAndroid Build Coastguard Worker
118*61046927SAndroid Build Coastguard Worker drmdir = opendir(perf->sysfs_dev_dir);
119*61046927SAndroid Build Coastguard Worker if (!drmdir) {
120*61046927SAndroid Build Coastguard Worker DBG("Failed to open %s: %m\n", perf->sysfs_dev_dir);
121*61046927SAndroid Build Coastguard Worker return false;
122*61046927SAndroid Build Coastguard Worker }
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker while ((drm_entry = readdir(drmdir))) {
125*61046927SAndroid Build Coastguard Worker if (is_dir_or_link(drm_entry, perf->sysfs_dev_dir) &&
126*61046927SAndroid Build Coastguard Worker strncmp(drm_entry->d_name, "card", 4) == 0)
127*61046927SAndroid Build Coastguard Worker {
128*61046927SAndroid Build Coastguard Worker len = snprintf(perf->sysfs_dev_dir,
129*61046927SAndroid Build Coastguard Worker sizeof(perf->sysfs_dev_dir),
130*61046927SAndroid Build Coastguard Worker "/sys/dev/char/%d:%d/device/drm/%s",
131*61046927SAndroid Build Coastguard Worker maj, min, drm_entry->d_name);
132*61046927SAndroid Build Coastguard Worker closedir(drmdir);
133*61046927SAndroid Build Coastguard Worker if (len < 0 || len >= sizeof(perf->sysfs_dev_dir))
134*61046927SAndroid Build Coastguard Worker return false;
135*61046927SAndroid Build Coastguard Worker else
136*61046927SAndroid Build Coastguard Worker return true;
137*61046927SAndroid Build Coastguard Worker }
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker closedir(drmdir);
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker DBG("Failed to find cardX directory under /sys/dev/char/%d:%d/device/drm\n",
143*61046927SAndroid Build Coastguard Worker maj, min);
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker return false;
146*61046927SAndroid Build Coastguard Worker }
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker static bool
read_sysfs_drm_device_file_uint64(struct intel_perf_config * perf,const char * file,uint64_t * value)149*61046927SAndroid Build Coastguard Worker read_sysfs_drm_device_file_uint64(struct intel_perf_config *perf,
150*61046927SAndroid Build Coastguard Worker const char *file,
151*61046927SAndroid Build Coastguard Worker uint64_t *value)
152*61046927SAndroid Build Coastguard Worker {
153*61046927SAndroid Build Coastguard Worker char buf[512];
154*61046927SAndroid Build Coastguard Worker int len;
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker len = snprintf(buf, sizeof(buf), "%s/%s", perf->sysfs_dev_dir, file);
157*61046927SAndroid Build Coastguard Worker if (len < 0 || len >= sizeof(buf)) {
158*61046927SAndroid Build Coastguard Worker DBG("Failed to concatenate sys filename to read u64 from\n");
159*61046927SAndroid Build Coastguard Worker return false;
160*61046927SAndroid Build Coastguard Worker }
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker return read_file_uint64(buf, value);
163*61046927SAndroid Build Coastguard Worker }
164*61046927SAndroid Build Coastguard Worker
165*61046927SAndroid Build Coastguard Worker static bool
oa_config_enabled(struct intel_perf_config * perf,const struct intel_perf_query_info * query)166*61046927SAndroid Build Coastguard Worker oa_config_enabled(struct intel_perf_config *perf,
167*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_info *query) {
168*61046927SAndroid Build Coastguard Worker // Hide extended metrics unless enabled with env param
169*61046927SAndroid Build Coastguard Worker bool is_extended_metric = strncmp(query->name, "Ext", 3) == 0;
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker return perf->enable_all_metrics || !is_extended_metric;
172*61046927SAndroid Build Coastguard Worker }
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker static void
register_oa_config(struct intel_perf_config * perf,const struct intel_device_info * devinfo,const struct intel_perf_query_info * query,uint64_t config_id)175*61046927SAndroid Build Coastguard Worker register_oa_config(struct intel_perf_config *perf,
176*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo,
177*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_info *query,
178*61046927SAndroid Build Coastguard Worker uint64_t config_id)
179*61046927SAndroid Build Coastguard Worker {
180*61046927SAndroid Build Coastguard Worker if (!oa_config_enabled(perf, query))
181*61046927SAndroid Build Coastguard Worker return;
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker struct intel_perf_query_info *registered_query =
184*61046927SAndroid Build Coastguard Worker intel_perf_append_query_info(perf, 0);
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker *registered_query = *query;
187*61046927SAndroid Build Coastguard Worker registered_query->oa_metrics_set_id = config_id;
188*61046927SAndroid Build Coastguard Worker DBG("metric set registered: id = %" PRIu64", guid = %s\n",
189*61046927SAndroid Build Coastguard Worker registered_query->oa_metrics_set_id, query->guid);
190*61046927SAndroid Build Coastguard Worker }
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker static void
enumerate_sysfs_metrics(struct intel_perf_config * perf,const struct intel_device_info * devinfo)193*61046927SAndroid Build Coastguard Worker enumerate_sysfs_metrics(struct intel_perf_config *perf,
194*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo)
195*61046927SAndroid Build Coastguard Worker {
196*61046927SAndroid Build Coastguard Worker DIR *metricsdir = NULL;
197*61046927SAndroid Build Coastguard Worker struct dirent *metric_entry;
198*61046927SAndroid Build Coastguard Worker char buf[256];
199*61046927SAndroid Build Coastguard Worker int len;
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker len = snprintf(buf, sizeof(buf), "%s/metrics", perf->sysfs_dev_dir);
202*61046927SAndroid Build Coastguard Worker if (len < 0 || len >= sizeof(buf)) {
203*61046927SAndroid Build Coastguard Worker DBG("Failed to concatenate path to sysfs metrics/ directory\n");
204*61046927SAndroid Build Coastguard Worker return;
205*61046927SAndroid Build Coastguard Worker }
206*61046927SAndroid Build Coastguard Worker
207*61046927SAndroid Build Coastguard Worker metricsdir = opendir(buf);
208*61046927SAndroid Build Coastguard Worker if (!metricsdir) {
209*61046927SAndroid Build Coastguard Worker DBG("Failed to open %s: %m\n", buf);
210*61046927SAndroid Build Coastguard Worker return;
211*61046927SAndroid Build Coastguard Worker }
212*61046927SAndroid Build Coastguard Worker
213*61046927SAndroid Build Coastguard Worker while ((metric_entry = readdir(metricsdir))) {
214*61046927SAndroid Build Coastguard Worker struct hash_entry *entry;
215*61046927SAndroid Build Coastguard Worker if (!is_dir_or_link(metric_entry, buf) ||
216*61046927SAndroid Build Coastguard Worker metric_entry->d_name[0] == '.')
217*61046927SAndroid Build Coastguard Worker continue;
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker DBG("metric set: %s\n", metric_entry->d_name);
220*61046927SAndroid Build Coastguard Worker entry = _mesa_hash_table_search(perf->oa_metrics_table,
221*61046927SAndroid Build Coastguard Worker metric_entry->d_name);
222*61046927SAndroid Build Coastguard Worker if (entry) {
223*61046927SAndroid Build Coastguard Worker uint64_t id;
224*61046927SAndroid Build Coastguard Worker if (!intel_perf_load_metric_id(perf, metric_entry->d_name, &id)) {
225*61046927SAndroid Build Coastguard Worker DBG("Failed to read metric set id from %s: %m", buf);
226*61046927SAndroid Build Coastguard Worker continue;
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker register_oa_config(perf, devinfo,
230*61046927SAndroid Build Coastguard Worker (const struct intel_perf_query_info *)entry->data, id);
231*61046927SAndroid Build Coastguard Worker } else
232*61046927SAndroid Build Coastguard Worker DBG("metric set not known by mesa (skipping)\n");
233*61046927SAndroid Build Coastguard Worker }
234*61046927SAndroid Build Coastguard Worker
235*61046927SAndroid Build Coastguard Worker closedir(metricsdir);
236*61046927SAndroid Build Coastguard Worker }
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker static void
add_all_metrics(struct intel_perf_config * perf,const struct intel_device_info * devinfo)239*61046927SAndroid Build Coastguard Worker add_all_metrics(struct intel_perf_config *perf,
240*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo)
241*61046927SAndroid Build Coastguard Worker {
242*61046927SAndroid Build Coastguard Worker hash_table_foreach(perf->oa_metrics_table, entry) {
243*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_info *query = entry->data;
244*61046927SAndroid Build Coastguard Worker register_oa_config(perf, devinfo, query, 0);
245*61046927SAndroid Build Coastguard Worker }
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker static bool
kernel_has_dynamic_config_support(struct intel_perf_config * perf,int fd)249*61046927SAndroid Build Coastguard Worker kernel_has_dynamic_config_support(struct intel_perf_config *perf, int fd)
250*61046927SAndroid Build Coastguard Worker {
251*61046927SAndroid Build Coastguard Worker switch (perf->devinfo->kmd_type) {
252*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
253*61046927SAndroid Build Coastguard Worker return i915_has_dynamic_config_support(perf, fd);
254*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
255*61046927SAndroid Build Coastguard Worker return true;
256*61046927SAndroid Build Coastguard Worker default:
257*61046927SAndroid Build Coastguard Worker unreachable("missing");
258*61046927SAndroid Build Coastguard Worker return false;
259*61046927SAndroid Build Coastguard Worker }
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker bool
intel_perf_load_metric_id(struct intel_perf_config * perf_cfg,const char * guid,uint64_t * metric_id)263*61046927SAndroid Build Coastguard Worker intel_perf_load_metric_id(struct intel_perf_config *perf_cfg,
264*61046927SAndroid Build Coastguard Worker const char *guid,
265*61046927SAndroid Build Coastguard Worker uint64_t *metric_id)
266*61046927SAndroid Build Coastguard Worker {
267*61046927SAndroid Build Coastguard Worker char config_path[280];
268*61046927SAndroid Build Coastguard Worker
269*61046927SAndroid Build Coastguard Worker snprintf(config_path, sizeof(config_path), "%s/metrics/%s/id",
270*61046927SAndroid Build Coastguard Worker perf_cfg->sysfs_dev_dir, guid);
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker /* Don't recreate already loaded configs. */
273*61046927SAndroid Build Coastguard Worker return read_file_uint64(config_path, metric_id);
274*61046927SAndroid Build Coastguard Worker }
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker static uint64_t
kmd_add_config(struct intel_perf_config * perf,int fd,const struct intel_perf_registers * config,const char * guid)277*61046927SAndroid Build Coastguard Worker kmd_add_config(struct intel_perf_config *perf, int fd,
278*61046927SAndroid Build Coastguard Worker const struct intel_perf_registers *config,
279*61046927SAndroid Build Coastguard Worker const char *guid)
280*61046927SAndroid Build Coastguard Worker {
281*61046927SAndroid Build Coastguard Worker switch (perf->devinfo->kmd_type) {
282*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
283*61046927SAndroid Build Coastguard Worker return i915_add_config(perf, fd, config, guid);
284*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
285*61046927SAndroid Build Coastguard Worker return xe_add_config(perf, fd, config, guid);
286*61046927SAndroid Build Coastguard Worker default:
287*61046927SAndroid Build Coastguard Worker unreachable("missing");
288*61046927SAndroid Build Coastguard Worker return 0;
289*61046927SAndroid Build Coastguard Worker }
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker
292*61046927SAndroid Build Coastguard Worker static void
init_oa_configs(struct intel_perf_config * perf,int fd,const struct intel_device_info * devinfo)293*61046927SAndroid Build Coastguard Worker init_oa_configs(struct intel_perf_config *perf, int fd,
294*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo)
295*61046927SAndroid Build Coastguard Worker {
296*61046927SAndroid Build Coastguard Worker hash_table_foreach(perf->oa_metrics_table, entry) {
297*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_info *query = entry->data;
298*61046927SAndroid Build Coastguard Worker uint64_t config_id;
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker if (intel_perf_load_metric_id(perf, query->guid, &config_id)) {
301*61046927SAndroid Build Coastguard Worker DBG("metric set: %s (already loaded)\n", query->guid);
302*61046927SAndroid Build Coastguard Worker register_oa_config(perf, devinfo, query, config_id);
303*61046927SAndroid Build Coastguard Worker continue;
304*61046927SAndroid Build Coastguard Worker }
305*61046927SAndroid Build Coastguard Worker
306*61046927SAndroid Build Coastguard Worker uint64_t ret = kmd_add_config(perf, fd, &query->config, query->guid);
307*61046927SAndroid Build Coastguard Worker if (ret == 0) {
308*61046927SAndroid Build Coastguard Worker DBG("Failed to load \"%s\" (%s) metrics set in kernel: %s\n",
309*61046927SAndroid Build Coastguard Worker query->name, query->guid, strerror(errno));
310*61046927SAndroid Build Coastguard Worker continue;
311*61046927SAndroid Build Coastguard Worker }
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker register_oa_config(perf, devinfo, query, ret);
314*61046927SAndroid Build Coastguard Worker DBG("metric set: %s (added)\n", query->guid);
315*61046927SAndroid Build Coastguard Worker }
316*61046927SAndroid Build Coastguard Worker }
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker static void
compute_topology_builtins(struct intel_perf_config * perf)319*61046927SAndroid Build Coastguard Worker compute_topology_builtins(struct intel_perf_config *perf)
320*61046927SAndroid Build Coastguard Worker {
321*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo = perf->devinfo;
322*61046927SAndroid Build Coastguard Worker
323*61046927SAndroid Build Coastguard Worker perf->sys_vars.slice_mask = devinfo->slice_masks;
324*61046927SAndroid Build Coastguard Worker perf->sys_vars.n_eu_slices = devinfo->num_slices;
325*61046927SAndroid Build Coastguard Worker
326*61046927SAndroid Build Coastguard Worker perf->sys_vars.n_eu_slice0123 = 0;
327*61046927SAndroid Build Coastguard Worker for (int s = 0; s < MIN2(4, devinfo->max_slices); s++) {
328*61046927SAndroid Build Coastguard Worker if (!intel_device_info_slice_available(devinfo, s))
329*61046927SAndroid Build Coastguard Worker continue;
330*61046927SAndroid Build Coastguard Worker
331*61046927SAndroid Build Coastguard Worker for (int ss = 0; ss < devinfo->max_subslices_per_slice; ss++) {
332*61046927SAndroid Build Coastguard Worker if (!intel_device_info_subslice_available(devinfo, s, ss))
333*61046927SAndroid Build Coastguard Worker continue;
334*61046927SAndroid Build Coastguard Worker
335*61046927SAndroid Build Coastguard Worker for (int eu = 0; eu < devinfo->max_eus_per_subslice; eu++) {
336*61046927SAndroid Build Coastguard Worker if (intel_device_info_eu_available(devinfo, s, ss, eu))
337*61046927SAndroid Build Coastguard Worker perf->sys_vars.n_eu_slice0123++;
338*61046927SAndroid Build Coastguard Worker }
339*61046927SAndroid Build Coastguard Worker }
340*61046927SAndroid Build Coastguard Worker }
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker perf->sys_vars.n_eu_sub_slices = intel_device_info_subslice_total(devinfo);
343*61046927SAndroid Build Coastguard Worker perf->sys_vars.n_eus = intel_device_info_eu_total(devinfo);
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker /* The subslice mask builtin contains bits for all slices. Prior to Gfx11
346*61046927SAndroid Build Coastguard Worker * it had groups of 3bits for each slice, on Gfx11 and above it's 8bits for
347*61046927SAndroid Build Coastguard Worker * each slice.
348*61046927SAndroid Build Coastguard Worker *
349*61046927SAndroid Build Coastguard Worker * Ideally equations would be updated to have a slice/subslice query
350*61046927SAndroid Build Coastguard Worker * function/operator.
351*61046927SAndroid Build Coastguard Worker */
352*61046927SAndroid Build Coastguard Worker perf->sys_vars.subslice_mask = 0;
353*61046927SAndroid Build Coastguard Worker
354*61046927SAndroid Build Coastguard Worker int bits_per_subslice = devinfo->ver >= 11 ? 8 : 3;
355*61046927SAndroid Build Coastguard Worker
356*61046927SAndroid Build Coastguard Worker for (int s = 0; s < util_last_bit(devinfo->slice_masks); s++) {
357*61046927SAndroid Build Coastguard Worker for (int ss = 0; ss < (devinfo->subslice_slice_stride * 8); ss++) {
358*61046927SAndroid Build Coastguard Worker if (intel_device_info_subslice_available(devinfo, s, ss))
359*61046927SAndroid Build Coastguard Worker perf->sys_vars.subslice_mask |= 1ULL << (s * bits_per_subslice + ss);
360*61046927SAndroid Build Coastguard Worker }
361*61046927SAndroid Build Coastguard Worker }
362*61046927SAndroid Build Coastguard Worker }
363*61046927SAndroid Build Coastguard Worker
364*61046927SAndroid Build Coastguard Worker static bool
init_oa_sys_vars(struct intel_perf_config * perf,bool use_register_snapshots)365*61046927SAndroid Build Coastguard Worker init_oa_sys_vars(struct intel_perf_config *perf,
366*61046927SAndroid Build Coastguard Worker bool use_register_snapshots)
367*61046927SAndroid Build Coastguard Worker {
368*61046927SAndroid Build Coastguard Worker uint64_t min_freq_mhz = 0, max_freq_mhz = 0;
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker if (!INTEL_DEBUG(DEBUG_NO_OACONFIG)) {
371*61046927SAndroid Build Coastguard Worker const char *min_file, *max_file;
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker switch (perf->devinfo->kmd_type) {
374*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
375*61046927SAndroid Build Coastguard Worker min_file = "gt_min_freq_mhz";
376*61046927SAndroid Build Coastguard Worker max_file = "gt_max_freq_mhz";
377*61046927SAndroid Build Coastguard Worker break;
378*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
379*61046927SAndroid Build Coastguard Worker min_file = "device/tile0/gt0/freq0/min_freq";
380*61046927SAndroid Build Coastguard Worker max_file = "device/tile0/gt0/freq0/max_freq";
381*61046927SAndroid Build Coastguard Worker break;
382*61046927SAndroid Build Coastguard Worker default:
383*61046927SAndroid Build Coastguard Worker unreachable("missing");
384*61046927SAndroid Build Coastguard Worker return false;
385*61046927SAndroid Build Coastguard Worker }
386*61046927SAndroid Build Coastguard Worker
387*61046927SAndroid Build Coastguard Worker if (!read_sysfs_drm_device_file_uint64(perf, min_file, &min_freq_mhz))
388*61046927SAndroid Build Coastguard Worker return false;
389*61046927SAndroid Build Coastguard Worker
390*61046927SAndroid Build Coastguard Worker if (!read_sysfs_drm_device_file_uint64(perf, max_file, &max_freq_mhz))
391*61046927SAndroid Build Coastguard Worker return false;
392*61046927SAndroid Build Coastguard Worker } else {
393*61046927SAndroid Build Coastguard Worker min_freq_mhz = 300;
394*61046927SAndroid Build Coastguard Worker max_freq_mhz = 1000;
395*61046927SAndroid Build Coastguard Worker }
396*61046927SAndroid Build Coastguard Worker
397*61046927SAndroid Build Coastguard Worker memset(&perf->sys_vars, 0, sizeof(perf->sys_vars));
398*61046927SAndroid Build Coastguard Worker perf->sys_vars.gt_min_freq = min_freq_mhz * 1000000;
399*61046927SAndroid Build Coastguard Worker perf->sys_vars.gt_max_freq = max_freq_mhz * 1000000;
400*61046927SAndroid Build Coastguard Worker perf->sys_vars.query_mode = use_register_snapshots;
401*61046927SAndroid Build Coastguard Worker compute_topology_builtins(perf);
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker return true;
404*61046927SAndroid Build Coastguard Worker }
405*61046927SAndroid Build Coastguard Worker
406*61046927SAndroid Build Coastguard Worker typedef void (*perf_register_oa_queries_t)(struct intel_perf_config *);
407*61046927SAndroid Build Coastguard Worker
408*61046927SAndroid Build Coastguard Worker static perf_register_oa_queries_t
get_register_queries_function(const struct intel_device_info * devinfo)409*61046927SAndroid Build Coastguard Worker get_register_queries_function(const struct intel_device_info *devinfo)
410*61046927SAndroid Build Coastguard Worker {
411*61046927SAndroid Build Coastguard Worker switch (devinfo->platform) {
412*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_HSW:
413*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_hsw;
414*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_CHV:
415*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_chv;
416*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_BDW:
417*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_bdw;
418*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_BXT:
419*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_bxt;
420*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_SKL:
421*61046927SAndroid Build Coastguard Worker if (devinfo->gt == 2)
422*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_sklgt2;
423*61046927SAndroid Build Coastguard Worker if (devinfo->gt == 3)
424*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_sklgt3;
425*61046927SAndroid Build Coastguard Worker if (devinfo->gt == 4)
426*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_sklgt4;
427*61046927SAndroid Build Coastguard Worker return NULL;
428*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_KBL:
429*61046927SAndroid Build Coastguard Worker if (devinfo->gt == 2)
430*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_kblgt2;
431*61046927SAndroid Build Coastguard Worker if (devinfo->gt == 3)
432*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_kblgt3;
433*61046927SAndroid Build Coastguard Worker return NULL;
434*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_GLK:
435*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_glk;
436*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_CFL:
437*61046927SAndroid Build Coastguard Worker if (devinfo->gt == 2)
438*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_cflgt2;
439*61046927SAndroid Build Coastguard Worker if (devinfo->gt == 3)
440*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_cflgt3;
441*61046927SAndroid Build Coastguard Worker return NULL;
442*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_ICL:
443*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_icl;
444*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_EHL:
445*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_ehl;
446*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_TGL:
447*61046927SAndroid Build Coastguard Worker if (devinfo->gt == 1)
448*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_tglgt1;
449*61046927SAndroid Build Coastguard Worker if (devinfo->gt == 2)
450*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_tglgt2;
451*61046927SAndroid Build Coastguard Worker return NULL;
452*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_RKL:
453*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_rkl;
454*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_DG1:
455*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_dg1;
456*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_ADL:
457*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_RPL:
458*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_adl;
459*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_DG2_G10:
460*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_acmgt3;
461*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_DG2_G11:
462*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_acmgt1;
463*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_DG2_G12:
464*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_acmgt2;
465*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_MTL_U:
466*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_MTL_H:
467*61046927SAndroid Build Coastguard Worker if (intel_device_info_eu_total(devinfo) <= 64)
468*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_mtlgt2;
469*61046927SAndroid Build Coastguard Worker if (intel_device_info_eu_total(devinfo) <= 128)
470*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_mtlgt3;
471*61046927SAndroid Build Coastguard Worker return NULL;
472*61046927SAndroid Build Coastguard Worker case INTEL_PLATFORM_LNL:
473*61046927SAndroid Build Coastguard Worker return intel_oa_register_queries_lnl;
474*61046927SAndroid Build Coastguard Worker default:
475*61046927SAndroid Build Coastguard Worker return NULL;
476*61046927SAndroid Build Coastguard Worker }
477*61046927SAndroid Build Coastguard Worker }
478*61046927SAndroid Build Coastguard Worker
479*61046927SAndroid Build Coastguard Worker static int
intel_perf_compare_counter_names(const void * v1,const void * v2)480*61046927SAndroid Build Coastguard Worker intel_perf_compare_counter_names(const void *v1, const void *v2)
481*61046927SAndroid Build Coastguard Worker {
482*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_counter *c1 = v1;
483*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_counter *c2 = v2;
484*61046927SAndroid Build Coastguard Worker
485*61046927SAndroid Build Coastguard Worker return strcmp(c1->name, c2->name);
486*61046927SAndroid Build Coastguard Worker }
487*61046927SAndroid Build Coastguard Worker
488*61046927SAndroid Build Coastguard Worker static void
sort_query(struct intel_perf_query_info * q)489*61046927SAndroid Build Coastguard Worker sort_query(struct intel_perf_query_info *q)
490*61046927SAndroid Build Coastguard Worker {
491*61046927SAndroid Build Coastguard Worker qsort(q->counters, q->n_counters, sizeof(q->counters[0]),
492*61046927SAndroid Build Coastguard Worker intel_perf_compare_counter_names);
493*61046927SAndroid Build Coastguard Worker }
494*61046927SAndroid Build Coastguard Worker
495*61046927SAndroid Build Coastguard Worker static void
load_pipeline_statistic_metrics(struct intel_perf_config * perf_cfg,const struct intel_device_info * devinfo)496*61046927SAndroid Build Coastguard Worker load_pipeline_statistic_metrics(struct intel_perf_config *perf_cfg,
497*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo)
498*61046927SAndroid Build Coastguard Worker {
499*61046927SAndroid Build Coastguard Worker struct intel_perf_query_info *query =
500*61046927SAndroid Build Coastguard Worker intel_perf_append_query_info(perf_cfg, MAX_STAT_COUNTERS);
501*61046927SAndroid Build Coastguard Worker
502*61046927SAndroid Build Coastguard Worker query->kind = INTEL_PERF_QUERY_TYPE_PIPELINE;
503*61046927SAndroid Build Coastguard Worker query->name = "Pipeline Statistics Registers";
504*61046927SAndroid Build Coastguard Worker
505*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, IA_VERTICES_COUNT,
506*61046927SAndroid Build Coastguard Worker "N vertices submitted");
507*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, IA_PRIMITIVES_COUNT,
508*61046927SAndroid Build Coastguard Worker "N primitives submitted");
509*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, VS_INVOCATION_COUNT,
510*61046927SAndroid Build Coastguard Worker "N vertex shader invocations");
511*61046927SAndroid Build Coastguard Worker
512*61046927SAndroid Build Coastguard Worker if (devinfo->ver == 6) {
513*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX6_SO_PRIM_STORAGE_NEEDED, 1, 1,
514*61046927SAndroid Build Coastguard Worker "SO_PRIM_STORAGE_NEEDED",
515*61046927SAndroid Build Coastguard Worker "N geometry shader stream-out primitives (total)");
516*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX6_SO_NUM_PRIMS_WRITTEN, 1, 1,
517*61046927SAndroid Build Coastguard Worker "SO_NUM_PRIMS_WRITTEN",
518*61046927SAndroid Build Coastguard Worker "N geometry shader stream-out primitives (written)");
519*61046927SAndroid Build Coastguard Worker } else {
520*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX7_SO_PRIM_STORAGE_NEEDED(0), 1, 1,
521*61046927SAndroid Build Coastguard Worker "SO_PRIM_STORAGE_NEEDED (Stream 0)",
522*61046927SAndroid Build Coastguard Worker "N stream-out (stream 0) primitives (total)");
523*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX7_SO_PRIM_STORAGE_NEEDED(1), 1, 1,
524*61046927SAndroid Build Coastguard Worker "SO_PRIM_STORAGE_NEEDED (Stream 1)",
525*61046927SAndroid Build Coastguard Worker "N stream-out (stream 1) primitives (total)");
526*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX7_SO_PRIM_STORAGE_NEEDED(2), 1, 1,
527*61046927SAndroid Build Coastguard Worker "SO_PRIM_STORAGE_NEEDED (Stream 2)",
528*61046927SAndroid Build Coastguard Worker "N stream-out (stream 2) primitives (total)");
529*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX7_SO_PRIM_STORAGE_NEEDED(3), 1, 1,
530*61046927SAndroid Build Coastguard Worker "SO_PRIM_STORAGE_NEEDED (Stream 3)",
531*61046927SAndroid Build Coastguard Worker "N stream-out (stream 3) primitives (total)");
532*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX7_SO_NUM_PRIMS_WRITTEN(0), 1, 1,
533*61046927SAndroid Build Coastguard Worker "SO_NUM_PRIMS_WRITTEN (Stream 0)",
534*61046927SAndroid Build Coastguard Worker "N stream-out (stream 0) primitives (written)");
535*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX7_SO_NUM_PRIMS_WRITTEN(1), 1, 1,
536*61046927SAndroid Build Coastguard Worker "SO_NUM_PRIMS_WRITTEN (Stream 1)",
537*61046927SAndroid Build Coastguard Worker "N stream-out (stream 1) primitives (written)");
538*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX7_SO_NUM_PRIMS_WRITTEN(2), 1, 1,
539*61046927SAndroid Build Coastguard Worker "SO_NUM_PRIMS_WRITTEN (Stream 2)",
540*61046927SAndroid Build Coastguard Worker "N stream-out (stream 2) primitives (written)");
541*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, GFX7_SO_NUM_PRIMS_WRITTEN(3), 1, 1,
542*61046927SAndroid Build Coastguard Worker "SO_NUM_PRIMS_WRITTEN (Stream 3)",
543*61046927SAndroid Build Coastguard Worker "N stream-out (stream 3) primitives (written)");
544*61046927SAndroid Build Coastguard Worker }
545*61046927SAndroid Build Coastguard Worker
546*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, HS_INVOCATION_COUNT,
547*61046927SAndroid Build Coastguard Worker "N TCS shader invocations");
548*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, DS_INVOCATION_COUNT,
549*61046927SAndroid Build Coastguard Worker "N TES shader invocations");
550*61046927SAndroid Build Coastguard Worker
551*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, GS_INVOCATION_COUNT,
552*61046927SAndroid Build Coastguard Worker "N geometry shader invocations");
553*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, GS_PRIMITIVES_COUNT,
554*61046927SAndroid Build Coastguard Worker "N geometry shader primitives emitted");
555*61046927SAndroid Build Coastguard Worker
556*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, CL_INVOCATION_COUNT,
557*61046927SAndroid Build Coastguard Worker "N primitives entering clipping");
558*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, CL_PRIMITIVES_COUNT,
559*61046927SAndroid Build Coastguard Worker "N primitives leaving clipping");
560*61046927SAndroid Build Coastguard Worker
561*61046927SAndroid Build Coastguard Worker if (devinfo->verx10 == 75 || devinfo->ver == 8) {
562*61046927SAndroid Build Coastguard Worker intel_perf_query_add_stat_reg(query, PS_INVOCATION_COUNT, 1, 4,
563*61046927SAndroid Build Coastguard Worker "N fragment shader invocations",
564*61046927SAndroid Build Coastguard Worker "N fragment shader invocations");
565*61046927SAndroid Build Coastguard Worker } else {
566*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, PS_INVOCATION_COUNT,
567*61046927SAndroid Build Coastguard Worker "N fragment shader invocations");
568*61046927SAndroid Build Coastguard Worker }
569*61046927SAndroid Build Coastguard Worker
570*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, PS_DEPTH_COUNT,
571*61046927SAndroid Build Coastguard Worker "N z-pass fragments");
572*61046927SAndroid Build Coastguard Worker
573*61046927SAndroid Build Coastguard Worker if (devinfo->ver >= 7) {
574*61046927SAndroid Build Coastguard Worker intel_perf_query_add_basic_stat_reg(query, CS_INVOCATION_COUNT,
575*61046927SAndroid Build Coastguard Worker "N compute shader invocations");
576*61046927SAndroid Build Coastguard Worker }
577*61046927SAndroid Build Coastguard Worker
578*61046927SAndroid Build Coastguard Worker query->data_size = sizeof(uint64_t) * query->n_counters;
579*61046927SAndroid Build Coastguard Worker
580*61046927SAndroid Build Coastguard Worker sort_query(query);
581*61046927SAndroid Build Coastguard Worker }
582*61046927SAndroid Build Coastguard Worker
583*61046927SAndroid Build Coastguard Worker static inline int
compare_str_or_null(const char * s1,const char * s2)584*61046927SAndroid Build Coastguard Worker compare_str_or_null(const char *s1, const char *s2)
585*61046927SAndroid Build Coastguard Worker {
586*61046927SAndroid Build Coastguard Worker if (s1 == NULL && s2 == NULL)
587*61046927SAndroid Build Coastguard Worker return 0;
588*61046927SAndroid Build Coastguard Worker if (s1 == NULL)
589*61046927SAndroid Build Coastguard Worker return -1;
590*61046927SAndroid Build Coastguard Worker if (s2 == NULL)
591*61046927SAndroid Build Coastguard Worker return 1;
592*61046927SAndroid Build Coastguard Worker
593*61046927SAndroid Build Coastguard Worker return strcmp(s1, s2);
594*61046927SAndroid Build Coastguard Worker }
595*61046927SAndroid Build Coastguard Worker
596*61046927SAndroid Build Coastguard Worker static int
compare_counter_categories_and_names(const void * _c1,const void * _c2)597*61046927SAndroid Build Coastguard Worker compare_counter_categories_and_names(const void *_c1, const void *_c2)
598*61046927SAndroid Build Coastguard Worker {
599*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_counter_info *c1 = (const struct intel_perf_query_counter_info *)_c1;
600*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_counter_info *c2 = (const struct intel_perf_query_counter_info *)_c2;
601*61046927SAndroid Build Coastguard Worker
602*61046927SAndroid Build Coastguard Worker /* pipeline counters don't have an assigned category */
603*61046927SAndroid Build Coastguard Worker int r = compare_str_or_null(c1->counter->category, c2->counter->category);
604*61046927SAndroid Build Coastguard Worker if (r)
605*61046927SAndroid Build Coastguard Worker return r;
606*61046927SAndroid Build Coastguard Worker
607*61046927SAndroid Build Coastguard Worker return strcmp(c1->counter->name, c2->counter->name);
608*61046927SAndroid Build Coastguard Worker }
609*61046927SAndroid Build Coastguard Worker
610*61046927SAndroid Build Coastguard Worker static void
build_unique_counter_list(struct intel_perf_config * perf)611*61046927SAndroid Build Coastguard Worker build_unique_counter_list(struct intel_perf_config *perf)
612*61046927SAndroid Build Coastguard Worker {
613*61046927SAndroid Build Coastguard Worker size_t max_counters = 0;
614*61046927SAndroid Build Coastguard Worker
615*61046927SAndroid Build Coastguard Worker for (int q = 0; q < perf->n_queries; q++)
616*61046927SAndroid Build Coastguard Worker max_counters += perf->queries[q].n_counters;
617*61046927SAndroid Build Coastguard Worker
618*61046927SAndroid Build Coastguard Worker /*
619*61046927SAndroid Build Coastguard Worker * Allocate big enough array to hold maximum possible number of counters.
620*61046927SAndroid Build Coastguard Worker * We can't alloc it small and realloc when needed because the hash table
621*61046927SAndroid Build Coastguard Worker * below contains pointers to this array.
622*61046927SAndroid Build Coastguard Worker */
623*61046927SAndroid Build Coastguard Worker struct intel_perf_query_counter_info *counter_infos =
624*61046927SAndroid Build Coastguard Worker rzalloc_array_size(perf, sizeof(counter_infos[0]), max_counters);
625*61046927SAndroid Build Coastguard Worker
626*61046927SAndroid Build Coastguard Worker perf->n_counters = 0;
627*61046927SAndroid Build Coastguard Worker
628*61046927SAndroid Build Coastguard Worker struct hash_table *counters_table =
629*61046927SAndroid Build Coastguard Worker _mesa_hash_table_create(NULL,
630*61046927SAndroid Build Coastguard Worker _mesa_hash_string,
631*61046927SAndroid Build Coastguard Worker _mesa_key_string_equal);
632*61046927SAndroid Build Coastguard Worker struct hash_entry *entry;
633*61046927SAndroid Build Coastguard Worker for (int q = 0; q < perf->n_queries ; q++) {
634*61046927SAndroid Build Coastguard Worker struct intel_perf_query_info *query = &perf->queries[q];
635*61046927SAndroid Build Coastguard Worker
636*61046927SAndroid Build Coastguard Worker for (int c = 0; c < query->n_counters; c++) {
637*61046927SAndroid Build Coastguard Worker struct intel_perf_query_counter *counter;
638*61046927SAndroid Build Coastguard Worker struct intel_perf_query_counter_info *counter_info;
639*61046927SAndroid Build Coastguard Worker
640*61046927SAndroid Build Coastguard Worker counter = &query->counters[c];
641*61046927SAndroid Build Coastguard Worker entry = _mesa_hash_table_search(counters_table, counter->symbol_name);
642*61046927SAndroid Build Coastguard Worker
643*61046927SAndroid Build Coastguard Worker if (entry) {
644*61046927SAndroid Build Coastguard Worker counter_info = entry->data;
645*61046927SAndroid Build Coastguard Worker BITSET_SET(counter_info->query_mask, q);
646*61046927SAndroid Build Coastguard Worker continue;
647*61046927SAndroid Build Coastguard Worker }
648*61046927SAndroid Build Coastguard Worker assert(perf->n_counters < max_counters);
649*61046927SAndroid Build Coastguard Worker
650*61046927SAndroid Build Coastguard Worker counter_info = &counter_infos[perf->n_counters++];
651*61046927SAndroid Build Coastguard Worker counter_info->counter = counter;
652*61046927SAndroid Build Coastguard Worker BITSET_SET(counter_info->query_mask, q);
653*61046927SAndroid Build Coastguard Worker
654*61046927SAndroid Build Coastguard Worker counter_info->location.group_idx = q;
655*61046927SAndroid Build Coastguard Worker counter_info->location.counter_idx = c;
656*61046927SAndroid Build Coastguard Worker
657*61046927SAndroid Build Coastguard Worker _mesa_hash_table_insert(counters_table, counter->symbol_name, counter_info);
658*61046927SAndroid Build Coastguard Worker }
659*61046927SAndroid Build Coastguard Worker }
660*61046927SAndroid Build Coastguard Worker
661*61046927SAndroid Build Coastguard Worker _mesa_hash_table_destroy(counters_table, NULL);
662*61046927SAndroid Build Coastguard Worker
663*61046927SAndroid Build Coastguard Worker perf->counter_infos = counter_infos;
664*61046927SAndroid Build Coastguard Worker
665*61046927SAndroid Build Coastguard Worker qsort(perf->counter_infos, perf->n_counters, sizeof(perf->counter_infos[0]),
666*61046927SAndroid Build Coastguard Worker compare_counter_categories_and_names);
667*61046927SAndroid Build Coastguard Worker }
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker static bool
oa_metrics_available(struct intel_perf_config * perf,int fd,const struct intel_device_info * devinfo,bool use_register_snapshots)670*61046927SAndroid Build Coastguard Worker oa_metrics_available(struct intel_perf_config *perf, int fd,
671*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo,
672*61046927SAndroid Build Coastguard Worker bool use_register_snapshots)
673*61046927SAndroid Build Coastguard Worker {
674*61046927SAndroid Build Coastguard Worker perf_register_oa_queries_t oa_register = get_register_queries_function(devinfo);
675*61046927SAndroid Build Coastguard Worker bool oa_metrics_available = false;
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker perf->devinfo = devinfo;
678*61046927SAndroid Build Coastguard Worker
679*61046927SAndroid Build Coastguard Worker /* Consider an invalid as supported. */
680*61046927SAndroid Build Coastguard Worker if (fd == -1) {
681*61046927SAndroid Build Coastguard Worker perf->features_supported = INTEL_PERF_FEATURE_QUERY_PERF;
682*61046927SAndroid Build Coastguard Worker return true;
683*61046927SAndroid Build Coastguard Worker }
684*61046927SAndroid Build Coastguard Worker
685*61046927SAndroid Build Coastguard Worker perf->enable_all_metrics = debug_get_bool_option("INTEL_EXTENDED_METRICS", false);
686*61046927SAndroid Build Coastguard Worker
687*61046927SAndroid Build Coastguard Worker /* TODO: We should query this from i915?
688*61046927SAndroid Build Coastguard Worker * Looks like Xe2 platforms don't need it but don't have a spec quote to
689*61046927SAndroid Build Coastguard Worker * back it.
690*61046927SAndroid Build Coastguard Worker */
691*61046927SAndroid Build Coastguard Worker if (devinfo->verx10 == 125)
692*61046927SAndroid Build Coastguard Worker perf->oa_timestamp_shift = 1;
693*61046927SAndroid Build Coastguard Worker
694*61046927SAndroid Build Coastguard Worker perf->oa_timestamp_mask =
695*61046927SAndroid Build Coastguard Worker 0xffffffffffffffffull >> (32 + perf->oa_timestamp_shift);
696*61046927SAndroid Build Coastguard Worker
697*61046927SAndroid Build Coastguard Worker switch (devinfo->kmd_type) {
698*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
699*61046927SAndroid Build Coastguard Worker oa_metrics_available = i915_oa_metrics_available(perf, fd, use_register_snapshots);
700*61046927SAndroid Build Coastguard Worker break;
701*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
702*61046927SAndroid Build Coastguard Worker oa_metrics_available = xe_oa_metrics_available(perf, fd, use_register_snapshots);
703*61046927SAndroid Build Coastguard Worker break;
704*61046927SAndroid Build Coastguard Worker default:
705*61046927SAndroid Build Coastguard Worker unreachable("missing");
706*61046927SAndroid Build Coastguard Worker break;
707*61046927SAndroid Build Coastguard Worker }
708*61046927SAndroid Build Coastguard Worker
709*61046927SAndroid Build Coastguard Worker return oa_metrics_available &&
710*61046927SAndroid Build Coastguard Worker oa_register &&
711*61046927SAndroid Build Coastguard Worker get_sysfs_dev_dir(perf, fd) &&
712*61046927SAndroid Build Coastguard Worker init_oa_sys_vars(perf, use_register_snapshots);
713*61046927SAndroid Build Coastguard Worker }
714*61046927SAndroid Build Coastguard Worker
715*61046927SAndroid Build Coastguard Worker static void
load_oa_metrics(struct intel_perf_config * perf,int fd,const struct intel_device_info * devinfo)716*61046927SAndroid Build Coastguard Worker load_oa_metrics(struct intel_perf_config *perf, int fd,
717*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo)
718*61046927SAndroid Build Coastguard Worker {
719*61046927SAndroid Build Coastguard Worker int existing_queries = perf->n_queries;
720*61046927SAndroid Build Coastguard Worker
721*61046927SAndroid Build Coastguard Worker perf_register_oa_queries_t oa_register = get_register_queries_function(devinfo);
722*61046927SAndroid Build Coastguard Worker
723*61046927SAndroid Build Coastguard Worker perf->oa_metrics_table =
724*61046927SAndroid Build Coastguard Worker _mesa_hash_table_create(perf, _mesa_hash_string,
725*61046927SAndroid Build Coastguard Worker _mesa_key_string_equal);
726*61046927SAndroid Build Coastguard Worker
727*61046927SAndroid Build Coastguard Worker /* Index all the metric sets mesa knows about before looking to see what
728*61046927SAndroid Build Coastguard Worker * the kernel is advertising.
729*61046927SAndroid Build Coastguard Worker */
730*61046927SAndroid Build Coastguard Worker oa_register(perf);
731*61046927SAndroid Build Coastguard Worker
732*61046927SAndroid Build Coastguard Worker if (!INTEL_DEBUG(DEBUG_NO_OACONFIG)) {
733*61046927SAndroid Build Coastguard Worker if (kernel_has_dynamic_config_support(perf, fd))
734*61046927SAndroid Build Coastguard Worker init_oa_configs(perf, fd, devinfo);
735*61046927SAndroid Build Coastguard Worker else
736*61046927SAndroid Build Coastguard Worker enumerate_sysfs_metrics(perf, devinfo);
737*61046927SAndroid Build Coastguard Worker } else {
738*61046927SAndroid Build Coastguard Worker add_all_metrics(perf, devinfo);
739*61046927SAndroid Build Coastguard Worker }
740*61046927SAndroid Build Coastguard Worker
741*61046927SAndroid Build Coastguard Worker /* sort counters in each individual group created by this function by name */
742*61046927SAndroid Build Coastguard Worker for (int i = existing_queries; i < perf->n_queries; ++i)
743*61046927SAndroid Build Coastguard Worker sort_query(&perf->queries[i]);
744*61046927SAndroid Build Coastguard Worker
745*61046927SAndroid Build Coastguard Worker /* Select a fallback OA metric. Look for the TestOa metric or use the last
746*61046927SAndroid Build Coastguard Worker * one if no present (on HSW).
747*61046927SAndroid Build Coastguard Worker */
748*61046927SAndroid Build Coastguard Worker for (int i = existing_queries; i < perf->n_queries; i++) {
749*61046927SAndroid Build Coastguard Worker if (perf->queries[i].symbol_name &&
750*61046927SAndroid Build Coastguard Worker strcmp(perf->queries[i].symbol_name, "TestOa") == 0) {
751*61046927SAndroid Build Coastguard Worker perf->fallback_raw_oa_metric = perf->queries[i].oa_metrics_set_id;
752*61046927SAndroid Build Coastguard Worker break;
753*61046927SAndroid Build Coastguard Worker }
754*61046927SAndroid Build Coastguard Worker }
755*61046927SAndroid Build Coastguard Worker if (perf->fallback_raw_oa_metric == 0 && perf->n_queries > 0)
756*61046927SAndroid Build Coastguard Worker perf->fallback_raw_oa_metric = perf->queries[perf->n_queries - 1].oa_metrics_set_id;
757*61046927SAndroid Build Coastguard Worker }
758*61046927SAndroid Build Coastguard Worker
759*61046927SAndroid Build Coastguard Worker struct intel_perf_registers *
intel_perf_load_configuration(struct intel_perf_config * perf_cfg,int fd,const char * guid)760*61046927SAndroid Build Coastguard Worker intel_perf_load_configuration(struct intel_perf_config *perf_cfg, int fd, const char *guid)
761*61046927SAndroid Build Coastguard Worker {
762*61046927SAndroid Build Coastguard Worker if (!(perf_cfg->features_supported & INTEL_PERF_FEATURE_QUERY_PERF))
763*61046927SAndroid Build Coastguard Worker return NULL;
764*61046927SAndroid Build Coastguard Worker
765*61046927SAndroid Build Coastguard Worker switch (perf_cfg->devinfo->kmd_type) {
766*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
767*61046927SAndroid Build Coastguard Worker return i915_perf_load_configurations(perf_cfg, fd, guid);
768*61046927SAndroid Build Coastguard Worker default:
769*61046927SAndroid Build Coastguard Worker unreachable("missing");
770*61046927SAndroid Build Coastguard Worker return NULL;
771*61046927SAndroid Build Coastguard Worker }
772*61046927SAndroid Build Coastguard Worker }
773*61046927SAndroid Build Coastguard Worker
774*61046927SAndroid Build Coastguard Worker uint64_t
intel_perf_store_configuration(struct intel_perf_config * perf_cfg,int fd,const struct intel_perf_registers * config,const char * guid)775*61046927SAndroid Build Coastguard Worker intel_perf_store_configuration(struct intel_perf_config *perf_cfg, int fd,
776*61046927SAndroid Build Coastguard Worker const struct intel_perf_registers *config,
777*61046927SAndroid Build Coastguard Worker const char *guid)
778*61046927SAndroid Build Coastguard Worker {
779*61046927SAndroid Build Coastguard Worker if (guid)
780*61046927SAndroid Build Coastguard Worker return kmd_add_config(perf_cfg, fd, config, guid);
781*61046927SAndroid Build Coastguard Worker
782*61046927SAndroid Build Coastguard Worker struct mesa_sha1 sha1_ctx;
783*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&sha1_ctx);
784*61046927SAndroid Build Coastguard Worker
785*61046927SAndroid Build Coastguard Worker if (config->flex_regs) {
786*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&sha1_ctx, config->flex_regs,
787*61046927SAndroid Build Coastguard Worker sizeof(config->flex_regs[0]) *
788*61046927SAndroid Build Coastguard Worker config->n_flex_regs);
789*61046927SAndroid Build Coastguard Worker }
790*61046927SAndroid Build Coastguard Worker if (config->mux_regs) {
791*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&sha1_ctx, config->mux_regs,
792*61046927SAndroid Build Coastguard Worker sizeof(config->mux_regs[0]) *
793*61046927SAndroid Build Coastguard Worker config->n_mux_regs);
794*61046927SAndroid Build Coastguard Worker }
795*61046927SAndroid Build Coastguard Worker if (config->b_counter_regs) {
796*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&sha1_ctx, config->b_counter_regs,
797*61046927SAndroid Build Coastguard Worker sizeof(config->b_counter_regs[0]) *
798*61046927SAndroid Build Coastguard Worker config->n_b_counter_regs);
799*61046927SAndroid Build Coastguard Worker }
800*61046927SAndroid Build Coastguard Worker
801*61046927SAndroid Build Coastguard Worker uint8_t hash[20];
802*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&sha1_ctx, hash);
803*61046927SAndroid Build Coastguard Worker
804*61046927SAndroid Build Coastguard Worker char formatted_hash[41];
805*61046927SAndroid Build Coastguard Worker _mesa_sha1_format(formatted_hash, hash);
806*61046927SAndroid Build Coastguard Worker
807*61046927SAndroid Build Coastguard Worker char generated_guid[37];
808*61046927SAndroid Build Coastguard Worker snprintf(generated_guid, sizeof(generated_guid),
809*61046927SAndroid Build Coastguard Worker "%.8s-%.4s-%.4s-%.4s-%.12s",
810*61046927SAndroid Build Coastguard Worker &formatted_hash[0], &formatted_hash[8],
811*61046927SAndroid Build Coastguard Worker &formatted_hash[8 + 4], &formatted_hash[8 + 4 + 4],
812*61046927SAndroid Build Coastguard Worker &formatted_hash[8 + 4 + 4 + 4]);
813*61046927SAndroid Build Coastguard Worker
814*61046927SAndroid Build Coastguard Worker /* Check if already present. */
815*61046927SAndroid Build Coastguard Worker uint64_t id;
816*61046927SAndroid Build Coastguard Worker if (intel_perf_load_metric_id(perf_cfg, generated_guid, &id))
817*61046927SAndroid Build Coastguard Worker return id;
818*61046927SAndroid Build Coastguard Worker
819*61046927SAndroid Build Coastguard Worker return kmd_add_config(perf_cfg, fd, config, generated_guid);
820*61046927SAndroid Build Coastguard Worker }
821*61046927SAndroid Build Coastguard Worker
822*61046927SAndroid Build Coastguard Worker void
intel_perf_remove_configuration(struct intel_perf_config * perf_cfg,int fd,uint64_t config_id)823*61046927SAndroid Build Coastguard Worker intel_perf_remove_configuration(struct intel_perf_config *perf_cfg, int fd,
824*61046927SAndroid Build Coastguard Worker uint64_t config_id)
825*61046927SAndroid Build Coastguard Worker {
826*61046927SAndroid Build Coastguard Worker switch (perf_cfg->devinfo->kmd_type) {
827*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
828*61046927SAndroid Build Coastguard Worker i915_remove_config(perf_cfg, fd, config_id);
829*61046927SAndroid Build Coastguard Worker break;
830*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
831*61046927SAndroid Build Coastguard Worker xe_remove_config(perf_cfg, fd, config_id);
832*61046927SAndroid Build Coastguard Worker break;
833*61046927SAndroid Build Coastguard Worker default:
834*61046927SAndroid Build Coastguard Worker unreachable("missing");
835*61046927SAndroid Build Coastguard Worker }
836*61046927SAndroid Build Coastguard Worker }
837*61046927SAndroid Build Coastguard Worker
838*61046927SAndroid Build Coastguard Worker static void
get_passes_mask(struct intel_perf_config * perf,const uint32_t * counter_indices,uint32_t counter_indices_count,BITSET_WORD * queries_mask)839*61046927SAndroid Build Coastguard Worker get_passes_mask(struct intel_perf_config *perf,
840*61046927SAndroid Build Coastguard Worker const uint32_t *counter_indices,
841*61046927SAndroid Build Coastguard Worker uint32_t counter_indices_count,
842*61046927SAndroid Build Coastguard Worker BITSET_WORD *queries_mask)
843*61046927SAndroid Build Coastguard Worker {
844*61046927SAndroid Build Coastguard Worker /* For each counter, look if it's already computed by a selected metric set
845*61046927SAndroid Build Coastguard Worker * or find one that can compute it.
846*61046927SAndroid Build Coastguard Worker */
847*61046927SAndroid Build Coastguard Worker for (uint32_t c = 0; c < counter_indices_count; c++) {
848*61046927SAndroid Build Coastguard Worker uint32_t counter_idx = counter_indices[c];
849*61046927SAndroid Build Coastguard Worker assert(counter_idx < perf->n_counters);
850*61046927SAndroid Build Coastguard Worker
851*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_counter_info *counter_info =
852*61046927SAndroid Build Coastguard Worker &perf->counter_infos[counter_idx];
853*61046927SAndroid Build Coastguard Worker
854*61046927SAndroid Build Coastguard Worker /* Check if the counter is already computed by one of the selected
855*61046927SAndroid Build Coastguard Worker * metric set. If it is, there is nothing more to do with this counter.
856*61046927SAndroid Build Coastguard Worker */
857*61046927SAndroid Build Coastguard Worker uint32_t match = UINT32_MAX;
858*61046927SAndroid Build Coastguard Worker for (uint32_t w = 0; w < BITSET_WORDS(INTEL_PERF_MAX_METRIC_SETS); w++) {
859*61046927SAndroid Build Coastguard Worker if (queries_mask[w] & counter_info->query_mask[w]) {
860*61046927SAndroid Build Coastguard Worker match = w * BITSET_WORDBITS + ffsll(queries_mask[w] & counter_info->query_mask[w]) - 1;
861*61046927SAndroid Build Coastguard Worker break;
862*61046927SAndroid Build Coastguard Worker }
863*61046927SAndroid Build Coastguard Worker }
864*61046927SAndroid Build Coastguard Worker if (match != UINT32_MAX)
865*61046927SAndroid Build Coastguard Worker continue;
866*61046927SAndroid Build Coastguard Worker
867*61046927SAndroid Build Coastguard Worker /* Now go through each metric set and find one that contains this
868*61046927SAndroid Build Coastguard Worker * counter.
869*61046927SAndroid Build Coastguard Worker */
870*61046927SAndroid Build Coastguard Worker bool found = false;
871*61046927SAndroid Build Coastguard Worker for (uint32_t w = 0; w < BITSET_WORDS(INTEL_PERF_MAX_METRIC_SETS); w++) {
872*61046927SAndroid Build Coastguard Worker if (!counter_info->query_mask[w])
873*61046927SAndroid Build Coastguard Worker continue;
874*61046927SAndroid Build Coastguard Worker
875*61046927SAndroid Build Coastguard Worker uint32_t query_idx = w * BITSET_WORDBITS + ffsll(counter_info->query_mask[w]) - 1;
876*61046927SAndroid Build Coastguard Worker
877*61046927SAndroid Build Coastguard Worker /* Since we already looked for this in the query_mask, it should not
878*61046927SAndroid Build Coastguard Worker * be set.
879*61046927SAndroid Build Coastguard Worker */
880*61046927SAndroid Build Coastguard Worker assert(!BITSET_TEST(queries_mask, query_idx));
881*61046927SAndroid Build Coastguard Worker
882*61046927SAndroid Build Coastguard Worker BITSET_SET(queries_mask, query_idx);
883*61046927SAndroid Build Coastguard Worker found = true;
884*61046927SAndroid Build Coastguard Worker break;
885*61046927SAndroid Build Coastguard Worker }
886*61046927SAndroid Build Coastguard Worker assert(found);
887*61046927SAndroid Build Coastguard Worker }
888*61046927SAndroid Build Coastguard Worker }
889*61046927SAndroid Build Coastguard Worker
890*61046927SAndroid Build Coastguard Worker uint32_t
intel_perf_get_n_passes(struct intel_perf_config * perf,const uint32_t * counter_indices,uint32_t counter_indices_count,struct intel_perf_query_info ** pass_queries)891*61046927SAndroid Build Coastguard Worker intel_perf_get_n_passes(struct intel_perf_config *perf,
892*61046927SAndroid Build Coastguard Worker const uint32_t *counter_indices,
893*61046927SAndroid Build Coastguard Worker uint32_t counter_indices_count,
894*61046927SAndroid Build Coastguard Worker struct intel_perf_query_info **pass_queries)
895*61046927SAndroid Build Coastguard Worker {
896*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(queries_mask, INTEL_PERF_MAX_METRIC_SETS);
897*61046927SAndroid Build Coastguard Worker BITSET_ZERO(queries_mask);
898*61046927SAndroid Build Coastguard Worker
899*61046927SAndroid Build Coastguard Worker get_passes_mask(perf, counter_indices, counter_indices_count, queries_mask);
900*61046927SAndroid Build Coastguard Worker
901*61046927SAndroid Build Coastguard Worker if (pass_queries) {
902*61046927SAndroid Build Coastguard Worker uint32_t pass = 0;
903*61046927SAndroid Build Coastguard Worker for (uint32_t q = 0; q < perf->n_queries; q++) {
904*61046927SAndroid Build Coastguard Worker if (BITSET_TEST(queries_mask, q))
905*61046927SAndroid Build Coastguard Worker pass_queries[pass++] = &perf->queries[q];
906*61046927SAndroid Build Coastguard Worker }
907*61046927SAndroid Build Coastguard Worker }
908*61046927SAndroid Build Coastguard Worker
909*61046927SAndroid Build Coastguard Worker return BITSET_COUNT(queries_mask);
910*61046927SAndroid Build Coastguard Worker }
911*61046927SAndroid Build Coastguard Worker
912*61046927SAndroid Build Coastguard Worker void
intel_perf_get_counters_passes(struct intel_perf_config * perf,const uint32_t * counter_indices,uint32_t counter_indices_count,struct intel_perf_counter_pass * counter_pass)913*61046927SAndroid Build Coastguard Worker intel_perf_get_counters_passes(struct intel_perf_config *perf,
914*61046927SAndroid Build Coastguard Worker const uint32_t *counter_indices,
915*61046927SAndroid Build Coastguard Worker uint32_t counter_indices_count,
916*61046927SAndroid Build Coastguard Worker struct intel_perf_counter_pass *counter_pass)
917*61046927SAndroid Build Coastguard Worker {
918*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(queries_mask, INTEL_PERF_MAX_METRIC_SETS);
919*61046927SAndroid Build Coastguard Worker BITSET_ZERO(queries_mask);
920*61046927SAndroid Build Coastguard Worker
921*61046927SAndroid Build Coastguard Worker get_passes_mask(perf, counter_indices, counter_indices_count, queries_mask);
922*61046927SAndroid Build Coastguard Worker
923*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < counter_indices_count; i++) {
924*61046927SAndroid Build Coastguard Worker assert(counter_indices[i] < perf->n_counters);
925*61046927SAndroid Build Coastguard Worker
926*61046927SAndroid Build Coastguard Worker uint32_t counter_idx = counter_indices[i];
927*61046927SAndroid Build Coastguard Worker counter_pass[i].counter = perf->counter_infos[counter_idx].counter;
928*61046927SAndroid Build Coastguard Worker
929*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_counter_info *counter_info =
930*61046927SAndroid Build Coastguard Worker &perf->counter_infos[counter_idx];
931*61046927SAndroid Build Coastguard Worker
932*61046927SAndroid Build Coastguard Worker uint32_t query_idx = UINT32_MAX;
933*61046927SAndroid Build Coastguard Worker for (uint32_t w = 0; w < BITSET_WORDS(INTEL_PERF_MAX_METRIC_SETS); w++) {
934*61046927SAndroid Build Coastguard Worker if (counter_info->query_mask[w] & queries_mask[w]) {
935*61046927SAndroid Build Coastguard Worker query_idx = w * BITSET_WORDBITS +
936*61046927SAndroid Build Coastguard Worker ffsll(counter_info->query_mask[w] & queries_mask[w]) - 1;
937*61046927SAndroid Build Coastguard Worker break;
938*61046927SAndroid Build Coastguard Worker }
939*61046927SAndroid Build Coastguard Worker }
940*61046927SAndroid Build Coastguard Worker assert(query_idx != UINT32_MAX);
941*61046927SAndroid Build Coastguard Worker
942*61046927SAndroid Build Coastguard Worker counter_pass[i].query = &perf->queries[query_idx];
943*61046927SAndroid Build Coastguard Worker }
944*61046927SAndroid Build Coastguard Worker }
945*61046927SAndroid Build Coastguard Worker
946*61046927SAndroid Build Coastguard Worker /* Accumulate 32bits OA counters */
947*61046927SAndroid Build Coastguard Worker static inline void
accumulate_uint32(const uint32_t * report0,const uint32_t * report1,uint64_t * accumulator)948*61046927SAndroid Build Coastguard Worker accumulate_uint32(const uint32_t *report0,
949*61046927SAndroid Build Coastguard Worker const uint32_t *report1,
950*61046927SAndroid Build Coastguard Worker uint64_t *accumulator)
951*61046927SAndroid Build Coastguard Worker {
952*61046927SAndroid Build Coastguard Worker *accumulator += (uint32_t)(*report1 - *report0);
953*61046927SAndroid Build Coastguard Worker }
954*61046927SAndroid Build Coastguard Worker
955*61046927SAndroid Build Coastguard Worker /* Accumulate 40bits OA counters */
956*61046927SAndroid Build Coastguard Worker static inline void
accumulate_uint40(int a_index,const uint32_t * report0,const uint32_t * report1,uint64_t * accumulator)957*61046927SAndroid Build Coastguard Worker accumulate_uint40(int a_index,
958*61046927SAndroid Build Coastguard Worker const uint32_t *report0,
959*61046927SAndroid Build Coastguard Worker const uint32_t *report1,
960*61046927SAndroid Build Coastguard Worker uint64_t *accumulator)
961*61046927SAndroid Build Coastguard Worker {
962*61046927SAndroid Build Coastguard Worker const uint8_t *high_bytes0 = (uint8_t *)(report0 + 40);
963*61046927SAndroid Build Coastguard Worker const uint8_t *high_bytes1 = (uint8_t *)(report1 + 40);
964*61046927SAndroid Build Coastguard Worker uint64_t high0 = (uint64_t)(high_bytes0[a_index]) << 32;
965*61046927SAndroid Build Coastguard Worker uint64_t high1 = (uint64_t)(high_bytes1[a_index]) << 32;
966*61046927SAndroid Build Coastguard Worker uint64_t value0 = report0[a_index + 4] | high0;
967*61046927SAndroid Build Coastguard Worker uint64_t value1 = report1[a_index + 4] | high1;
968*61046927SAndroid Build Coastguard Worker uint64_t delta;
969*61046927SAndroid Build Coastguard Worker
970*61046927SAndroid Build Coastguard Worker if (value0 > value1)
971*61046927SAndroid Build Coastguard Worker delta = (1ULL << 40) + value1 - value0;
972*61046927SAndroid Build Coastguard Worker else
973*61046927SAndroid Build Coastguard Worker delta = value1 - value0;
974*61046927SAndroid Build Coastguard Worker
975*61046927SAndroid Build Coastguard Worker *accumulator += delta;
976*61046927SAndroid Build Coastguard Worker }
977*61046927SAndroid Build Coastguard Worker
978*61046927SAndroid Build Coastguard Worker /* Accumulate 64bits OA counters */
979*61046927SAndroid Build Coastguard Worker static inline void
accumulate_uint64(const uint32_t * report0,const uint32_t * report1,uint64_t * accumulator)980*61046927SAndroid Build Coastguard Worker accumulate_uint64(const uint32_t *report0,
981*61046927SAndroid Build Coastguard Worker const uint32_t *report1,
982*61046927SAndroid Build Coastguard Worker uint64_t *accumulator)
983*61046927SAndroid Build Coastguard Worker {
984*61046927SAndroid Build Coastguard Worker *accumulator += *((const uint64_t *)report1) - *((const uint64_t *)report0);
985*61046927SAndroid Build Coastguard Worker }
986*61046927SAndroid Build Coastguard Worker
987*61046927SAndroid Build Coastguard Worker static void
gfx8_read_report_clock_ratios(const uint32_t * report,uint64_t * slice_freq_hz,uint64_t * unslice_freq_hz)988*61046927SAndroid Build Coastguard Worker gfx8_read_report_clock_ratios(const uint32_t *report,
989*61046927SAndroid Build Coastguard Worker uint64_t *slice_freq_hz,
990*61046927SAndroid Build Coastguard Worker uint64_t *unslice_freq_hz)
991*61046927SAndroid Build Coastguard Worker {
992*61046927SAndroid Build Coastguard Worker /* The lower 16bits of the RPT_ID field of the OA reports contains a
993*61046927SAndroid Build Coastguard Worker * snapshot of the bits coming from the RP_FREQ_NORMAL register and is
994*61046927SAndroid Build Coastguard Worker * divided this way :
995*61046927SAndroid Build Coastguard Worker *
996*61046927SAndroid Build Coastguard Worker * RPT_ID[31:25]: RP_FREQ_NORMAL[20:14] (low squashed_slice_clock_frequency)
997*61046927SAndroid Build Coastguard Worker * RPT_ID[10:9]: RP_FREQ_NORMAL[22:21] (high squashed_slice_clock_frequency)
998*61046927SAndroid Build Coastguard Worker * RPT_ID[8:0]: RP_FREQ_NORMAL[31:23] (squashed_unslice_clock_frequency)
999*61046927SAndroid Build Coastguard Worker *
1000*61046927SAndroid Build Coastguard Worker * RP_FREQ_NORMAL[31:23]: Software Unslice Ratio Request
1001*61046927SAndroid Build Coastguard Worker * Multiple of 33.33MHz 2xclk (16 MHz 1xclk)
1002*61046927SAndroid Build Coastguard Worker *
1003*61046927SAndroid Build Coastguard Worker * RP_FREQ_NORMAL[22:14]: Software Slice Ratio Request
1004*61046927SAndroid Build Coastguard Worker * Multiple of 33.33MHz 2xclk (16 MHz 1xclk)
1005*61046927SAndroid Build Coastguard Worker */
1006*61046927SAndroid Build Coastguard Worker
1007*61046927SAndroid Build Coastguard Worker uint32_t unslice_freq = report[0] & 0x1ff;
1008*61046927SAndroid Build Coastguard Worker uint32_t slice_freq_low = (report[0] >> 25) & 0x7f;
1009*61046927SAndroid Build Coastguard Worker uint32_t slice_freq_high = (report[0] >> 9) & 0x3;
1010*61046927SAndroid Build Coastguard Worker uint32_t slice_freq = slice_freq_low | (slice_freq_high << 7);
1011*61046927SAndroid Build Coastguard Worker
1012*61046927SAndroid Build Coastguard Worker *slice_freq_hz = slice_freq * 16666667ULL;
1013*61046927SAndroid Build Coastguard Worker *unslice_freq_hz = unslice_freq * 16666667ULL;
1014*61046927SAndroid Build Coastguard Worker }
1015*61046927SAndroid Build Coastguard Worker
1016*61046927SAndroid Build Coastguard Worker void
intel_perf_query_result_read_frequencies(struct intel_perf_query_result * result,const struct intel_device_info * devinfo,const uint32_t * start,const uint32_t * end)1017*61046927SAndroid Build Coastguard Worker intel_perf_query_result_read_frequencies(struct intel_perf_query_result *result,
1018*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo,
1019*61046927SAndroid Build Coastguard Worker const uint32_t *start,
1020*61046927SAndroid Build Coastguard Worker const uint32_t *end)
1021*61046927SAndroid Build Coastguard Worker {
1022*61046927SAndroid Build Coastguard Worker /* Slice/Unslice frequency is only available in the OA reports when the
1023*61046927SAndroid Build Coastguard Worker * "Disable OA reports due to clock ratio change" field in
1024*61046927SAndroid Build Coastguard Worker * OA_DEBUG_REGISTER is set to 1. This is how the kernel programs this
1025*61046927SAndroid Build Coastguard Worker * global register (see drivers/gpu/drm/i915/i915_perf.c)
1026*61046927SAndroid Build Coastguard Worker *
1027*61046927SAndroid Build Coastguard Worker * Documentation says this should be available on Gfx9+ but experimentation
1028*61046927SAndroid Build Coastguard Worker * shows that Gfx8 reports similar values, so we enable it there too.
1029*61046927SAndroid Build Coastguard Worker */
1030*61046927SAndroid Build Coastguard Worker if (devinfo->ver < 8)
1031*61046927SAndroid Build Coastguard Worker return;
1032*61046927SAndroid Build Coastguard Worker
1033*61046927SAndroid Build Coastguard Worker gfx8_read_report_clock_ratios(start,
1034*61046927SAndroid Build Coastguard Worker &result->slice_frequency[0],
1035*61046927SAndroid Build Coastguard Worker &result->unslice_frequency[0]);
1036*61046927SAndroid Build Coastguard Worker gfx8_read_report_clock_ratios(end,
1037*61046927SAndroid Build Coastguard Worker &result->slice_frequency[1],
1038*61046927SAndroid Build Coastguard Worker &result->unslice_frequency[1]);
1039*61046927SAndroid Build Coastguard Worker }
1040*61046927SAndroid Build Coastguard Worker
1041*61046927SAndroid Build Coastguard Worker static inline bool
can_use_mi_rpc_bc_counters(const struct intel_device_info * devinfo)1042*61046927SAndroid Build Coastguard Worker can_use_mi_rpc_bc_counters(const struct intel_device_info *devinfo)
1043*61046927SAndroid Build Coastguard Worker {
1044*61046927SAndroid Build Coastguard Worker return devinfo->ver <= 11;
1045*61046927SAndroid Build Coastguard Worker }
1046*61046927SAndroid Build Coastguard Worker
1047*61046927SAndroid Build Coastguard Worker uint64_t
intel_perf_report_timestamp(const struct intel_perf_query_info * query,const struct intel_device_info * devinfo,const uint32_t * report)1048*61046927SAndroid Build Coastguard Worker intel_perf_report_timestamp(const struct intel_perf_query_info *query,
1049*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo,
1050*61046927SAndroid Build Coastguard Worker const uint32_t *report)
1051*61046927SAndroid Build Coastguard Worker {
1052*61046927SAndroid Build Coastguard Worker if (query->perf->devinfo->verx10 >= 200) {
1053*61046927SAndroid Build Coastguard Worker uint64_t data_u64 = *((const uint64_t *)&report[2]);
1054*61046927SAndroid Build Coastguard Worker return data_u64 >> query->perf->oa_timestamp_shift;
1055*61046927SAndroid Build Coastguard Worker }
1056*61046927SAndroid Build Coastguard Worker
1057*61046927SAndroid Build Coastguard Worker return report[1] >> query->perf->oa_timestamp_shift;
1058*61046927SAndroid Build Coastguard Worker }
1059*61046927SAndroid Build Coastguard Worker
1060*61046927SAndroid Build Coastguard Worker void
intel_perf_query_result_accumulate(struct intel_perf_query_result * result,const struct intel_perf_query_info * query,const uint32_t * start,const uint32_t * end)1061*61046927SAndroid Build Coastguard Worker intel_perf_query_result_accumulate(struct intel_perf_query_result *result,
1062*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_info *query,
1063*61046927SAndroid Build Coastguard Worker const uint32_t *start,
1064*61046927SAndroid Build Coastguard Worker const uint32_t *end)
1065*61046927SAndroid Build Coastguard Worker {
1066*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo = query->perf->devinfo;
1067*61046927SAndroid Build Coastguard Worker int i;
1068*61046927SAndroid Build Coastguard Worker
1069*61046927SAndroid Build Coastguard Worker if (query->perf->devinfo->verx10 >= 200) {
1070*61046927SAndroid Build Coastguard Worker if (result->hw_id == INTEL_PERF_INVALID_CTX_ID &&
1071*61046927SAndroid Build Coastguard Worker start[4] != INTEL_PERF_INVALID_CTX_ID)
1072*61046927SAndroid Build Coastguard Worker result->hw_id = start[4];
1073*61046927SAndroid Build Coastguard Worker } else {
1074*61046927SAndroid Build Coastguard Worker if (result->hw_id == INTEL_PERF_INVALID_CTX_ID &&
1075*61046927SAndroid Build Coastguard Worker start[2] != INTEL_PERF_INVALID_CTX_ID)
1076*61046927SAndroid Build Coastguard Worker result->hw_id = start[2];
1077*61046927SAndroid Build Coastguard Worker }
1078*61046927SAndroid Build Coastguard Worker
1079*61046927SAndroid Build Coastguard Worker if (result->reports_accumulated == 0)
1080*61046927SAndroid Build Coastguard Worker result->begin_timestamp = intel_perf_report_timestamp(query, devinfo, start);
1081*61046927SAndroid Build Coastguard Worker result->end_timestamp = intel_perf_report_timestamp(query, devinfo, end);
1082*61046927SAndroid Build Coastguard Worker result->reports_accumulated++;
1083*61046927SAndroid Build Coastguard Worker
1084*61046927SAndroid Build Coastguard Worker /* oa format handling needs to match with platform version returned in
1085*61046927SAndroid Build Coastguard Worker * intel_perf_get_oa_format()
1086*61046927SAndroid Build Coastguard Worker */
1087*61046927SAndroid Build Coastguard Worker assert(intel_perf_get_oa_format(query->perf) == query->oa_format);
1088*61046927SAndroid Build Coastguard Worker if (query->perf->devinfo->verx10 >= 200) {
1089*61046927SAndroid Build Coastguard Worker /* PEC64u64 */
1090*61046927SAndroid Build Coastguard Worker result->accumulator[query->gpu_time_offset] =
1091*61046927SAndroid Build Coastguard Worker intel_perf_report_timestamp(query, devinfo, end) -
1092*61046927SAndroid Build Coastguard Worker intel_perf_report_timestamp(query, devinfo, start);
1093*61046927SAndroid Build Coastguard Worker accumulate_uint64(start + 6, end + 6, &result->accumulator[query->gpu_clock_offset]);
1094*61046927SAndroid Build Coastguard Worker
1095*61046927SAndroid Build Coastguard Worker for (i = 0; i < 64; i++)
1096*61046927SAndroid Build Coastguard Worker accumulate_uint64(start + 8 + (2 * i), end + 8 + (2 * i),
1097*61046927SAndroid Build Coastguard Worker &result->accumulator[query->pec_offset + i]);
1098*61046927SAndroid Build Coastguard Worker } else if (query->perf->devinfo->verx10 >= 125) {
1099*61046927SAndroid Build Coastguard Worker /* I915_OA_FORMAT_A24u40_A14u32_B8_C8 */
1100*61046927SAndroid Build Coastguard Worker result->accumulator[query->gpu_time_offset] =
1101*61046927SAndroid Build Coastguard Worker intel_perf_report_timestamp(query, devinfo, end) -
1102*61046927SAndroid Build Coastguard Worker intel_perf_report_timestamp(query, devinfo, start);
1103*61046927SAndroid Build Coastguard Worker
1104*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 3, end + 3,
1105*61046927SAndroid Build Coastguard Worker result->accumulator + query->gpu_clock_offset); /* clock */
1106*61046927SAndroid Build Coastguard Worker
1107*61046927SAndroid Build Coastguard Worker /* A0-A3 counters are 32bits */
1108*61046927SAndroid Build Coastguard Worker for (i = 0; i < 4; i++) {
1109*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 4 + i, end + 4 + i,
1110*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + i);
1111*61046927SAndroid Build Coastguard Worker }
1112*61046927SAndroid Build Coastguard Worker
1113*61046927SAndroid Build Coastguard Worker /* A4-A23 counters are 40bits */
1114*61046927SAndroid Build Coastguard Worker for (i = 4; i < 24; i++) {
1115*61046927SAndroid Build Coastguard Worker accumulate_uint40(i, start, end,
1116*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + i);
1117*61046927SAndroid Build Coastguard Worker }
1118*61046927SAndroid Build Coastguard Worker
1119*61046927SAndroid Build Coastguard Worker /* A24-27 counters are 32bits */
1120*61046927SAndroid Build Coastguard Worker for (i = 0; i < 4; i++) {
1121*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 28 + i, end + 28 + i,
1122*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + 24 + i);
1123*61046927SAndroid Build Coastguard Worker }
1124*61046927SAndroid Build Coastguard Worker
1125*61046927SAndroid Build Coastguard Worker /* A28-31 counters are 40bits */
1126*61046927SAndroid Build Coastguard Worker for (i = 28; i < 32; i++) {
1127*61046927SAndroid Build Coastguard Worker accumulate_uint40(i, start, end,
1128*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + i);
1129*61046927SAndroid Build Coastguard Worker }
1130*61046927SAndroid Build Coastguard Worker
1131*61046927SAndroid Build Coastguard Worker /* A32-35 counters are 32bits */
1132*61046927SAndroid Build Coastguard Worker for (i = 0; i < 4; i++) {
1133*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 36 + i, end + 36 + i,
1134*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + 32 + i);
1135*61046927SAndroid Build Coastguard Worker }
1136*61046927SAndroid Build Coastguard Worker
1137*61046927SAndroid Build Coastguard Worker if (can_use_mi_rpc_bc_counters(query->perf->devinfo) ||
1138*61046927SAndroid Build Coastguard Worker !query->perf->sys_vars.query_mode) {
1139*61046927SAndroid Build Coastguard Worker /* A36-37 counters are 32bits */
1140*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 40, end + 40,
1141*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + 36);
1142*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 46, end + 46,
1143*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + 37);
1144*61046927SAndroid Build Coastguard Worker
1145*61046927SAndroid Build Coastguard Worker /* 8x 32bit B counters */
1146*61046927SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
1147*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 48 + i, end + 48 + i,
1148*61046927SAndroid Build Coastguard Worker result->accumulator + query->b_offset + i);
1149*61046927SAndroid Build Coastguard Worker }
1150*61046927SAndroid Build Coastguard Worker
1151*61046927SAndroid Build Coastguard Worker /* 8x 32bit C counters... */
1152*61046927SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
1153*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 56 + i, end + 56 + i,
1154*61046927SAndroid Build Coastguard Worker result->accumulator + query->c_offset + i);
1155*61046927SAndroid Build Coastguard Worker }
1156*61046927SAndroid Build Coastguard Worker }
1157*61046927SAndroid Build Coastguard Worker } else if (query->perf->devinfo->verx10 >= 120) {
1158*61046927SAndroid Build Coastguard Worker /* I915_OA_FORMAT_A32u40_A4u32_B8_C8 */
1159*61046927SAndroid Build Coastguard Worker result->accumulator[query->gpu_time_offset] =
1160*61046927SAndroid Build Coastguard Worker intel_perf_report_timestamp(query, devinfo, end) -
1161*61046927SAndroid Build Coastguard Worker intel_perf_report_timestamp(query, devinfo, start);
1162*61046927SAndroid Build Coastguard Worker
1163*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 3, end + 3,
1164*61046927SAndroid Build Coastguard Worker result->accumulator + query->gpu_clock_offset); /* clock */
1165*61046927SAndroid Build Coastguard Worker
1166*61046927SAndroid Build Coastguard Worker /* 32x 40bit A counters... */
1167*61046927SAndroid Build Coastguard Worker for (i = 0; i < 32; i++) {
1168*61046927SAndroid Build Coastguard Worker accumulate_uint40(i, start, end,
1169*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + i);
1170*61046927SAndroid Build Coastguard Worker }
1171*61046927SAndroid Build Coastguard Worker
1172*61046927SAndroid Build Coastguard Worker /* 4x 32bit A counters... */
1173*61046927SAndroid Build Coastguard Worker for (i = 0; i < 4; i++) {
1174*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 36 + i, end + 36 + i,
1175*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + 32 + i);
1176*61046927SAndroid Build Coastguard Worker }
1177*61046927SAndroid Build Coastguard Worker
1178*61046927SAndroid Build Coastguard Worker if (can_use_mi_rpc_bc_counters(query->perf->devinfo) ||
1179*61046927SAndroid Build Coastguard Worker !query->perf->sys_vars.query_mode) {
1180*61046927SAndroid Build Coastguard Worker /* 8x 32bit B counters */
1181*61046927SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
1182*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 48 + i, end + 48 + i,
1183*61046927SAndroid Build Coastguard Worker result->accumulator + query->b_offset + i);
1184*61046927SAndroid Build Coastguard Worker }
1185*61046927SAndroid Build Coastguard Worker
1186*61046927SAndroid Build Coastguard Worker /* 8x 32bit C counters... */
1187*61046927SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
1188*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 56 + i, end + 56 + i,
1189*61046927SAndroid Build Coastguard Worker result->accumulator + query->c_offset + i);
1190*61046927SAndroid Build Coastguard Worker }
1191*61046927SAndroid Build Coastguard Worker }
1192*61046927SAndroid Build Coastguard Worker } else {
1193*61046927SAndroid Build Coastguard Worker /* I915_OA_FORMAT_A24u40_A14u32_B8_C8 */
1194*61046927SAndroid Build Coastguard Worker result->accumulator[query->gpu_time_offset] =
1195*61046927SAndroid Build Coastguard Worker intel_perf_report_timestamp(query, devinfo, end) -
1196*61046927SAndroid Build Coastguard Worker intel_perf_report_timestamp(query, devinfo, start);
1197*61046927SAndroid Build Coastguard Worker
1198*61046927SAndroid Build Coastguard Worker for (i = 0; i < 61; i++) {
1199*61046927SAndroid Build Coastguard Worker accumulate_uint32(start + 3 + i, end + 3 + i,
1200*61046927SAndroid Build Coastguard Worker result->accumulator + query->a_offset + i);
1201*61046927SAndroid Build Coastguard Worker }
1202*61046927SAndroid Build Coastguard Worker }
1203*61046927SAndroid Build Coastguard Worker }
1204*61046927SAndroid Build Coastguard Worker
1205*61046927SAndroid Build Coastguard Worker #define GET_FIELD(word, field) (((word) & field ## _MASK) >> field ## _SHIFT)
1206*61046927SAndroid Build Coastguard Worker
1207*61046927SAndroid Build Coastguard Worker void
intel_perf_query_result_read_gt_frequency(struct intel_perf_query_result * result,const struct intel_device_info * devinfo,const uint32_t start,const uint32_t end)1208*61046927SAndroid Build Coastguard Worker intel_perf_query_result_read_gt_frequency(struct intel_perf_query_result *result,
1209*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo,
1210*61046927SAndroid Build Coastguard Worker const uint32_t start,
1211*61046927SAndroid Build Coastguard Worker const uint32_t end)
1212*61046927SAndroid Build Coastguard Worker {
1213*61046927SAndroid Build Coastguard Worker switch (devinfo->ver) {
1214*61046927SAndroid Build Coastguard Worker case 7:
1215*61046927SAndroid Build Coastguard Worker case 8:
1216*61046927SAndroid Build Coastguard Worker result->gt_frequency[0] = GET_FIELD(start, GFX7_RPSTAT1_CURR_GT_FREQ) * 50ULL;
1217*61046927SAndroid Build Coastguard Worker result->gt_frequency[1] = GET_FIELD(end, GFX7_RPSTAT1_CURR_GT_FREQ) * 50ULL;
1218*61046927SAndroid Build Coastguard Worker break;
1219*61046927SAndroid Build Coastguard Worker case 9:
1220*61046927SAndroid Build Coastguard Worker case 11:
1221*61046927SAndroid Build Coastguard Worker case 12:
1222*61046927SAndroid Build Coastguard Worker case 20:
1223*61046927SAndroid Build Coastguard Worker result->gt_frequency[0] = GET_FIELD(start, GFX9_RPSTAT0_CURR_GT_FREQ) * 50ULL / 3ULL;
1224*61046927SAndroid Build Coastguard Worker result->gt_frequency[1] = GET_FIELD(end, GFX9_RPSTAT0_CURR_GT_FREQ) * 50ULL / 3ULL;
1225*61046927SAndroid Build Coastguard Worker break;
1226*61046927SAndroid Build Coastguard Worker default:
1227*61046927SAndroid Build Coastguard Worker unreachable("unexpected gen");
1228*61046927SAndroid Build Coastguard Worker }
1229*61046927SAndroid Build Coastguard Worker
1230*61046927SAndroid Build Coastguard Worker /* Put the numbers into Hz. */
1231*61046927SAndroid Build Coastguard Worker result->gt_frequency[0] *= 1000000ULL;
1232*61046927SAndroid Build Coastguard Worker result->gt_frequency[1] *= 1000000ULL;
1233*61046927SAndroid Build Coastguard Worker }
1234*61046927SAndroid Build Coastguard Worker
1235*61046927SAndroid Build Coastguard Worker void
intel_perf_query_result_read_perfcnts(struct intel_perf_query_result * result,const struct intel_perf_query_info * query,const uint64_t * start,const uint64_t * end)1236*61046927SAndroid Build Coastguard Worker intel_perf_query_result_read_perfcnts(struct intel_perf_query_result *result,
1237*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_info *query,
1238*61046927SAndroid Build Coastguard Worker const uint64_t *start,
1239*61046927SAndroid Build Coastguard Worker const uint64_t *end)
1240*61046927SAndroid Build Coastguard Worker {
1241*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < 2; i++) {
1242*61046927SAndroid Build Coastguard Worker uint64_t v0 = start[i] & PERF_CNT_VALUE_MASK;
1243*61046927SAndroid Build Coastguard Worker uint64_t v1 = end[i] & PERF_CNT_VALUE_MASK;
1244*61046927SAndroid Build Coastguard Worker
1245*61046927SAndroid Build Coastguard Worker result->accumulator[query->perfcnt_offset + i] = v0 > v1 ?
1246*61046927SAndroid Build Coastguard Worker (PERF_CNT_VALUE_MASK + 1 + v1 - v0) :
1247*61046927SAndroid Build Coastguard Worker (v1 - v0);
1248*61046927SAndroid Build Coastguard Worker }
1249*61046927SAndroid Build Coastguard Worker }
1250*61046927SAndroid Build Coastguard Worker
1251*61046927SAndroid Build Coastguard Worker static uint32_t
query_accumulator_offset(const struct intel_perf_query_info * query,enum intel_perf_query_field_type type,uint8_t index)1252*61046927SAndroid Build Coastguard Worker query_accumulator_offset(const struct intel_perf_query_info *query,
1253*61046927SAndroid Build Coastguard Worker enum intel_perf_query_field_type type,
1254*61046927SAndroid Build Coastguard Worker uint8_t index)
1255*61046927SAndroid Build Coastguard Worker {
1256*61046927SAndroid Build Coastguard Worker switch (type) {
1257*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_SRM_PERFCNT:
1258*61046927SAndroid Build Coastguard Worker return query->perfcnt_offset + index;
1259*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_A:
1260*61046927SAndroid Build Coastguard Worker return query->a_offset + index;
1261*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_B:
1262*61046927SAndroid Build Coastguard Worker return query->b_offset + index;
1263*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_C:
1264*61046927SAndroid Build Coastguard Worker return query->c_offset + index;
1265*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_PEC:
1266*61046927SAndroid Build Coastguard Worker return query->pec_offset + index;
1267*61046927SAndroid Build Coastguard Worker default:
1268*61046927SAndroid Build Coastguard Worker unreachable("Invalid register type");
1269*61046927SAndroid Build Coastguard Worker return 0;
1270*61046927SAndroid Build Coastguard Worker }
1271*61046927SAndroid Build Coastguard Worker }
1272*61046927SAndroid Build Coastguard Worker
1273*61046927SAndroid Build Coastguard Worker void
intel_perf_query_result_accumulate_fields(struct intel_perf_query_result * result,const struct intel_perf_query_info * query,const void * start,const void * end,bool no_oa_accumulate)1274*61046927SAndroid Build Coastguard Worker intel_perf_query_result_accumulate_fields(struct intel_perf_query_result *result,
1275*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_info *query,
1276*61046927SAndroid Build Coastguard Worker const void *start,
1277*61046927SAndroid Build Coastguard Worker const void *end,
1278*61046927SAndroid Build Coastguard Worker bool no_oa_accumulate)
1279*61046927SAndroid Build Coastguard Worker {
1280*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_field_layout *layout = &query->perf->query_layout;
1281*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo = query->perf->devinfo;
1282*61046927SAndroid Build Coastguard Worker
1283*61046927SAndroid Build Coastguard Worker for (uint32_t r = 0; r < layout->n_fields; r++) {
1284*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_field *field = &layout->fields[r];
1285*61046927SAndroid Build Coastguard Worker
1286*61046927SAndroid Build Coastguard Worker if (field->type == INTEL_PERF_QUERY_FIELD_TYPE_MI_RPC) {
1287*61046927SAndroid Build Coastguard Worker intel_perf_query_result_read_frequencies(result, devinfo,
1288*61046927SAndroid Build Coastguard Worker start + field->location,
1289*61046927SAndroid Build Coastguard Worker end + field->location);
1290*61046927SAndroid Build Coastguard Worker /* no_oa_accumulate=true is used when doing GL perf queries, we
1291*61046927SAndroid Build Coastguard Worker * manually parse the OA reports from the OA buffer and subtract
1292*61046927SAndroid Build Coastguard Worker * unrelated deltas, so don't accumulate the begin/end reports here.
1293*61046927SAndroid Build Coastguard Worker */
1294*61046927SAndroid Build Coastguard Worker if (!no_oa_accumulate) {
1295*61046927SAndroid Build Coastguard Worker intel_perf_query_result_accumulate(result, query,
1296*61046927SAndroid Build Coastguard Worker start + field->location,
1297*61046927SAndroid Build Coastguard Worker end + field->location);
1298*61046927SAndroid Build Coastguard Worker }
1299*61046927SAndroid Build Coastguard Worker } else {
1300*61046927SAndroid Build Coastguard Worker uint64_t v0, v1;
1301*61046927SAndroid Build Coastguard Worker
1302*61046927SAndroid Build Coastguard Worker if (field->size == 4) {
1303*61046927SAndroid Build Coastguard Worker v0 = *(const uint32_t *)(start + field->location);
1304*61046927SAndroid Build Coastguard Worker v1 = *(const uint32_t *)(end + field->location);
1305*61046927SAndroid Build Coastguard Worker } else {
1306*61046927SAndroid Build Coastguard Worker assert(field->size == 8);
1307*61046927SAndroid Build Coastguard Worker v0 = *(const uint64_t *)(start + field->location);
1308*61046927SAndroid Build Coastguard Worker v1 = *(const uint64_t *)(end + field->location);
1309*61046927SAndroid Build Coastguard Worker }
1310*61046927SAndroid Build Coastguard Worker
1311*61046927SAndroid Build Coastguard Worker if (field->mask) {
1312*61046927SAndroid Build Coastguard Worker v0 = field->mask & v0;
1313*61046927SAndroid Build Coastguard Worker v1 = field->mask & v1;
1314*61046927SAndroid Build Coastguard Worker }
1315*61046927SAndroid Build Coastguard Worker
1316*61046927SAndroid Build Coastguard Worker /* RPSTAT is a bit of a special case because its begin/end values
1317*61046927SAndroid Build Coastguard Worker * represent frequencies. We store it in a separate location.
1318*61046927SAndroid Build Coastguard Worker */
1319*61046927SAndroid Build Coastguard Worker if (field->type == INTEL_PERF_QUERY_FIELD_TYPE_SRM_RPSTAT)
1320*61046927SAndroid Build Coastguard Worker intel_perf_query_result_read_gt_frequency(result, devinfo, v0, v1);
1321*61046927SAndroid Build Coastguard Worker else
1322*61046927SAndroid Build Coastguard Worker result->accumulator[query_accumulator_offset(query, field->type, field->index)] = v1 - v0;
1323*61046927SAndroid Build Coastguard Worker }
1324*61046927SAndroid Build Coastguard Worker }
1325*61046927SAndroid Build Coastguard Worker }
1326*61046927SAndroid Build Coastguard Worker
1327*61046927SAndroid Build Coastguard Worker void
intel_perf_query_result_clear(struct intel_perf_query_result * result)1328*61046927SAndroid Build Coastguard Worker intel_perf_query_result_clear(struct intel_perf_query_result *result)
1329*61046927SAndroid Build Coastguard Worker {
1330*61046927SAndroid Build Coastguard Worker memset(result, 0, sizeof(*result));
1331*61046927SAndroid Build Coastguard Worker result->hw_id = INTEL_PERF_INVALID_CTX_ID;
1332*61046927SAndroid Build Coastguard Worker }
1333*61046927SAndroid Build Coastguard Worker
1334*61046927SAndroid Build Coastguard Worker void
intel_perf_query_result_print_fields(const struct intel_perf_query_info * query,const void * data)1335*61046927SAndroid Build Coastguard Worker intel_perf_query_result_print_fields(const struct intel_perf_query_info *query,
1336*61046927SAndroid Build Coastguard Worker const void *data)
1337*61046927SAndroid Build Coastguard Worker {
1338*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_field_layout *layout = &query->perf->query_layout;
1339*61046927SAndroid Build Coastguard Worker
1340*61046927SAndroid Build Coastguard Worker for (uint32_t r = 0; r < layout->n_fields; r++) {
1341*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_field *field = &layout->fields[r];
1342*61046927SAndroid Build Coastguard Worker const uint32_t *value32 = data + field->location;
1343*61046927SAndroid Build Coastguard Worker
1344*61046927SAndroid Build Coastguard Worker switch (field->type) {
1345*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_MI_RPC:
1346*61046927SAndroid Build Coastguard Worker fprintf(stderr, "MI_RPC:\n");
1347*61046927SAndroid Build Coastguard Worker fprintf(stderr, " TS: 0x%08x\n", *(value32 + 1));
1348*61046927SAndroid Build Coastguard Worker fprintf(stderr, " CLK: 0x%08x\n", *(value32 + 3));
1349*61046927SAndroid Build Coastguard Worker break;
1350*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_A:
1351*61046927SAndroid Build Coastguard Worker fprintf(stderr, "A%u: 0x%08x\n", field->index, *value32);
1352*61046927SAndroid Build Coastguard Worker break;
1353*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_B:
1354*61046927SAndroid Build Coastguard Worker fprintf(stderr, "B%u: 0x%08x\n", field->index, *value32);
1355*61046927SAndroid Build Coastguard Worker break;
1356*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_C:
1357*61046927SAndroid Build Coastguard Worker fprintf(stderr, "C%u: 0x%08x\n", field->index, *value32);
1358*61046927SAndroid Build Coastguard Worker break;
1359*61046927SAndroid Build Coastguard Worker case INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_PEC: {
1360*61046927SAndroid Build Coastguard Worker const uint64_t *value64 = data + field->location;
1361*61046927SAndroid Build Coastguard Worker fprintf(stderr, "PEC%u: 0x%" PRIx64 "\n", field->index, *value64);
1362*61046927SAndroid Build Coastguard Worker break;
1363*61046927SAndroid Build Coastguard Worker }
1364*61046927SAndroid Build Coastguard Worker default:
1365*61046927SAndroid Build Coastguard Worker break;
1366*61046927SAndroid Build Coastguard Worker }
1367*61046927SAndroid Build Coastguard Worker }
1368*61046927SAndroid Build Coastguard Worker }
1369*61046927SAndroid Build Coastguard Worker
1370*61046927SAndroid Build Coastguard Worker static int
intel_perf_compare_query_names(const void * v1,const void * v2)1371*61046927SAndroid Build Coastguard Worker intel_perf_compare_query_names(const void *v1, const void *v2)
1372*61046927SAndroid Build Coastguard Worker {
1373*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_info *q1 = v1;
1374*61046927SAndroid Build Coastguard Worker const struct intel_perf_query_info *q2 = v2;
1375*61046927SAndroid Build Coastguard Worker
1376*61046927SAndroid Build Coastguard Worker return strcmp(q1->name, q2->name);
1377*61046927SAndroid Build Coastguard Worker }
1378*61046927SAndroid Build Coastguard Worker
1379*61046927SAndroid Build Coastguard Worker /* Xe2: (64 x PEC) + SRM_RPSTAT + MI_RPC */
1380*61046927SAndroid Build Coastguard Worker #define MAX_QUERY_FIELDS(devinfo) (devinfo->verx10 >= 200 ? (64 + 2) : (5 + 16))
1381*61046927SAndroid Build Coastguard Worker
1382*61046927SAndroid Build Coastguard Worker static inline struct intel_perf_query_field *
add_query_register(struct intel_perf_config * perf_cfg,enum intel_perf_query_field_type type,uint32_t offset,uint16_t size,uint8_t index)1383*61046927SAndroid Build Coastguard Worker add_query_register(struct intel_perf_config *perf_cfg,
1384*61046927SAndroid Build Coastguard Worker enum intel_perf_query_field_type type,
1385*61046927SAndroid Build Coastguard Worker uint32_t offset,
1386*61046927SAndroid Build Coastguard Worker uint16_t size,
1387*61046927SAndroid Build Coastguard Worker uint8_t index)
1388*61046927SAndroid Build Coastguard Worker {
1389*61046927SAndroid Build Coastguard Worker struct intel_perf_query_field_layout *layout = &perf_cfg->query_layout;
1390*61046927SAndroid Build Coastguard Worker
1391*61046927SAndroid Build Coastguard Worker /* Align MI_RPC to 64bytes (HW requirement) & 64bit registers to 8bytes
1392*61046927SAndroid Build Coastguard Worker * (shows up nicely in the debugger).
1393*61046927SAndroid Build Coastguard Worker */
1394*61046927SAndroid Build Coastguard Worker if (type == INTEL_PERF_QUERY_FIELD_TYPE_MI_RPC)
1395*61046927SAndroid Build Coastguard Worker layout->size = align(layout->size, 64);
1396*61046927SAndroid Build Coastguard Worker else if (size % 8 == 0)
1397*61046927SAndroid Build Coastguard Worker layout->size = align(layout->size, 8);
1398*61046927SAndroid Build Coastguard Worker
1399*61046927SAndroid Build Coastguard Worker assert(layout->n_fields < MAX_QUERY_FIELDS(perf_cfg->devinfo));
1400*61046927SAndroid Build Coastguard Worker layout->fields[layout->n_fields++] = (struct intel_perf_query_field) {
1401*61046927SAndroid Build Coastguard Worker .mmio_offset = offset,
1402*61046927SAndroid Build Coastguard Worker .location = layout->size,
1403*61046927SAndroid Build Coastguard Worker .type = type,
1404*61046927SAndroid Build Coastguard Worker .index = index,
1405*61046927SAndroid Build Coastguard Worker .size = size,
1406*61046927SAndroid Build Coastguard Worker };
1407*61046927SAndroid Build Coastguard Worker layout->size += size;
1408*61046927SAndroid Build Coastguard Worker
1409*61046927SAndroid Build Coastguard Worker return &layout->fields[layout->n_fields - 1];
1410*61046927SAndroid Build Coastguard Worker }
1411*61046927SAndroid Build Coastguard Worker
1412*61046927SAndroid Build Coastguard Worker static void
intel_perf_init_query_fields(struct intel_perf_config * perf_cfg,const struct intel_device_info * devinfo,bool use_register_snapshots)1413*61046927SAndroid Build Coastguard Worker intel_perf_init_query_fields(struct intel_perf_config *perf_cfg,
1414*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo,
1415*61046927SAndroid Build Coastguard Worker bool use_register_snapshots)
1416*61046927SAndroid Build Coastguard Worker {
1417*61046927SAndroid Build Coastguard Worker struct intel_perf_query_field_layout *layout = &perf_cfg->query_layout;
1418*61046927SAndroid Build Coastguard Worker
1419*61046927SAndroid Build Coastguard Worker layout->n_fields = 0;
1420*61046927SAndroid Build Coastguard Worker
1421*61046927SAndroid Build Coastguard Worker /* MI_RPC requires a 64byte alignment. */
1422*61046927SAndroid Build Coastguard Worker layout->alignment = 64;
1423*61046927SAndroid Build Coastguard Worker
1424*61046927SAndroid Build Coastguard Worker layout->fields = rzalloc_array(perf_cfg, struct intel_perf_query_field,
1425*61046927SAndroid Build Coastguard Worker MAX_QUERY_FIELDS(devinfo));
1426*61046927SAndroid Build Coastguard Worker
1427*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg, INTEL_PERF_QUERY_FIELD_TYPE_MI_RPC,
1428*61046927SAndroid Build Coastguard Worker 0, perf_cfg->oa_sample_size, 0);
1429*61046927SAndroid Build Coastguard Worker
1430*61046927SAndroid Build Coastguard Worker if (use_register_snapshots) {
1431*61046927SAndroid Build Coastguard Worker if (devinfo->ver <= 11) {
1432*61046927SAndroid Build Coastguard Worker struct intel_perf_query_field *field =
1433*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg,
1434*61046927SAndroid Build Coastguard Worker INTEL_PERF_QUERY_FIELD_TYPE_SRM_PERFCNT,
1435*61046927SAndroid Build Coastguard Worker PERF_CNT_1_DW0, 8, 0);
1436*61046927SAndroid Build Coastguard Worker field->mask = PERF_CNT_VALUE_MASK;
1437*61046927SAndroid Build Coastguard Worker
1438*61046927SAndroid Build Coastguard Worker field = add_query_register(perf_cfg,
1439*61046927SAndroid Build Coastguard Worker INTEL_PERF_QUERY_FIELD_TYPE_SRM_PERFCNT,
1440*61046927SAndroid Build Coastguard Worker PERF_CNT_2_DW0, 8, 1);
1441*61046927SAndroid Build Coastguard Worker field->mask = PERF_CNT_VALUE_MASK;
1442*61046927SAndroid Build Coastguard Worker }
1443*61046927SAndroid Build Coastguard Worker
1444*61046927SAndroid Build Coastguard Worker if (devinfo->ver == 8 && devinfo->platform != INTEL_PLATFORM_CHV) {
1445*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg,
1446*61046927SAndroid Build Coastguard Worker INTEL_PERF_QUERY_FIELD_TYPE_SRM_RPSTAT,
1447*61046927SAndroid Build Coastguard Worker GFX7_RPSTAT1, 4, 0);
1448*61046927SAndroid Build Coastguard Worker }
1449*61046927SAndroid Build Coastguard Worker
1450*61046927SAndroid Build Coastguard Worker if (devinfo->ver >= 9) {
1451*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg,
1452*61046927SAndroid Build Coastguard Worker INTEL_PERF_QUERY_FIELD_TYPE_SRM_RPSTAT,
1453*61046927SAndroid Build Coastguard Worker GFX9_RPSTAT0, 4, 0);
1454*61046927SAndroid Build Coastguard Worker }
1455*61046927SAndroid Build Coastguard Worker
1456*61046927SAndroid Build Coastguard Worker if (!can_use_mi_rpc_bc_counters(devinfo)) {
1457*61046927SAndroid Build Coastguard Worker if (devinfo->ver >= 8 && devinfo->ver <= 11) {
1458*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < GFX8_N_OA_PERF_B32; i++) {
1459*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg, INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_B,
1460*61046927SAndroid Build Coastguard Worker GFX8_OA_PERF_B32(i), 4, i);
1461*61046927SAndroid Build Coastguard Worker }
1462*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < GFX8_N_OA_PERF_C32; i++) {
1463*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg, INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_C,
1464*61046927SAndroid Build Coastguard Worker GFX8_OA_PERF_C32(i), 4, i);
1465*61046927SAndroid Build Coastguard Worker }
1466*61046927SAndroid Build Coastguard Worker } else if (devinfo->verx10 == 120) {
1467*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < GFX12_N_OAG_PERF_B32; i++) {
1468*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg, INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_B,
1469*61046927SAndroid Build Coastguard Worker GFX12_OAG_PERF_B32(i), 4, i);
1470*61046927SAndroid Build Coastguard Worker }
1471*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < GFX12_N_OAG_PERF_C32; i++) {
1472*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg, INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_C,
1473*61046927SAndroid Build Coastguard Worker GFX12_OAG_PERF_C32(i), 4, i);
1474*61046927SAndroid Build Coastguard Worker }
1475*61046927SAndroid Build Coastguard Worker } else if (devinfo->verx10 == 125) {
1476*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg, INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_A,
1477*61046927SAndroid Build Coastguard Worker GFX125_OAG_PERF_A36, 4, 36);
1478*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg, INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_A,
1479*61046927SAndroid Build Coastguard Worker GFX125_OAG_PERF_A37, 4, 37);
1480*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < GFX12_N_OAG_PERF_B32; i++) {
1481*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg, INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_B,
1482*61046927SAndroid Build Coastguard Worker GFX12_OAG_PERF_B32(i), 4, i);
1483*61046927SAndroid Build Coastguard Worker }
1484*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < GFX12_N_OAG_PERF_C32; i++) {
1485*61046927SAndroid Build Coastguard Worker add_query_register(perf_cfg, INTEL_PERF_QUERY_FIELD_TYPE_SRM_OA_C,
1486*61046927SAndroid Build Coastguard Worker GFX12_OAG_PERF_C32(i), 4, i);
1487*61046927SAndroid Build Coastguard Worker }
1488*61046927SAndroid Build Coastguard Worker }
1489*61046927SAndroid Build Coastguard Worker }
1490*61046927SAndroid Build Coastguard Worker }
1491*61046927SAndroid Build Coastguard Worker
1492*61046927SAndroid Build Coastguard Worker /* Align the whole package to 64bytes so that 2 snapshots can be put
1493*61046927SAndroid Build Coastguard Worker * together without extract alignment for the user.
1494*61046927SAndroid Build Coastguard Worker */
1495*61046927SAndroid Build Coastguard Worker layout->size = align(layout->size, 64);
1496*61046927SAndroid Build Coastguard Worker }
1497*61046927SAndroid Build Coastguard Worker
1498*61046927SAndroid Build Coastguard Worker static size_t
intel_perf_get_oa_format_size(const struct intel_device_info * devinfo)1499*61046927SAndroid Build Coastguard Worker intel_perf_get_oa_format_size(const struct intel_device_info *devinfo)
1500*61046927SAndroid Build Coastguard Worker {
1501*61046927SAndroid Build Coastguard Worker if (devinfo->verx10 >= 200)
1502*61046927SAndroid Build Coastguard Worker return 576;
1503*61046927SAndroid Build Coastguard Worker
1504*61046927SAndroid Build Coastguard Worker return 256;
1505*61046927SAndroid Build Coastguard Worker }
1506*61046927SAndroid Build Coastguard Worker
1507*61046927SAndroid Build Coastguard Worker void
intel_perf_init_metrics(struct intel_perf_config * perf_cfg,const struct intel_device_info * devinfo,int drm_fd,bool include_pipeline_statistics,bool use_register_snapshots)1508*61046927SAndroid Build Coastguard Worker intel_perf_init_metrics(struct intel_perf_config *perf_cfg,
1509*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo,
1510*61046927SAndroid Build Coastguard Worker int drm_fd,
1511*61046927SAndroid Build Coastguard Worker bool include_pipeline_statistics,
1512*61046927SAndroid Build Coastguard Worker bool use_register_snapshots)
1513*61046927SAndroid Build Coastguard Worker {
1514*61046927SAndroid Build Coastguard Worker perf_cfg->devinfo = devinfo;
1515*61046927SAndroid Build Coastguard Worker perf_cfg->oa_sample_size = intel_perf_get_oa_format_size(devinfo);
1516*61046927SAndroid Build Coastguard Worker
1517*61046927SAndroid Build Coastguard Worker intel_perf_init_query_fields(perf_cfg, devinfo, use_register_snapshots);
1518*61046927SAndroid Build Coastguard Worker
1519*61046927SAndroid Build Coastguard Worker if (include_pipeline_statistics) {
1520*61046927SAndroid Build Coastguard Worker load_pipeline_statistic_metrics(perf_cfg, devinfo);
1521*61046927SAndroid Build Coastguard Worker intel_perf_register_mdapi_statistic_query(perf_cfg, devinfo);
1522*61046927SAndroid Build Coastguard Worker }
1523*61046927SAndroid Build Coastguard Worker
1524*61046927SAndroid Build Coastguard Worker bool oa_metrics = oa_metrics_available(perf_cfg, drm_fd, devinfo,
1525*61046927SAndroid Build Coastguard Worker use_register_snapshots);
1526*61046927SAndroid Build Coastguard Worker if (oa_metrics)
1527*61046927SAndroid Build Coastguard Worker load_oa_metrics(perf_cfg, drm_fd, devinfo);
1528*61046927SAndroid Build Coastguard Worker
1529*61046927SAndroid Build Coastguard Worker /* sort query groups by name */
1530*61046927SAndroid Build Coastguard Worker qsort(perf_cfg->queries, perf_cfg->n_queries,
1531*61046927SAndroid Build Coastguard Worker sizeof(perf_cfg->queries[0]), intel_perf_compare_query_names);
1532*61046927SAndroid Build Coastguard Worker
1533*61046927SAndroid Build Coastguard Worker build_unique_counter_list(perf_cfg);
1534*61046927SAndroid Build Coastguard Worker
1535*61046927SAndroid Build Coastguard Worker if (oa_metrics)
1536*61046927SAndroid Build Coastguard Worker intel_perf_register_mdapi_oa_query(perf_cfg, devinfo);
1537*61046927SAndroid Build Coastguard Worker }
1538*61046927SAndroid Build Coastguard Worker
1539*61046927SAndroid Build Coastguard Worker void
intel_perf_free(struct intel_perf_config * perf_cfg)1540*61046927SAndroid Build Coastguard Worker intel_perf_free(struct intel_perf_config *perf_cfg)
1541*61046927SAndroid Build Coastguard Worker {
1542*61046927SAndroid Build Coastguard Worker ralloc_free(perf_cfg);
1543*61046927SAndroid Build Coastguard Worker }
1544*61046927SAndroid Build Coastguard Worker
1545*61046927SAndroid Build Coastguard Worker uint64_t
intel_perf_get_oa_format(struct intel_perf_config * perf_cfg)1546*61046927SAndroid Build Coastguard Worker intel_perf_get_oa_format(struct intel_perf_config *perf_cfg)
1547*61046927SAndroid Build Coastguard Worker {
1548*61046927SAndroid Build Coastguard Worker switch (perf_cfg->devinfo->kmd_type) {
1549*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
1550*61046927SAndroid Build Coastguard Worker return i915_perf_get_oa_format(perf_cfg);
1551*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
1552*61046927SAndroid Build Coastguard Worker return xe_perf_get_oa_format(perf_cfg);
1553*61046927SAndroid Build Coastguard Worker default:
1554*61046927SAndroid Build Coastguard Worker unreachable("missing");
1555*61046927SAndroid Build Coastguard Worker return 0;
1556*61046927SAndroid Build Coastguard Worker }
1557*61046927SAndroid Build Coastguard Worker }
1558*61046927SAndroid Build Coastguard Worker
1559*61046927SAndroid Build Coastguard Worker int
intel_perf_stream_open(struct intel_perf_config * perf_config,int drm_fd,uint32_t ctx_id,uint64_t metrics_set_id,uint64_t period_exponent,bool hold_preemption,bool enable)1560*61046927SAndroid Build Coastguard Worker intel_perf_stream_open(struct intel_perf_config *perf_config, int drm_fd,
1561*61046927SAndroid Build Coastguard Worker uint32_t ctx_id, uint64_t metrics_set_id,
1562*61046927SAndroid Build Coastguard Worker uint64_t period_exponent, bool hold_preemption,
1563*61046927SAndroid Build Coastguard Worker bool enable)
1564*61046927SAndroid Build Coastguard Worker {
1565*61046927SAndroid Build Coastguard Worker uint64_t report_format = intel_perf_get_oa_format(perf_config);
1566*61046927SAndroid Build Coastguard Worker
1567*61046927SAndroid Build Coastguard Worker switch (perf_config->devinfo->kmd_type) {
1568*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
1569*61046927SAndroid Build Coastguard Worker return i915_perf_stream_open(perf_config, drm_fd, ctx_id, metrics_set_id,
1570*61046927SAndroid Build Coastguard Worker report_format, period_exponent,
1571*61046927SAndroid Build Coastguard Worker hold_preemption, enable);
1572*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
1573*61046927SAndroid Build Coastguard Worker return xe_perf_stream_open(perf_config, drm_fd, ctx_id, metrics_set_id,
1574*61046927SAndroid Build Coastguard Worker report_format, period_exponent,
1575*61046927SAndroid Build Coastguard Worker hold_preemption, enable);
1576*61046927SAndroid Build Coastguard Worker default:
1577*61046927SAndroid Build Coastguard Worker unreachable("missing");
1578*61046927SAndroid Build Coastguard Worker return 0;
1579*61046927SAndroid Build Coastguard Worker }
1580*61046927SAndroid Build Coastguard Worker }
1581*61046927SAndroid Build Coastguard Worker
1582*61046927SAndroid Build Coastguard Worker /*
1583*61046927SAndroid Build Coastguard Worker * Read perf stream samples.
1584*61046927SAndroid Build Coastguard Worker *
1585*61046927SAndroid Build Coastguard Worker * buffer will be filled with multiple struct intel_perf_record_header + data.
1586*61046927SAndroid Build Coastguard Worker *
1587*61046927SAndroid Build Coastguard Worker * Returns 0 if no sample is available, -errno value if a error happened or
1588*61046927SAndroid Build Coastguard Worker * the number of bytes read on success.
1589*61046927SAndroid Build Coastguard Worker */
1590*61046927SAndroid Build Coastguard Worker int
intel_perf_stream_read_samples(struct intel_perf_config * perf_config,int perf_stream_fd,uint8_t * buffer,size_t buffer_len)1591*61046927SAndroid Build Coastguard Worker intel_perf_stream_read_samples(struct intel_perf_config *perf_config,
1592*61046927SAndroid Build Coastguard Worker int perf_stream_fd, uint8_t *buffer,
1593*61046927SAndroid Build Coastguard Worker size_t buffer_len)
1594*61046927SAndroid Build Coastguard Worker {
1595*61046927SAndroid Build Coastguard Worker switch (perf_config->devinfo->kmd_type) {
1596*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
1597*61046927SAndroid Build Coastguard Worker return i915_perf_stream_read_samples(perf_config, perf_stream_fd, buffer, buffer_len);
1598*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
1599*61046927SAndroid Build Coastguard Worker return xe_perf_stream_read_samples(perf_config, perf_stream_fd, buffer, buffer_len);
1600*61046927SAndroid Build Coastguard Worker default:
1601*61046927SAndroid Build Coastguard Worker unreachable("missing");
1602*61046927SAndroid Build Coastguard Worker return -1;
1603*61046927SAndroid Build Coastguard Worker }
1604*61046927SAndroid Build Coastguard Worker }
1605*61046927SAndroid Build Coastguard Worker
1606*61046927SAndroid Build Coastguard Worker int
intel_perf_stream_set_state(struct intel_perf_config * perf_config,int perf_stream_fd,bool enable)1607*61046927SAndroid Build Coastguard Worker intel_perf_stream_set_state(struct intel_perf_config *perf_config,
1608*61046927SAndroid Build Coastguard Worker int perf_stream_fd, bool enable)
1609*61046927SAndroid Build Coastguard Worker {
1610*61046927SAndroid Build Coastguard Worker switch (perf_config->devinfo->kmd_type) {
1611*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
1612*61046927SAndroid Build Coastguard Worker return i915_perf_stream_set_state(perf_stream_fd, enable);
1613*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
1614*61046927SAndroid Build Coastguard Worker return xe_perf_stream_set_state(perf_stream_fd, enable);
1615*61046927SAndroid Build Coastguard Worker default:
1616*61046927SAndroid Build Coastguard Worker unreachable("missing");
1617*61046927SAndroid Build Coastguard Worker return -1;
1618*61046927SAndroid Build Coastguard Worker }
1619*61046927SAndroid Build Coastguard Worker }
1620*61046927SAndroid Build Coastguard Worker
1621*61046927SAndroid Build Coastguard Worker int
intel_perf_stream_set_metrics_id(struct intel_perf_config * perf_config,int perf_stream_fd,uint64_t metrics_set_id)1622*61046927SAndroid Build Coastguard Worker intel_perf_stream_set_metrics_id(struct intel_perf_config *perf_config,
1623*61046927SAndroid Build Coastguard Worker int perf_stream_fd, uint64_t metrics_set_id)
1624*61046927SAndroid Build Coastguard Worker {
1625*61046927SAndroid Build Coastguard Worker switch (perf_config->devinfo->kmd_type) {
1626*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_I915:
1627*61046927SAndroid Build Coastguard Worker return i915_perf_stream_set_metrics_id(perf_stream_fd, metrics_set_id);
1628*61046927SAndroid Build Coastguard Worker case INTEL_KMD_TYPE_XE:
1629*61046927SAndroid Build Coastguard Worker return xe_perf_stream_set_metrics_id(perf_stream_fd, metrics_set_id);
1630*61046927SAndroid Build Coastguard Worker default:
1631*61046927SAndroid Build Coastguard Worker unreachable("missing");
1632*61046927SAndroid Build Coastguard Worker return -1;
1633*61046927SAndroid Build Coastguard Worker }
1634*61046927SAndroid Build Coastguard Worker }
1635