11
11
#include <linux/perf_event.h>
12
12
13
13
/* Performance monitor configuration */
14
- #define PMCFG1 0x00
15
- #define PMCFG1_RD_TRANS_FILT_EN BIT(31)
16
- #define PMCFG1_WR_TRANS_FILT_EN BIT(30)
17
- #define PMCFG1_RD_BT_FILT_EN BIT(29)
18
- #define PMCFG1_ID_MASK GENMASK(17, 0)
14
+ #define PMCFG1 0x00
15
+ #define MX93_PMCFG1_RD_TRANS_FILT_EN BIT(31)
16
+ #define MX93_PMCFG1_WR_TRANS_FILT_EN BIT(30)
17
+ #define MX93_PMCFG1_RD_BT_FILT_EN BIT(29)
18
+ #define MX93_PMCFG1_ID_MASK GENMASK(17, 0)
19
19
20
- #define PMCFG2 0x04
21
- #define PMCFG2_ID GENMASK(17, 0)
20
+ #define PMCFG2 0x04
21
+ #define MX93_PMCFG2_ID GENMASK(17, 0)
22
22
23
23
/* Global control register affects all counters and takes priority over local control registers */
24
24
#define PMGC0 0x40
@@ -75,6 +75,11 @@ static const struct imx_ddr_devtype_data imx93_devtype_data = {
75
75
.identifier = "imx93" ,
76
76
};
77
77
78
+ static inline bool is_imx93 (struct ddr_pmu * pmu )
79
+ {
80
+ return pmu -> devtype_data == & imx93_devtype_data ;
81
+ }
82
+
78
83
static const struct of_device_id imx_ddr_pmu_dt_ids [] = {
79
84
{.compatible = "fsl,imx93-ddr-pmu" , .data = & imx93_devtype_data },
80
85
{ /* sentinel */ }
@@ -122,24 +127,37 @@ static const struct attribute_group ddr_perf_cpumask_attr_group = {
122
127
.attrs = ddr_perf_cpumask_attrs ,
123
128
};
124
129
130
+ struct imx9_pmu_events_attr {
131
+ struct device_attribute attr ;
132
+ u64 id ;
133
+ const void * devtype_data ;
134
+ };
135
+
125
136
static ssize_t ddr_pmu_event_show (struct device * dev ,
126
137
struct device_attribute * attr , char * page )
127
138
{
128
- struct perf_pmu_events_attr * pmu_attr ;
139
+ struct imx9_pmu_events_attr * pmu_attr ;
129
140
130
- pmu_attr = container_of (attr , struct perf_pmu_events_attr , attr );
141
+ pmu_attr = container_of (attr , struct imx9_pmu_events_attr , attr );
131
142
return sysfs_emit (page , "event=0x%02llx\n" , pmu_attr -> id );
132
143
}
133
144
134
145
#define COUNTER_OFFSET_IN_EVENT 8
135
146
#define ID (counter , id ) ((counter << COUNTER_OFFSET_IN_EVENT) | id)
136
147
137
- #define IMX9_DDR_PMU_EVENT_ATTR (_name , _id ) \
138
- (&((struct perf_pmu_events_attr []) { \
148
+ #define DDR_PMU_EVENT_ATTR_COMM (_name , _id , _data ) \
149
+ (&((struct imx9_pmu_events_attr []) { \
139
150
{ .attr = __ATTR(_name, 0444, ddr_pmu_event_show, NULL),\
140
- .id = _id, } \
151
+ .id = _id, \
152
+ .devtype_data = _data, } \
141
153
})[0].attr.attr)
142
154
155
+ #define IMX9_DDR_PMU_EVENT_ATTR (_name , _id ) \
156
+ DDR_PMU_EVENT_ATTR_COMM(_name, _id, NULL)
157
+
158
+ #define IMX93_DDR_PMU_EVENT_ATTR (_name , _id ) \
159
+ DDR_PMU_EVENT_ATTR_COMM(_name, _id, &imx93_devtype_data)
160
+
143
161
static struct attribute * ddr_perf_events_attrs [] = {
144
162
/* counter0 cycles event */
145
163
IMX9_DDR_PMU_EVENT_ATTR (cycles , 0 ),
@@ -185,7 +203,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
185
203
IMX9_DDR_PMU_EVENT_ATTR (ddrc_ld_wiq_6 , ID (2 , 70 )),
186
204
IMX9_DDR_PMU_EVENT_ATTR (ddrc_ld_wiq_7 , ID (2 , 71 )),
187
205
IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pmon_empty , ID (2 , 72 )),
188
- IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pm_rd_trans_filt , ID (2 , 73 )),
206
+ IMX93_DDR_PMU_EVENT_ATTR (eddrtq_pm_rd_trans_filt , ID (2 , 73 )), /* imx93 specific*/
189
207
190
208
/* counter3 specific events */
191
209
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_collision_0 , ID (3 , 64 )),
@@ -197,7 +215,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
197
215
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_collision_6 , ID (3 , 70 )),
198
216
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_collision_7 , ID (3 , 71 )),
199
217
IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pmon_full , ID (3 , 72 )),
200
- IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pm_wr_trans_filt , ID (3 , 73 )),
218
+ IMX93_DDR_PMU_EVENT_ATTR (eddrtq_pm_wr_trans_filt , ID (3 , 73 )), /* imx93 specific*/
201
219
202
220
/* counter4 specific events */
203
221
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_open_0 , ID (4 , 64 )),
@@ -209,7 +227,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
209
227
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_open_6 , ID (4 , 70 )),
210
228
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_open_7 , ID (4 , 71 )),
211
229
IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pmon_ld_rdq2_rmw , ID (4 , 72 )),
212
- IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pm_rd_beat_filt , ID (4 , 73 )),
230
+ IMX93_DDR_PMU_EVENT_ATTR (eddrtq_pm_rd_beat_filt , ID (4 , 73 )), /* imx93 specific*/
213
231
214
232
/* counter5 specific events */
215
233
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_valid_start_0 , ID (5 , 64 )),
@@ -244,9 +262,29 @@ static struct attribute *ddr_perf_events_attrs[] = {
244
262
NULL ,
245
263
};
246
264
265
+ static umode_t
266
+ ddr_perf_events_attrs_is_visible (struct kobject * kobj ,
267
+ struct attribute * attr , int unused )
268
+ {
269
+ struct pmu * pmu = dev_get_drvdata (kobj_to_dev (kobj ));
270
+ struct ddr_pmu * ddr_pmu = to_ddr_pmu (pmu );
271
+ struct imx9_pmu_events_attr * eattr ;
272
+
273
+ eattr = container_of (attr , typeof (* eattr ), attr .attr );
274
+
275
+ if (!eattr -> devtype_data )
276
+ return attr -> mode ;
277
+
278
+ if (eattr -> devtype_data != ddr_pmu -> devtype_data )
279
+ return 0 ;
280
+
281
+ return attr -> mode ;
282
+ }
283
+
247
284
static const struct attribute_group ddr_perf_events_attr_group = {
248
285
.name = "events" ,
249
286
.attrs = ddr_perf_events_attrs ,
287
+ .is_visible = ddr_perf_events_attrs_is_visible ,
250
288
};
251
289
252
290
PMU_FORMAT_ATTR (event , "config:0-7,16-23" );
@@ -370,36 +408,28 @@ static void ddr_perf_counter_local_config(struct ddr_pmu *pmu, int config,
370
408
}
371
409
}
372
410
373
- static void ddr_perf_monitor_config (struct ddr_pmu * pmu , int event ,
374
- int counter , int axi_id , int axi_mask )
411
+ static void imx93_ddr_perf_monitor_config (struct ddr_pmu * pmu , int event ,
412
+ int counter , int axi_id , int axi_mask )
375
413
{
376
414
u32 pmcfg1 , pmcfg2 ;
415
+ u32 mask [] = { MX93_PMCFG1_RD_TRANS_FILT_EN ,
416
+ MX93_PMCFG1_WR_TRANS_FILT_EN ,
417
+ MX93_PMCFG1_RD_BT_FILT_EN };
377
418
378
419
pmcfg1 = readl_relaxed (pmu -> base + PMCFG1 );
379
420
380
- if (counter == 2 && event == 73 )
381
- pmcfg1 |= PMCFG1_RD_TRANS_FILT_EN ;
382
- else if (counter == 2 && event != 73 )
383
- pmcfg1 &= ~PMCFG1_RD_TRANS_FILT_EN ;
384
-
385
- if (counter == 3 && event == 73 )
386
- pmcfg1 |= PMCFG1_WR_TRANS_FILT_EN ;
387
- else if (counter == 3 && event != 73 )
388
- pmcfg1 &= ~PMCFG1_WR_TRANS_FILT_EN ;
389
-
390
- if (counter == 4 && event == 73 )
391
- pmcfg1 |= PMCFG1_RD_BT_FILT_EN ;
392
- else if (counter == 4 && event != 73 )
393
- pmcfg1 &= ~PMCFG1_RD_BT_FILT_EN ;
421
+ if (counter >= 2 && counter <= 4 )
422
+ pmcfg1 = event == 73 ? pmcfg1 | mask [counter - 2 ] :
423
+ pmcfg1 & ~mask [counter - 2 ];
394
424
395
- pmcfg1 &= ~FIELD_PREP (PMCFG1_ID_MASK , 0x3FFFF );
396
- pmcfg1 |= FIELD_PREP (PMCFG1_ID_MASK , axi_mask );
397
- writel (pmcfg1 , pmu -> base + PMCFG1 );
425
+ pmcfg1 &= ~FIELD_PREP (MX93_PMCFG1_ID_MASK , 0x3FFFF );
426
+ pmcfg1 |= FIELD_PREP (MX93_PMCFG1_ID_MASK , axi_mask );
427
+ writel_relaxed (pmcfg1 , pmu -> base + PMCFG1 );
398
428
399
429
pmcfg2 = readl_relaxed (pmu -> base + PMCFG2 );
400
- pmcfg2 &= ~FIELD_PREP (PMCFG2_ID , 0x3FFFF );
401
- pmcfg2 |= FIELD_PREP (PMCFG2_ID , axi_id );
402
- writel (pmcfg2 , pmu -> base + PMCFG2 );
430
+ pmcfg2 &= ~FIELD_PREP (MX93_PMCFG2_ID , 0x3FFFF );
431
+ pmcfg2 |= FIELD_PREP (MX93_PMCFG2_ID , axi_id );
432
+ writel_relaxed (pmcfg2 , pmu -> base + PMCFG2 );
403
433
}
404
434
405
435
static void ddr_perf_event_update (struct perf_event * event )
@@ -515,7 +545,7 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
515
545
ddr_perf_event_start (event , flags );
516
546
517
547
/* read trans, write trans, read beat */
518
- ddr_perf_monitor_config (pmu , event_id , counter , cfg1 , cfg2 );
548
+ imx93_ddr_perf_monitor_config (pmu , event_id , counter , cfg1 , cfg2 );
519
549
520
550
return 0 ;
521
551
}
0 commit comments