17
17
#define MX93_PMCFG1_RD_BT_FILT_EN BIT(29)
18
18
#define MX93_PMCFG1_ID_MASK GENMASK(17, 0)
19
19
20
+ #define MX95_PMCFG1_WR_BEAT_FILT_EN BIT(31)
21
+ #define MX95_PMCFG1_RD_BEAT_FILT_EN BIT(30)
22
+
20
23
#define PMCFG2 0x04
21
24
#define MX93_PMCFG2_ID GENMASK(17, 0)
22
25
26
+ #define PMCFG3 0x08
27
+ #define PMCFG4 0x0C
28
+ #define PMCFG5 0x10
29
+ #define PMCFG6 0x14
30
+ #define MX95_PMCFG_ID_MASK GENMASK(9, 0)
31
+ #define MX95_PMCFG_ID GENMASK(25, 16)
32
+
23
33
/* Global control register affects all counters and takes priority over local control registers */
24
34
#define PMGC0 0x40
25
35
/* Global control register bits */
@@ -75,13 +85,23 @@ static const struct imx_ddr_devtype_data imx93_devtype_data = {
75
85
.identifier = "imx93" ,
76
86
};
77
87
88
+ static const struct imx_ddr_devtype_data imx95_devtype_data = {
89
+ .identifier = "imx95" ,
90
+ };
91
+
78
92
static inline bool is_imx93 (struct ddr_pmu * pmu )
79
93
{
80
94
return pmu -> devtype_data == & imx93_devtype_data ;
81
95
}
82
96
97
+ static inline bool is_imx95 (struct ddr_pmu * pmu )
98
+ {
99
+ return pmu -> devtype_data == & imx95_devtype_data ;
100
+ }
101
+
83
102
static const struct of_device_id imx_ddr_pmu_dt_ids [] = {
84
- {.compatible = "fsl,imx93-ddr-pmu" , .data = & imx93_devtype_data },
103
+ { .compatible = "fsl,imx93-ddr-pmu" , .data = & imx93_devtype_data },
104
+ { .compatible = "fsl,imx95-ddr-pmu" , .data = & imx95_devtype_data },
85
105
{ /* sentinel */ }
86
106
};
87
107
MODULE_DEVICE_TABLE (of , imx_ddr_pmu_dt_ids );
@@ -158,6 +178,9 @@ static ssize_t ddr_pmu_event_show(struct device *dev,
158
178
#define IMX93_DDR_PMU_EVENT_ATTR (_name , _id ) \
159
179
DDR_PMU_EVENT_ATTR_COMM(_name, _id, &imx93_devtype_data)
160
180
181
+ #define IMX95_DDR_PMU_EVENT_ATTR (_name , _id ) \
182
+ DDR_PMU_EVENT_ATTR_COMM(_name, _id, &imx95_devtype_data)
183
+
161
184
static struct attribute * ddr_perf_events_attrs [] = {
162
185
/* counter0 cycles event */
163
186
IMX9_DDR_PMU_EVENT_ATTR (cycles , 0 ),
@@ -204,6 +227,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
204
227
IMX9_DDR_PMU_EVENT_ATTR (ddrc_ld_wiq_7 , ID (2 , 71 )),
205
228
IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pmon_empty , ID (2 , 72 )),
206
229
IMX93_DDR_PMU_EVENT_ATTR (eddrtq_pm_rd_trans_filt , ID (2 , 73 )), /* imx93 specific*/
230
+ IMX95_DDR_PMU_EVENT_ATTR (eddrtq_pm_wr_beat_filt , ID (2 , 73 )), /* imx95 specific*/
207
231
208
232
/* counter3 specific events */
209
233
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_collision_0 , ID (3 , 64 )),
@@ -216,6 +240,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
216
240
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_collision_7 , ID (3 , 71 )),
217
241
IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pmon_full , ID (3 , 72 )),
218
242
IMX93_DDR_PMU_EVENT_ATTR (eddrtq_pm_wr_trans_filt , ID (3 , 73 )), /* imx93 specific*/
243
+ IMX95_DDR_PMU_EVENT_ATTR (eddrtq_pm_rd_beat_filt2 , ID (3 , 73 )), /* imx95 specific*/
219
244
220
245
/* counter4 specific events */
221
246
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_open_0 , ID (4 , 64 )),
@@ -228,6 +253,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
228
253
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_open_7 , ID (4 , 71 )),
229
254
IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pmon_ld_rdq2_rmw , ID (4 , 72 )),
230
255
IMX93_DDR_PMU_EVENT_ATTR (eddrtq_pm_rd_beat_filt , ID (4 , 73 )), /* imx93 specific*/
256
+ IMX95_DDR_PMU_EVENT_ATTR (eddrtq_pm_rd_beat_filt1 , ID (4 , 73 )), /* imx95 specific*/
231
257
232
258
/* counter5 specific events */
233
259
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_valid_start_0 , ID (5 , 64 )),
@@ -239,6 +265,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
239
265
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_valid_start_6 , ID (5 , 70 )),
240
266
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_valid_start_7 , ID (5 , 71 )),
241
267
IMX9_DDR_PMU_EVENT_ATTR (eddrtq_pmon_ld_rdq1 , ID (5 , 72 )),
268
+ IMX95_DDR_PMU_EVENT_ATTR (eddrtq_pm_rd_beat_filt0 , ID (5 , 73 )), /* imx95 specific*/
242
269
243
270
/* counter6 specific events */
244
271
IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_valid_end_0 , ID (6 , 64 )),
@@ -432,6 +459,57 @@ static void imx93_ddr_perf_monitor_config(struct ddr_pmu *pmu, int event,
432
459
writel_relaxed (pmcfg2 , pmu -> base + PMCFG2 );
433
460
}
434
461
462
+ static void imx95_ddr_perf_monitor_config (struct ddr_pmu * pmu , int event ,
463
+ int counter , int axi_id , int axi_mask )
464
+ {
465
+ u32 pmcfg1 , pmcfg , offset = 0 ;
466
+
467
+ pmcfg1 = readl_relaxed (pmu -> base + PMCFG1 );
468
+
469
+ if (event == 73 ) {
470
+ switch (counter ) {
471
+ case 2 :
472
+ pmcfg1 |= MX95_PMCFG1_WR_BEAT_FILT_EN ;
473
+ offset = PMCFG3 ;
474
+ break ;
475
+ case 3 :
476
+ pmcfg1 |= MX95_PMCFG1_RD_BEAT_FILT_EN ;
477
+ offset = PMCFG4 ;
478
+ break ;
479
+ case 4 :
480
+ pmcfg1 |= MX95_PMCFG1_RD_BEAT_FILT_EN ;
481
+ offset = PMCFG5 ;
482
+ break ;
483
+ case 5 :
484
+ pmcfg1 |= MX95_PMCFG1_RD_BEAT_FILT_EN ;
485
+ offset = PMCFG6 ;
486
+ break ;
487
+ }
488
+ } else {
489
+ switch (counter ) {
490
+ case 2 :
491
+ pmcfg1 &= ~MX95_PMCFG1_WR_BEAT_FILT_EN ;
492
+ break ;
493
+ case 3 :
494
+ case 4 :
495
+ case 5 :
496
+ pmcfg1 &= ~MX95_PMCFG1_RD_BEAT_FILT_EN ;
497
+ break ;
498
+ }
499
+ }
500
+
501
+ writel_relaxed (pmcfg1 , pmu -> base + PMCFG1 );
502
+
503
+ if (offset ) {
504
+ pmcfg = readl_relaxed (pmu -> base + offset );
505
+ pmcfg &= ~(FIELD_PREP (MX95_PMCFG_ID_MASK , 0x3FF ) |
506
+ FIELD_PREP (MX95_PMCFG_ID , 0x3FF ));
507
+ pmcfg |= (FIELD_PREP (MX95_PMCFG_ID_MASK , axi_mask ) |
508
+ FIELD_PREP (MX95_PMCFG_ID , axi_id ));
509
+ writel_relaxed (pmcfg , pmu -> base + offset );
510
+ }
511
+ }
512
+
435
513
static void ddr_perf_event_update (struct perf_event * event )
436
514
{
437
515
struct ddr_pmu * pmu = to_ddr_pmu (event -> pmu );
@@ -541,8 +619,13 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
541
619
hwc -> idx = counter ;
542
620
hwc -> state |= PERF_HES_STOPPED ;
543
621
544
- /* read trans, write trans, read beat */
545
- imx93_ddr_perf_monitor_config (pmu , event_id , counter , cfg1 , cfg2 );
622
+ if (is_imx93 (pmu ))
623
+ /* read trans, write trans, read beat */
624
+ imx93_ddr_perf_monitor_config (pmu , event_id , counter , cfg1 , cfg2 );
625
+
626
+ if (is_imx95 (pmu ))
627
+ /* write beat, read beat2, read beat1, read beat */
628
+ imx95_ddr_perf_monitor_config (pmu , event_id , counter , cfg1 , cfg2 );
546
629
547
630
if (flags & PERF_EF_START )
548
631
ddr_perf_event_start (event , flags );
0 commit comments