summaryrefslogtreecommitdiff
path: root/drivers/perf
diff options
context:
space:
mode:
authorTiberiu Breana <andrei-tiberiu.breana@nxp.com>2017-06-14 17:45:47 +0300
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:27:07 +0800
commit5cf5b4a912ad0804c1d73f58900e1fcd1c38f0e9 (patch)
treeb1c3b2810c0cc51b58a03b804606f25e6b6f9903 /drivers/perf
parenta4fb469392f43d61354fe504eaf238decd2d788f (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.c74
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;
}