Merge tag 'irqchip-fixes-5.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / arch / powerpc / perf / generic-compat-pmu.c
1 // SPDX-License-Identifier: GPL-2.0+
2 //
3 // Copyright 2019 Madhavan Srinivasan, IBM Corporation.
4
5 #define pr_fmt(fmt)     "generic-compat-pmu: " fmt
6
7 #include "isa207-common.h"
8
9 /*
10  * Raw event encoding:
11  *
12  *        60        56        52        48        44        40        36        32
13  * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
14  *
15  *        28        24        20        16        12         8         4         0
16  * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
17  *                                 [ pmc ]   [unit ]   [ ]   m   [    pmcxsel    ]
18  *                                                     |     |
19  *                                                     |     *- mark
20  *                                                     |
21  *                                                     |
22  *                                                     *- combine
23  *
24  * Below uses IBM bit numbering.
25  *
26  * MMCR1[x:y] = unit    (PMCxUNIT)
27  * MMCR1[24]   = pmc1combine[0]
28  * MMCR1[25]   = pmc1combine[1]
29  * MMCR1[26]   = pmc2combine[0]
30  * MMCR1[27]   = pmc2combine[1]
31  * MMCR1[28]   = pmc3combine[0]
32  * MMCR1[29]   = pmc3combine[1]
33  * MMCR1[30]   = pmc4combine[0]
34  * MMCR1[31]   = pmc4combine[1]
35  *
36  */
37
38 /*
39  * Some power9 event codes.
40  */
41 #define EVENT(_name, _code)     _name = _code,
42
43 enum {
44 EVENT(PM_CYC,                                   0x0001e)
45 EVENT(PM_INST_CMPL,                             0x00002)
46 };
47
48 #undef EVENT
49
50 GENERIC_EVENT_ATTR(cpu-cycles,                  PM_CYC);
51 GENERIC_EVENT_ATTR(instructions,                PM_INST_CMPL);
52
53 static struct attribute *generic_compat_events_attr[] = {
54         GENERIC_EVENT_PTR(PM_CYC),
55         GENERIC_EVENT_PTR(PM_INST_CMPL),
56         NULL
57 };
58
59 static struct attribute_group generic_compat_pmu_events_group = {
60         .name = "events",
61         .attrs = generic_compat_events_attr,
62 };
63
64 PMU_FORMAT_ATTR(event,          "config:0-19");
65 PMU_FORMAT_ATTR(pmcxsel,        "config:0-7");
66 PMU_FORMAT_ATTR(mark,           "config:8");
67 PMU_FORMAT_ATTR(combine,        "config:10-11");
68 PMU_FORMAT_ATTR(unit,           "config:12-15");
69 PMU_FORMAT_ATTR(pmc,            "config:16-19");
70
71 static struct attribute *generic_compat_pmu_format_attr[] = {
72         &format_attr_event.attr,
73         &format_attr_pmcxsel.attr,
74         &format_attr_mark.attr,
75         &format_attr_combine.attr,
76         &format_attr_unit.attr,
77         &format_attr_pmc.attr,
78         NULL,
79 };
80
81 static struct attribute_group generic_compat_pmu_format_group = {
82         .name = "format",
83         .attrs = generic_compat_pmu_format_attr,
84 };
85
86 static const struct attribute_group *generic_compat_pmu_attr_groups[] = {
87         &generic_compat_pmu_format_group,
88         &generic_compat_pmu_events_group,
89         NULL,
90 };
91
92 static int compat_generic_events[] = {
93         [PERF_COUNT_HW_CPU_CYCLES] =                    PM_CYC,
94         [PERF_COUNT_HW_INSTRUCTIONS] =                  PM_INST_CMPL,
95 };
96
97 #define C(x)    PERF_COUNT_HW_CACHE_##x
98
99 /*
100  * Table of generalized cache-related events.
101  * 0 means not supported, -1 means nonsensical, other values
102  * are event codes.
103  */
104 static int generic_compat_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
105         [ C(L1D) ] = {
106                 [ C(OP_READ) ] = {
107                         [ C(RESULT_ACCESS) ] = 0,
108                         [ C(RESULT_MISS)   ] = 0,
109                 },
110                 [ C(OP_WRITE) ] = {
111                         [ C(RESULT_ACCESS) ] = 0,
112                         [ C(RESULT_MISS)   ] = 0,
113                 },
114                 [ C(OP_PREFETCH) ] = {
115                         [ C(RESULT_ACCESS) ] = 0,
116                         [ C(RESULT_MISS)   ] = 0,
117                 },
118         },
119         [ C(L1I) ] = {
120                 [ C(OP_READ) ] = {
121                         [ C(RESULT_ACCESS) ] = 0,
122                         [ C(RESULT_MISS)   ] = 0,
123                 },
124                 [ C(OP_WRITE) ] = {
125                         [ C(RESULT_ACCESS) ] = 0,
126                         [ C(RESULT_MISS)   ] = -1,
127                 },
128                 [ C(OP_PREFETCH) ] = {
129                         [ C(RESULT_ACCESS) ] = 0,
130                         [ C(RESULT_MISS)   ] = 0,
131                 },
132         },
133         [ C(LL) ] = {
134                 [ C(OP_READ) ] = {
135                         [ C(RESULT_ACCESS) ] = 0,
136                         [ C(RESULT_MISS)   ] = 0,
137                 },
138                 [ C(OP_WRITE) ] = {
139                         [ C(RESULT_ACCESS) ] = 0,
140                         [ C(RESULT_MISS)   ] = 0,
141                 },
142                 [ C(OP_PREFETCH) ] = {
143                         [ C(RESULT_ACCESS) ] = 0,
144                         [ C(RESULT_MISS)   ] = 0,
145                 },
146         },
147         [ C(DTLB) ] = {
148                 [ C(OP_READ) ] = {
149                         [ C(RESULT_ACCESS) ] = 0,
150                         [ C(RESULT_MISS)   ] = 0,
151                 },
152                 [ C(OP_WRITE) ] = {
153                         [ C(RESULT_ACCESS) ] = -1,
154                         [ C(RESULT_MISS)   ] = -1,
155                 },
156                 [ C(OP_PREFETCH) ] = {
157                         [ C(RESULT_ACCESS) ] = -1,
158                         [ C(RESULT_MISS)   ] = -1,
159                 },
160         },
161         [ C(ITLB) ] = {
162                 [ C(OP_READ) ] = {
163                         [ C(RESULT_ACCESS) ] = 0,
164                         [ C(RESULT_MISS)   ] = 0,
165                 },
166                 [ C(OP_WRITE) ] = {
167                         [ C(RESULT_ACCESS) ] = -1,
168                         [ C(RESULT_MISS)   ] = -1,
169                 },
170                 [ C(OP_PREFETCH) ] = {
171                         [ C(RESULT_ACCESS) ] = -1,
172                         [ C(RESULT_MISS)   ] = -1,
173                 },
174         },
175         [ C(BPU) ] = {
176                 [ C(OP_READ) ] = {
177                         [ C(RESULT_ACCESS) ] = 0,
178                         [ C(RESULT_MISS)   ] = 0,
179                 },
180                 [ C(OP_WRITE) ] = {
181                         [ C(RESULT_ACCESS) ] = -1,
182                         [ C(RESULT_MISS)   ] = -1,
183                 },
184                 [ C(OP_PREFETCH) ] = {
185                         [ C(RESULT_ACCESS) ] = -1,
186                         [ C(RESULT_MISS)   ] = -1,
187                 },
188         },
189         [ C(NODE) ] = {
190                 [ C(OP_READ) ] = {
191                         [ C(RESULT_ACCESS) ] = -1,
192                         [ C(RESULT_MISS)   ] = -1,
193                 },
194                 [ C(OP_WRITE) ] = {
195                         [ C(RESULT_ACCESS) ] = -1,
196                         [ C(RESULT_MISS)   ] = -1,
197                 },
198                 [ C(OP_PREFETCH) ] = {
199                         [ C(RESULT_ACCESS) ] = -1,
200                         [ C(RESULT_MISS)   ] = -1,
201                 },
202         },
203 };
204
205 #undef C
206
207 static struct power_pmu generic_compat_pmu = {
208         .name                   = "GENERIC_COMPAT",
209         .n_counter              = MAX_PMU_COUNTERS,
210         .add_fields             = ISA207_ADD_FIELDS,
211         .test_adder             = ISA207_TEST_ADDER,
212         .compute_mmcr           = isa207_compute_mmcr,
213         .get_constraint         = isa207_get_constraint,
214         .disable_pmc            = isa207_disable_pmc,
215         .flags                  = PPMU_HAS_SIER | PPMU_ARCH_207S,
216         .n_generic              = ARRAY_SIZE(compat_generic_events),
217         .generic_events         = compat_generic_events,
218         .cache_events           = &generic_compat_cache_events,
219         .attr_groups            = generic_compat_pmu_attr_groups,
220 };
221
222 int init_generic_compat_pmu(void)
223 {
224         int rc = 0;
225
226         rc = register_power_pmu(&generic_compat_pmu);
227         if (rc)
228                 return rc;
229
230         /* Tell userspace that EBB is supported */
231         cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
232
233         return 0;
234 }