Skip to content

Commit 27e4a65

Browse files
Xu Yangwilldeacon
authored andcommitted
perf: imx_perf: let the driver manage the counter usage rather the user
In current design, the user of perf app needs to input counter ID to count events. However, this is not user-friendly since the user needs to lookup the map table to find the counter. Instead of letting the user to input the counter, let this driver to manage the counters in this patch. This will be implemented by: 1. allocate counter 0 for cycle event. 2. find unused counter from 1-10 for reference events. 3. allocate specific counter for counter-specific events. In this patch, counter attr will be kept for back-compatible but all the value passed down by counter=<n> will be ignored. To mark counter-specific events, counter ID will be encoded into perf_pmu_events_attr.id. 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 4773dd1 commit 27e4a65

File tree

1 file changed

+100
-68
lines changed

1 file changed

+100
-68
lines changed

drivers/perf/fsl_imx9_ddr_perf.c

Lines changed: 100 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@
4141

4242
#define NUM_COUNTERS 11
4343
#define CYCLES_COUNTER 0
44+
#define CYCLES_EVENT_ID 0
4445

4546
#define CONFIG_EVENT_MASK GENMASK(7, 0)
46-
#define CONFIG_COUNTER_MASK GENMASK(15, 8)
47+
#define CONFIG_COUNTER_MASK GENMASK(23, 16)
4748

4849
#define to_ddr_pmu(p) container_of(p, struct ddr_pmu, pmu)
4950

@@ -130,6 +131,9 @@ static ssize_t ddr_pmu_event_show(struct device *dev,
130131
return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
131132
}
132133

134+
#define COUNTER_OFFSET_IN_EVENT 8
135+
#define ID(counter, id) ((counter << COUNTER_OFFSET_IN_EVENT) | id)
136+
133137
#define IMX9_DDR_PMU_EVENT_ATTR(_name, _id) \
134138
(&((struct perf_pmu_events_attr[]) { \
135139
{ .attr = __ATTR(_name, 0444, ddr_pmu_event_show, NULL),\
@@ -162,81 +166,81 @@ static struct attribute *ddr_perf_events_attrs[] = {
162166
IMX9_DDR_PMU_EVENT_ATTR(ddrc_pm_29, 63),
163167

164168
/* counter1 specific events */
165-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_0, 64),
166-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_1, 65),
167-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_2, 66),
168-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_3, 67),
169-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_4, 68),
170-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_5, 69),
171-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_6, 70),
172-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_7, 71),
169+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_0, ID(1, 64)),
170+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_1, ID(1, 65)),
171+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_2, ID(1, 66)),
172+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_3, ID(1, 67)),
173+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_4, ID(1, 68)),
174+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_5, ID(1, 69)),
175+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_6, ID(1, 70)),
176+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_riq_7, ID(1, 71)),
173177

174178
/* counter2 specific events */
175-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_0, 64),
176-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_1, 65),
177-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_2, 66),
178-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_3, 67),
179-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_4, 68),
180-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_5, 69),
181-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_6, 70),
182-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_7, 71),
183-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_empty, 72),
184-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_rd_trans_filt, 73),
179+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_0, ID(2, 64)),
180+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_1, ID(2, 65)),
181+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_2, ID(2, 66)),
182+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_3, ID(2, 67)),
183+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_4, ID(2, 68)),
184+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_5, ID(2, 69)),
185+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_6, ID(2, 70)),
186+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_7, ID(2, 71)),
187+
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)),
185189

186190
/* counter3 specific events */
187-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_0, 64),
188-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_1, 65),
189-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_2, 66),
190-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_3, 67),
191-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_4, 68),
192-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_5, 69),
193-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_6, 70),
194-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_7, 71),
195-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_full, 72),
196-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_wr_trans_filt, 73),
191+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_0, ID(3, 64)),
192+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_1, ID(3, 65)),
193+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_2, ID(3, 66)),
194+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_3, ID(3, 67)),
195+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_4, ID(3, 68)),
196+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_5, ID(3, 69)),
197+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_6, ID(3, 70)),
198+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_7, ID(3, 71)),
199+
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)),
197201

198202
/* counter4 specific events */
199-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_0, 64),
200-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_1, 65),
201-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_2, 66),
202-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_3, 67),
203-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_4, 68),
204-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_5, 69),
205-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_6, 70),
206-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_7, 71),
207-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_rdq2_rmw, 72),
208-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_rd_beat_filt, 73),
203+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_0, ID(4, 64)),
204+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_1, ID(4, 65)),
205+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_2, ID(4, 66)),
206+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_3, ID(4, 67)),
207+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_4, ID(4, 68)),
208+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_5, ID(4, 69)),
209+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_6, ID(4, 70)),
210+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_7, ID(4, 71)),
211+
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)),
209213

210214
/* counter5 specific events */
211-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_0, 64),
212-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_1, 65),
213-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_2, 66),
214-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_3, 67),
215-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_4, 68),
216-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_5, 69),
217-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_6, 70),
218-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_7, 71),
219-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_rdq1, 72),
215+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_0, ID(5, 64)),
216+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_1, ID(5, 65)),
217+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_2, ID(5, 66)),
218+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_3, ID(5, 67)),
219+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_4, ID(5, 68)),
220+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_5, ID(5, 69)),
221+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_6, ID(5, 70)),
222+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_7, ID(5, 71)),
223+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_rdq1, ID(5, 72)),
220224

221225
/* counter6 specific events */
222-
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_end_0, 64),
223-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_rdq2, 72),
226+
IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_end_0, ID(6, 64)),
227+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_rdq2, ID(6, 72)),
224228

225229
/* counter7 specific events */
226-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_1_2_full, 64),
227-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_wrq0, 65),
230+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_1_2_full, ID(7, 64)),
231+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_wrq0, ID(7, 65)),
228232

229233
/* counter8 specific events */
230-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_bias_switched, 64),
231-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_1_4_full, 65),
234+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_bias_switched, ID(8, 64)),
235+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_1_4_full, ID(8, 65)),
232236

233237
/* counter9 specific events */
234-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_wrq1, 65),
235-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_3_4_full, 66),
238+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_wrq1, ID(9, 65)),
239+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_3_4_full, ID(9, 66)),
236240

237241
/* counter10 specific events */
238-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_misc_mrk, 65),
239-
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_rdq0, 66),
242+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_misc_mrk, ID(10, 65)),
243+
IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_rdq0, ID(10, 66)),
240244
NULL,
241245
};
242246

@@ -245,7 +249,7 @@ static const struct attribute_group ddr_perf_events_attr_group = {
245249
.attrs = ddr_perf_events_attrs,
246250
};
247251

248-
PMU_FORMAT_ATTR(event, "config:0-7");
252+
PMU_FORMAT_ATTR(event, "config:0-7,16-23");
249253
PMU_FORMAT_ATTR(counter, "config:8-15");
250254
PMU_FORMAT_ATTR(axi_id, "config1:0-17");
251255
PMU_FORMAT_ATTR(axi_mask, "config2:0-17");
@@ -366,13 +370,10 @@ static void ddr_perf_counter_local_config(struct ddr_pmu *pmu, int config,
366370
}
367371
}
368372

369-
static void ddr_perf_monitor_config(struct ddr_pmu *pmu, int cfg, int cfg1, int cfg2)
373+
static void ddr_perf_monitor_config(struct ddr_pmu *pmu, int event,
374+
int counter, int axi_id, int axi_mask)
370375
{
371376
u32 pmcfg1, pmcfg2;
372-
int event, counter;
373-
374-
event = FIELD_GET(CONFIG_EVENT_MASK, cfg);
375-
counter = FIELD_GET(CONFIG_COUNTER_MASK, cfg);
376377

377378
pmcfg1 = readl_relaxed(pmu->base + PMCFG1);
378379

@@ -392,12 +393,12 @@ static void ddr_perf_monitor_config(struct ddr_pmu *pmu, int cfg, int cfg1, int
392393
pmcfg1 &= ~PMCFG1_RD_BT_FILT_EN;
393394

394395
pmcfg1 &= ~FIELD_PREP(PMCFG1_ID_MASK, 0x3FFFF);
395-
pmcfg1 |= FIELD_PREP(PMCFG1_ID_MASK, cfg2);
396+
pmcfg1 |= FIELD_PREP(PMCFG1_ID_MASK, axi_mask);
396397
writel(pmcfg1, pmu->base + PMCFG1);
397398

398399
pmcfg2 = readl_relaxed(pmu->base + PMCFG2);
399400
pmcfg2 &= ~FIELD_PREP(PMCFG2_ID, 0x3FFFF);
400-
pmcfg2 |= FIELD_PREP(PMCFG2_ID, cfg1);
401+
pmcfg2 |= FIELD_PREP(PMCFG2_ID, axi_id);
401402
writel(pmcfg2, pmu->base + PMCFG2);
402403
}
403404

@@ -465,17 +466,46 @@ static void ddr_perf_event_start(struct perf_event *event, int flags)
465466
hwc->state = 0;
466467
}
467468

469+
static int ddr_perf_alloc_counter(struct ddr_pmu *pmu, int event, int counter)
470+
{
471+
int i;
472+
473+
if (event == CYCLES_EVENT_ID) {
474+
// Cycles counter is dedicated for cycle event.
475+
if (pmu->events[CYCLES_COUNTER] == NULL)
476+
return CYCLES_COUNTER;
477+
} else if (counter != 0) {
478+
// Counter specific event use specific counter.
479+
if (pmu->events[counter] == NULL)
480+
return counter;
481+
} else {
482+
// Auto allocate counter for referene event.
483+
for (i = 1; i < NUM_COUNTERS; i++)
484+
if (pmu->events[i] == NULL)
485+
return i;
486+
}
487+
488+
return -ENOENT;
489+
}
490+
468491
static int ddr_perf_event_add(struct perf_event *event, int flags)
469492
{
470493
struct ddr_pmu *pmu = to_ddr_pmu(event->pmu);
471494
struct hw_perf_event *hwc = &event->hw;
472495
int cfg = event->attr.config;
473496
int cfg1 = event->attr.config1;
474497
int cfg2 = event->attr.config2;
475-
int counter;
498+
int event_id, counter;
476499

500+
event_id = FIELD_GET(CONFIG_EVENT_MASK, cfg);
477501
counter = FIELD_GET(CONFIG_COUNTER_MASK, cfg);
478502

503+
counter = ddr_perf_alloc_counter(pmu, event_id, counter);
504+
if (counter < 0) {
505+
dev_dbg(pmu->dev, "There are not enough counters\n");
506+
return -EOPNOTSUPP;
507+
}
508+
479509
pmu->events[counter] = event;
480510
pmu->active_events++;
481511
hwc->idx = counter;
@@ -485,7 +515,7 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
485515
ddr_perf_event_start(event, flags);
486516

487517
/* read trans, write trans, read beat */
488-
ddr_perf_monitor_config(pmu, cfg, cfg1, cfg2);
518+
ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
489519

490520
return 0;
491521
}
@@ -506,9 +536,11 @@ static void ddr_perf_event_del(struct perf_event *event, int flags)
506536
{
507537
struct ddr_pmu *pmu = to_ddr_pmu(event->pmu);
508538
struct hw_perf_event *hwc = &event->hw;
539+
int counter = hwc->idx;
509540

510541
ddr_perf_event_stop(event, PERF_EF_UPDATE);
511542

543+
pmu->events[counter] = NULL;
512544
pmu->active_events--;
513545
hwc->idx = -1;
514546
}

0 commit comments

Comments
 (0)