aboutsummaryrefslogtreecommitdiff
path: root/arch/metag/kernel/perf/perf_event.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/metag/kernel/perf/perf_event.h')
-rw-r--r--arch/metag/kernel/perf/perf_event.h106
1 files changed, 106 insertions, 0 deletions
diff --git a/arch/metag/kernel/perf/perf_event.h b/arch/metag/kernel/perf/perf_event.h
new file mode 100644
index 00000000000..fd10a1345b6
--- /dev/null
+++ b/arch/metag/kernel/perf/perf_event.h
@@ -0,0 +1,106 @@
+/*
+ * Meta performance counter support.
+ * Copyright (C) 2012 Imagination Technologies Ltd
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef METAG_PERF_EVENT_H_
+#define METAG_PERF_EVENT_H_
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/perf_event.h>
+
+/* For performance counter definitions */
+#include <asm/metag_mem.h>
+
+/*
+ * The Meta core has two performance counters, with 24-bit resolution. Newer
+ * cores generate an overflow interrupt on transition from 0xffffff to 0.
+ *
+ * Each counter consists of the counter id, hardware thread id, and the count
+ * itself; each counter can be assigned to multiple hardware threads at any
+ * one time, with the returned count being an aggregate of events. A small
+ * number of events are thread global, i.e. they count the aggregate of all
+ * threads' events, regardless of the thread selected.
+ *
+ * Newer cores can store an arbitrary 24-bit number in the counter, whereas
+ * older cores will clear the counter bits on write.
+ *
+ * We also have a pseudo-counter in the form of the thread active cycles
+ * counter (which, incidentally, is also bound to
+ */
+
+#define MAX_HWEVENTS 3
+#define MAX_PERIOD ((1UL << 24) - 1)
+#define METAG_INST_COUNTER (MAX_HWEVENTS - 1)
+
+/**
+ * struct cpu_hw_events - a processor core's performance events
+ * @events: an array of perf_events active for a given index.
+ * @used_mask: a bitmap of in-use counters.
+ * @pmu_lock: a perf counter lock
+ *
+ * This is a per-cpu/core structure that maintains a record of its
+ * performance counters' state.
+ */
+struct cpu_hw_events {
+ struct perf_event *events[MAX_HWEVENTS];
+ unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+ raw_spinlock_t pmu_lock;
+};
+
+/**
+ * struct metag_pmu - the Meta PMU structure
+ * @pmu: core pmu structure
+ * @name: pmu name
+ * @version: core version
+ * @handle_irq: overflow interrupt handler
+ * @enable: enable a counter
+ * @disable: disable a counter
+ * @read: read the value of a counter
+ * @write: write a value to a counter
+ * @event_map: kernel event to counter event id map
+ * @cache_events: kernel cache counter to core cache counter map
+ * @max_period: maximum value of the counter before overflow
+ * @max_events: maximum number of counters available at any one time
+ * @active_events: number of active counters
+ * @reserve_mutex: counter reservation mutex
+ *
+ * This describes the main functionality and data used by the performance
+ * event core.
+ */
+struct metag_pmu {
+ struct pmu pmu;
+ const char *name;
+ u32 version;
+ irqreturn_t (*handle_irq)(int irq_num, void *dev);
+ void (*enable)(struct hw_perf_event *evt, int idx);
+ void (*disable)(struct hw_perf_event *evt, int idx);
+ u64 (*read)(int idx);
+ void (*write)(int idx, u32 val);
+ int (*event_map)(int idx);
+ const int (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+ u32 max_period;
+ int max_events;
+ atomic_t active_events;
+ struct mutex reserve_mutex;
+};
+
+/* Convenience macros for accessing the perf counters */
+/* Define some convenience accessors */
+#define PERF_COUNT(x) (PERF_COUNT0 + (sizeof(u64) * (x)))
+#define PERF_ICORE(x) (PERF_ICORE0 + (sizeof(u64) * (x)))
+#define PERF_CHAN(x) (PERF_CHAN0 + (sizeof(u64) * (x)))
+
+/* Cache index macros */
+#define C(x) PERF_COUNT_HW_CACHE_##x
+#define CACHE_OP_UNSUPPORTED 0xfffe
+#define CACHE_OP_NONSENSE 0xffff
+
+#endif