diff options
Diffstat (limited to 'drivers/perf/fsl_imx8_ddr_perf.c')
-rw-r--r-- | drivers/perf/fsl_imx8_ddr_perf.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c index d9864d235e76..7db3a2df80db 100644 --- a/drivers/perf/fsl_imx8_ddr_perf.c +++ b/drivers/perf/fsl_imx8_ddr_perf.c @@ -47,6 +47,8 @@ #define EVENT_CYCLES_COUNTER 0 #define NUM_COUNTERS 4 +/* For removing bias if cycle counter CNTL.CP is set to 0xf0 */ +#define CYCLES_COUNTER_MASK 0x0FFFFFFF #define AXI_MASKING_REVERT 0xffff0000 /* AXI_MASKING(MSB 16bits) + AXI_ID(LSB 16bits) */ #define to_ddr_pmu(p) container_of(p, struct ddr_pmu, pmu) @@ -535,16 +537,13 @@ static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config, val |= FIELD_PREP(CNTL_CSV_MASK, config); /* - * Workaround for i.MX8MP: - * Common counters and byte counters share the same COUNTER_CNTL, - * and byte counters could overflow before cycle counter. Need set - * counter parameter(CP) of cycle counter to give it initial value - * which can speed up cycle counter overflow frequency. + * On i.MX8MP we need to bias the cycle counter to overflow more often. + * We do this by initializing bits [23:16] of the counter value via the + * COUNTER_CTRL Counter Parameter (CP) field. */ - if ((pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED) == - DDR_CAP_AXI_ID_FILTER_ENHANCED) { + if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED) { if (counter == EVENT_CYCLES_COUNTER) - val |= FIELD_PREP(CNTL_CP_MASK, 0xe8); + val |= FIELD_PREP(CNTL_CP_MASK, 0xf0); } writel(val, pmu->base + reg); @@ -586,6 +585,12 @@ static void ddr_perf_event_update(struct perf_event *event) int ret; new_raw_count = ddr_perf_read_counter(pmu, counter); + /* Remove the bias applied in ddr_perf_counter_enable(). */ + if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED) { + if (counter == EVENT_CYCLES_COUNTER) + new_raw_count &= CYCLES_COUNTER_MASK; + } + local64_add(new_raw_count, &event->count); /* |