Skip to content

Commit fab5e5a

Browse files
Xu Yangwilldeacon
authored andcommitted
perf: imx_perf: refactor driver for imx93
This driver is initinally used to support imx93 Soc and now it's time to add support for imx95 Soc. However, some macro definitions and events are different on these two Socs. For preparing imx95 supports, this will refactor driver for imx93. Reviewed-by: Frank Li <[email protected]> Signed-off-by: Xu Yang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 27e4a65 commit fab5e5a

File tree

1 file changed

+68
-38
lines changed

1 file changed

+68
-38
lines changed

drivers/perf/fsl_imx9_ddr_perf.c

Lines changed: 68 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
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+
7883
static 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+
125136
static 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+
143161
static 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+
247284
static 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

252290
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,
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

405435
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)
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

Comments
 (0)