1/*
2 * Copyright (C) 2018 Rob Clark <robclark@freedesktop.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 *    Rob Clark <robclark@freedesktop.org>
25 */
26
27#ifndef FREEDRENO_PERFCNTR_H_
28#define FREEDRENO_PERFCNTR_H_
29
30#include "util/macros.h"
31
32#include "freedreno_dev_info.h"
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38/*
39 * Mapping very closely to the AMD_performance_monitor extension, adreno has
40 * groups of performance counters where each group has N counters, which can
41 * select from M different countables (things that can be counted), where
42 * generally M > N.
43 */
44
45/* Describes a single counter: */
46struct fd_perfcntr_counter {
47   /* offset of the select register to choose what to count: */
48   unsigned select_reg;
49   /* offset of the lo/hi 32b to read current counter value: */
50   unsigned counter_reg_lo;
51   unsigned counter_reg_hi;
52   /* Optional, most counters don't have enable/clear registers: */
53   unsigned enable;
54   unsigned clear;
55};
56
57enum fd_perfcntr_type {
58   FD_PERFCNTR_TYPE_UINT64,
59   FD_PERFCNTR_TYPE_UINT,
60   FD_PERFCNTR_TYPE_FLOAT,
61   FD_PERFCNTR_TYPE_PERCENTAGE,
62   FD_PERFCNTR_TYPE_BYTES,
63   FD_PERFCNTR_TYPE_MICROSECONDS,
64   FD_PERFCNTR_TYPE_HZ,
65   FD_PERFCNTR_TYPE_DBM,
66   FD_PERFCNTR_TYPE_TEMPERATURE,
67   FD_PERFCNTR_TYPE_VOLTS,
68   FD_PERFCNTR_TYPE_AMPS,
69   FD_PERFCNTR_TYPE_WATTS,
70};
71
72/* Whether an average value per frame or a cumulative value should be
73 * displayed.
74 */
75enum fd_perfcntr_result_type {
76   FD_PERFCNTR_RESULT_TYPE_AVERAGE,
77   FD_PERFCNTR_RESULT_TYPE_CUMULATIVE,
78};
79
80/* Describes a single countable: */
81struct fd_perfcntr_countable {
82   const char *name;
83   /* selector register enum value to select this countable: */
84   unsigned selector;
85
86   /* description of the countable: */
87   enum fd_perfcntr_type query_type;
88   enum fd_perfcntr_result_type result_type;
89};
90
91/* Describes an entire counter group: */
92struct fd_perfcntr_group {
93   const char *name;
94   unsigned num_counters;
95   const struct fd_perfcntr_counter *counters;
96   unsigned num_countables;
97   const struct fd_perfcntr_countable *countables;
98};
99
100const struct fd_perfcntr_group *fd_perfcntrs(const struct fd_dev_id *id, unsigned *count);
101
102#define COUNTER(_sel, _lo, _hi) {                                              \
103      .select_reg = REG(_sel), .counter_reg_lo = REG(_lo),                     \
104      .counter_reg_hi = REG(_hi),                                              \
105   }
106
107#define COUNTER2(_sel, _lo, _hi, _en, _clr) {                                  \
108      .select_reg = REG(_sel), .counter_reg_lo = REG(_lo),                     \
109      .counter_reg_hi = REG(_hi), .enable = REG(_en), .clear = REG(_clr),      \
110   }
111
112#define COUNTABLE(_selector, _query_type, _result_type) {                      \
113      .name = #_selector, .selector = _selector,                               \
114      .query_type = FD_PERFCNTR_TYPE_##_query_type,                            \
115      .result_type = FD_PERFCNTR_RESULT_TYPE_##_result_type,                   \
116   }
117
118#define GROUP(_name, _counters, _countables) {                                 \
119      .name = _name, .num_counters = ARRAY_SIZE(_counters),                    \
120      .counters = _counters, .num_countables = ARRAY_SIZE(_countables),        \
121      .countables = _countables,                                               \
122   }
123
124#ifdef __cplusplus
125} /* end of extern "C" */
126#endif
127
128#endif /* FREEDRENO_PERFCNTR_H_ */
129