xref: /openbmc/linux/arch/arm/mm/cache-l2x0-pmu.c (revision 45051539)
145051539SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2b828f960SMark Rutland /*
3b828f960SMark Rutland  * L220/L310 cache controller support
4b828f960SMark Rutland  *
5b828f960SMark Rutland  * Copyright (C) 2016 ARM Limited
6b828f960SMark Rutland  */
7b828f960SMark Rutland #include <linux/errno.h>
8b828f960SMark Rutland #include <linux/hrtimer.h>
9b828f960SMark Rutland #include <linux/io.h>
10b828f960SMark Rutland #include <linux/list.h>
11b828f960SMark Rutland #include <linux/perf_event.h>
12b828f960SMark Rutland #include <linux/printk.h>
13b828f960SMark Rutland #include <linux/slab.h>
14b828f960SMark Rutland #include <linux/types.h>
15b828f960SMark Rutland 
16b828f960SMark Rutland #include <asm/hardware/cache-l2x0.h>
17b828f960SMark Rutland 
18b828f960SMark Rutland #define PMU_NR_COUNTERS 2
19b828f960SMark Rutland 
20b828f960SMark Rutland static void __iomem *l2x0_base;
21b828f960SMark Rutland static struct pmu *l2x0_pmu;
22b828f960SMark Rutland static cpumask_t pmu_cpu;
23b828f960SMark Rutland 
24b828f960SMark Rutland static const char *l2x0_name;
25b828f960SMark Rutland 
26b828f960SMark Rutland static ktime_t l2x0_pmu_poll_period;
27b828f960SMark Rutland static struct hrtimer l2x0_pmu_hrtimer;
28b828f960SMark Rutland 
29b828f960SMark Rutland /*
30b828f960SMark Rutland  * The L220/PL310 PMU has two equivalent counters, Counter1 and Counter0.
31b828f960SMark Rutland  * Registers controlling these are laid out in pairs, in descending order, i.e.
32b828f960SMark Rutland  * the register for Counter1 comes first, followed by the register for
33b828f960SMark Rutland  * Counter0.
34b828f960SMark Rutland  * We ensure that idx 0 -> Counter0, and idx1 -> Counter1.
35b828f960SMark Rutland  */
36b828f960SMark Rutland static struct perf_event *events[PMU_NR_COUNTERS];
37b828f960SMark Rutland 
38b828f960SMark Rutland /* Find an unused counter */
l2x0_pmu_find_idx(void)39b828f960SMark Rutland static int l2x0_pmu_find_idx(void)
40b828f960SMark Rutland {
41b828f960SMark Rutland 	int i;
42b828f960SMark Rutland 
43b828f960SMark Rutland 	for (i = 0; i < PMU_NR_COUNTERS; i++) {
44b828f960SMark Rutland 		if (!events[i])
45b828f960SMark Rutland 			return i;
46b828f960SMark Rutland 	}
47b828f960SMark Rutland 
48b828f960SMark Rutland 	return -1;
49b828f960SMark Rutland }
50b828f960SMark Rutland 
51b828f960SMark Rutland /* How many counters are allocated? */
l2x0_pmu_num_active_counters(void)52b828f960SMark Rutland static int l2x0_pmu_num_active_counters(void)
53b828f960SMark Rutland {
54b828f960SMark Rutland 	int i, cnt = 0;
55b828f960SMark Rutland 
56b828f960SMark Rutland 	for (i = 0; i < PMU_NR_COUNTERS; i++) {
57b828f960SMark Rutland 		if (events[i])
58b828f960SMark Rutland 			cnt++;
59b828f960SMark Rutland 	}
60b828f960SMark Rutland 
61b828f960SMark Rutland 	return cnt;
62b828f960SMark Rutland }
63b828f960SMark Rutland 
l2x0_pmu_counter_config_write(int idx,u32 val)64b828f960SMark Rutland static void l2x0_pmu_counter_config_write(int idx, u32 val)
65b828f960SMark Rutland {
66b828f960SMark Rutland 	writel_relaxed(val, l2x0_base + L2X0_EVENT_CNT0_CFG - 4 * idx);
67b828f960SMark Rutland }
68b828f960SMark Rutland 
l2x0_pmu_counter_read(int idx)69b828f960SMark Rutland static u32 l2x0_pmu_counter_read(int idx)
70b828f960SMark Rutland {
71b828f960SMark Rutland 	return readl_relaxed(l2x0_base + L2X0_EVENT_CNT0_VAL - 4 * idx);
72b828f960SMark Rutland }
73b828f960SMark Rutland 
l2x0_pmu_counter_write(int idx,u32 val)74b828f960SMark Rutland static void l2x0_pmu_counter_write(int idx, u32 val)
75b828f960SMark Rutland {
76b828f960SMark Rutland 	writel_relaxed(val, l2x0_base + L2X0_EVENT_CNT0_VAL - 4 * idx);
77b828f960SMark Rutland }
78b828f960SMark Rutland 
__l2x0_pmu_enable(void)79b828f960SMark Rutland static void __l2x0_pmu_enable(void)
80b828f960SMark Rutland {
81b828f960SMark Rutland 	u32 val = readl_relaxed(l2x0_base + L2X0_EVENT_CNT_CTRL);
82b828f960SMark Rutland 	val |= L2X0_EVENT_CNT_CTRL_ENABLE;
83b828f960SMark Rutland 	writel_relaxed(val, l2x0_base + L2X0_EVENT_CNT_CTRL);
84b828f960SMark Rutland }
85b828f960SMark Rutland 
__l2x0_pmu_disable(void)86b828f960SMark Rutland static void __l2x0_pmu_disable(void)
87b828f960SMark Rutland {
88b828f960SMark Rutland 	u32 val = readl_relaxed(l2x0_base + L2X0_EVENT_CNT_CTRL);
89b828f960SMark Rutland 	val &= ~L2X0_EVENT_CNT_CTRL_ENABLE;
90b828f960SMark Rutland 	writel_relaxed(val, l2x0_base + L2X0_EVENT_CNT_CTRL);
91b828f960SMark Rutland }
92b828f960SMark Rutland 
l2x0_pmu_enable(struct pmu * pmu)93b828f960SMark Rutland static void l2x0_pmu_enable(struct pmu *pmu)
94b828f960SMark Rutland {
95b828f960SMark Rutland 	if (l2x0_pmu_num_active_counters() == 0)
96b828f960SMark Rutland 		return;
97b828f960SMark Rutland 
98b828f960SMark Rutland 	__l2x0_pmu_enable();
99b828f960SMark Rutland }
100b828f960SMark Rutland 
l2x0_pmu_disable(struct pmu * pmu)101b828f960SMark Rutland static void l2x0_pmu_disable(struct pmu *pmu)
102b828f960SMark Rutland {
103b828f960SMark Rutland 	if (l2x0_pmu_num_active_counters() == 0)
104b828f960SMark Rutland 		return;
105b828f960SMark Rutland 
106b828f960SMark Rutland 	__l2x0_pmu_disable();
107b828f960SMark Rutland }
108b828f960SMark Rutland 
warn_if_saturated(u32 count)109b828f960SMark Rutland static void warn_if_saturated(u32 count)
110b828f960SMark Rutland {
111b828f960SMark Rutland 	if (count != 0xffffffff)
112b828f960SMark Rutland 		return;
113b828f960SMark Rutland 
114b828f960SMark Rutland 	pr_warn_ratelimited("L2X0 counter saturated. Poll period too long\n");
115b828f960SMark Rutland }
116b828f960SMark Rutland 
l2x0_pmu_event_read(struct perf_event * event)117b828f960SMark Rutland static void l2x0_pmu_event_read(struct perf_event *event)
118b828f960SMark Rutland {
119b828f960SMark Rutland 	struct hw_perf_event *hw = &event->hw;
120b828f960SMark Rutland 	u64 prev_count, new_count, mask;
121b828f960SMark Rutland 
122b828f960SMark Rutland 	do {
123b828f960SMark Rutland 		 prev_count = local64_read(&hw->prev_count);
124b828f960SMark Rutland 		 new_count = l2x0_pmu_counter_read(hw->idx);
125b828f960SMark Rutland 	} while (local64_xchg(&hw->prev_count, new_count) != prev_count);
126b828f960SMark Rutland 
127b828f960SMark Rutland 	mask = GENMASK_ULL(31, 0);
128b828f960SMark Rutland 	local64_add((new_count - prev_count) & mask, &event->count);
129b828f960SMark Rutland 
130b828f960SMark Rutland 	warn_if_saturated(new_count);
131b828f960SMark Rutland }
132b828f960SMark Rutland 
l2x0_pmu_event_configure(struct perf_event * event)133b828f960SMark Rutland static void l2x0_pmu_event_configure(struct perf_event *event)
134b828f960SMark Rutland {
135b828f960SMark Rutland 	struct hw_perf_event *hw = &event->hw;
136b828f960SMark Rutland 
137b828f960SMark Rutland 	/*
138b828f960SMark Rutland 	 * The L2X0 counters saturate at 0xffffffff rather than wrapping, so we
139b828f960SMark Rutland 	 * will *always* lose some number of events when a counter saturates,
140b828f960SMark Rutland 	 * and have no way of detecting how many were lost.
141b828f960SMark Rutland 	 *
142b828f960SMark Rutland 	 * To minimize the impact of this, we try to maximize the period by
143b828f960SMark Rutland 	 * always starting counters at zero. To ensure that group ratios are
144b828f960SMark Rutland 	 * representative, we poll periodically to avoid counters saturating.
145b828f960SMark Rutland 	 * See l2x0_pmu_poll().
146b828f960SMark Rutland 	 */
147b828f960SMark Rutland 	local64_set(&hw->prev_count, 0);
148b828f960SMark Rutland 	l2x0_pmu_counter_write(hw->idx, 0);
149b828f960SMark Rutland }
150b828f960SMark Rutland 
l2x0_pmu_poll(struct hrtimer * hrtimer)151b828f960SMark Rutland static enum hrtimer_restart l2x0_pmu_poll(struct hrtimer *hrtimer)
152b828f960SMark Rutland {
153b828f960SMark Rutland 	unsigned long flags;
154b828f960SMark Rutland 	int i;
155b828f960SMark Rutland 
156b828f960SMark Rutland 	local_irq_save(flags);
157b828f960SMark Rutland 	__l2x0_pmu_disable();
158b828f960SMark Rutland 
159b828f960SMark Rutland 	for (i = 0; i < PMU_NR_COUNTERS; i++) {
160b828f960SMark Rutland 		struct perf_event *event = events[i];
161b828f960SMark Rutland 
162b828f960SMark Rutland 		if (!event)
163b828f960SMark Rutland 			continue;
164b828f960SMark Rutland 
165b828f960SMark Rutland 		l2x0_pmu_event_read(event);
166b828f960SMark Rutland 		l2x0_pmu_event_configure(event);
167b828f960SMark Rutland 	}
168b828f960SMark Rutland 
169b828f960SMark Rutland 	__l2x0_pmu_enable();
170b828f960SMark Rutland 	local_irq_restore(flags);
171b828f960SMark Rutland 
172b828f960SMark Rutland 	hrtimer_forward_now(hrtimer, l2x0_pmu_poll_period);
173b828f960SMark Rutland 	return HRTIMER_RESTART;
174b828f960SMark Rutland }
175b828f960SMark Rutland 
176b828f960SMark Rutland 
__l2x0_pmu_event_enable(int idx,u32 event)177b828f960SMark Rutland static void __l2x0_pmu_event_enable(int idx, u32 event)
178b828f960SMark Rutland {
179b828f960SMark Rutland 	u32 val;
180b828f960SMark Rutland 
181b828f960SMark Rutland 	val = event << L2X0_EVENT_CNT_CFG_SRC_SHIFT;
182b828f960SMark Rutland 	val |= L2X0_EVENT_CNT_CFG_INT_DISABLED;
183b828f960SMark Rutland 	l2x0_pmu_counter_config_write(idx, val);
184b828f960SMark Rutland }
185b828f960SMark Rutland 
l2x0_pmu_event_start(struct perf_event * event,int flags)186b828f960SMark Rutland static void l2x0_pmu_event_start(struct perf_event *event, int flags)
187b828f960SMark Rutland {
188b828f960SMark Rutland 	struct hw_perf_event *hw = &event->hw;
189b828f960SMark Rutland 
190b828f960SMark Rutland 	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
191b828f960SMark Rutland 		return;
192b828f960SMark Rutland 
193b828f960SMark Rutland 	if (flags & PERF_EF_RELOAD) {
194b828f960SMark Rutland 		WARN_ON_ONCE(!(hw->state & PERF_HES_UPTODATE));
195b828f960SMark Rutland 		l2x0_pmu_event_configure(event);
196b828f960SMark Rutland 	}
197b828f960SMark Rutland 
198b828f960SMark Rutland 	hw->state = 0;
199b828f960SMark Rutland 
200b828f960SMark Rutland 	__l2x0_pmu_event_enable(hw->idx, hw->config_base);
201b828f960SMark Rutland }
202b828f960SMark Rutland 
__l2x0_pmu_event_disable(int idx)203b828f960SMark Rutland static void __l2x0_pmu_event_disable(int idx)
204b828f960SMark Rutland {
205b828f960SMark Rutland 	u32 val;
206b828f960SMark Rutland 
207b828f960SMark Rutland 	val = L2X0_EVENT_CNT_CFG_SRC_DISABLED << L2X0_EVENT_CNT_CFG_SRC_SHIFT;
208b828f960SMark Rutland 	val |= L2X0_EVENT_CNT_CFG_INT_DISABLED;
209b828f960SMark Rutland 	l2x0_pmu_counter_config_write(idx, val);
210b828f960SMark Rutland }
211b828f960SMark Rutland 
l2x0_pmu_event_stop(struct perf_event * event,int flags)212b828f960SMark Rutland static void l2x0_pmu_event_stop(struct perf_event *event, int flags)
213b828f960SMark Rutland {
214b828f960SMark Rutland 	struct hw_perf_event *hw = &event->hw;
215b828f960SMark Rutland 
216b828f960SMark Rutland 	if (WARN_ON_ONCE(event->hw.state & PERF_HES_STOPPED))
217b828f960SMark Rutland 		return;
218b828f960SMark Rutland 
219b828f960SMark Rutland 	__l2x0_pmu_event_disable(hw->idx);
220b828f960SMark Rutland 
221b828f960SMark Rutland 	hw->state |= PERF_HES_STOPPED;
222b828f960SMark Rutland 
223b828f960SMark Rutland 	if (flags & PERF_EF_UPDATE) {
224b828f960SMark Rutland 		l2x0_pmu_event_read(event);
225b828f960SMark Rutland 		hw->state |= PERF_HES_UPTODATE;
226b828f960SMark Rutland 	}
227b828f960SMark Rutland }
228b828f960SMark Rutland 
l2x0_pmu_event_add(struct perf_event * event,int flags)229b828f960SMark Rutland static int l2x0_pmu_event_add(struct perf_event *event, int flags)
230b828f960SMark Rutland {
231b828f960SMark Rutland 	struct hw_perf_event *hw = &event->hw;
232b828f960SMark Rutland 	int idx = l2x0_pmu_find_idx();
233b828f960SMark Rutland 
234b828f960SMark Rutland 	if (idx == -1)
235b828f960SMark Rutland 		return -EAGAIN;
236b828f960SMark Rutland 
237b828f960SMark Rutland 	/*
238b828f960SMark Rutland 	 * Pin the timer, so that the overflows are handled by the chosen
239b828f960SMark Rutland 	 * event->cpu (this is the same one as presented in "cpumask"
240b828f960SMark Rutland 	 * attribute).
241b828f960SMark Rutland 	 */
242b828f960SMark Rutland 	if (l2x0_pmu_num_active_counters() == 0)
243b828f960SMark Rutland 		hrtimer_start(&l2x0_pmu_hrtimer, l2x0_pmu_poll_period,
244b828f960SMark Rutland 			      HRTIMER_MODE_REL_PINNED);
245b828f960SMark Rutland 
246b828f960SMark Rutland 	events[idx] = event;
247b828f960SMark Rutland 	hw->idx = idx;
248b828f960SMark Rutland 
249b828f960SMark Rutland 	l2x0_pmu_event_configure(event);
250b828f960SMark Rutland 
251b828f960SMark Rutland 	hw->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
252b828f960SMark Rutland 
253b828f960SMark Rutland 	if (flags & PERF_EF_START)
254b828f960SMark Rutland 		l2x0_pmu_event_start(event, 0);
255b828f960SMark Rutland 
256b828f960SMark Rutland 	return 0;
257b828f960SMark Rutland }
258b828f960SMark Rutland 
l2x0_pmu_event_del(struct perf_event * event,int flags)259b828f960SMark Rutland static void l2x0_pmu_event_del(struct perf_event *event, int flags)
260b828f960SMark Rutland {
261b828f960SMark Rutland 	struct hw_perf_event *hw = &event->hw;
262b828f960SMark Rutland 
263b828f960SMark Rutland 	l2x0_pmu_event_stop(event, PERF_EF_UPDATE);
264b828f960SMark Rutland 
265b828f960SMark Rutland 	events[hw->idx] = NULL;
266b828f960SMark Rutland 	hw->idx = -1;
267b828f960SMark Rutland 
268b828f960SMark Rutland 	if (l2x0_pmu_num_active_counters() == 0)
269b828f960SMark Rutland 		hrtimer_cancel(&l2x0_pmu_hrtimer);
270b828f960SMark Rutland }
271b828f960SMark Rutland 
l2x0_pmu_group_is_valid(struct perf_event * event)272b828f960SMark Rutland static bool l2x0_pmu_group_is_valid(struct perf_event *event)
273b828f960SMark Rutland {
274b828f960SMark Rutland 	struct pmu *pmu = event->pmu;
275b828f960SMark Rutland 	struct perf_event *leader = event->group_leader;
276b828f960SMark Rutland 	struct perf_event *sibling;
277b828f960SMark Rutland 	int num_hw = 0;
278b828f960SMark Rutland 
279b828f960SMark Rutland 	if (leader->pmu == pmu)
280b828f960SMark Rutland 		num_hw++;
281b828f960SMark Rutland 	else if (!is_software_event(leader))
282b828f960SMark Rutland 		return false;
283b828f960SMark Rutland 
284edb39592SPeter Zijlstra 	for_each_sibling_event(sibling, leader) {
285b828f960SMark Rutland 		if (sibling->pmu == pmu)
286b828f960SMark Rutland 			num_hw++;
287b828f960SMark Rutland 		else if (!is_software_event(sibling))
288b828f960SMark Rutland 			return false;
289b828f960SMark Rutland 	}
290b828f960SMark Rutland 
291b828f960SMark Rutland 	return num_hw <= PMU_NR_COUNTERS;
292b828f960SMark Rutland }
293b828f960SMark Rutland 
l2x0_pmu_event_init(struct perf_event * event)294b828f960SMark Rutland static int l2x0_pmu_event_init(struct perf_event *event)
295b828f960SMark Rutland {
296b828f960SMark Rutland 	struct hw_perf_event *hw = &event->hw;
297b828f960SMark Rutland 
298b828f960SMark Rutland 	if (event->attr.type != l2x0_pmu->type)
299b828f960SMark Rutland 		return -ENOENT;
300b828f960SMark Rutland 
301b828f960SMark Rutland 	if (is_sampling_event(event) ||
302b828f960SMark Rutland 	    event->attach_state & PERF_ATTACH_TASK)
303b828f960SMark Rutland 		return -EINVAL;
304b828f960SMark Rutland 
305b828f960SMark Rutland 	if (event->cpu < 0)
306b828f960SMark Rutland 		return -EINVAL;
307b828f960SMark Rutland 
308b828f960SMark Rutland 	if (event->attr.config & ~L2X0_EVENT_CNT_CFG_SRC_MASK)
309b828f960SMark Rutland 		return -EINVAL;
310b828f960SMark Rutland 
311b828f960SMark Rutland 	hw->config_base = event->attr.config;
312b828f960SMark Rutland 
313b828f960SMark Rutland 	if (!l2x0_pmu_group_is_valid(event))
314b828f960SMark Rutland 		return -EINVAL;
315b828f960SMark Rutland 
316b828f960SMark Rutland 	event->cpu = cpumask_first(&pmu_cpu);
317b828f960SMark Rutland 
318b828f960SMark Rutland 	return 0;
319b828f960SMark Rutland }
320b828f960SMark Rutland 
321b828f960SMark Rutland struct l2x0_event_attribute {
322b828f960SMark Rutland 	struct device_attribute attr;
323b828f960SMark Rutland 	unsigned int config;
324b828f960SMark Rutland 	bool pl310_only;
325b828f960SMark Rutland };
326b828f960SMark Rutland 
327b828f960SMark Rutland #define L2X0_EVENT_ATTR(_name, _config, _pl310_only)				\
328b828f960SMark Rutland 	(&((struct l2x0_event_attribute[]) {{					\
329b828f960SMark Rutland 		.attr = __ATTR(_name, S_IRUGO, l2x0_pmu_event_show, NULL),	\
330b828f960SMark Rutland 		.config = _config,						\
331b828f960SMark Rutland 		.pl310_only = _pl310_only,					\
332b828f960SMark Rutland 	}})[0].attr.attr)
333b828f960SMark Rutland 
334b828f960SMark Rutland #define L220_PLUS_EVENT_ATTR(_name, _config)					\
335b828f960SMark Rutland 	L2X0_EVENT_ATTR(_name, _config, false)
336b828f960SMark Rutland 
337b828f960SMark Rutland #define PL310_EVENT_ATTR(_name, _config)					\
338b828f960SMark Rutland 	L2X0_EVENT_ATTR(_name, _config, true)
339b828f960SMark Rutland 
l2x0_pmu_event_show(struct device * dev,struct device_attribute * attr,char * buf)340b828f960SMark Rutland static ssize_t l2x0_pmu_event_show(struct device *dev,
341b828f960SMark Rutland 				   struct device_attribute *attr, char *buf)
342b828f960SMark Rutland {
343b828f960SMark Rutland 	struct l2x0_event_attribute *lattr;
344b828f960SMark Rutland 
345b828f960SMark Rutland 	lattr = container_of(attr, typeof(*lattr), attr);
346b828f960SMark Rutland 	return snprintf(buf, PAGE_SIZE, "config=0x%x\n", lattr->config);
347b828f960SMark Rutland }
348b828f960SMark Rutland 
l2x0_pmu_event_attr_is_visible(struct kobject * kobj,struct attribute * attr,int unused)349b828f960SMark Rutland static umode_t l2x0_pmu_event_attr_is_visible(struct kobject *kobj,
350b828f960SMark Rutland 					      struct attribute *attr,
351b828f960SMark Rutland 					      int unused)
352b828f960SMark Rutland {
353b828f960SMark Rutland 	struct device *dev = kobj_to_dev(kobj);
354b828f960SMark Rutland 	struct pmu *pmu = dev_get_drvdata(dev);
355b828f960SMark Rutland 	struct l2x0_event_attribute *lattr;
356b828f960SMark Rutland 
357b828f960SMark Rutland 	lattr = container_of(attr, typeof(*lattr), attr.attr);
358b828f960SMark Rutland 
359b828f960SMark Rutland 	if (!lattr->pl310_only || strcmp("l2c_310", pmu->name) == 0)
360b828f960SMark Rutland 		return attr->mode;
361b828f960SMark Rutland 
362b828f960SMark Rutland 	return 0;
363b828f960SMark Rutland }
364b828f960SMark Rutland 
365b828f960SMark Rutland static struct attribute *l2x0_pmu_event_attrs[] = {
366b828f960SMark Rutland 	L220_PLUS_EVENT_ATTR(co,	0x1),
367b828f960SMark Rutland 	L220_PLUS_EVENT_ATTR(drhit,	0x2),
368b828f960SMark Rutland 	L220_PLUS_EVENT_ATTR(drreq,	0x3),
369b828f960SMark Rutland 	L220_PLUS_EVENT_ATTR(dwhit,	0x4),
370b828f960SMark Rutland 	L220_PLUS_EVENT_ATTR(dwreq,	0x5),
371b828f960SMark Rutland 	L220_PLUS_EVENT_ATTR(dwtreq,	0x6),
372b828f960SMark Rutland 	L220_PLUS_EVENT_ATTR(irhit,	0x7),
373b828f960SMark Rutland 	L220_PLUS_EVENT_ATTR(irreq,	0x8),
374b828f960SMark Rutland 	L220_PLUS_EVENT_ATTR(wa,	0x9),
375b828f960SMark Rutland 	PL310_EVENT_ATTR(ipfalloc,	0xa),
376b828f960SMark Rutland 	PL310_EVENT_ATTR(epfhit,	0xb),
377b828f960SMark Rutland 	PL310_EVENT_ATTR(epfalloc,	0xc),
378b828f960SMark Rutland 	PL310_EVENT_ATTR(srrcvd,	0xd),
379b828f960SMark Rutland 	PL310_EVENT_ATTR(srconf,	0xe),
380b828f960SMark Rutland 	PL310_EVENT_ATTR(epfrcvd,	0xf),
381b828f960SMark Rutland 	NULL
382b828f960SMark Rutland };
383b828f960SMark Rutland 
384b828f960SMark Rutland static struct attribute_group l2x0_pmu_event_attrs_group = {
385b828f960SMark Rutland 	.name = "events",
386b828f960SMark Rutland 	.attrs = l2x0_pmu_event_attrs,
387b828f960SMark Rutland 	.is_visible = l2x0_pmu_event_attr_is_visible,
388b828f960SMark Rutland };
389b828f960SMark Rutland 
l2x0_pmu_cpumask_show(struct device * dev,struct device_attribute * attr,char * buf)390b828f960SMark Rutland static ssize_t l2x0_pmu_cpumask_show(struct device *dev,
391b828f960SMark Rutland 				     struct device_attribute *attr, char *buf)
392b828f960SMark Rutland {
393b828f960SMark Rutland 	return cpumap_print_to_pagebuf(true, buf, &pmu_cpu);
394b828f960SMark Rutland }
395b828f960SMark Rutland 
396b828f960SMark Rutland static struct device_attribute l2x0_pmu_cpumask_attr =
397b828f960SMark Rutland 		__ATTR(cpumask, S_IRUGO, l2x0_pmu_cpumask_show, NULL);
398b828f960SMark Rutland 
399b828f960SMark Rutland static struct attribute *l2x0_pmu_cpumask_attrs[] = {
400b828f960SMark Rutland 	&l2x0_pmu_cpumask_attr.attr,
401b828f960SMark Rutland 	NULL,
402b828f960SMark Rutland };
403b828f960SMark Rutland 
404b828f960SMark Rutland static struct attribute_group l2x0_pmu_cpumask_attr_group = {
405b828f960SMark Rutland 	.attrs = l2x0_pmu_cpumask_attrs,
406b828f960SMark Rutland };
407b828f960SMark Rutland 
408b828f960SMark Rutland static const struct attribute_group *l2x0_pmu_attr_groups[] = {
409b828f960SMark Rutland 	&l2x0_pmu_event_attrs_group,
410b828f960SMark Rutland 	&l2x0_pmu_cpumask_attr_group,
411b828f960SMark Rutland 	NULL,
412b828f960SMark Rutland };
413b828f960SMark Rutland 
l2x0_pmu_reset(void)414b828f960SMark Rutland static void l2x0_pmu_reset(void)
415b828f960SMark Rutland {
416b828f960SMark Rutland 	int i;
417b828f960SMark Rutland 
418b828f960SMark Rutland 	__l2x0_pmu_disable();
419b828f960SMark Rutland 
420b828f960SMark Rutland 	for (i = 0; i < PMU_NR_COUNTERS; i++)
421b828f960SMark Rutland 		__l2x0_pmu_event_disable(i);
422b828f960SMark Rutland }
423b828f960SMark Rutland 
l2x0_pmu_offline_cpu(unsigned int cpu)424b828f960SMark Rutland static int l2x0_pmu_offline_cpu(unsigned int cpu)
425b828f960SMark Rutland {
426b828f960SMark Rutland 	unsigned int target;
427b828f960SMark Rutland 
428b828f960SMark Rutland 	if (!cpumask_test_and_clear_cpu(cpu, &pmu_cpu))
429b828f960SMark Rutland 		return 0;
430b828f960SMark Rutland 
431b828f960SMark Rutland 	target = cpumask_any_but(cpu_online_mask, cpu);
432b828f960SMark Rutland 	if (target >= nr_cpu_ids)
433b828f960SMark Rutland 		return 0;
434b828f960SMark Rutland 
435b828f960SMark Rutland 	perf_pmu_migrate_context(l2x0_pmu, cpu, target);
436b828f960SMark Rutland 	cpumask_set_cpu(target, &pmu_cpu);
437b828f960SMark Rutland 
438b828f960SMark Rutland 	return 0;
439b828f960SMark Rutland }
440b828f960SMark Rutland 
l2x0_pmu_suspend(void)441b828f960SMark Rutland void l2x0_pmu_suspend(void)
442b828f960SMark Rutland {
443b828f960SMark Rutland 	int i;
444b828f960SMark Rutland 
445b828f960SMark Rutland 	if (!l2x0_pmu)
446b828f960SMark Rutland 		return;
447b828f960SMark Rutland 
448b828f960SMark Rutland 	l2x0_pmu_disable(l2x0_pmu);
449b828f960SMark Rutland 
450b828f960SMark Rutland 	for (i = 0; i < PMU_NR_COUNTERS; i++) {
451b828f960SMark Rutland 		if (events[i])
452b828f960SMark Rutland 			l2x0_pmu_event_stop(events[i], PERF_EF_UPDATE);
453b828f960SMark Rutland 	}
454b828f960SMark Rutland 
455b828f960SMark Rutland }
456b828f960SMark Rutland 
l2x0_pmu_resume(void)457b828f960SMark Rutland void l2x0_pmu_resume(void)
458b828f960SMark Rutland {
459b828f960SMark Rutland 	int i;
460b828f960SMark Rutland 
461b828f960SMark Rutland 	if (!l2x0_pmu)
462b828f960SMark Rutland 		return;
463b828f960SMark Rutland 
464b828f960SMark Rutland 	l2x0_pmu_reset();
465b828f960SMark Rutland 
466b828f960SMark Rutland 	for (i = 0; i < PMU_NR_COUNTERS; i++) {
467b828f960SMark Rutland 		if (events[i])
468b828f960SMark Rutland 			l2x0_pmu_event_start(events[i], PERF_EF_RELOAD);
469b828f960SMark Rutland 	}
470b828f960SMark Rutland 
471b828f960SMark Rutland 	l2x0_pmu_enable(l2x0_pmu);
472b828f960SMark Rutland }
473b828f960SMark Rutland 
l2x0_pmu_register(void __iomem * base,u32 part)474b828f960SMark Rutland void __init l2x0_pmu_register(void __iomem *base, u32 part)
475b828f960SMark Rutland {
476b828f960SMark Rutland 	/*
477b828f960SMark Rutland 	 * Determine whether we support the PMU, and choose the name for sysfs.
478b828f960SMark Rutland 	 * This is also used by l2x0_pmu_event_attr_is_visible to determine
479b828f960SMark Rutland 	 * which events to display, as the PL310 PMU supports a superset of
480b828f960SMark Rutland 	 * L220 events.
481b828f960SMark Rutland 	 *
482b828f960SMark Rutland 	 * The L210 PMU has a different programmer's interface, and is not
483b828f960SMark Rutland 	 * supported by this driver.
484b828f960SMark Rutland 	 *
485b828f960SMark Rutland 	 * We must defer registering the PMU until the perf subsystem is up and
486b828f960SMark Rutland 	 * running, so just stash the name and base, and leave that to another
487b828f960SMark Rutland 	 * initcall.
488b828f960SMark Rutland 	 */
489b828f960SMark Rutland 	switch (part & L2X0_CACHE_ID_PART_MASK) {
490b828f960SMark Rutland 	case L2X0_CACHE_ID_PART_L220:
491b828f960SMark Rutland 		l2x0_name = "l2c_220";
492b828f960SMark Rutland 		break;
493b828f960SMark Rutland 	case L2X0_CACHE_ID_PART_L310:
494b828f960SMark Rutland 		l2x0_name = "l2c_310";
495b828f960SMark Rutland 		break;
496b828f960SMark Rutland 	default:
497b828f960SMark Rutland 		return;
498b828f960SMark Rutland 	}
499b828f960SMark Rutland 
500b828f960SMark Rutland 	l2x0_base = base;
501b828f960SMark Rutland }
502b828f960SMark Rutland 
l2x0_pmu_init(void)503b828f960SMark Rutland static __init int l2x0_pmu_init(void)
504b828f960SMark Rutland {
505b828f960SMark Rutland 	int ret;
506b828f960SMark Rutland 
507b828f960SMark Rutland 	if (!l2x0_base)
508b828f960SMark Rutland 		return 0;
509b828f960SMark Rutland 
510b828f960SMark Rutland 	l2x0_pmu = kzalloc(sizeof(*l2x0_pmu), GFP_KERNEL);
511b828f960SMark Rutland 	if (!l2x0_pmu) {
512b828f960SMark Rutland 		pr_warn("Unable to allocate L2x0 PMU\n");
513b828f960SMark Rutland 		return -ENOMEM;
514b828f960SMark Rutland 	}
515b828f960SMark Rutland 
516b828f960SMark Rutland 	*l2x0_pmu = (struct pmu) {
517b828f960SMark Rutland 		.task_ctx_nr = perf_invalid_context,
518b828f960SMark Rutland 		.pmu_enable = l2x0_pmu_enable,
519b828f960SMark Rutland 		.pmu_disable = l2x0_pmu_disable,
520b828f960SMark Rutland 		.read = l2x0_pmu_event_read,
521b828f960SMark Rutland 		.start = l2x0_pmu_event_start,
522b828f960SMark Rutland 		.stop = l2x0_pmu_event_stop,
523b828f960SMark Rutland 		.add = l2x0_pmu_event_add,
524b828f960SMark Rutland 		.del = l2x0_pmu_event_del,
525b828f960SMark Rutland 		.event_init = l2x0_pmu_event_init,
526b828f960SMark Rutland 		.attr_groups = l2x0_pmu_attr_groups,
527cafa780eSAndrew Murray 		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
528b828f960SMark Rutland 	};
529b828f960SMark Rutland 
530b828f960SMark Rutland 	l2x0_pmu_reset();
531b828f960SMark Rutland 
532b828f960SMark Rutland 	/*
533b828f960SMark Rutland 	 * We always use a hrtimer rather than an interrupt.
534b828f960SMark Rutland 	 * See comments in l2x0_pmu_event_configure and l2x0_pmu_poll.
535b828f960SMark Rutland 	 *
536b828f960SMark Rutland 	 * Polling once a second allows the counters to fill up to 1/128th on a
537b828f960SMark Rutland 	 * quad-core test chip with cores clocked at 400MHz. Hopefully this
538b828f960SMark Rutland 	 * leaves sufficient headroom to avoid overflow on production silicon
539b828f960SMark Rutland 	 * at higher frequencies.
540b828f960SMark Rutland 	 */
541b828f960SMark Rutland 	l2x0_pmu_poll_period = ms_to_ktime(1000);
542b828f960SMark Rutland 	hrtimer_init(&l2x0_pmu_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
543b828f960SMark Rutland 	l2x0_pmu_hrtimer.function = l2x0_pmu_poll;
544b828f960SMark Rutland 
545b828f960SMark Rutland 	cpumask_set_cpu(0, &pmu_cpu);
546b828f960SMark Rutland 	ret = cpuhp_setup_state_nocalls(CPUHP_AP_PERF_ARM_L2X0_ONLINE,
54773c1b41eSThomas Gleixner 					"perf/arm/l2x0:online", NULL,
548b828f960SMark Rutland 					l2x0_pmu_offline_cpu);
549b828f960SMark Rutland 	if (ret)
550b828f960SMark Rutland 		goto out_pmu;
551b828f960SMark Rutland 
552b828f960SMark Rutland 	ret = perf_pmu_register(l2x0_pmu, l2x0_name, -1);
553b828f960SMark Rutland 	if (ret)
554b828f960SMark Rutland 		goto out_cpuhp;
555b828f960SMark Rutland 
556b828f960SMark Rutland 	return 0;
557b828f960SMark Rutland 
558b828f960SMark Rutland out_cpuhp:
559b828f960SMark Rutland 	cpuhp_remove_state_nocalls(CPUHP_AP_PERF_ARM_L2X0_ONLINE);
560b828f960SMark Rutland out_pmu:
561b828f960SMark Rutland 	kfree(l2x0_pmu);
562b828f960SMark Rutland 	l2x0_pmu = NULL;
563b828f960SMark Rutland 	return ret;
564b828f960SMark Rutland }
565b828f960SMark Rutland device_initcall(l2x0_pmu_init);
566