summaryrefslogtreecommitdiff
path: root/drivers/perf
diff options
context:
space:
mode:
authorTiberiu Breana <andrei-tiberiu.breana@nxp.com>2017-06-19 11:21:52 +0300
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:27:07 +0800
commitec5ce5e04022a27923e00457d4ca93b08c5499b3 (patch)
tree63682b3d7fc7cecf8999ef68e8ccc714b436cb67 /drivers/perf
parent5cf5b4a912ad0804c1d73f58900e1fcd1c38f0e9 (diff)
MLK-13855-2: perf: ddr-perf: Always enable the cycles counter
Always enable cycles counter 0, regardless if it is explicitly selected by the user or not. The cycles counter generates overflow interrupts that will be used to update other counters. Signed-off-by: Tiberiu Breana <andrei-tiberiu.breana@nxp.com>
Diffstat (limited to 'drivers/perf')
-rw-r--r--drivers/perf/ddr-perf.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/perf/ddr-perf.c b/drivers/perf/ddr-perf.c
index ead9d97d5d00..7bc05859d4bb 100644
--- a/drivers/perf/ddr-perf.c
+++ b/drivers/perf/ddr-perf.c
@@ -30,6 +30,7 @@
#define CNTL_CSV_MASK (0xFF << CNTL_CSV_SHIFT)
#define EVENT_CYCLES_ID 0
+#define EVENT_CYCLES_COUNTER 0
#define NUM_COUNTER 4
#define MAX_EVENT 3
@@ -85,6 +86,7 @@ struct ddr_pmu {
struct device *dev;
struct perf_event *active_events[NUM_COUNTER];
int total_events;
+ bool cycles_active;
};
static ssize_t ddr_perf_cpumask_show(struct device *dev,
@@ -170,7 +172,7 @@ static u32 ddr_perf_alloc_counter(struct ddr_pmu *pmu, int event)
/* Always map cycle event to counter 0 */
if (event == EVENT_CYCLES_ID)
- return 0;
+ return EVENT_CYCLES_COUNTER;
for (i = 1; i < NUM_COUNTER; i++)
if (pmu->active_events[i] == NULL)
@@ -261,6 +263,9 @@ static void ddr_perf_event_enable(struct ddr_pmu *pmu, int config,
}
writel(val, pmu->base + reg);
+
+ if (config == EVENT_CYCLES_ID)
+ pmu->cycles_active = enable;
}
static void ddr_perf_event_start(struct perf_event *event, int flags)
@@ -272,6 +277,13 @@ static void ddr_perf_event_start(struct perf_event *event, int flags)
local64_set(&hwc->prev_count, 0);
ddr_perf_event_enable(pmu, event->attr.config, counter, true);
+ /*
+ * If the cycles counter wasn't explicitly selected,
+ * we will enable it now.
+ */
+ if (counter > 0 && !pmu->cycles_active)
+ ddr_perf_event_enable(pmu, EVENT_CYCLES_ID,
+ EVENT_CYCLES_COUNTER, true);
}
static int ddr_perf_event_add(struct perf_event *event, int flags)
@@ -320,6 +332,11 @@ static void ddr_perf_event_del(struct perf_event *event, int flags)
ddr_perf_free_counter(pmu, counter);
pmu->total_events--;
hwc->idx = -1;
+
+ /* If all events have stopped, stop the cycles counter as well */
+ if ((pmu->total_events == 0) && pmu->cycles_active)
+ ddr_perf_event_enable(pmu, EVENT_CYCLES_ID,
+ EVENT_CYCLES_COUNTER, false);
}
static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,