diff options
author | Tiberiu Breana <andrei-tiberiu.breana@nxp.com> | 2017-06-14 17:45:47 +0300 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:27:07 +0800 |
commit | 5cf5b4a912ad0804c1d73f58900e1fcd1c38f0e9 (patch) | |
tree | b1c3b2810c0cc51b58a03b804606f25e6b6f9903 /drivers/perf | |
parent | a4fb469392f43d61354fe504eaf238decd2d788f (diff) |
MLK-13855-1: perf: ddr-perf: Clean up driver
- repurpose e2c_map array to a perf_event* array
- add ddr_perf_event_enable function
- tidy up indenting
Signed-off-by: Tiberiu Breana <andrei-tiberiu.breana@nxp.com>
Diffstat (limited to 'drivers/perf')
-rw-r--r-- | drivers/perf/ddr-perf.c | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/drivers/perf/ddr-perf.c b/drivers/perf/ddr-perf.c index 958645cdfd8b..ead9d97d5d00 100644 --- a/drivers/perf/ddr-perf.c +++ b/drivers/perf/ddr-perf.c @@ -17,23 +17,25 @@ #include <linux/slab.h> -#define COUNTER_CNTL 0x0 -#define COUNTER_READ 0x20 +#define COUNTER_CNTL 0x0 +#define COUNTER_READ 0x20 -#define CNTL_OVER 0x1 -#define CNTL_CLEAR 0x2 -#define CNTL_EN 0x4 +#define CNTL_OVER 0x1 +#define CNTL_CLEAR 0x2 +#define CNTL_EN 0x4 +#define CNTL_EN_MASK 0xFFFFFFFB +#define CNTL_CLEAR_MASK 0xFFFFFFFD -#define CNTL_CP_SHIFT 16 -#define CNTL_CP_MASK (0xFF << CNTL_CP_SHIFT) +#define CNTL_CSV_SHIFT 24 +#define CNTL_CSV_MASK (0xFF << CNTL_CSV_SHIFT) -#define CNTL_CSV_SHIFT 24 -#define CNTL_CSV_MASK (0xFF << CNTL_CSV_SHIFT) +#define EVENT_CYCLES_ID 0 +#define NUM_COUNTER 4 +#define MAX_EVENT 3 -#define NUM_COUNTER 4 -#define MAX_EVENT 3 +#define to_ddr_pmu(p) container_of(p, struct ddr_pmu, pmu) -#define to_ddr_pmu(p) container_of(p, struct ddr_pmu, pmu) +#define DDR_PERF_DEV_NAME "ddr_perf" static DEFINE_IDA(ddr_ida); @@ -81,7 +83,8 @@ struct ddr_pmu { cpumask_t cpu; struct hlist_node node; struct device *dev; - int e2c_map[NUM_COUNTER]; + struct perf_event *active_events[NUM_COUNTER]; + int total_events; }; static ssize_t ddr_perf_cpumask_show(struct device *dev, @@ -165,15 +168,13 @@ static u32 ddr_perf_alloc_counter(struct ddr_pmu *pmu, int event) { int i; - if (event == 0) - return 0; /* always map cycle event to counter 0 */ + /* Always map cycle event to counter 0 */ + if (event == EVENT_CYCLES_ID) + return 0; - for (i = 1; i < NUM_COUNTER; i++) { - if (pmu->e2c_map[i] == 0) { - pmu->e2c_map[i] = event; + for (i = 1; i < NUM_COUNTER; i++) + if (pmu->active_events[i] == NULL) return i; - } - } return -ENOENT; } @@ -183,7 +184,7 @@ static u32 ddr_perf_free_counter(struct ddr_pmu *pmu, int counter) if (counter < 0 || counter >= NUM_COUNTER) return -ENOENT; - pmu->e2c_map[counter] = 0; + pmu->active_events[counter] = NULL; return 0; } @@ -243,19 +244,34 @@ static void ddr_perf_event_update(struct perf_event *event) local64_add(delta, &event->count); } +static void ddr_perf_event_enable(struct ddr_pmu *pmu, int config, + int counter, bool enable) +{ + u8 reg = counter * 4 + COUNTER_CNTL; + int val; + + if (enable) { + /* Clear counter, then enable it. */ + writel(0, pmu->base + reg); + val = CNTL_EN | CNTL_CLEAR; + val |= (config << CNTL_CSV_SHIFT) & CNTL_CSV_MASK; + } else { + /* Disable counter */ + val = readl(pmu->base + reg) & CNTL_EN_MASK; + } + + writel(val, pmu->base + reg); +} + static void ddr_perf_event_start(struct perf_event *event, int flags) { struct ddr_pmu *pmu = to_ddr_pmu(event->pmu); struct hw_perf_event *hwc = &event->hw; - int reg; int counter = hwc->idx; local64_set(&hwc->prev_count, 0); - writel(0, pmu->base + counter * 4 + COUNTER_CNTL); - reg = CNTL_EN | CNTL_CLEAR; - reg |= (event->attr.config << CNTL_CSV_SHIFT) & CNTL_CSV_MASK; - writel(reg, pmu->base + counter * 4 + COUNTER_CNTL); + ddr_perf_event_enable(pmu, event->attr.config, counter, true); } static int ddr_perf_event_add(struct perf_event *event, int flags) @@ -271,6 +287,8 @@ static int ddr_perf_event_add(struct perf_event *event, int flags) return -EOPNOTSUPP; } + pmu->active_events[counter] = event; + pmu->total_events++; hwc->idx = counter; if (flags & PERF_EF_START) @@ -287,7 +305,8 @@ static void ddr_perf_event_stop(struct perf_event *event, int flags) struct hw_perf_event *hwc = &event->hw; int counter = hwc->idx; - writel(0, pmu->base + counter * 4 + COUNTER_CNTL); + ddr_perf_event_enable(pmu, event->attr.config, counter, false); + ddr_perf_event_update(event); } static void ddr_perf_event_del(struct perf_event *event, int flags) @@ -299,6 +318,7 @@ static void ddr_perf_event_del(struct perf_event *event, int flags) ddr_perf_event_stop(event, PERF_EF_UPDATE); ddr_perf_free_counter(pmu, counter); + pmu->total_events--; hwc->idx = -1; } |