xref: /OK3568_Linux_fs/kernel/drivers/perf/arm-cci.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun // CCI Cache Coherent Interconnect PMU driver
3*4882a593Smuzhiyun // Copyright (C) 2013-2018 Arm Ltd.
4*4882a593Smuzhiyun // Author: Punit Agrawal <punit.agrawal@arm.com>, Suzuki Poulose <suzuki.poulose@arm.com>
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/arm-cci.h>
7*4882a593Smuzhiyun #include <linux/io.h>
8*4882a593Smuzhiyun #include <linux/interrupt.h>
9*4882a593Smuzhiyun #include <linux/module.h>
10*4882a593Smuzhiyun #include <linux/of_address.h>
11*4882a593Smuzhiyun #include <linux/of_device.h>
12*4882a593Smuzhiyun #include <linux/of_irq.h>
13*4882a593Smuzhiyun #include <linux/of_platform.h>
14*4882a593Smuzhiyun #include <linux/perf_event.h>
15*4882a593Smuzhiyun #include <linux/platform_device.h>
16*4882a593Smuzhiyun #include <linux/slab.h>
17*4882a593Smuzhiyun #include <linux/spinlock.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define DRIVER_NAME		"ARM-CCI PMU"
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #define CCI_PMCR		0x0100
22*4882a593Smuzhiyun #define CCI_PID2		0x0fe8
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #define CCI_PMCR_CEN		0x00000001
25*4882a593Smuzhiyun #define CCI_PMCR_NCNT_MASK	0x0000f800
26*4882a593Smuzhiyun #define CCI_PMCR_NCNT_SHIFT	11
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define CCI_PID2_REV_MASK	0xf0
29*4882a593Smuzhiyun #define CCI_PID2_REV_SHIFT	4
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define CCI_PMU_EVT_SEL		0x000
32*4882a593Smuzhiyun #define CCI_PMU_CNTR		0x004
33*4882a593Smuzhiyun #define CCI_PMU_CNTR_CTRL	0x008
34*4882a593Smuzhiyun #define CCI_PMU_OVRFLW		0x00c
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #define CCI_PMU_OVRFLW_FLAG	1
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #define CCI_PMU_CNTR_SIZE(model)	((model)->cntr_size)
39*4882a593Smuzhiyun #define CCI_PMU_CNTR_BASE(model, idx)	((idx) * CCI_PMU_CNTR_SIZE(model))
40*4882a593Smuzhiyun #define CCI_PMU_CNTR_MASK		((1ULL << 32) -1)
41*4882a593Smuzhiyun #define CCI_PMU_CNTR_LAST(cci_pmu)	(cci_pmu->num_cntrs - 1)
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #define CCI_PMU_MAX_HW_CNTRS(model) \
44*4882a593Smuzhiyun 	((model)->num_hw_cntrs + (model)->fixed_hw_cntrs)
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun /* Types of interfaces that can generate events */
47*4882a593Smuzhiyun enum {
48*4882a593Smuzhiyun 	CCI_IF_SLAVE,
49*4882a593Smuzhiyun 	CCI_IF_MASTER,
50*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI5xx_PMU
51*4882a593Smuzhiyun 	CCI_IF_GLOBAL,
52*4882a593Smuzhiyun #endif
53*4882a593Smuzhiyun 	CCI_IF_MAX,
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #define NUM_HW_CNTRS_CII_4XX	4
57*4882a593Smuzhiyun #define NUM_HW_CNTRS_CII_5XX	8
58*4882a593Smuzhiyun #define NUM_HW_CNTRS_MAX	NUM_HW_CNTRS_CII_5XX
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun #define FIXED_HW_CNTRS_CII_4XX	1
61*4882a593Smuzhiyun #define FIXED_HW_CNTRS_CII_5XX	0
62*4882a593Smuzhiyun #define FIXED_HW_CNTRS_MAX	FIXED_HW_CNTRS_CII_4XX
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define HW_CNTRS_MAX		(NUM_HW_CNTRS_MAX + FIXED_HW_CNTRS_MAX)
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun struct event_range {
67*4882a593Smuzhiyun 	u32 min;
68*4882a593Smuzhiyun 	u32 max;
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun struct cci_pmu_hw_events {
72*4882a593Smuzhiyun 	struct perf_event **events;
73*4882a593Smuzhiyun 	unsigned long *used_mask;
74*4882a593Smuzhiyun 	raw_spinlock_t pmu_lock;
75*4882a593Smuzhiyun };
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun struct cci_pmu;
78*4882a593Smuzhiyun /*
79*4882a593Smuzhiyun  * struct cci_pmu_model:
80*4882a593Smuzhiyun  * @fixed_hw_cntrs - Number of fixed event counters
81*4882a593Smuzhiyun  * @num_hw_cntrs - Maximum number of programmable event counters
82*4882a593Smuzhiyun  * @cntr_size - Size of an event counter mapping
83*4882a593Smuzhiyun  */
84*4882a593Smuzhiyun struct cci_pmu_model {
85*4882a593Smuzhiyun 	char *name;
86*4882a593Smuzhiyun 	u32 fixed_hw_cntrs;
87*4882a593Smuzhiyun 	u32 num_hw_cntrs;
88*4882a593Smuzhiyun 	u32 cntr_size;
89*4882a593Smuzhiyun 	struct attribute **format_attrs;
90*4882a593Smuzhiyun 	struct attribute **event_attrs;
91*4882a593Smuzhiyun 	struct event_range event_ranges[CCI_IF_MAX];
92*4882a593Smuzhiyun 	int (*validate_hw_event)(struct cci_pmu *, unsigned long);
93*4882a593Smuzhiyun 	int (*get_event_idx)(struct cci_pmu *, struct cci_pmu_hw_events *, unsigned long);
94*4882a593Smuzhiyun 	void (*write_counters)(struct cci_pmu *, unsigned long *);
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun static struct cci_pmu_model cci_pmu_models[];
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun struct cci_pmu {
100*4882a593Smuzhiyun 	void __iomem *base;
101*4882a593Smuzhiyun 	void __iomem *ctrl_base;
102*4882a593Smuzhiyun 	struct pmu pmu;
103*4882a593Smuzhiyun 	int cpu;
104*4882a593Smuzhiyun 	int nr_irqs;
105*4882a593Smuzhiyun 	int *irqs;
106*4882a593Smuzhiyun 	unsigned long active_irqs;
107*4882a593Smuzhiyun 	const struct cci_pmu_model *model;
108*4882a593Smuzhiyun 	struct cci_pmu_hw_events hw_events;
109*4882a593Smuzhiyun 	struct platform_device *plat_device;
110*4882a593Smuzhiyun 	int num_cntrs;
111*4882a593Smuzhiyun 	atomic_t active_events;
112*4882a593Smuzhiyun 	struct mutex reserve_mutex;
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun #define to_cci_pmu(c)	(container_of(c, struct cci_pmu, pmu))
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun static struct cci_pmu *g_cci_pmu;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun enum cci_models {
120*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI400_PMU
121*4882a593Smuzhiyun 	CCI400_R0,
122*4882a593Smuzhiyun 	CCI400_R1,
123*4882a593Smuzhiyun #endif
124*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI5xx_PMU
125*4882a593Smuzhiyun 	CCI500_R0,
126*4882a593Smuzhiyun 	CCI550_R0,
127*4882a593Smuzhiyun #endif
128*4882a593Smuzhiyun 	CCI_MODEL_MAX
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun static void pmu_write_counters(struct cci_pmu *cci_pmu,
132*4882a593Smuzhiyun 				 unsigned long *mask);
133*4882a593Smuzhiyun static ssize_t __maybe_unused cci_pmu_format_show(struct device *dev,
134*4882a593Smuzhiyun 			struct device_attribute *attr, char *buf);
135*4882a593Smuzhiyun static ssize_t __maybe_unused cci_pmu_event_show(struct device *dev,
136*4882a593Smuzhiyun 			struct device_attribute *attr, char *buf);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun #define CCI_EXT_ATTR_ENTRY(_name, _func, _config) 				\
139*4882a593Smuzhiyun 	&((struct dev_ext_attribute[]) {					\
140*4882a593Smuzhiyun 		{ __ATTR(_name, S_IRUGO, _func, NULL), (void *)_config }	\
141*4882a593Smuzhiyun 	})[0].attr.attr
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun #define CCI_FORMAT_EXT_ATTR_ENTRY(_name, _config) \
144*4882a593Smuzhiyun 	CCI_EXT_ATTR_ENTRY(_name, cci_pmu_format_show, (char *)_config)
145*4882a593Smuzhiyun #define CCI_EVENT_EXT_ATTR_ENTRY(_name, _config) \
146*4882a593Smuzhiyun 	CCI_EXT_ATTR_ENTRY(_name, cci_pmu_event_show, (unsigned long)_config)
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun /* CCI400 PMU Specific definitions */
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI400_PMU
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun /* Port ids */
153*4882a593Smuzhiyun #define CCI400_PORT_S0		0
154*4882a593Smuzhiyun #define CCI400_PORT_S1		1
155*4882a593Smuzhiyun #define CCI400_PORT_S2		2
156*4882a593Smuzhiyun #define CCI400_PORT_S3		3
157*4882a593Smuzhiyun #define CCI400_PORT_S4		4
158*4882a593Smuzhiyun #define CCI400_PORT_M0		5
159*4882a593Smuzhiyun #define CCI400_PORT_M1		6
160*4882a593Smuzhiyun #define CCI400_PORT_M2		7
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun #define CCI400_R1_PX		5
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun /*
165*4882a593Smuzhiyun  * Instead of an event id to monitor CCI cycles, a dedicated counter is
166*4882a593Smuzhiyun  * provided. Use 0xff to represent CCI cycles and hope that no future revisions
167*4882a593Smuzhiyun  * make use of this event in hardware.
168*4882a593Smuzhiyun  */
169*4882a593Smuzhiyun enum cci400_perf_events {
170*4882a593Smuzhiyun 	CCI400_PMU_CYCLES = 0xff
171*4882a593Smuzhiyun };
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun #define CCI400_PMU_CYCLE_CNTR_IDX	0
174*4882a593Smuzhiyun #define CCI400_PMU_CNTR0_IDX		1
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun /*
177*4882a593Smuzhiyun  * CCI PMU event id is an 8-bit value made of two parts - bits 7:5 for one of 8
178*4882a593Smuzhiyun  * ports and bits 4:0 are event codes. There are different event codes
179*4882a593Smuzhiyun  * associated with each port type.
180*4882a593Smuzhiyun  *
181*4882a593Smuzhiyun  * Additionally, the range of events associated with the port types changed
182*4882a593Smuzhiyun  * between Rev0 and Rev1.
183*4882a593Smuzhiyun  *
184*4882a593Smuzhiyun  * The constants below define the range of valid codes for each port type for
185*4882a593Smuzhiyun  * the different revisions and are used to validate the event to be monitored.
186*4882a593Smuzhiyun  */
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun #define CCI400_PMU_EVENT_MASK		0xffUL
189*4882a593Smuzhiyun #define CCI400_PMU_EVENT_SOURCE_SHIFT	5
190*4882a593Smuzhiyun #define CCI400_PMU_EVENT_SOURCE_MASK	0x7
191*4882a593Smuzhiyun #define CCI400_PMU_EVENT_CODE_SHIFT	0
192*4882a593Smuzhiyun #define CCI400_PMU_EVENT_CODE_MASK	0x1f
193*4882a593Smuzhiyun #define CCI400_PMU_EVENT_SOURCE(event) \
194*4882a593Smuzhiyun 	((event >> CCI400_PMU_EVENT_SOURCE_SHIFT) & \
195*4882a593Smuzhiyun 			CCI400_PMU_EVENT_SOURCE_MASK)
196*4882a593Smuzhiyun #define CCI400_PMU_EVENT_CODE(event) \
197*4882a593Smuzhiyun 	((event >> CCI400_PMU_EVENT_CODE_SHIFT) & CCI400_PMU_EVENT_CODE_MASK)
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun #define CCI400_R0_SLAVE_PORT_MIN_EV	0x00
200*4882a593Smuzhiyun #define CCI400_R0_SLAVE_PORT_MAX_EV	0x13
201*4882a593Smuzhiyun #define CCI400_R0_MASTER_PORT_MIN_EV	0x14
202*4882a593Smuzhiyun #define CCI400_R0_MASTER_PORT_MAX_EV	0x1a
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun #define CCI400_R1_SLAVE_PORT_MIN_EV	0x00
205*4882a593Smuzhiyun #define CCI400_R1_SLAVE_PORT_MAX_EV	0x14
206*4882a593Smuzhiyun #define CCI400_R1_MASTER_PORT_MIN_EV	0x00
207*4882a593Smuzhiyun #define CCI400_R1_MASTER_PORT_MAX_EV	0x11
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun #define CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(_name, _config) \
210*4882a593Smuzhiyun 	CCI_EXT_ATTR_ENTRY(_name, cci400_pmu_cycle_event_show, \
211*4882a593Smuzhiyun 					(unsigned long)_config)
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun static ssize_t cci400_pmu_cycle_event_show(struct device *dev,
214*4882a593Smuzhiyun 			struct device_attribute *attr, char *buf);
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun static struct attribute *cci400_pmu_format_attrs[] = {
217*4882a593Smuzhiyun 	CCI_FORMAT_EXT_ATTR_ENTRY(event, "config:0-4"),
218*4882a593Smuzhiyun 	CCI_FORMAT_EXT_ATTR_ENTRY(source, "config:5-7"),
219*4882a593Smuzhiyun 	NULL
220*4882a593Smuzhiyun };
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun static struct attribute *cci400_r0_pmu_event_attrs[] = {
223*4882a593Smuzhiyun 	/* Slave events */
224*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_any, 0x0),
225*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_device, 0x01),
226*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_normal_or_nonshareable, 0x2),
227*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_inner_or_outershareable, 0x3),
228*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_cache_maintenance, 0x4),
229*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_mem_barrier, 0x5),
230*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_sync_barrier, 0x6),
231*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg, 0x7),
232*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg_sync, 0x8),
233*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_tt_full, 0x9),
234*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_last_hs_snoop, 0xA),
235*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_stall_rvalids_h_rready_l, 0xB),
236*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_any, 0xC),
237*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_device, 0xD),
238*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_normal_or_nonshareable, 0xE),
239*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_inner_or_outershare_wback_wclean, 0xF),
240*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_unique, 0x10),
241*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_line_unique, 0x11),
242*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_evict, 0x12),
243*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_stall_tt_full, 0x13),
244*4882a593Smuzhiyun 	/* Master events */
245*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_retry_speculative_fetch, 0x14),
246*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_addr_hazard, 0x15),
247*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_id_hazard, 0x16),
248*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_tt_full, 0x17),
249*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_barrier_hazard, 0x18),
250*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_barrier_hazard, 0x19),
251*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_tt_full, 0x1A),
252*4882a593Smuzhiyun 	/* Special event for cycles counter */
253*4882a593Smuzhiyun 	CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(cycles, 0xff),
254*4882a593Smuzhiyun 	NULL
255*4882a593Smuzhiyun };
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun static struct attribute *cci400_r1_pmu_event_attrs[] = {
258*4882a593Smuzhiyun 	/* Slave events */
259*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_any, 0x0),
260*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_device, 0x01),
261*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_normal_or_nonshareable, 0x2),
262*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_inner_or_outershareable, 0x3),
263*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_cache_maintenance, 0x4),
264*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_mem_barrier, 0x5),
265*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_sync_barrier, 0x6),
266*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg, 0x7),
267*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg_sync, 0x8),
268*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_tt_full, 0x9),
269*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_last_hs_snoop, 0xA),
270*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_stall_rvalids_h_rready_l, 0xB),
271*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_any, 0xC),
272*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_device, 0xD),
273*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_normal_or_nonshareable, 0xE),
274*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_inner_or_outershare_wback_wclean, 0xF),
275*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_unique, 0x10),
276*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_line_unique, 0x11),
277*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_evict, 0x12),
278*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_stall_tt_full, 0x13),
279*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_slave_id_hazard, 0x14),
280*4882a593Smuzhiyun 	/* Master events */
281*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_retry_speculative_fetch, 0x0),
282*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_stall_cycle_addr_hazard, 0x1),
283*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_master_id_hazard, 0x2),
284*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_hi_prio_rtq_full, 0x3),
285*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_barrier_hazard, 0x4),
286*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_barrier_hazard, 0x5),
287*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_wtq_full, 0x6),
288*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_low_prio_rtq_full, 0x7),
289*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_mid_prio_rtq_full, 0x8),
290*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn0, 0x9),
291*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn1, 0xA),
292*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn2, 0xB),
293*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn3, 0xC),
294*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn0, 0xD),
295*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn1, 0xE),
296*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn2, 0xF),
297*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn3, 0x10),
298*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_unique_or_line_unique_addr_hazard, 0x11),
299*4882a593Smuzhiyun 	/* Special event for cycles counter */
300*4882a593Smuzhiyun 	CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(cycles, 0xff),
301*4882a593Smuzhiyun 	NULL
302*4882a593Smuzhiyun };
303*4882a593Smuzhiyun 
cci400_pmu_cycle_event_show(struct device * dev,struct device_attribute * attr,char * buf)304*4882a593Smuzhiyun static ssize_t cci400_pmu_cycle_event_show(struct device *dev,
305*4882a593Smuzhiyun 			struct device_attribute *attr, char *buf)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun 	struct dev_ext_attribute *eattr = container_of(attr,
308*4882a593Smuzhiyun 				struct dev_ext_attribute, attr);
309*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "config=0x%lx\n", (unsigned long)eattr->var);
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun 
cci400_get_event_idx(struct cci_pmu * cci_pmu,struct cci_pmu_hw_events * hw,unsigned long cci_event)312*4882a593Smuzhiyun static int cci400_get_event_idx(struct cci_pmu *cci_pmu,
313*4882a593Smuzhiyun 				struct cci_pmu_hw_events *hw,
314*4882a593Smuzhiyun 				unsigned long cci_event)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun 	int idx;
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	/* cycles event idx is fixed */
319*4882a593Smuzhiyun 	if (cci_event == CCI400_PMU_CYCLES) {
320*4882a593Smuzhiyun 		if (test_and_set_bit(CCI400_PMU_CYCLE_CNTR_IDX, hw->used_mask))
321*4882a593Smuzhiyun 			return -EAGAIN;
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 		return CCI400_PMU_CYCLE_CNTR_IDX;
324*4882a593Smuzhiyun 	}
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	for (idx = CCI400_PMU_CNTR0_IDX; idx <= CCI_PMU_CNTR_LAST(cci_pmu); ++idx)
327*4882a593Smuzhiyun 		if (!test_and_set_bit(idx, hw->used_mask))
328*4882a593Smuzhiyun 			return idx;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	/* No counters available */
331*4882a593Smuzhiyun 	return -EAGAIN;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun 
cci400_validate_hw_event(struct cci_pmu * cci_pmu,unsigned long hw_event)334*4882a593Smuzhiyun static int cci400_validate_hw_event(struct cci_pmu *cci_pmu, unsigned long hw_event)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun 	u8 ev_source = CCI400_PMU_EVENT_SOURCE(hw_event);
337*4882a593Smuzhiyun 	u8 ev_code = CCI400_PMU_EVENT_CODE(hw_event);
338*4882a593Smuzhiyun 	int if_type;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	if (hw_event & ~CCI400_PMU_EVENT_MASK)
341*4882a593Smuzhiyun 		return -ENOENT;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	if (hw_event == CCI400_PMU_CYCLES)
344*4882a593Smuzhiyun 		return hw_event;
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	switch (ev_source) {
347*4882a593Smuzhiyun 	case CCI400_PORT_S0:
348*4882a593Smuzhiyun 	case CCI400_PORT_S1:
349*4882a593Smuzhiyun 	case CCI400_PORT_S2:
350*4882a593Smuzhiyun 	case CCI400_PORT_S3:
351*4882a593Smuzhiyun 	case CCI400_PORT_S4:
352*4882a593Smuzhiyun 		/* Slave Interface */
353*4882a593Smuzhiyun 		if_type = CCI_IF_SLAVE;
354*4882a593Smuzhiyun 		break;
355*4882a593Smuzhiyun 	case CCI400_PORT_M0:
356*4882a593Smuzhiyun 	case CCI400_PORT_M1:
357*4882a593Smuzhiyun 	case CCI400_PORT_M2:
358*4882a593Smuzhiyun 		/* Master Interface */
359*4882a593Smuzhiyun 		if_type = CCI_IF_MASTER;
360*4882a593Smuzhiyun 		break;
361*4882a593Smuzhiyun 	default:
362*4882a593Smuzhiyun 		return -ENOENT;
363*4882a593Smuzhiyun 	}
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
366*4882a593Smuzhiyun 		ev_code <= cci_pmu->model->event_ranges[if_type].max)
367*4882a593Smuzhiyun 		return hw_event;
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	return -ENOENT;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun 
probe_cci400_revision(struct cci_pmu * cci_pmu)372*4882a593Smuzhiyun static int probe_cci400_revision(struct cci_pmu *cci_pmu)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun 	int rev;
375*4882a593Smuzhiyun 	rev = readl_relaxed(cci_pmu->ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK;
376*4882a593Smuzhiyun 	rev >>= CCI_PID2_REV_SHIFT;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	if (rev < CCI400_R1_PX)
379*4882a593Smuzhiyun 		return CCI400_R0;
380*4882a593Smuzhiyun 	else
381*4882a593Smuzhiyun 		return CCI400_R1;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun 
probe_cci_model(struct cci_pmu * cci_pmu)384*4882a593Smuzhiyun static const struct cci_pmu_model *probe_cci_model(struct cci_pmu *cci_pmu)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun 	if (platform_has_secure_cci_access())
387*4882a593Smuzhiyun 		return &cci_pmu_models[probe_cci400_revision(cci_pmu)];
388*4882a593Smuzhiyun 	return NULL;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun #else	/* !CONFIG_ARM_CCI400_PMU */
probe_cci_model(struct cci_pmu * cci_pmu)391*4882a593Smuzhiyun static inline struct cci_pmu_model *probe_cci_model(struct cci_pmu *cci_pmu)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun 	return NULL;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun #endif	/* CONFIG_ARM_CCI400_PMU */
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI5xx_PMU
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun /*
400*4882a593Smuzhiyun  * CCI5xx PMU event id is an 9-bit value made of two parts.
401*4882a593Smuzhiyun  *	 bits [8:5] - Source for the event
402*4882a593Smuzhiyun  *	 bits [4:0] - Event code (specific to type of interface)
403*4882a593Smuzhiyun  *
404*4882a593Smuzhiyun  *
405*4882a593Smuzhiyun  */
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun /* Port ids */
408*4882a593Smuzhiyun #define CCI5xx_PORT_S0			0x0
409*4882a593Smuzhiyun #define CCI5xx_PORT_S1			0x1
410*4882a593Smuzhiyun #define CCI5xx_PORT_S2			0x2
411*4882a593Smuzhiyun #define CCI5xx_PORT_S3			0x3
412*4882a593Smuzhiyun #define CCI5xx_PORT_S4			0x4
413*4882a593Smuzhiyun #define CCI5xx_PORT_S5			0x5
414*4882a593Smuzhiyun #define CCI5xx_PORT_S6			0x6
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun #define CCI5xx_PORT_M0			0x8
417*4882a593Smuzhiyun #define CCI5xx_PORT_M1			0x9
418*4882a593Smuzhiyun #define CCI5xx_PORT_M2			0xa
419*4882a593Smuzhiyun #define CCI5xx_PORT_M3			0xb
420*4882a593Smuzhiyun #define CCI5xx_PORT_M4			0xc
421*4882a593Smuzhiyun #define CCI5xx_PORT_M5			0xd
422*4882a593Smuzhiyun #define CCI5xx_PORT_M6			0xe
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun #define CCI5xx_PORT_GLOBAL		0xf
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun #define CCI5xx_PMU_EVENT_MASK		0x1ffUL
427*4882a593Smuzhiyun #define CCI5xx_PMU_EVENT_SOURCE_SHIFT	0x5
428*4882a593Smuzhiyun #define CCI5xx_PMU_EVENT_SOURCE_MASK	0xf
429*4882a593Smuzhiyun #define CCI5xx_PMU_EVENT_CODE_SHIFT	0x0
430*4882a593Smuzhiyun #define CCI5xx_PMU_EVENT_CODE_MASK	0x1f
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun #define CCI5xx_PMU_EVENT_SOURCE(event)	\
433*4882a593Smuzhiyun 	((event >> CCI5xx_PMU_EVENT_SOURCE_SHIFT) & CCI5xx_PMU_EVENT_SOURCE_MASK)
434*4882a593Smuzhiyun #define CCI5xx_PMU_EVENT_CODE(event)	\
435*4882a593Smuzhiyun 	((event >> CCI5xx_PMU_EVENT_CODE_SHIFT) & CCI5xx_PMU_EVENT_CODE_MASK)
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun #define CCI5xx_SLAVE_PORT_MIN_EV	0x00
438*4882a593Smuzhiyun #define CCI5xx_SLAVE_PORT_MAX_EV	0x1f
439*4882a593Smuzhiyun #define CCI5xx_MASTER_PORT_MIN_EV	0x00
440*4882a593Smuzhiyun #define CCI5xx_MASTER_PORT_MAX_EV	0x06
441*4882a593Smuzhiyun #define CCI5xx_GLOBAL_PORT_MIN_EV	0x00
442*4882a593Smuzhiyun #define CCI5xx_GLOBAL_PORT_MAX_EV	0x0f
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun #define CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(_name, _config) \
446*4882a593Smuzhiyun 	CCI_EXT_ATTR_ENTRY(_name, cci5xx_pmu_global_event_show, \
447*4882a593Smuzhiyun 					(unsigned long) _config)
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun static ssize_t cci5xx_pmu_global_event_show(struct device *dev,
450*4882a593Smuzhiyun 				struct device_attribute *attr, char *buf);
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun static struct attribute *cci5xx_pmu_format_attrs[] = {
453*4882a593Smuzhiyun 	CCI_FORMAT_EXT_ATTR_ENTRY(event, "config:0-4"),
454*4882a593Smuzhiyun 	CCI_FORMAT_EXT_ATTR_ENTRY(source, "config:5-8"),
455*4882a593Smuzhiyun 	NULL,
456*4882a593Smuzhiyun };
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun static struct attribute *cci5xx_pmu_event_attrs[] = {
459*4882a593Smuzhiyun 	/* Slave events */
460*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_arvalid, 0x0),
461*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_dev, 0x1),
462*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_nonshareable, 0x2),
463*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_shareable_non_alloc, 0x3),
464*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_shareable_alloc, 0x4),
465*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_invalidate, 0x5),
466*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_cache_maint, 0x6),
467*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg, 0x7),
468*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_rval, 0x8),
469*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_rlast_snoop, 0x9),
470*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_awalid, 0xA),
471*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_dev, 0xB),
472*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_non_shareable, 0xC),
473*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_share_wb, 0xD),
474*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_share_wlu, 0xE),
475*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_share_wunique, 0xF),
476*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_evict, 0x10),
477*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_wrevict, 0x11),
478*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_w_data_beat, 0x12),
479*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_acvalid, 0x13),
480*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_read, 0x14),
481*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_clean, 0x15),
482*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_data_transfer_low, 0x16),
483*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_arvalid, 0x17),
484*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_stall, 0x18),
485*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_stall, 0x19),
486*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_w_data_stall, 0x1A),
487*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_w_resp_stall, 0x1B),
488*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_stall, 0x1C),
489*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_s_data_stall, 0x1D),
490*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_rq_stall_ot_limit, 0x1E),
491*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(si_r_stall_arbit, 0x1F),
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 	/* Master events */
494*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_r_data_beat_any, 0x0),
495*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_w_data_beat_any, 0x1),
496*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall, 0x2),
497*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_r_data_stall, 0x3),
498*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall, 0x4),
499*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_w_data_stall, 0x5),
500*4882a593Smuzhiyun 	CCI_EVENT_EXT_ATTR_ENTRY(mi_w_resp_stall, 0x6),
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	/* Global events */
503*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_0_1, 0x0),
504*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_2_3, 0x1),
505*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_4_5, 0x2),
506*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_6_7, 0x3),
507*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_0_1, 0x4),
508*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_2_3, 0x5),
509*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_4_5, 0x6),
510*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_6_7, 0x7),
511*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_back_invalidation, 0x8),
512*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_alloc_busy, 0x9),
513*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_tt_full, 0xA),
514*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_wrq, 0xB),
515*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_cd_hs, 0xC),
516*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_rq_stall_addr_hazard, 0xD),
517*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_stall_tt_full, 0xE),
518*4882a593Smuzhiyun 	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_tzmp1_prot, 0xF),
519*4882a593Smuzhiyun 	NULL
520*4882a593Smuzhiyun };
521*4882a593Smuzhiyun 
cci5xx_pmu_global_event_show(struct device * dev,struct device_attribute * attr,char * buf)522*4882a593Smuzhiyun static ssize_t cci5xx_pmu_global_event_show(struct device *dev,
523*4882a593Smuzhiyun 				struct device_attribute *attr, char *buf)
524*4882a593Smuzhiyun {
525*4882a593Smuzhiyun 	struct dev_ext_attribute *eattr = container_of(attr,
526*4882a593Smuzhiyun 					struct dev_ext_attribute, attr);
527*4882a593Smuzhiyun 	/* Global events have single fixed source code */
528*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "event=0x%lx,source=0x%x\n",
529*4882a593Smuzhiyun 				(unsigned long)eattr->var, CCI5xx_PORT_GLOBAL);
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun /*
533*4882a593Smuzhiyun  * CCI500 provides 8 independent event counters that can count
534*4882a593Smuzhiyun  * any of the events available.
535*4882a593Smuzhiyun  * CCI500 PMU event source ids
536*4882a593Smuzhiyun  *	0x0-0x6 - Slave interfaces
537*4882a593Smuzhiyun  *	0x8-0xD - Master interfaces
538*4882a593Smuzhiyun  *	0xf     - Global Events
539*4882a593Smuzhiyun  *	0x7,0xe - Reserved
540*4882a593Smuzhiyun  */
cci500_validate_hw_event(struct cci_pmu * cci_pmu,unsigned long hw_event)541*4882a593Smuzhiyun static int cci500_validate_hw_event(struct cci_pmu *cci_pmu,
542*4882a593Smuzhiyun 					unsigned long hw_event)
543*4882a593Smuzhiyun {
544*4882a593Smuzhiyun 	u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event);
545*4882a593Smuzhiyun 	u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event);
546*4882a593Smuzhiyun 	int if_type;
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	if (hw_event & ~CCI5xx_PMU_EVENT_MASK)
549*4882a593Smuzhiyun 		return -ENOENT;
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	switch (ev_source) {
552*4882a593Smuzhiyun 	case CCI5xx_PORT_S0:
553*4882a593Smuzhiyun 	case CCI5xx_PORT_S1:
554*4882a593Smuzhiyun 	case CCI5xx_PORT_S2:
555*4882a593Smuzhiyun 	case CCI5xx_PORT_S3:
556*4882a593Smuzhiyun 	case CCI5xx_PORT_S4:
557*4882a593Smuzhiyun 	case CCI5xx_PORT_S5:
558*4882a593Smuzhiyun 	case CCI5xx_PORT_S6:
559*4882a593Smuzhiyun 		if_type = CCI_IF_SLAVE;
560*4882a593Smuzhiyun 		break;
561*4882a593Smuzhiyun 	case CCI5xx_PORT_M0:
562*4882a593Smuzhiyun 	case CCI5xx_PORT_M1:
563*4882a593Smuzhiyun 	case CCI5xx_PORT_M2:
564*4882a593Smuzhiyun 	case CCI5xx_PORT_M3:
565*4882a593Smuzhiyun 	case CCI5xx_PORT_M4:
566*4882a593Smuzhiyun 	case CCI5xx_PORT_M5:
567*4882a593Smuzhiyun 		if_type = CCI_IF_MASTER;
568*4882a593Smuzhiyun 		break;
569*4882a593Smuzhiyun 	case CCI5xx_PORT_GLOBAL:
570*4882a593Smuzhiyun 		if_type = CCI_IF_GLOBAL;
571*4882a593Smuzhiyun 		break;
572*4882a593Smuzhiyun 	default:
573*4882a593Smuzhiyun 		return -ENOENT;
574*4882a593Smuzhiyun 	}
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
577*4882a593Smuzhiyun 		ev_code <= cci_pmu->model->event_ranges[if_type].max)
578*4882a593Smuzhiyun 		return hw_event;
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	return -ENOENT;
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun /*
584*4882a593Smuzhiyun  * CCI550 provides 8 independent event counters that can count
585*4882a593Smuzhiyun  * any of the events available.
586*4882a593Smuzhiyun  * CCI550 PMU event source ids
587*4882a593Smuzhiyun  *	0x0-0x6 - Slave interfaces
588*4882a593Smuzhiyun  *	0x8-0xe - Master interfaces
589*4882a593Smuzhiyun  *	0xf     - Global Events
590*4882a593Smuzhiyun  *	0x7	- Reserved
591*4882a593Smuzhiyun  */
cci550_validate_hw_event(struct cci_pmu * cci_pmu,unsigned long hw_event)592*4882a593Smuzhiyun static int cci550_validate_hw_event(struct cci_pmu *cci_pmu,
593*4882a593Smuzhiyun 					unsigned long hw_event)
594*4882a593Smuzhiyun {
595*4882a593Smuzhiyun 	u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event);
596*4882a593Smuzhiyun 	u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event);
597*4882a593Smuzhiyun 	int if_type;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	if (hw_event & ~CCI5xx_PMU_EVENT_MASK)
600*4882a593Smuzhiyun 		return -ENOENT;
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	switch (ev_source) {
603*4882a593Smuzhiyun 	case CCI5xx_PORT_S0:
604*4882a593Smuzhiyun 	case CCI5xx_PORT_S1:
605*4882a593Smuzhiyun 	case CCI5xx_PORT_S2:
606*4882a593Smuzhiyun 	case CCI5xx_PORT_S3:
607*4882a593Smuzhiyun 	case CCI5xx_PORT_S4:
608*4882a593Smuzhiyun 	case CCI5xx_PORT_S5:
609*4882a593Smuzhiyun 	case CCI5xx_PORT_S6:
610*4882a593Smuzhiyun 		if_type = CCI_IF_SLAVE;
611*4882a593Smuzhiyun 		break;
612*4882a593Smuzhiyun 	case CCI5xx_PORT_M0:
613*4882a593Smuzhiyun 	case CCI5xx_PORT_M1:
614*4882a593Smuzhiyun 	case CCI5xx_PORT_M2:
615*4882a593Smuzhiyun 	case CCI5xx_PORT_M3:
616*4882a593Smuzhiyun 	case CCI5xx_PORT_M4:
617*4882a593Smuzhiyun 	case CCI5xx_PORT_M5:
618*4882a593Smuzhiyun 	case CCI5xx_PORT_M6:
619*4882a593Smuzhiyun 		if_type = CCI_IF_MASTER;
620*4882a593Smuzhiyun 		break;
621*4882a593Smuzhiyun 	case CCI5xx_PORT_GLOBAL:
622*4882a593Smuzhiyun 		if_type = CCI_IF_GLOBAL;
623*4882a593Smuzhiyun 		break;
624*4882a593Smuzhiyun 	default:
625*4882a593Smuzhiyun 		return -ENOENT;
626*4882a593Smuzhiyun 	}
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
629*4882a593Smuzhiyun 		ev_code <= cci_pmu->model->event_ranges[if_type].max)
630*4882a593Smuzhiyun 		return hw_event;
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	return -ENOENT;
633*4882a593Smuzhiyun }
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun #endif	/* CONFIG_ARM_CCI5xx_PMU */
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun /*
638*4882a593Smuzhiyun  * Program the CCI PMU counters which have PERF_HES_ARCH set
639*4882a593Smuzhiyun  * with the event period and mark them ready before we enable
640*4882a593Smuzhiyun  * PMU.
641*4882a593Smuzhiyun  */
cci_pmu_sync_counters(struct cci_pmu * cci_pmu)642*4882a593Smuzhiyun static void cci_pmu_sync_counters(struct cci_pmu *cci_pmu)
643*4882a593Smuzhiyun {
644*4882a593Smuzhiyun 	int i;
645*4882a593Smuzhiyun 	struct cci_pmu_hw_events *cci_hw = &cci_pmu->hw_events;
646*4882a593Smuzhiyun 	DECLARE_BITMAP(mask, HW_CNTRS_MAX);
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	bitmap_zero(mask, cci_pmu->num_cntrs);
649*4882a593Smuzhiyun 	for_each_set_bit(i, cci_pmu->hw_events.used_mask, cci_pmu->num_cntrs) {
650*4882a593Smuzhiyun 		struct perf_event *event = cci_hw->events[i];
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 		if (WARN_ON(!event))
653*4882a593Smuzhiyun 			continue;
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 		/* Leave the events which are not counting */
656*4882a593Smuzhiyun 		if (event->hw.state & PERF_HES_STOPPED)
657*4882a593Smuzhiyun 			continue;
658*4882a593Smuzhiyun 		if (event->hw.state & PERF_HES_ARCH) {
659*4882a593Smuzhiyun 			set_bit(i, mask);
660*4882a593Smuzhiyun 			event->hw.state &= ~PERF_HES_ARCH;
661*4882a593Smuzhiyun 		}
662*4882a593Smuzhiyun 	}
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun 	pmu_write_counters(cci_pmu, mask);
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun /* Should be called with cci_pmu->hw_events->pmu_lock held */
__cci_pmu_enable_nosync(struct cci_pmu * cci_pmu)668*4882a593Smuzhiyun static void __cci_pmu_enable_nosync(struct cci_pmu *cci_pmu)
669*4882a593Smuzhiyun {
670*4882a593Smuzhiyun 	u32 val;
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	/* Enable all the PMU counters. */
673*4882a593Smuzhiyun 	val = readl_relaxed(cci_pmu->ctrl_base + CCI_PMCR) | CCI_PMCR_CEN;
674*4882a593Smuzhiyun 	writel(val, cci_pmu->ctrl_base + CCI_PMCR);
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun /* Should be called with cci_pmu->hw_events->pmu_lock held */
__cci_pmu_enable_sync(struct cci_pmu * cci_pmu)678*4882a593Smuzhiyun static void __cci_pmu_enable_sync(struct cci_pmu *cci_pmu)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun 	cci_pmu_sync_counters(cci_pmu);
681*4882a593Smuzhiyun 	__cci_pmu_enable_nosync(cci_pmu);
682*4882a593Smuzhiyun }
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun /* Should be called with cci_pmu->hw_events->pmu_lock held */
__cci_pmu_disable(struct cci_pmu * cci_pmu)685*4882a593Smuzhiyun static void __cci_pmu_disable(struct cci_pmu *cci_pmu)
686*4882a593Smuzhiyun {
687*4882a593Smuzhiyun 	u32 val;
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	/* Disable all the PMU counters. */
690*4882a593Smuzhiyun 	val = readl_relaxed(cci_pmu->ctrl_base + CCI_PMCR) & ~CCI_PMCR_CEN;
691*4882a593Smuzhiyun 	writel(val, cci_pmu->ctrl_base + CCI_PMCR);
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun 
cci_pmu_format_show(struct device * dev,struct device_attribute * attr,char * buf)694*4882a593Smuzhiyun static ssize_t cci_pmu_format_show(struct device *dev,
695*4882a593Smuzhiyun 			struct device_attribute *attr, char *buf)
696*4882a593Smuzhiyun {
697*4882a593Smuzhiyun 	struct dev_ext_attribute *eattr = container_of(attr,
698*4882a593Smuzhiyun 				struct dev_ext_attribute, attr);
699*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "%s\n", (char *)eattr->var);
700*4882a593Smuzhiyun }
701*4882a593Smuzhiyun 
cci_pmu_event_show(struct device * dev,struct device_attribute * attr,char * buf)702*4882a593Smuzhiyun static ssize_t cci_pmu_event_show(struct device *dev,
703*4882a593Smuzhiyun 			struct device_attribute *attr, char *buf)
704*4882a593Smuzhiyun {
705*4882a593Smuzhiyun 	struct dev_ext_attribute *eattr = container_of(attr,
706*4882a593Smuzhiyun 				struct dev_ext_attribute, attr);
707*4882a593Smuzhiyun 	/* source parameter is mandatory for normal PMU events */
708*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "source=?,event=0x%lx\n",
709*4882a593Smuzhiyun 					 (unsigned long)eattr->var);
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun 
pmu_is_valid_counter(struct cci_pmu * cci_pmu,int idx)712*4882a593Smuzhiyun static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx)
713*4882a593Smuzhiyun {
714*4882a593Smuzhiyun 	return 0 <= idx && idx <= CCI_PMU_CNTR_LAST(cci_pmu);
715*4882a593Smuzhiyun }
716*4882a593Smuzhiyun 
pmu_read_register(struct cci_pmu * cci_pmu,int idx,unsigned int offset)717*4882a593Smuzhiyun static u32 pmu_read_register(struct cci_pmu *cci_pmu, int idx, unsigned int offset)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun 	return readl_relaxed(cci_pmu->base +
720*4882a593Smuzhiyun 			     CCI_PMU_CNTR_BASE(cci_pmu->model, idx) + offset);
721*4882a593Smuzhiyun }
722*4882a593Smuzhiyun 
pmu_write_register(struct cci_pmu * cci_pmu,u32 value,int idx,unsigned int offset)723*4882a593Smuzhiyun static void pmu_write_register(struct cci_pmu *cci_pmu, u32 value,
724*4882a593Smuzhiyun 			       int idx, unsigned int offset)
725*4882a593Smuzhiyun {
726*4882a593Smuzhiyun 	writel_relaxed(value, cci_pmu->base +
727*4882a593Smuzhiyun 		       CCI_PMU_CNTR_BASE(cci_pmu->model, idx) + offset);
728*4882a593Smuzhiyun }
729*4882a593Smuzhiyun 
pmu_disable_counter(struct cci_pmu * cci_pmu,int idx)730*4882a593Smuzhiyun static void pmu_disable_counter(struct cci_pmu *cci_pmu, int idx)
731*4882a593Smuzhiyun {
732*4882a593Smuzhiyun 	pmu_write_register(cci_pmu, 0, idx, CCI_PMU_CNTR_CTRL);
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun 
pmu_enable_counter(struct cci_pmu * cci_pmu,int idx)735*4882a593Smuzhiyun static void pmu_enable_counter(struct cci_pmu *cci_pmu, int idx)
736*4882a593Smuzhiyun {
737*4882a593Smuzhiyun 	pmu_write_register(cci_pmu, 1, idx, CCI_PMU_CNTR_CTRL);
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun static bool __maybe_unused
pmu_counter_is_enabled(struct cci_pmu * cci_pmu,int idx)741*4882a593Smuzhiyun pmu_counter_is_enabled(struct cci_pmu *cci_pmu, int idx)
742*4882a593Smuzhiyun {
743*4882a593Smuzhiyun 	return (pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR_CTRL) & 0x1) != 0;
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun 
pmu_set_event(struct cci_pmu * cci_pmu,int idx,unsigned long event)746*4882a593Smuzhiyun static void pmu_set_event(struct cci_pmu *cci_pmu, int idx, unsigned long event)
747*4882a593Smuzhiyun {
748*4882a593Smuzhiyun 	pmu_write_register(cci_pmu, event, idx, CCI_PMU_EVT_SEL);
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun /*
752*4882a593Smuzhiyun  * For all counters on the CCI-PMU, disable any 'enabled' counters,
753*4882a593Smuzhiyun  * saving the changed counters in the mask, so that we can restore
754*4882a593Smuzhiyun  * it later using pmu_restore_counters. The mask is private to the
755*4882a593Smuzhiyun  * caller. We cannot rely on the used_mask maintained by the CCI_PMU
756*4882a593Smuzhiyun  * as it only tells us if the counter is assigned to perf_event or not.
757*4882a593Smuzhiyun  * The state of the perf_event cannot be locked by the PMU layer, hence
758*4882a593Smuzhiyun  * we check the individual counter status (which can be locked by
759*4882a593Smuzhiyun  * cci_pm->hw_events->pmu_lock).
760*4882a593Smuzhiyun  *
761*4882a593Smuzhiyun  * @mask should be initialised to empty by the caller.
762*4882a593Smuzhiyun  */
763*4882a593Smuzhiyun static void __maybe_unused
pmu_save_counters(struct cci_pmu * cci_pmu,unsigned long * mask)764*4882a593Smuzhiyun pmu_save_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
765*4882a593Smuzhiyun {
766*4882a593Smuzhiyun 	int i;
767*4882a593Smuzhiyun 
768*4882a593Smuzhiyun 	for (i = 0; i < cci_pmu->num_cntrs; i++) {
769*4882a593Smuzhiyun 		if (pmu_counter_is_enabled(cci_pmu, i)) {
770*4882a593Smuzhiyun 			set_bit(i, mask);
771*4882a593Smuzhiyun 			pmu_disable_counter(cci_pmu, i);
772*4882a593Smuzhiyun 		}
773*4882a593Smuzhiyun 	}
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun 
776*4882a593Smuzhiyun /*
777*4882a593Smuzhiyun  * Restore the status of the counters. Reversal of the pmu_save_counters().
778*4882a593Smuzhiyun  * For each counter set in the mask, enable the counter back.
779*4882a593Smuzhiyun  */
780*4882a593Smuzhiyun static void __maybe_unused
pmu_restore_counters(struct cci_pmu * cci_pmu,unsigned long * mask)781*4882a593Smuzhiyun pmu_restore_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
782*4882a593Smuzhiyun {
783*4882a593Smuzhiyun 	int i;
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	for_each_set_bit(i, mask, cci_pmu->num_cntrs)
786*4882a593Smuzhiyun 		pmu_enable_counter(cci_pmu, i);
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun /*
790*4882a593Smuzhiyun  * Returns the number of programmable counters actually implemented
791*4882a593Smuzhiyun  * by the cci
792*4882a593Smuzhiyun  */
pmu_get_max_counters(struct cci_pmu * cci_pmu)793*4882a593Smuzhiyun static u32 pmu_get_max_counters(struct cci_pmu *cci_pmu)
794*4882a593Smuzhiyun {
795*4882a593Smuzhiyun 	return (readl_relaxed(cci_pmu->ctrl_base + CCI_PMCR) &
796*4882a593Smuzhiyun 		CCI_PMCR_NCNT_MASK) >> CCI_PMCR_NCNT_SHIFT;
797*4882a593Smuzhiyun }
798*4882a593Smuzhiyun 
pmu_get_event_idx(struct cci_pmu_hw_events * hw,struct perf_event * event)799*4882a593Smuzhiyun static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, struct perf_event *event)
800*4882a593Smuzhiyun {
801*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
802*4882a593Smuzhiyun 	unsigned long cci_event = event->hw.config_base;
803*4882a593Smuzhiyun 	int idx;
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	if (cci_pmu->model->get_event_idx)
806*4882a593Smuzhiyun 		return cci_pmu->model->get_event_idx(cci_pmu, hw, cci_event);
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun 	/* Generic code to find an unused idx from the mask */
809*4882a593Smuzhiyun 	for(idx = 0; idx <= CCI_PMU_CNTR_LAST(cci_pmu); idx++)
810*4882a593Smuzhiyun 		if (!test_and_set_bit(idx, hw->used_mask))
811*4882a593Smuzhiyun 			return idx;
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun 	/* No counters available */
814*4882a593Smuzhiyun 	return -EAGAIN;
815*4882a593Smuzhiyun }
816*4882a593Smuzhiyun 
pmu_map_event(struct perf_event * event)817*4882a593Smuzhiyun static int pmu_map_event(struct perf_event *event)
818*4882a593Smuzhiyun {
819*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 	if (event->attr.type < PERF_TYPE_MAX ||
822*4882a593Smuzhiyun 			!cci_pmu->model->validate_hw_event)
823*4882a593Smuzhiyun 		return -ENOENT;
824*4882a593Smuzhiyun 
825*4882a593Smuzhiyun 	return	cci_pmu->model->validate_hw_event(cci_pmu, event->attr.config);
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun 
pmu_request_irq(struct cci_pmu * cci_pmu,irq_handler_t handler)828*4882a593Smuzhiyun static int pmu_request_irq(struct cci_pmu *cci_pmu, irq_handler_t handler)
829*4882a593Smuzhiyun {
830*4882a593Smuzhiyun 	int i;
831*4882a593Smuzhiyun 	struct platform_device *pmu_device = cci_pmu->plat_device;
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 	if (unlikely(!pmu_device))
834*4882a593Smuzhiyun 		return -ENODEV;
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	if (cci_pmu->nr_irqs < 1) {
837*4882a593Smuzhiyun 		dev_err(&pmu_device->dev, "no irqs for CCI PMUs defined\n");
838*4882a593Smuzhiyun 		return -ENODEV;
839*4882a593Smuzhiyun 	}
840*4882a593Smuzhiyun 
841*4882a593Smuzhiyun 	/*
842*4882a593Smuzhiyun 	 * Register all available CCI PMU interrupts. In the interrupt handler
843*4882a593Smuzhiyun 	 * we iterate over the counters checking for interrupt source (the
844*4882a593Smuzhiyun 	 * overflowing counter) and clear it.
845*4882a593Smuzhiyun 	 *
846*4882a593Smuzhiyun 	 * This should allow handling of non-unique interrupt for the counters.
847*4882a593Smuzhiyun 	 */
848*4882a593Smuzhiyun 	for (i = 0; i < cci_pmu->nr_irqs; i++) {
849*4882a593Smuzhiyun 		int err = request_irq(cci_pmu->irqs[i], handler, IRQF_SHARED,
850*4882a593Smuzhiyun 				"arm-cci-pmu", cci_pmu);
851*4882a593Smuzhiyun 		if (err) {
852*4882a593Smuzhiyun 			dev_err(&pmu_device->dev, "unable to request IRQ%d for ARM CCI PMU counters\n",
853*4882a593Smuzhiyun 				cci_pmu->irqs[i]);
854*4882a593Smuzhiyun 			return err;
855*4882a593Smuzhiyun 		}
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun 		set_bit(i, &cci_pmu->active_irqs);
858*4882a593Smuzhiyun 	}
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun 	return 0;
861*4882a593Smuzhiyun }
862*4882a593Smuzhiyun 
pmu_free_irq(struct cci_pmu * cci_pmu)863*4882a593Smuzhiyun static void pmu_free_irq(struct cci_pmu *cci_pmu)
864*4882a593Smuzhiyun {
865*4882a593Smuzhiyun 	int i;
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 	for (i = 0; i < cci_pmu->nr_irqs; i++) {
868*4882a593Smuzhiyun 		if (!test_and_clear_bit(i, &cci_pmu->active_irqs))
869*4882a593Smuzhiyun 			continue;
870*4882a593Smuzhiyun 
871*4882a593Smuzhiyun 		free_irq(cci_pmu->irqs[i], cci_pmu);
872*4882a593Smuzhiyun 	}
873*4882a593Smuzhiyun }
874*4882a593Smuzhiyun 
pmu_read_counter(struct perf_event * event)875*4882a593Smuzhiyun static u32 pmu_read_counter(struct perf_event *event)
876*4882a593Smuzhiyun {
877*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
878*4882a593Smuzhiyun 	struct hw_perf_event *hw_counter = &event->hw;
879*4882a593Smuzhiyun 	int idx = hw_counter->idx;
880*4882a593Smuzhiyun 	u32 value;
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 	if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
883*4882a593Smuzhiyun 		dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
884*4882a593Smuzhiyun 		return 0;
885*4882a593Smuzhiyun 	}
886*4882a593Smuzhiyun 	value = pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR);
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 	return value;
889*4882a593Smuzhiyun }
890*4882a593Smuzhiyun 
pmu_write_counter(struct cci_pmu * cci_pmu,u32 value,int idx)891*4882a593Smuzhiyun static void pmu_write_counter(struct cci_pmu *cci_pmu, u32 value, int idx)
892*4882a593Smuzhiyun {
893*4882a593Smuzhiyun 	pmu_write_register(cci_pmu, value, idx, CCI_PMU_CNTR);
894*4882a593Smuzhiyun }
895*4882a593Smuzhiyun 
__pmu_write_counters(struct cci_pmu * cci_pmu,unsigned long * mask)896*4882a593Smuzhiyun static void __pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
897*4882a593Smuzhiyun {
898*4882a593Smuzhiyun 	int i;
899*4882a593Smuzhiyun 	struct cci_pmu_hw_events *cci_hw = &cci_pmu->hw_events;
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun 	for_each_set_bit(i, mask, cci_pmu->num_cntrs) {
902*4882a593Smuzhiyun 		struct perf_event *event = cci_hw->events[i];
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 		if (WARN_ON(!event))
905*4882a593Smuzhiyun 			continue;
906*4882a593Smuzhiyun 		pmu_write_counter(cci_pmu, local64_read(&event->hw.prev_count), i);
907*4882a593Smuzhiyun 	}
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun 
pmu_write_counters(struct cci_pmu * cci_pmu,unsigned long * mask)910*4882a593Smuzhiyun static void pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
911*4882a593Smuzhiyun {
912*4882a593Smuzhiyun 	if (cci_pmu->model->write_counters)
913*4882a593Smuzhiyun 		cci_pmu->model->write_counters(cci_pmu, mask);
914*4882a593Smuzhiyun 	else
915*4882a593Smuzhiyun 		__pmu_write_counters(cci_pmu, mask);
916*4882a593Smuzhiyun }
917*4882a593Smuzhiyun 
918*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI5xx_PMU
919*4882a593Smuzhiyun 
920*4882a593Smuzhiyun /*
921*4882a593Smuzhiyun  * CCI-500/CCI-550 has advanced power saving policies, which could gate the
922*4882a593Smuzhiyun  * clocks to the PMU counters, which makes the writes to them ineffective.
923*4882a593Smuzhiyun  * The only way to write to those counters is when the global counters
924*4882a593Smuzhiyun  * are enabled and the particular counter is enabled.
925*4882a593Smuzhiyun  *
926*4882a593Smuzhiyun  * So we do the following :
927*4882a593Smuzhiyun  *
928*4882a593Smuzhiyun  * 1) Disable all the PMU counters, saving their current state
929*4882a593Smuzhiyun  * 2) Enable the global PMU profiling, now that all counters are
930*4882a593Smuzhiyun  *    disabled.
931*4882a593Smuzhiyun  *
932*4882a593Smuzhiyun  * For each counter to be programmed, repeat steps 3-7:
933*4882a593Smuzhiyun  *
934*4882a593Smuzhiyun  * 3) Write an invalid event code to the event control register for the
935*4882a593Smuzhiyun       counter, so that the counters are not modified.
936*4882a593Smuzhiyun  * 4) Enable the counter control for the counter.
937*4882a593Smuzhiyun  * 5) Set the counter value
938*4882a593Smuzhiyun  * 6) Disable the counter
939*4882a593Smuzhiyun  * 7) Restore the event in the target counter
940*4882a593Smuzhiyun  *
941*4882a593Smuzhiyun  * 8) Disable the global PMU.
942*4882a593Smuzhiyun  * 9) Restore the status of the rest of the counters.
943*4882a593Smuzhiyun  *
944*4882a593Smuzhiyun  * We choose an event which for CCI-5xx is guaranteed not to count.
945*4882a593Smuzhiyun  * We use the highest possible event code (0x1f) for the master interface 0.
946*4882a593Smuzhiyun  */
947*4882a593Smuzhiyun #define CCI5xx_INVALID_EVENT	((CCI5xx_PORT_M0 << CCI5xx_PMU_EVENT_SOURCE_SHIFT) | \
948*4882a593Smuzhiyun 				 (CCI5xx_PMU_EVENT_CODE_MASK << CCI5xx_PMU_EVENT_CODE_SHIFT))
cci5xx_pmu_write_counters(struct cci_pmu * cci_pmu,unsigned long * mask)949*4882a593Smuzhiyun static void cci5xx_pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
950*4882a593Smuzhiyun {
951*4882a593Smuzhiyun 	int i;
952*4882a593Smuzhiyun 	DECLARE_BITMAP(saved_mask, HW_CNTRS_MAX);
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun 	bitmap_zero(saved_mask, cci_pmu->num_cntrs);
955*4882a593Smuzhiyun 	pmu_save_counters(cci_pmu, saved_mask);
956*4882a593Smuzhiyun 
957*4882a593Smuzhiyun 	/*
958*4882a593Smuzhiyun 	 * Now that all the counters are disabled, we can safely turn the PMU on,
959*4882a593Smuzhiyun 	 * without syncing the status of the counters
960*4882a593Smuzhiyun 	 */
961*4882a593Smuzhiyun 	__cci_pmu_enable_nosync(cci_pmu);
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun 	for_each_set_bit(i, mask, cci_pmu->num_cntrs) {
964*4882a593Smuzhiyun 		struct perf_event *event = cci_pmu->hw_events.events[i];
965*4882a593Smuzhiyun 
966*4882a593Smuzhiyun 		if (WARN_ON(!event))
967*4882a593Smuzhiyun 			continue;
968*4882a593Smuzhiyun 
969*4882a593Smuzhiyun 		pmu_set_event(cci_pmu, i, CCI5xx_INVALID_EVENT);
970*4882a593Smuzhiyun 		pmu_enable_counter(cci_pmu, i);
971*4882a593Smuzhiyun 		pmu_write_counter(cci_pmu, local64_read(&event->hw.prev_count), i);
972*4882a593Smuzhiyun 		pmu_disable_counter(cci_pmu, i);
973*4882a593Smuzhiyun 		pmu_set_event(cci_pmu, i, event->hw.config_base);
974*4882a593Smuzhiyun 	}
975*4882a593Smuzhiyun 
976*4882a593Smuzhiyun 	__cci_pmu_disable(cci_pmu);
977*4882a593Smuzhiyun 
978*4882a593Smuzhiyun 	pmu_restore_counters(cci_pmu, saved_mask);
979*4882a593Smuzhiyun }
980*4882a593Smuzhiyun 
981*4882a593Smuzhiyun #endif	/* CONFIG_ARM_CCI5xx_PMU */
982*4882a593Smuzhiyun 
pmu_event_update(struct perf_event * event)983*4882a593Smuzhiyun static u64 pmu_event_update(struct perf_event *event)
984*4882a593Smuzhiyun {
985*4882a593Smuzhiyun 	struct hw_perf_event *hwc = &event->hw;
986*4882a593Smuzhiyun 	u64 delta, prev_raw_count, new_raw_count;
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun 	do {
989*4882a593Smuzhiyun 		prev_raw_count = local64_read(&hwc->prev_count);
990*4882a593Smuzhiyun 		new_raw_count = pmu_read_counter(event);
991*4882a593Smuzhiyun 	} while (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
992*4882a593Smuzhiyun 		 new_raw_count) != prev_raw_count);
993*4882a593Smuzhiyun 
994*4882a593Smuzhiyun 	delta = (new_raw_count - prev_raw_count) & CCI_PMU_CNTR_MASK;
995*4882a593Smuzhiyun 
996*4882a593Smuzhiyun 	local64_add(delta, &event->count);
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun 	return new_raw_count;
999*4882a593Smuzhiyun }
1000*4882a593Smuzhiyun 
pmu_read(struct perf_event * event)1001*4882a593Smuzhiyun static void pmu_read(struct perf_event *event)
1002*4882a593Smuzhiyun {
1003*4882a593Smuzhiyun 	pmu_event_update(event);
1004*4882a593Smuzhiyun }
1005*4882a593Smuzhiyun 
pmu_event_set_period(struct perf_event * event)1006*4882a593Smuzhiyun static void pmu_event_set_period(struct perf_event *event)
1007*4882a593Smuzhiyun {
1008*4882a593Smuzhiyun 	struct hw_perf_event *hwc = &event->hw;
1009*4882a593Smuzhiyun 	/*
1010*4882a593Smuzhiyun 	 * The CCI PMU counters have a period of 2^32. To account for the
1011*4882a593Smuzhiyun 	 * possiblity of extreme interrupt latency we program for a period of
1012*4882a593Smuzhiyun 	 * half that. Hopefully we can handle the interrupt before another 2^31
1013*4882a593Smuzhiyun 	 * events occur and the counter overtakes its previous value.
1014*4882a593Smuzhiyun 	 */
1015*4882a593Smuzhiyun 	u64 val = 1ULL << 31;
1016*4882a593Smuzhiyun 	local64_set(&hwc->prev_count, val);
1017*4882a593Smuzhiyun 
1018*4882a593Smuzhiyun 	/*
1019*4882a593Smuzhiyun 	 * CCI PMU uses PERF_HES_ARCH to keep track of the counters, whose
1020*4882a593Smuzhiyun 	 * values needs to be sync-ed with the s/w state before the PMU is
1021*4882a593Smuzhiyun 	 * enabled.
1022*4882a593Smuzhiyun 	 * Mark this counter for sync.
1023*4882a593Smuzhiyun 	 */
1024*4882a593Smuzhiyun 	hwc->state |= PERF_HES_ARCH;
1025*4882a593Smuzhiyun }
1026*4882a593Smuzhiyun 
pmu_handle_irq(int irq_num,void * dev)1027*4882a593Smuzhiyun static irqreturn_t pmu_handle_irq(int irq_num, void *dev)
1028*4882a593Smuzhiyun {
1029*4882a593Smuzhiyun 	unsigned long flags;
1030*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = dev;
1031*4882a593Smuzhiyun 	struct cci_pmu_hw_events *events = &cci_pmu->hw_events;
1032*4882a593Smuzhiyun 	int idx, handled = IRQ_NONE;
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
1035*4882a593Smuzhiyun 
1036*4882a593Smuzhiyun 	/* Disable the PMU while we walk through the counters */
1037*4882a593Smuzhiyun 	__cci_pmu_disable(cci_pmu);
1038*4882a593Smuzhiyun 	/*
1039*4882a593Smuzhiyun 	 * Iterate over counters and update the corresponding perf events.
1040*4882a593Smuzhiyun 	 * This should work regardless of whether we have per-counter overflow
1041*4882a593Smuzhiyun 	 * interrupt or a combined overflow interrupt.
1042*4882a593Smuzhiyun 	 */
1043*4882a593Smuzhiyun 	for (idx = 0; idx <= CCI_PMU_CNTR_LAST(cci_pmu); idx++) {
1044*4882a593Smuzhiyun 		struct perf_event *event = events->events[idx];
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 		if (!event)
1047*4882a593Smuzhiyun 			continue;
1048*4882a593Smuzhiyun 
1049*4882a593Smuzhiyun 		/* Did this counter overflow? */
1050*4882a593Smuzhiyun 		if (!(pmu_read_register(cci_pmu, idx, CCI_PMU_OVRFLW) &
1051*4882a593Smuzhiyun 		      CCI_PMU_OVRFLW_FLAG))
1052*4882a593Smuzhiyun 			continue;
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun 		pmu_write_register(cci_pmu, CCI_PMU_OVRFLW_FLAG, idx,
1055*4882a593Smuzhiyun 							CCI_PMU_OVRFLW);
1056*4882a593Smuzhiyun 
1057*4882a593Smuzhiyun 		pmu_event_update(event);
1058*4882a593Smuzhiyun 		pmu_event_set_period(event);
1059*4882a593Smuzhiyun 		handled = IRQ_HANDLED;
1060*4882a593Smuzhiyun 	}
1061*4882a593Smuzhiyun 
1062*4882a593Smuzhiyun 	/* Enable the PMU and sync possibly overflowed counters */
1063*4882a593Smuzhiyun 	__cci_pmu_enable_sync(cci_pmu);
1064*4882a593Smuzhiyun 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1065*4882a593Smuzhiyun 
1066*4882a593Smuzhiyun 	return IRQ_RETVAL(handled);
1067*4882a593Smuzhiyun }
1068*4882a593Smuzhiyun 
cci_pmu_get_hw(struct cci_pmu * cci_pmu)1069*4882a593Smuzhiyun static int cci_pmu_get_hw(struct cci_pmu *cci_pmu)
1070*4882a593Smuzhiyun {
1071*4882a593Smuzhiyun 	int ret = pmu_request_irq(cci_pmu, pmu_handle_irq);
1072*4882a593Smuzhiyun 	if (ret) {
1073*4882a593Smuzhiyun 		pmu_free_irq(cci_pmu);
1074*4882a593Smuzhiyun 		return ret;
1075*4882a593Smuzhiyun 	}
1076*4882a593Smuzhiyun 	return 0;
1077*4882a593Smuzhiyun }
1078*4882a593Smuzhiyun 
cci_pmu_put_hw(struct cci_pmu * cci_pmu)1079*4882a593Smuzhiyun static void cci_pmu_put_hw(struct cci_pmu *cci_pmu)
1080*4882a593Smuzhiyun {
1081*4882a593Smuzhiyun 	pmu_free_irq(cci_pmu);
1082*4882a593Smuzhiyun }
1083*4882a593Smuzhiyun 
hw_perf_event_destroy(struct perf_event * event)1084*4882a593Smuzhiyun static void hw_perf_event_destroy(struct perf_event *event)
1085*4882a593Smuzhiyun {
1086*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
1087*4882a593Smuzhiyun 	atomic_t *active_events = &cci_pmu->active_events;
1088*4882a593Smuzhiyun 	struct mutex *reserve_mutex = &cci_pmu->reserve_mutex;
1089*4882a593Smuzhiyun 
1090*4882a593Smuzhiyun 	if (atomic_dec_and_mutex_lock(active_events, reserve_mutex)) {
1091*4882a593Smuzhiyun 		cci_pmu_put_hw(cci_pmu);
1092*4882a593Smuzhiyun 		mutex_unlock(reserve_mutex);
1093*4882a593Smuzhiyun 	}
1094*4882a593Smuzhiyun }
1095*4882a593Smuzhiyun 
cci_pmu_enable(struct pmu * pmu)1096*4882a593Smuzhiyun static void cci_pmu_enable(struct pmu *pmu)
1097*4882a593Smuzhiyun {
1098*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
1099*4882a593Smuzhiyun 	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
1100*4882a593Smuzhiyun 	int enabled = bitmap_weight(hw_events->used_mask, cci_pmu->num_cntrs);
1101*4882a593Smuzhiyun 	unsigned long flags;
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun 	if (!enabled)
1104*4882a593Smuzhiyun 		return;
1105*4882a593Smuzhiyun 
1106*4882a593Smuzhiyun 	raw_spin_lock_irqsave(&hw_events->pmu_lock, flags);
1107*4882a593Smuzhiyun 	__cci_pmu_enable_sync(cci_pmu);
1108*4882a593Smuzhiyun 	raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags);
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun }
1111*4882a593Smuzhiyun 
cci_pmu_disable(struct pmu * pmu)1112*4882a593Smuzhiyun static void cci_pmu_disable(struct pmu *pmu)
1113*4882a593Smuzhiyun {
1114*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
1115*4882a593Smuzhiyun 	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
1116*4882a593Smuzhiyun 	unsigned long flags;
1117*4882a593Smuzhiyun 
1118*4882a593Smuzhiyun 	raw_spin_lock_irqsave(&hw_events->pmu_lock, flags);
1119*4882a593Smuzhiyun 	__cci_pmu_disable(cci_pmu);
1120*4882a593Smuzhiyun 	raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags);
1121*4882a593Smuzhiyun }
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun /*
1124*4882a593Smuzhiyun  * Check if the idx represents a non-programmable counter.
1125*4882a593Smuzhiyun  * All the fixed event counters are mapped before the programmable
1126*4882a593Smuzhiyun  * counters.
1127*4882a593Smuzhiyun  */
pmu_fixed_hw_idx(struct cci_pmu * cci_pmu,int idx)1128*4882a593Smuzhiyun static bool pmu_fixed_hw_idx(struct cci_pmu *cci_pmu, int idx)
1129*4882a593Smuzhiyun {
1130*4882a593Smuzhiyun 	return (idx >= 0) && (idx < cci_pmu->model->fixed_hw_cntrs);
1131*4882a593Smuzhiyun }
1132*4882a593Smuzhiyun 
cci_pmu_start(struct perf_event * event,int pmu_flags)1133*4882a593Smuzhiyun static void cci_pmu_start(struct perf_event *event, int pmu_flags)
1134*4882a593Smuzhiyun {
1135*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
1136*4882a593Smuzhiyun 	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
1137*4882a593Smuzhiyun 	struct hw_perf_event *hwc = &event->hw;
1138*4882a593Smuzhiyun 	int idx = hwc->idx;
1139*4882a593Smuzhiyun 	unsigned long flags;
1140*4882a593Smuzhiyun 
1141*4882a593Smuzhiyun 	/*
1142*4882a593Smuzhiyun 	 * To handle interrupt latency, we always reprogram the period
1143*4882a593Smuzhiyun 	 * regardlesss of PERF_EF_RELOAD.
1144*4882a593Smuzhiyun 	 */
1145*4882a593Smuzhiyun 	if (pmu_flags & PERF_EF_RELOAD)
1146*4882a593Smuzhiyun 		WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
1147*4882a593Smuzhiyun 
1148*4882a593Smuzhiyun 	hwc->state = 0;
1149*4882a593Smuzhiyun 
1150*4882a593Smuzhiyun 	if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
1151*4882a593Smuzhiyun 		dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
1152*4882a593Smuzhiyun 		return;
1153*4882a593Smuzhiyun 	}
1154*4882a593Smuzhiyun 
1155*4882a593Smuzhiyun 	raw_spin_lock_irqsave(&hw_events->pmu_lock, flags);
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 	/* Configure the counter unless you are counting a fixed event */
1158*4882a593Smuzhiyun 	if (!pmu_fixed_hw_idx(cci_pmu, idx))
1159*4882a593Smuzhiyun 		pmu_set_event(cci_pmu, idx, hwc->config_base);
1160*4882a593Smuzhiyun 
1161*4882a593Smuzhiyun 	pmu_event_set_period(event);
1162*4882a593Smuzhiyun 	pmu_enable_counter(cci_pmu, idx);
1163*4882a593Smuzhiyun 
1164*4882a593Smuzhiyun 	raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags);
1165*4882a593Smuzhiyun }
1166*4882a593Smuzhiyun 
cci_pmu_stop(struct perf_event * event,int pmu_flags)1167*4882a593Smuzhiyun static void cci_pmu_stop(struct perf_event *event, int pmu_flags)
1168*4882a593Smuzhiyun {
1169*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
1170*4882a593Smuzhiyun 	struct hw_perf_event *hwc = &event->hw;
1171*4882a593Smuzhiyun 	int idx = hwc->idx;
1172*4882a593Smuzhiyun 
1173*4882a593Smuzhiyun 	if (hwc->state & PERF_HES_STOPPED)
1174*4882a593Smuzhiyun 		return;
1175*4882a593Smuzhiyun 
1176*4882a593Smuzhiyun 	if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
1177*4882a593Smuzhiyun 		dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
1178*4882a593Smuzhiyun 		return;
1179*4882a593Smuzhiyun 	}
1180*4882a593Smuzhiyun 
1181*4882a593Smuzhiyun 	/*
1182*4882a593Smuzhiyun 	 * We always reprogram the counter, so ignore PERF_EF_UPDATE. See
1183*4882a593Smuzhiyun 	 * cci_pmu_start()
1184*4882a593Smuzhiyun 	 */
1185*4882a593Smuzhiyun 	pmu_disable_counter(cci_pmu, idx);
1186*4882a593Smuzhiyun 	pmu_event_update(event);
1187*4882a593Smuzhiyun 	hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
1188*4882a593Smuzhiyun }
1189*4882a593Smuzhiyun 
cci_pmu_add(struct perf_event * event,int flags)1190*4882a593Smuzhiyun static int cci_pmu_add(struct perf_event *event, int flags)
1191*4882a593Smuzhiyun {
1192*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
1193*4882a593Smuzhiyun 	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
1194*4882a593Smuzhiyun 	struct hw_perf_event *hwc = &event->hw;
1195*4882a593Smuzhiyun 	int idx;
1196*4882a593Smuzhiyun 
1197*4882a593Smuzhiyun 	/* If we don't have a space for the counter then finish early. */
1198*4882a593Smuzhiyun 	idx = pmu_get_event_idx(hw_events, event);
1199*4882a593Smuzhiyun 	if (idx < 0)
1200*4882a593Smuzhiyun 		return idx;
1201*4882a593Smuzhiyun 
1202*4882a593Smuzhiyun 	event->hw.idx = idx;
1203*4882a593Smuzhiyun 	hw_events->events[idx] = event;
1204*4882a593Smuzhiyun 
1205*4882a593Smuzhiyun 	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
1206*4882a593Smuzhiyun 	if (flags & PERF_EF_START)
1207*4882a593Smuzhiyun 		cci_pmu_start(event, PERF_EF_RELOAD);
1208*4882a593Smuzhiyun 
1209*4882a593Smuzhiyun 	/* Propagate our changes to the userspace mapping. */
1210*4882a593Smuzhiyun 	perf_event_update_userpage(event);
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun 	return 0;
1213*4882a593Smuzhiyun }
1214*4882a593Smuzhiyun 
cci_pmu_del(struct perf_event * event,int flags)1215*4882a593Smuzhiyun static void cci_pmu_del(struct perf_event *event, int flags)
1216*4882a593Smuzhiyun {
1217*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
1218*4882a593Smuzhiyun 	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
1219*4882a593Smuzhiyun 	struct hw_perf_event *hwc = &event->hw;
1220*4882a593Smuzhiyun 	int idx = hwc->idx;
1221*4882a593Smuzhiyun 
1222*4882a593Smuzhiyun 	cci_pmu_stop(event, PERF_EF_UPDATE);
1223*4882a593Smuzhiyun 	hw_events->events[idx] = NULL;
1224*4882a593Smuzhiyun 	clear_bit(idx, hw_events->used_mask);
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 	perf_event_update_userpage(event);
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun 
validate_event(struct pmu * cci_pmu,struct cci_pmu_hw_events * hw_events,struct perf_event * event)1229*4882a593Smuzhiyun static int validate_event(struct pmu *cci_pmu,
1230*4882a593Smuzhiyun 			  struct cci_pmu_hw_events *hw_events,
1231*4882a593Smuzhiyun 			  struct perf_event *event)
1232*4882a593Smuzhiyun {
1233*4882a593Smuzhiyun 	if (is_software_event(event))
1234*4882a593Smuzhiyun 		return 1;
1235*4882a593Smuzhiyun 
1236*4882a593Smuzhiyun 	/*
1237*4882a593Smuzhiyun 	 * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
1238*4882a593Smuzhiyun 	 * core perf code won't check that the pmu->ctx == leader->ctx
1239*4882a593Smuzhiyun 	 * until after pmu->event_init(event).
1240*4882a593Smuzhiyun 	 */
1241*4882a593Smuzhiyun 	if (event->pmu != cci_pmu)
1242*4882a593Smuzhiyun 		return 0;
1243*4882a593Smuzhiyun 
1244*4882a593Smuzhiyun 	if (event->state < PERF_EVENT_STATE_OFF)
1245*4882a593Smuzhiyun 		return 1;
1246*4882a593Smuzhiyun 
1247*4882a593Smuzhiyun 	if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
1248*4882a593Smuzhiyun 		return 1;
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun 	return pmu_get_event_idx(hw_events, event) >= 0;
1251*4882a593Smuzhiyun }
1252*4882a593Smuzhiyun 
validate_group(struct perf_event * event)1253*4882a593Smuzhiyun static int validate_group(struct perf_event *event)
1254*4882a593Smuzhiyun {
1255*4882a593Smuzhiyun 	struct perf_event *sibling, *leader = event->group_leader;
1256*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
1257*4882a593Smuzhiyun 	unsigned long mask[BITS_TO_LONGS(HW_CNTRS_MAX)];
1258*4882a593Smuzhiyun 	struct cci_pmu_hw_events fake_pmu = {
1259*4882a593Smuzhiyun 		/*
1260*4882a593Smuzhiyun 		 * Initialise the fake PMU. We only need to populate the
1261*4882a593Smuzhiyun 		 * used_mask for the purposes of validation.
1262*4882a593Smuzhiyun 		 */
1263*4882a593Smuzhiyun 		.used_mask = mask,
1264*4882a593Smuzhiyun 	};
1265*4882a593Smuzhiyun 	memset(mask, 0, BITS_TO_LONGS(cci_pmu->num_cntrs) * sizeof(unsigned long));
1266*4882a593Smuzhiyun 
1267*4882a593Smuzhiyun 	if (!validate_event(event->pmu, &fake_pmu, leader))
1268*4882a593Smuzhiyun 		return -EINVAL;
1269*4882a593Smuzhiyun 
1270*4882a593Smuzhiyun 	for_each_sibling_event(sibling, leader) {
1271*4882a593Smuzhiyun 		if (!validate_event(event->pmu, &fake_pmu, sibling))
1272*4882a593Smuzhiyun 			return -EINVAL;
1273*4882a593Smuzhiyun 	}
1274*4882a593Smuzhiyun 
1275*4882a593Smuzhiyun 	if (!validate_event(event->pmu, &fake_pmu, event))
1276*4882a593Smuzhiyun 		return -EINVAL;
1277*4882a593Smuzhiyun 
1278*4882a593Smuzhiyun 	return 0;
1279*4882a593Smuzhiyun }
1280*4882a593Smuzhiyun 
__hw_perf_event_init(struct perf_event * event)1281*4882a593Smuzhiyun static int __hw_perf_event_init(struct perf_event *event)
1282*4882a593Smuzhiyun {
1283*4882a593Smuzhiyun 	struct hw_perf_event *hwc = &event->hw;
1284*4882a593Smuzhiyun 	int mapping;
1285*4882a593Smuzhiyun 
1286*4882a593Smuzhiyun 	mapping = pmu_map_event(event);
1287*4882a593Smuzhiyun 
1288*4882a593Smuzhiyun 	if (mapping < 0) {
1289*4882a593Smuzhiyun 		pr_debug("event %x:%llx not supported\n", event->attr.type,
1290*4882a593Smuzhiyun 			 event->attr.config);
1291*4882a593Smuzhiyun 		return mapping;
1292*4882a593Smuzhiyun 	}
1293*4882a593Smuzhiyun 
1294*4882a593Smuzhiyun 	/*
1295*4882a593Smuzhiyun 	 * We don't assign an index until we actually place the event onto
1296*4882a593Smuzhiyun 	 * hardware. Use -1 to signify that we haven't decided where to put it
1297*4882a593Smuzhiyun 	 * yet.
1298*4882a593Smuzhiyun 	 */
1299*4882a593Smuzhiyun 	hwc->idx		= -1;
1300*4882a593Smuzhiyun 	hwc->config_base	= 0;
1301*4882a593Smuzhiyun 	hwc->config		= 0;
1302*4882a593Smuzhiyun 	hwc->event_base		= 0;
1303*4882a593Smuzhiyun 
1304*4882a593Smuzhiyun 	/*
1305*4882a593Smuzhiyun 	 * Store the event encoding into the config_base field.
1306*4882a593Smuzhiyun 	 */
1307*4882a593Smuzhiyun 	hwc->config_base	    |= (unsigned long)mapping;
1308*4882a593Smuzhiyun 
1309*4882a593Smuzhiyun 	if (event->group_leader != event) {
1310*4882a593Smuzhiyun 		if (validate_group(event) != 0)
1311*4882a593Smuzhiyun 			return -EINVAL;
1312*4882a593Smuzhiyun 	}
1313*4882a593Smuzhiyun 
1314*4882a593Smuzhiyun 	return 0;
1315*4882a593Smuzhiyun }
1316*4882a593Smuzhiyun 
cci_pmu_event_init(struct perf_event * event)1317*4882a593Smuzhiyun static int cci_pmu_event_init(struct perf_event *event)
1318*4882a593Smuzhiyun {
1319*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
1320*4882a593Smuzhiyun 	atomic_t *active_events = &cci_pmu->active_events;
1321*4882a593Smuzhiyun 	int err = 0;
1322*4882a593Smuzhiyun 
1323*4882a593Smuzhiyun 	if (event->attr.type != event->pmu->type)
1324*4882a593Smuzhiyun 		return -ENOENT;
1325*4882a593Smuzhiyun 
1326*4882a593Smuzhiyun 	/* Shared by all CPUs, no meaningful state to sample */
1327*4882a593Smuzhiyun 	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
1328*4882a593Smuzhiyun 		return -EOPNOTSUPP;
1329*4882a593Smuzhiyun 
1330*4882a593Smuzhiyun 	/*
1331*4882a593Smuzhiyun 	 * Following the example set by other "uncore" PMUs, we accept any CPU
1332*4882a593Smuzhiyun 	 * and rewrite its affinity dynamically rather than having perf core
1333*4882a593Smuzhiyun 	 * handle cpu == -1 and pid == -1 for this case.
1334*4882a593Smuzhiyun 	 *
1335*4882a593Smuzhiyun 	 * The perf core will pin online CPUs for the duration of this call and
1336*4882a593Smuzhiyun 	 * the event being installed into its context, so the PMU's CPU can't
1337*4882a593Smuzhiyun 	 * change under our feet.
1338*4882a593Smuzhiyun 	 */
1339*4882a593Smuzhiyun 	if (event->cpu < 0)
1340*4882a593Smuzhiyun 		return -EINVAL;
1341*4882a593Smuzhiyun 	event->cpu = cci_pmu->cpu;
1342*4882a593Smuzhiyun 
1343*4882a593Smuzhiyun 	event->destroy = hw_perf_event_destroy;
1344*4882a593Smuzhiyun 	if (!atomic_inc_not_zero(active_events)) {
1345*4882a593Smuzhiyun 		mutex_lock(&cci_pmu->reserve_mutex);
1346*4882a593Smuzhiyun 		if (atomic_read(active_events) == 0)
1347*4882a593Smuzhiyun 			err = cci_pmu_get_hw(cci_pmu);
1348*4882a593Smuzhiyun 		if (!err)
1349*4882a593Smuzhiyun 			atomic_inc(active_events);
1350*4882a593Smuzhiyun 		mutex_unlock(&cci_pmu->reserve_mutex);
1351*4882a593Smuzhiyun 	}
1352*4882a593Smuzhiyun 	if (err)
1353*4882a593Smuzhiyun 		return err;
1354*4882a593Smuzhiyun 
1355*4882a593Smuzhiyun 	err = __hw_perf_event_init(event);
1356*4882a593Smuzhiyun 	if (err)
1357*4882a593Smuzhiyun 		hw_perf_event_destroy(event);
1358*4882a593Smuzhiyun 
1359*4882a593Smuzhiyun 	return err;
1360*4882a593Smuzhiyun }
1361*4882a593Smuzhiyun 
pmu_cpumask_attr_show(struct device * dev,struct device_attribute * attr,char * buf)1362*4882a593Smuzhiyun static ssize_t pmu_cpumask_attr_show(struct device *dev,
1363*4882a593Smuzhiyun 				     struct device_attribute *attr, char *buf)
1364*4882a593Smuzhiyun {
1365*4882a593Smuzhiyun 	struct pmu *pmu = dev_get_drvdata(dev);
1366*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
1367*4882a593Smuzhiyun 
1368*4882a593Smuzhiyun 	return cpumap_print_to_pagebuf(true, buf, cpumask_of(cci_pmu->cpu));
1369*4882a593Smuzhiyun }
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun static struct device_attribute pmu_cpumask_attr =
1372*4882a593Smuzhiyun 	__ATTR(cpumask, S_IRUGO, pmu_cpumask_attr_show, NULL);
1373*4882a593Smuzhiyun 
1374*4882a593Smuzhiyun static struct attribute *pmu_attrs[] = {
1375*4882a593Smuzhiyun 	&pmu_cpumask_attr.attr,
1376*4882a593Smuzhiyun 	NULL,
1377*4882a593Smuzhiyun };
1378*4882a593Smuzhiyun 
1379*4882a593Smuzhiyun static struct attribute_group pmu_attr_group = {
1380*4882a593Smuzhiyun 	.attrs = pmu_attrs,
1381*4882a593Smuzhiyun };
1382*4882a593Smuzhiyun 
1383*4882a593Smuzhiyun static struct attribute_group pmu_format_attr_group = {
1384*4882a593Smuzhiyun 	.name = "format",
1385*4882a593Smuzhiyun 	.attrs = NULL,		/* Filled in cci_pmu_init_attrs */
1386*4882a593Smuzhiyun };
1387*4882a593Smuzhiyun 
1388*4882a593Smuzhiyun static struct attribute_group pmu_event_attr_group = {
1389*4882a593Smuzhiyun 	.name = "events",
1390*4882a593Smuzhiyun 	.attrs = NULL,		/* Filled in cci_pmu_init_attrs */
1391*4882a593Smuzhiyun };
1392*4882a593Smuzhiyun 
1393*4882a593Smuzhiyun static const struct attribute_group *pmu_attr_groups[] = {
1394*4882a593Smuzhiyun 	&pmu_attr_group,
1395*4882a593Smuzhiyun 	&pmu_format_attr_group,
1396*4882a593Smuzhiyun 	&pmu_event_attr_group,
1397*4882a593Smuzhiyun 	NULL
1398*4882a593Smuzhiyun };
1399*4882a593Smuzhiyun 
cci_pmu_init(struct cci_pmu * cci_pmu,struct platform_device * pdev)1400*4882a593Smuzhiyun static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
1401*4882a593Smuzhiyun {
1402*4882a593Smuzhiyun 	const struct cci_pmu_model *model = cci_pmu->model;
1403*4882a593Smuzhiyun 	char *name = model->name;
1404*4882a593Smuzhiyun 	u32 num_cntrs;
1405*4882a593Smuzhiyun 
1406*4882a593Smuzhiyun 	if (WARN_ON(model->num_hw_cntrs > NUM_HW_CNTRS_MAX))
1407*4882a593Smuzhiyun 		return -EINVAL;
1408*4882a593Smuzhiyun 	if (WARN_ON(model->fixed_hw_cntrs > FIXED_HW_CNTRS_MAX))
1409*4882a593Smuzhiyun 		return -EINVAL;
1410*4882a593Smuzhiyun 
1411*4882a593Smuzhiyun 	pmu_event_attr_group.attrs = model->event_attrs;
1412*4882a593Smuzhiyun 	pmu_format_attr_group.attrs = model->format_attrs;
1413*4882a593Smuzhiyun 
1414*4882a593Smuzhiyun 	cci_pmu->pmu = (struct pmu) {
1415*4882a593Smuzhiyun 		.module		= THIS_MODULE,
1416*4882a593Smuzhiyun 		.name		= cci_pmu->model->name,
1417*4882a593Smuzhiyun 		.task_ctx_nr	= perf_invalid_context,
1418*4882a593Smuzhiyun 		.pmu_enable	= cci_pmu_enable,
1419*4882a593Smuzhiyun 		.pmu_disable	= cci_pmu_disable,
1420*4882a593Smuzhiyun 		.event_init	= cci_pmu_event_init,
1421*4882a593Smuzhiyun 		.add		= cci_pmu_add,
1422*4882a593Smuzhiyun 		.del		= cci_pmu_del,
1423*4882a593Smuzhiyun 		.start		= cci_pmu_start,
1424*4882a593Smuzhiyun 		.stop		= cci_pmu_stop,
1425*4882a593Smuzhiyun 		.read		= pmu_read,
1426*4882a593Smuzhiyun 		.attr_groups	= pmu_attr_groups,
1427*4882a593Smuzhiyun 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
1428*4882a593Smuzhiyun 	};
1429*4882a593Smuzhiyun 
1430*4882a593Smuzhiyun 	cci_pmu->plat_device = pdev;
1431*4882a593Smuzhiyun 	num_cntrs = pmu_get_max_counters(cci_pmu);
1432*4882a593Smuzhiyun 	if (num_cntrs > cci_pmu->model->num_hw_cntrs) {
1433*4882a593Smuzhiyun 		dev_warn(&pdev->dev,
1434*4882a593Smuzhiyun 			"PMU implements more counters(%d) than supported by"
1435*4882a593Smuzhiyun 			" the model(%d), truncated.",
1436*4882a593Smuzhiyun 			num_cntrs, cci_pmu->model->num_hw_cntrs);
1437*4882a593Smuzhiyun 		num_cntrs = cci_pmu->model->num_hw_cntrs;
1438*4882a593Smuzhiyun 	}
1439*4882a593Smuzhiyun 	cci_pmu->num_cntrs = num_cntrs + cci_pmu->model->fixed_hw_cntrs;
1440*4882a593Smuzhiyun 
1441*4882a593Smuzhiyun 	return perf_pmu_register(&cci_pmu->pmu, name, -1);
1442*4882a593Smuzhiyun }
1443*4882a593Smuzhiyun 
cci_pmu_offline_cpu(unsigned int cpu)1444*4882a593Smuzhiyun static int cci_pmu_offline_cpu(unsigned int cpu)
1445*4882a593Smuzhiyun {
1446*4882a593Smuzhiyun 	int target;
1447*4882a593Smuzhiyun 
1448*4882a593Smuzhiyun 	if (!g_cci_pmu || cpu != g_cci_pmu->cpu)
1449*4882a593Smuzhiyun 		return 0;
1450*4882a593Smuzhiyun 
1451*4882a593Smuzhiyun 	target = cpumask_any_but(cpu_online_mask, cpu);
1452*4882a593Smuzhiyun 	if (target >= nr_cpu_ids)
1453*4882a593Smuzhiyun 		return 0;
1454*4882a593Smuzhiyun 
1455*4882a593Smuzhiyun 	perf_pmu_migrate_context(&g_cci_pmu->pmu, cpu, target);
1456*4882a593Smuzhiyun 	g_cci_pmu->cpu = target;
1457*4882a593Smuzhiyun 	return 0;
1458*4882a593Smuzhiyun }
1459*4882a593Smuzhiyun 
1460*4882a593Smuzhiyun static __maybe_unused struct cci_pmu_model cci_pmu_models[] = {
1461*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI400_PMU
1462*4882a593Smuzhiyun 	[CCI400_R0] = {
1463*4882a593Smuzhiyun 		.name = "CCI_400",
1464*4882a593Smuzhiyun 		.fixed_hw_cntrs = FIXED_HW_CNTRS_CII_4XX, /* Cycle counter */
1465*4882a593Smuzhiyun 		.num_hw_cntrs = NUM_HW_CNTRS_CII_4XX,
1466*4882a593Smuzhiyun 		.cntr_size = SZ_4K,
1467*4882a593Smuzhiyun 		.format_attrs = cci400_pmu_format_attrs,
1468*4882a593Smuzhiyun 		.event_attrs = cci400_r0_pmu_event_attrs,
1469*4882a593Smuzhiyun 		.event_ranges = {
1470*4882a593Smuzhiyun 			[CCI_IF_SLAVE] = {
1471*4882a593Smuzhiyun 				CCI400_R0_SLAVE_PORT_MIN_EV,
1472*4882a593Smuzhiyun 				CCI400_R0_SLAVE_PORT_MAX_EV,
1473*4882a593Smuzhiyun 			},
1474*4882a593Smuzhiyun 			[CCI_IF_MASTER] = {
1475*4882a593Smuzhiyun 				CCI400_R0_MASTER_PORT_MIN_EV,
1476*4882a593Smuzhiyun 				CCI400_R0_MASTER_PORT_MAX_EV,
1477*4882a593Smuzhiyun 			},
1478*4882a593Smuzhiyun 		},
1479*4882a593Smuzhiyun 		.validate_hw_event = cci400_validate_hw_event,
1480*4882a593Smuzhiyun 		.get_event_idx = cci400_get_event_idx,
1481*4882a593Smuzhiyun 	},
1482*4882a593Smuzhiyun 	[CCI400_R1] = {
1483*4882a593Smuzhiyun 		.name = "CCI_400_r1",
1484*4882a593Smuzhiyun 		.fixed_hw_cntrs = FIXED_HW_CNTRS_CII_4XX, /* Cycle counter */
1485*4882a593Smuzhiyun 		.num_hw_cntrs = NUM_HW_CNTRS_CII_4XX,
1486*4882a593Smuzhiyun 		.cntr_size = SZ_4K,
1487*4882a593Smuzhiyun 		.format_attrs = cci400_pmu_format_attrs,
1488*4882a593Smuzhiyun 		.event_attrs = cci400_r1_pmu_event_attrs,
1489*4882a593Smuzhiyun 		.event_ranges = {
1490*4882a593Smuzhiyun 			[CCI_IF_SLAVE] = {
1491*4882a593Smuzhiyun 				CCI400_R1_SLAVE_PORT_MIN_EV,
1492*4882a593Smuzhiyun 				CCI400_R1_SLAVE_PORT_MAX_EV,
1493*4882a593Smuzhiyun 			},
1494*4882a593Smuzhiyun 			[CCI_IF_MASTER] = {
1495*4882a593Smuzhiyun 				CCI400_R1_MASTER_PORT_MIN_EV,
1496*4882a593Smuzhiyun 				CCI400_R1_MASTER_PORT_MAX_EV,
1497*4882a593Smuzhiyun 			},
1498*4882a593Smuzhiyun 		},
1499*4882a593Smuzhiyun 		.validate_hw_event = cci400_validate_hw_event,
1500*4882a593Smuzhiyun 		.get_event_idx = cci400_get_event_idx,
1501*4882a593Smuzhiyun 	},
1502*4882a593Smuzhiyun #endif
1503*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI5xx_PMU
1504*4882a593Smuzhiyun 	[CCI500_R0] = {
1505*4882a593Smuzhiyun 		.name = "CCI_500",
1506*4882a593Smuzhiyun 		.fixed_hw_cntrs = FIXED_HW_CNTRS_CII_5XX,
1507*4882a593Smuzhiyun 		.num_hw_cntrs = NUM_HW_CNTRS_CII_5XX,
1508*4882a593Smuzhiyun 		.cntr_size = SZ_64K,
1509*4882a593Smuzhiyun 		.format_attrs = cci5xx_pmu_format_attrs,
1510*4882a593Smuzhiyun 		.event_attrs = cci5xx_pmu_event_attrs,
1511*4882a593Smuzhiyun 		.event_ranges = {
1512*4882a593Smuzhiyun 			[CCI_IF_SLAVE] = {
1513*4882a593Smuzhiyun 				CCI5xx_SLAVE_PORT_MIN_EV,
1514*4882a593Smuzhiyun 				CCI5xx_SLAVE_PORT_MAX_EV,
1515*4882a593Smuzhiyun 			},
1516*4882a593Smuzhiyun 			[CCI_IF_MASTER] = {
1517*4882a593Smuzhiyun 				CCI5xx_MASTER_PORT_MIN_EV,
1518*4882a593Smuzhiyun 				CCI5xx_MASTER_PORT_MAX_EV,
1519*4882a593Smuzhiyun 			},
1520*4882a593Smuzhiyun 			[CCI_IF_GLOBAL] = {
1521*4882a593Smuzhiyun 				CCI5xx_GLOBAL_PORT_MIN_EV,
1522*4882a593Smuzhiyun 				CCI5xx_GLOBAL_PORT_MAX_EV,
1523*4882a593Smuzhiyun 			},
1524*4882a593Smuzhiyun 		},
1525*4882a593Smuzhiyun 		.validate_hw_event = cci500_validate_hw_event,
1526*4882a593Smuzhiyun 		.write_counters	= cci5xx_pmu_write_counters,
1527*4882a593Smuzhiyun 	},
1528*4882a593Smuzhiyun 	[CCI550_R0] = {
1529*4882a593Smuzhiyun 		.name = "CCI_550",
1530*4882a593Smuzhiyun 		.fixed_hw_cntrs = FIXED_HW_CNTRS_CII_5XX,
1531*4882a593Smuzhiyun 		.num_hw_cntrs = NUM_HW_CNTRS_CII_5XX,
1532*4882a593Smuzhiyun 		.cntr_size = SZ_64K,
1533*4882a593Smuzhiyun 		.format_attrs = cci5xx_pmu_format_attrs,
1534*4882a593Smuzhiyun 		.event_attrs = cci5xx_pmu_event_attrs,
1535*4882a593Smuzhiyun 		.event_ranges = {
1536*4882a593Smuzhiyun 			[CCI_IF_SLAVE] = {
1537*4882a593Smuzhiyun 				CCI5xx_SLAVE_PORT_MIN_EV,
1538*4882a593Smuzhiyun 				CCI5xx_SLAVE_PORT_MAX_EV,
1539*4882a593Smuzhiyun 			},
1540*4882a593Smuzhiyun 			[CCI_IF_MASTER] = {
1541*4882a593Smuzhiyun 				CCI5xx_MASTER_PORT_MIN_EV,
1542*4882a593Smuzhiyun 				CCI5xx_MASTER_PORT_MAX_EV,
1543*4882a593Smuzhiyun 			},
1544*4882a593Smuzhiyun 			[CCI_IF_GLOBAL] = {
1545*4882a593Smuzhiyun 				CCI5xx_GLOBAL_PORT_MIN_EV,
1546*4882a593Smuzhiyun 				CCI5xx_GLOBAL_PORT_MAX_EV,
1547*4882a593Smuzhiyun 			},
1548*4882a593Smuzhiyun 		},
1549*4882a593Smuzhiyun 		.validate_hw_event = cci550_validate_hw_event,
1550*4882a593Smuzhiyun 		.write_counters	= cci5xx_pmu_write_counters,
1551*4882a593Smuzhiyun 	},
1552*4882a593Smuzhiyun #endif
1553*4882a593Smuzhiyun };
1554*4882a593Smuzhiyun 
1555*4882a593Smuzhiyun static const struct of_device_id arm_cci_pmu_matches[] = {
1556*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI400_PMU
1557*4882a593Smuzhiyun 	{
1558*4882a593Smuzhiyun 		.compatible = "arm,cci-400-pmu",
1559*4882a593Smuzhiyun 		.data	= NULL,
1560*4882a593Smuzhiyun 	},
1561*4882a593Smuzhiyun 	{
1562*4882a593Smuzhiyun 		.compatible = "arm,cci-400-pmu,r0",
1563*4882a593Smuzhiyun 		.data	= &cci_pmu_models[CCI400_R0],
1564*4882a593Smuzhiyun 	},
1565*4882a593Smuzhiyun 	{
1566*4882a593Smuzhiyun 		.compatible = "arm,cci-400-pmu,r1",
1567*4882a593Smuzhiyun 		.data	= &cci_pmu_models[CCI400_R1],
1568*4882a593Smuzhiyun 	},
1569*4882a593Smuzhiyun #endif
1570*4882a593Smuzhiyun #ifdef CONFIG_ARM_CCI5xx_PMU
1571*4882a593Smuzhiyun 	{
1572*4882a593Smuzhiyun 		.compatible = "arm,cci-500-pmu,r0",
1573*4882a593Smuzhiyun 		.data = &cci_pmu_models[CCI500_R0],
1574*4882a593Smuzhiyun 	},
1575*4882a593Smuzhiyun 	{
1576*4882a593Smuzhiyun 		.compatible = "arm,cci-550-pmu,r0",
1577*4882a593Smuzhiyun 		.data = &cci_pmu_models[CCI550_R0],
1578*4882a593Smuzhiyun 	},
1579*4882a593Smuzhiyun #endif
1580*4882a593Smuzhiyun 	{},
1581*4882a593Smuzhiyun };
1582*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, arm_cci_pmu_matches);
1583*4882a593Smuzhiyun 
is_duplicate_irq(int irq,int * irqs,int nr_irqs)1584*4882a593Smuzhiyun static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs)
1585*4882a593Smuzhiyun {
1586*4882a593Smuzhiyun 	int i;
1587*4882a593Smuzhiyun 
1588*4882a593Smuzhiyun 	for (i = 0; i < nr_irqs; i++)
1589*4882a593Smuzhiyun 		if (irq == irqs[i])
1590*4882a593Smuzhiyun 			return true;
1591*4882a593Smuzhiyun 
1592*4882a593Smuzhiyun 	return false;
1593*4882a593Smuzhiyun }
1594*4882a593Smuzhiyun 
cci_pmu_alloc(struct device * dev)1595*4882a593Smuzhiyun static struct cci_pmu *cci_pmu_alloc(struct device *dev)
1596*4882a593Smuzhiyun {
1597*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu;
1598*4882a593Smuzhiyun 	const struct cci_pmu_model *model;
1599*4882a593Smuzhiyun 
1600*4882a593Smuzhiyun 	/*
1601*4882a593Smuzhiyun 	 * All allocations are devm_* hence we don't have to free
1602*4882a593Smuzhiyun 	 * them explicitly on an error, as it would end up in driver
1603*4882a593Smuzhiyun 	 * detach.
1604*4882a593Smuzhiyun 	 */
1605*4882a593Smuzhiyun 	cci_pmu = devm_kzalloc(dev, sizeof(*cci_pmu), GFP_KERNEL);
1606*4882a593Smuzhiyun 	if (!cci_pmu)
1607*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
1608*4882a593Smuzhiyun 
1609*4882a593Smuzhiyun 	cci_pmu->ctrl_base = *(void __iomem **)dev->platform_data;
1610*4882a593Smuzhiyun 
1611*4882a593Smuzhiyun 	model = of_device_get_match_data(dev);
1612*4882a593Smuzhiyun 	if (!model) {
1613*4882a593Smuzhiyun 		dev_warn(dev,
1614*4882a593Smuzhiyun 			 "DEPRECATED compatible property, requires secure access to CCI registers");
1615*4882a593Smuzhiyun 		model = probe_cci_model(cci_pmu);
1616*4882a593Smuzhiyun 	}
1617*4882a593Smuzhiyun 	if (!model) {
1618*4882a593Smuzhiyun 		dev_warn(dev, "CCI PMU version not supported\n");
1619*4882a593Smuzhiyun 		return ERR_PTR(-ENODEV);
1620*4882a593Smuzhiyun 	}
1621*4882a593Smuzhiyun 
1622*4882a593Smuzhiyun 	cci_pmu->model = model;
1623*4882a593Smuzhiyun 	cci_pmu->irqs = devm_kcalloc(dev, CCI_PMU_MAX_HW_CNTRS(model),
1624*4882a593Smuzhiyun 					sizeof(*cci_pmu->irqs), GFP_KERNEL);
1625*4882a593Smuzhiyun 	if (!cci_pmu->irqs)
1626*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
1627*4882a593Smuzhiyun 	cci_pmu->hw_events.events = devm_kcalloc(dev,
1628*4882a593Smuzhiyun 					     CCI_PMU_MAX_HW_CNTRS(model),
1629*4882a593Smuzhiyun 					     sizeof(*cci_pmu->hw_events.events),
1630*4882a593Smuzhiyun 					     GFP_KERNEL);
1631*4882a593Smuzhiyun 	if (!cci_pmu->hw_events.events)
1632*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
1633*4882a593Smuzhiyun 	cci_pmu->hw_events.used_mask = devm_kcalloc(dev,
1634*4882a593Smuzhiyun 						BITS_TO_LONGS(CCI_PMU_MAX_HW_CNTRS(model)),
1635*4882a593Smuzhiyun 						sizeof(*cci_pmu->hw_events.used_mask),
1636*4882a593Smuzhiyun 						GFP_KERNEL);
1637*4882a593Smuzhiyun 	if (!cci_pmu->hw_events.used_mask)
1638*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
1639*4882a593Smuzhiyun 
1640*4882a593Smuzhiyun 	return cci_pmu;
1641*4882a593Smuzhiyun }
1642*4882a593Smuzhiyun 
cci_pmu_probe(struct platform_device * pdev)1643*4882a593Smuzhiyun static int cci_pmu_probe(struct platform_device *pdev)
1644*4882a593Smuzhiyun {
1645*4882a593Smuzhiyun 	struct cci_pmu *cci_pmu;
1646*4882a593Smuzhiyun 	int i, ret, irq;
1647*4882a593Smuzhiyun 
1648*4882a593Smuzhiyun 	cci_pmu = cci_pmu_alloc(&pdev->dev);
1649*4882a593Smuzhiyun 	if (IS_ERR(cci_pmu))
1650*4882a593Smuzhiyun 		return PTR_ERR(cci_pmu);
1651*4882a593Smuzhiyun 
1652*4882a593Smuzhiyun 	cci_pmu->base = devm_platform_ioremap_resource(pdev, 0);
1653*4882a593Smuzhiyun 	if (IS_ERR(cci_pmu->base))
1654*4882a593Smuzhiyun 		return -ENOMEM;
1655*4882a593Smuzhiyun 
1656*4882a593Smuzhiyun 	/*
1657*4882a593Smuzhiyun 	 * CCI PMU has one overflow interrupt per counter; but some may be tied
1658*4882a593Smuzhiyun 	 * together to a common interrupt.
1659*4882a593Smuzhiyun 	 */
1660*4882a593Smuzhiyun 	cci_pmu->nr_irqs = 0;
1661*4882a593Smuzhiyun 	for (i = 0; i < CCI_PMU_MAX_HW_CNTRS(cci_pmu->model); i++) {
1662*4882a593Smuzhiyun 		irq = platform_get_irq(pdev, i);
1663*4882a593Smuzhiyun 		if (irq < 0)
1664*4882a593Smuzhiyun 			break;
1665*4882a593Smuzhiyun 
1666*4882a593Smuzhiyun 		if (is_duplicate_irq(irq, cci_pmu->irqs, cci_pmu->nr_irqs))
1667*4882a593Smuzhiyun 			continue;
1668*4882a593Smuzhiyun 
1669*4882a593Smuzhiyun 		cci_pmu->irqs[cci_pmu->nr_irqs++] = irq;
1670*4882a593Smuzhiyun 	}
1671*4882a593Smuzhiyun 
1672*4882a593Smuzhiyun 	/*
1673*4882a593Smuzhiyun 	 * Ensure that the device tree has as many interrupts as the number
1674*4882a593Smuzhiyun 	 * of counters.
1675*4882a593Smuzhiyun 	 */
1676*4882a593Smuzhiyun 	if (i < CCI_PMU_MAX_HW_CNTRS(cci_pmu->model)) {
1677*4882a593Smuzhiyun 		dev_warn(&pdev->dev, "In-correct number of interrupts: %d, should be %d\n",
1678*4882a593Smuzhiyun 			i, CCI_PMU_MAX_HW_CNTRS(cci_pmu->model));
1679*4882a593Smuzhiyun 		return -EINVAL;
1680*4882a593Smuzhiyun 	}
1681*4882a593Smuzhiyun 
1682*4882a593Smuzhiyun 	raw_spin_lock_init(&cci_pmu->hw_events.pmu_lock);
1683*4882a593Smuzhiyun 	mutex_init(&cci_pmu->reserve_mutex);
1684*4882a593Smuzhiyun 	atomic_set(&cci_pmu->active_events, 0);
1685*4882a593Smuzhiyun 
1686*4882a593Smuzhiyun 	cci_pmu->cpu = raw_smp_processor_id();
1687*4882a593Smuzhiyun 	g_cci_pmu = cci_pmu;
1688*4882a593Smuzhiyun 	cpuhp_setup_state_nocalls(CPUHP_AP_PERF_ARM_CCI_ONLINE,
1689*4882a593Smuzhiyun 				  "perf/arm/cci:online", NULL,
1690*4882a593Smuzhiyun 				  cci_pmu_offline_cpu);
1691*4882a593Smuzhiyun 
1692*4882a593Smuzhiyun 	ret = cci_pmu_init(cci_pmu, pdev);
1693*4882a593Smuzhiyun 	if (ret)
1694*4882a593Smuzhiyun 		goto error_pmu_init;
1695*4882a593Smuzhiyun 
1696*4882a593Smuzhiyun 	pr_info("ARM %s PMU driver probed", cci_pmu->model->name);
1697*4882a593Smuzhiyun 	return 0;
1698*4882a593Smuzhiyun 
1699*4882a593Smuzhiyun error_pmu_init:
1700*4882a593Smuzhiyun 	cpuhp_remove_state(CPUHP_AP_PERF_ARM_CCI_ONLINE);
1701*4882a593Smuzhiyun 	g_cci_pmu = NULL;
1702*4882a593Smuzhiyun 	return ret;
1703*4882a593Smuzhiyun }
1704*4882a593Smuzhiyun 
cci_pmu_remove(struct platform_device * pdev)1705*4882a593Smuzhiyun static int cci_pmu_remove(struct platform_device *pdev)
1706*4882a593Smuzhiyun {
1707*4882a593Smuzhiyun 	if (!g_cci_pmu)
1708*4882a593Smuzhiyun 		return 0;
1709*4882a593Smuzhiyun 
1710*4882a593Smuzhiyun 	cpuhp_remove_state(CPUHP_AP_PERF_ARM_CCI_ONLINE);
1711*4882a593Smuzhiyun 	perf_pmu_unregister(&g_cci_pmu->pmu);
1712*4882a593Smuzhiyun 	g_cci_pmu = NULL;
1713*4882a593Smuzhiyun 
1714*4882a593Smuzhiyun 	return 0;
1715*4882a593Smuzhiyun }
1716*4882a593Smuzhiyun 
1717*4882a593Smuzhiyun static struct platform_driver cci_pmu_driver = {
1718*4882a593Smuzhiyun 	.driver = {
1719*4882a593Smuzhiyun 		   .name = DRIVER_NAME,
1720*4882a593Smuzhiyun 		   .of_match_table = arm_cci_pmu_matches,
1721*4882a593Smuzhiyun 		   .suppress_bind_attrs = true,
1722*4882a593Smuzhiyun 		  },
1723*4882a593Smuzhiyun 	.probe = cci_pmu_probe,
1724*4882a593Smuzhiyun 	.remove = cci_pmu_remove,
1725*4882a593Smuzhiyun };
1726*4882a593Smuzhiyun 
1727*4882a593Smuzhiyun module_platform_driver(cci_pmu_driver);
1728*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1729*4882a593Smuzhiyun MODULE_DESCRIPTION("ARM CCI PMU support");
1730