41
41
#define SLLC_SRCID_CMD_SHIFT 1
42
42
#define SLLC_SRCID_MSK_SHIFT 12
43
43
#define SLLC_NR_EVENTS 0x80
44
+ #define SLLC_EVENT_CNTn (cnt0 , n ) ((cnt0) + (n) * 8)
44
45
45
46
HISI_PMU_EVENT_ATTR_EXTRACTOR (tgtid_min , config1 , 10 , 0 );
46
47
HISI_PMU_EVENT_ATTR_EXTRACTOR (tgtid_max , config1 , 21 , 11 );
47
48
HISI_PMU_EVENT_ATTR_EXTRACTOR (srcid_cmd , config1 , 32 , 22 );
48
49
HISI_PMU_EVENT_ATTR_EXTRACTOR (srcid_msk , config1 , 43 , 33 );
49
50
HISI_PMU_EVENT_ATTR_EXTRACTOR (tracetag_en , config1 , 44 , 44 );
50
51
52
+ struct hisi_sllc_pmu_regs {
53
+ u32 int_mask ;
54
+ u32 int_clear ;
55
+ u32 int_status ;
56
+ u32 perf_ctrl ;
57
+ u32 srcid_ctrl ;
58
+ u32 srcid_cmd_shift ;
59
+ u32 srcid_mask_shift ;
60
+ u32 tgtid_ctrl ;
61
+ u32 tgtid_min_shift ;
62
+ u32 tgtid_max_shift ;
63
+ u32 event_ctrl ;
64
+ u32 event_type0 ;
65
+ u32 version ;
66
+ u32 event_cnt0 ;
67
+ };
68
+
51
69
static bool tgtid_is_valid (u32 max , u32 min )
52
70
{
53
71
return max > 0 && max >= min ;
@@ -56,96 +74,104 @@ static bool tgtid_is_valid(u32 max, u32 min)
56
74
static void hisi_sllc_pmu_enable_tracetag (struct perf_event * event )
57
75
{
58
76
struct hisi_pmu * sllc_pmu = to_hisi_pmu (event -> pmu );
77
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
59
78
u32 tt_en = hisi_get_tracetag_en (event );
60
79
61
80
if (tt_en ) {
62
81
u32 val ;
63
82
64
- val = readl (sllc_pmu -> base + SLLC_PERF_CTRL );
83
+ val = readl (sllc_pmu -> base + regs -> perf_ctrl );
65
84
val |= SLLC_TRACETAG_EN | SLLC_FILT_EN ;
66
- writel (val , sllc_pmu -> base + SLLC_PERF_CTRL );
85
+ writel (val , sllc_pmu -> base + regs -> perf_ctrl );
67
86
}
68
87
}
69
88
70
89
static void hisi_sllc_pmu_disable_tracetag (struct perf_event * event )
71
90
{
72
91
struct hisi_pmu * sllc_pmu = to_hisi_pmu (event -> pmu );
92
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
73
93
u32 tt_en = hisi_get_tracetag_en (event );
74
94
75
95
if (tt_en ) {
76
96
u32 val ;
77
97
78
- val = readl (sllc_pmu -> base + SLLC_PERF_CTRL );
98
+ val = readl (sllc_pmu -> base + regs -> perf_ctrl );
79
99
val &= ~(SLLC_TRACETAG_EN | SLLC_FILT_EN );
80
- writel (val , sllc_pmu -> base + SLLC_PERF_CTRL );
100
+ writel (val , sllc_pmu -> base + regs -> perf_ctrl );
81
101
}
82
102
}
83
103
84
104
static void hisi_sllc_pmu_config_tgtid (struct perf_event * event )
85
105
{
86
106
struct hisi_pmu * sllc_pmu = to_hisi_pmu (event -> pmu );
107
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
87
108
u32 min = hisi_get_tgtid_min (event );
88
109
u32 max = hisi_get_tgtid_max (event );
89
110
90
111
if (tgtid_is_valid (max , min )) {
91
- u32 val = (max << SLLC_TGTID_MAX_SHIFT ) | (min << SLLC_TGTID_MIN_SHIFT );
112
+ u32 val = (max << regs -> tgtid_max_shift ) |
113
+ (min << regs -> tgtid_min_shift );
92
114
93
- writel (val , sllc_pmu -> base + SLLC_TGTID_CTRL );
115
+ writel (val , sllc_pmu -> base + regs -> tgtid_ctrl );
94
116
/* Enable the tgtid */
95
- val = readl (sllc_pmu -> base + SLLC_PERF_CTRL );
117
+ val = readl (sllc_pmu -> base + regs -> perf_ctrl );
96
118
val |= SLLC_TGTID_EN | SLLC_FILT_EN ;
97
- writel (val , sllc_pmu -> base + SLLC_PERF_CTRL );
119
+ writel (val , sllc_pmu -> base + regs -> perf_ctrl );
98
120
}
99
121
}
100
122
101
123
static void hisi_sllc_pmu_clear_tgtid (struct perf_event * event )
102
124
{
103
125
struct hisi_pmu * sllc_pmu = to_hisi_pmu (event -> pmu );
126
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
104
127
u32 min = hisi_get_tgtid_min (event );
105
128
u32 max = hisi_get_tgtid_max (event );
106
129
107
130
if (tgtid_is_valid (max , min )) {
108
131
u32 val ;
109
132
110
- writel (SLLC_TGTID_NONE , sllc_pmu -> base + SLLC_TGTID_CTRL );
133
+ writel (SLLC_TGTID_NONE , sllc_pmu -> base + regs -> tgtid_ctrl );
111
134
/* Disable the tgtid */
112
- val = readl (sllc_pmu -> base + SLLC_PERF_CTRL );
135
+ val = readl (sllc_pmu -> base + regs -> perf_ctrl );
113
136
val &= ~(SLLC_TGTID_EN | SLLC_FILT_EN );
114
- writel (val , sllc_pmu -> base + SLLC_PERF_CTRL );
137
+ writel (val , sllc_pmu -> base + regs -> perf_ctrl );
115
138
}
116
139
}
117
140
118
141
static void hisi_sllc_pmu_config_srcid (struct perf_event * event )
119
142
{
120
143
struct hisi_pmu * sllc_pmu = to_hisi_pmu (event -> pmu );
144
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
121
145
u32 cmd = hisi_get_srcid_cmd (event );
122
146
123
147
if (cmd ) {
124
148
u32 val , msk ;
125
149
126
150
msk = hisi_get_srcid_msk (event );
127
- val = (cmd << SLLC_SRCID_CMD_SHIFT ) | (msk << SLLC_SRCID_MSK_SHIFT );
128
- writel (val , sllc_pmu -> base + SLLC_SRCID_CTRL );
151
+ val = (cmd << regs -> srcid_cmd_shift ) |
152
+ (msk << regs -> srcid_mask_shift );
153
+ writel (val , sllc_pmu -> base + regs -> srcid_ctrl );
129
154
/* Enable the srcid */
130
- val = readl (sllc_pmu -> base + SLLC_PERF_CTRL );
155
+ val = readl (sllc_pmu -> base + regs -> perf_ctrl );
131
156
val |= SLLC_SRCID_EN | SLLC_FILT_EN ;
132
- writel (val , sllc_pmu -> base + SLLC_PERF_CTRL );
157
+ writel (val , sllc_pmu -> base + regs -> perf_ctrl );
133
158
}
134
159
}
135
160
136
161
static void hisi_sllc_pmu_clear_srcid (struct perf_event * event )
137
162
{
138
163
struct hisi_pmu * sllc_pmu = to_hisi_pmu (event -> pmu );
164
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
139
165
u32 cmd = hisi_get_srcid_cmd (event );
140
166
141
167
if (cmd ) {
142
168
u32 val ;
143
169
144
- writel (SLLC_SRCID_NONE , sllc_pmu -> base + SLLC_SRCID_CTRL );
170
+ writel (SLLC_SRCID_NONE , sllc_pmu -> base + regs -> srcid_ctrl );
145
171
/* Disable the srcid */
146
- val = readl (sllc_pmu -> base + SLLC_PERF_CTRL );
172
+ val = readl (sllc_pmu -> base + regs -> perf_ctrl );
147
173
val &= ~(SLLC_SRCID_EN | SLLC_FILT_EN );
148
- writel (val , sllc_pmu -> base + SLLC_PERF_CTRL );
174
+ writel (val , sllc_pmu -> base + regs -> perf_ctrl );
149
175
}
150
176
}
151
177
@@ -167,29 +193,27 @@ static void hisi_sllc_pmu_clear_filter(struct perf_event *event)
167
193
}
168
194
}
169
195
170
- static u32 hisi_sllc_pmu_get_counter_offset (int idx )
171
- {
172
- return (SLLC_EVENT_CNT0_L + idx * 8 );
173
- }
174
-
175
196
static u64 hisi_sllc_pmu_read_counter (struct hisi_pmu * sllc_pmu ,
176
197
struct hw_perf_event * hwc )
177
198
{
178
- return readq (sllc_pmu -> base +
179
- hisi_sllc_pmu_get_counter_offset (hwc -> idx ));
199
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
200
+
201
+ return readq (sllc_pmu -> base + SLLC_EVENT_CNTn (regs -> event_cnt0 , hwc -> idx ));
180
202
}
181
203
182
204
static void hisi_sllc_pmu_write_counter (struct hisi_pmu * sllc_pmu ,
183
205
struct hw_perf_event * hwc , u64 val )
184
206
{
185
- writeq (val , sllc_pmu -> base +
186
- hisi_sllc_pmu_get_counter_offset (hwc -> idx ));
207
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
208
+
209
+ writeq (val , sllc_pmu -> base + SLLC_EVENT_CNTn (regs -> event_cnt0 , hwc -> idx ));
187
210
}
188
211
189
212
static void hisi_sllc_pmu_write_evtype (struct hisi_pmu * sllc_pmu , int idx ,
190
213
u32 type )
191
214
{
192
- u32 reg , reg_idx , shift , val ;
215
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
216
+ u32 reg , val ;
193
217
194
218
/*
195
219
* Select the appropriate event select register(SLLC_EVENT_TYPE0/1).
@@ -198,96 +222,98 @@ static void hisi_sllc_pmu_write_evtype(struct hisi_pmu *sllc_pmu, int idx,
198
222
* SLLC_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
199
223
* SLLC_EVENT_TYPE1 is chosen.
200
224
*/
201
- reg = SLLC_EVENT_TYPE0 + (idx / 4 ) * 4 ;
202
- reg_idx = idx % 4 ;
203
- shift = 8 * reg_idx ;
225
+ reg = regs -> event_type0 + (idx / 4 ) * 4 ;
204
226
205
227
/* Write event code to SLLC_EVENT_TYPEx Register */
206
228
val = readl (sllc_pmu -> base + reg );
207
- val &= ~(SLLC_EVTYPE_MASK << shift );
208
- val |= (type << shift );
229
+ val &= ~(SLLC_EVTYPE_MASK << HISI_PMU_EVTYPE_SHIFT ( idx ) );
230
+ val |= (type << HISI_PMU_EVTYPE_SHIFT ( idx ) );
209
231
writel (val , sllc_pmu -> base + reg );
210
232
}
211
233
212
234
static void hisi_sllc_pmu_start_counters (struct hisi_pmu * sllc_pmu )
213
235
{
236
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
214
237
u32 val ;
215
238
216
- val = readl (sllc_pmu -> base + SLLC_PERF_CTRL );
239
+ val = readl (sllc_pmu -> base + regs -> perf_ctrl );
217
240
val |= SLLC_PERF_CTRL_EN ;
218
- writel (val , sllc_pmu -> base + SLLC_PERF_CTRL );
241
+ writel (val , sllc_pmu -> base + regs -> perf_ctrl );
219
242
}
220
243
221
244
static void hisi_sllc_pmu_stop_counters (struct hisi_pmu * sllc_pmu )
222
245
{
246
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
223
247
u32 val ;
224
248
225
- val = readl (sllc_pmu -> base + SLLC_PERF_CTRL );
249
+ val = readl (sllc_pmu -> base + regs -> perf_ctrl );
226
250
val &= ~(SLLC_PERF_CTRL_EN );
227
- writel (val , sllc_pmu -> base + SLLC_PERF_CTRL );
251
+ writel (val , sllc_pmu -> base + regs -> perf_ctrl );
228
252
}
229
253
230
254
static void hisi_sllc_pmu_enable_counter (struct hisi_pmu * sllc_pmu ,
231
255
struct hw_perf_event * hwc )
232
256
{
257
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
233
258
u32 val ;
234
259
235
- val = readl (sllc_pmu -> base + SLLC_EVENT_CTRL );
236
- val |= 1 << hwc -> idx ;
237
- writel (val , sllc_pmu -> base + SLLC_EVENT_CTRL );
260
+ val = readl (sllc_pmu -> base + regs -> event_ctrl );
261
+ val |= BIT_ULL ( hwc -> idx ) ;
262
+ writel (val , sllc_pmu -> base + regs -> event_ctrl );
238
263
}
239
264
240
265
static void hisi_sllc_pmu_disable_counter (struct hisi_pmu * sllc_pmu ,
241
266
struct hw_perf_event * hwc )
242
267
{
268
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
243
269
u32 val ;
244
270
245
- val = readl (sllc_pmu -> base + SLLC_EVENT_CTRL );
246
- val &= ~( 1 << hwc -> idx );
247
- writel (val , sllc_pmu -> base + SLLC_EVENT_CTRL );
271
+ val = readl (sllc_pmu -> base + regs -> event_ctrl );
272
+ val &= ~BIT_ULL ( hwc -> idx );
273
+ writel (val , sllc_pmu -> base + regs -> event_ctrl );
248
274
}
249
275
250
276
static void hisi_sllc_pmu_enable_counter_int (struct hisi_pmu * sllc_pmu ,
251
277
struct hw_perf_event * hwc )
252
278
{
279
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
253
280
u32 val ;
254
281
255
- val = readl (sllc_pmu -> base + SLLC_INT_MASK );
256
- /* Write 0 to enable interrupt */
257
- val &= ~(1 << hwc -> idx );
258
- writel (val , sllc_pmu -> base + SLLC_INT_MASK );
282
+ val = readl (sllc_pmu -> base + regs -> int_mask );
283
+ val &= ~BIT_ULL (hwc -> idx );
284
+ writel (val , sllc_pmu -> base + regs -> int_mask );
259
285
}
260
286
261
287
static void hisi_sllc_pmu_disable_counter_int (struct hisi_pmu * sllc_pmu ,
262
288
struct hw_perf_event * hwc )
263
289
{
290
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
264
291
u32 val ;
265
292
266
- val = readl (sllc_pmu -> base + SLLC_INT_MASK );
267
- /* Write 1 to mask interrupt */
268
- val |= 1 << hwc -> idx ;
269
- writel (val , sllc_pmu -> base + SLLC_INT_MASK );
293
+ val = readl (sllc_pmu -> base + regs -> int_mask );
294
+ val |= BIT_ULL (hwc -> idx );
295
+ writel (val , sllc_pmu -> base + regs -> int_mask );
270
296
}
271
297
272
298
static u32 hisi_sllc_pmu_get_int_status (struct hisi_pmu * sllc_pmu )
273
299
{
274
- return readl (sllc_pmu -> base + SLLC_INT_STATUS );
300
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
301
+
302
+ return readl (sllc_pmu -> base + regs -> int_status );
275
303
}
276
304
277
305
static void hisi_sllc_pmu_clear_int_status (struct hisi_pmu * sllc_pmu , int idx )
278
306
{
279
- writel (1 << idx , sllc_pmu -> base + SLLC_INT_CLEAR );
280
- }
307
+ struct hisi_sllc_pmu_regs * regs = sllc_pmu -> dev_info -> private ;
281
308
282
- static const struct acpi_device_id hisi_sllc_pmu_acpi_match [] = {
283
- { "HISI0263" , },
284
- {}
285
- };
286
- MODULE_DEVICE_TABLE (acpi , hisi_sllc_pmu_acpi_match );
309
+ writel (BIT_ULL (idx ), sllc_pmu -> base + regs -> int_clear );
310
+ }
287
311
288
312
static int hisi_sllc_pmu_init_data (struct platform_device * pdev ,
289
313
struct hisi_pmu * sllc_pmu )
290
314
{
315
+ struct hisi_sllc_pmu_regs * regs ;
316
+
291
317
hisi_uncore_pmu_init_topology (sllc_pmu , & pdev -> dev );
292
318
293
319
/*
@@ -304,13 +330,18 @@ static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
304
330
return - EINVAL ;
305
331
}
306
332
333
+ sllc_pmu -> dev_info = device_get_match_data (& pdev -> dev );
334
+ if (!sllc_pmu -> dev_info )
335
+ return - ENODEV ;
336
+
307
337
sllc_pmu -> base = devm_platform_ioremap_resource (pdev , 0 );
308
338
if (IS_ERR (sllc_pmu -> base )) {
309
339
dev_err (& pdev -> dev , "ioremap failed for sllc_pmu resource.\n" );
310
340
return PTR_ERR (sllc_pmu -> base );
311
341
}
312
342
313
- sllc_pmu -> identifier = readl (sllc_pmu -> base + SLLC_VERSION );
343
+ regs = sllc_pmu -> dev_info -> private ;
344
+ sllc_pmu -> identifier = readl (sllc_pmu -> base + regs -> version );
314
345
315
346
return 0 ;
316
347
}
@@ -352,6 +383,27 @@ static const struct attribute_group *hisi_sllc_pmu_v2_attr_groups[] = {
352
383
NULL
353
384
};
354
385
386
+ static struct hisi_sllc_pmu_regs hisi_sllc_v2_pmu_regs = {
387
+ .int_mask = SLLC_INT_MASK ,
388
+ .int_clear = SLLC_INT_CLEAR ,
389
+ .int_status = SLLC_INT_STATUS ,
390
+ .perf_ctrl = SLLC_PERF_CTRL ,
391
+ .srcid_ctrl = SLLC_SRCID_CTRL ,
392
+ .srcid_cmd_shift = SLLC_SRCID_CMD_SHIFT ,
393
+ .srcid_mask_shift = SLLC_SRCID_MSK_SHIFT ,
394
+ .tgtid_ctrl = SLLC_TGTID_CTRL ,
395
+ .tgtid_min_shift = SLLC_TGTID_MIN_SHIFT ,
396
+ .tgtid_max_shift = SLLC_TGTID_MAX_SHIFT ,
397
+ .event_ctrl = SLLC_EVENT_CTRL ,
398
+ .event_type0 = SLLC_EVENT_TYPE0 ,
399
+ .version = SLLC_VERSION ,
400
+ .event_cnt0 = SLLC_EVENT_CNT0_L ,
401
+ };
402
+
403
+ static const struct hisi_pmu_dev_info hisi_sllc_v2 = {
404
+ .private = & hisi_sllc_v2_pmu_regs ,
405
+ };
406
+
355
407
static const struct hisi_uncore_ops hisi_uncore_sllc_ops = {
356
408
.write_evtype = hisi_sllc_pmu_write_evtype ,
357
409
.get_event_idx = hisi_uncore_pmu_get_event_idx ,
@@ -443,6 +495,12 @@ static void hisi_sllc_pmu_remove(struct platform_device *pdev)
443
495
& sllc_pmu -> node );
444
496
}
445
497
498
+ static const struct acpi_device_id hisi_sllc_pmu_acpi_match [] = {
499
+ { "HISI0263" , (kernel_ulong_t )& hisi_sllc_v2 },
500
+ {}
501
+ };
502
+ MODULE_DEVICE_TABLE (acpi , hisi_sllc_pmu_acpi_match );
503
+
446
504
static struct platform_driver hisi_sllc_pmu_driver = {
447
505
.driver = {
448
506
.name = "hisi_sllc_pmu" ,
0 commit comments