1111#include <linux/perf_event.h>
1212
1313/* 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)
1919
20- #define PMCFG2 0x04
21- #define PMCFG2_ID GENMASK(17, 0)
20+ #define PMCFG2 0x04
21+ #define MX93_PMCFG2_ID GENMASK(17, 0)
2222
2323/* Global control register affects all counters and takes priority over local control registers */
2424#define PMGC0 0x40
@@ -75,6 +75,11 @@ static const struct imx_ddr_devtype_data imx93_devtype_data = {
7575 .identifier = "imx93" ,
7676};
7777
78+ static inline bool is_imx93 (struct ddr_pmu * pmu )
79+ {
80+ return pmu -> devtype_data == & imx93_devtype_data ;
81+ }
82+
7883static const struct of_device_id imx_ddr_pmu_dt_ids [] = {
7984 {.compatible = "fsl,imx93-ddr-pmu" , .data = & imx93_devtype_data },
8085 { /* sentinel */ }
@@ -122,24 +127,37 @@ static const struct attribute_group ddr_perf_cpumask_attr_group = {
122127 .attrs = ddr_perf_cpumask_attrs ,
123128};
124129
130+ struct imx9_pmu_events_attr {
131+ struct device_attribute attr ;
132+ u64 id ;
133+ const void * devtype_data ;
134+ };
135+
125136static ssize_t ddr_pmu_event_show (struct device * dev ,
126137 struct device_attribute * attr , char * page )
127138{
128- struct perf_pmu_events_attr * pmu_attr ;
139+ struct imx9_pmu_events_attr * pmu_attr ;
129140
130- pmu_attr = container_of (attr , struct perf_pmu_events_attr , attr );
141+ pmu_attr = container_of (attr , struct imx9_pmu_events_attr , attr );
131142 return sysfs_emit (page , "event=0x%02llx\n" , pmu_attr -> id );
132143}
133144
134145#define COUNTER_OFFSET_IN_EVENT 8
135146#define ID (counter , id ) ((counter << COUNTER_OFFSET_IN_EVENT) | id)
136147
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 []) { \
139150 { .attr = __ATTR(_name, 0444, ddr_pmu_event_show, NULL),\
140- .id = _id, } \
151+ .id = _id, \
152+ .devtype_data = _data, } \
141153 })[0].attr.attr)
142154
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+
143161static struct attribute * ddr_perf_events_attrs [] = {
144162 /* counter0 cycles event */
145163 IMX9_DDR_PMU_EVENT_ATTR (cycles , 0 ),
@@ -185,7 +203,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
185203 IMX9_DDR_PMU_EVENT_ATTR (ddrc_ld_wiq_6 , ID (2 , 70 )),
186204 IMX9_DDR_PMU_EVENT_ATTR (ddrc_ld_wiq_7 , ID (2 , 71 )),
187205 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*/
189207
190208 /* counter3 specific events */
191209 IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_collision_0 , ID (3 , 64 )),
@@ -197,7 +215,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
197215 IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_collision_6 , ID (3 , 70 )),
198216 IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_collision_7 , ID (3 , 71 )),
199217 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*/
201219
202220 /* counter4 specific events */
203221 IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_open_0 , ID (4 , 64 )),
@@ -209,7 +227,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
209227 IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_open_6 , ID (4 , 70 )),
210228 IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_row_open_7 , ID (4 , 71 )),
211229 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*/
213231
214232 /* counter5 specific events */
215233 IMX9_DDR_PMU_EVENT_ATTR (ddrc_qx_valid_start_0 , ID (5 , 64 )),
@@ -244,9 +262,29 @@ static struct attribute *ddr_perf_events_attrs[] = {
244262 NULL ,
245263};
246264
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+
247284static const struct attribute_group ddr_perf_events_attr_group = {
248285 .name = "events" ,
249286 .attrs = ddr_perf_events_attrs ,
287+ .is_visible = ddr_perf_events_attrs_is_visible ,
250288};
251289
252290PMU_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,
370408 }
371409}
372410
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 )
375413{
376414 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 };
377418
378419 pmcfg1 = readl_relaxed (pmu -> base + PMCFG1 );
379420
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 ];
394424
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 );
398428
399429 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 );
403433}
404434
405435static 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)
515545 ddr_perf_event_start (event , flags );
516546
517547 /* 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 );
519549
520550 return 0 ;
521551}
0 commit comments