xref: /openbmc/linux/arch/powerpc/include/asm/imc-pmu.h (revision 1fa0a7dc)
1 #ifndef __ASM_POWERPC_IMC_PMU_H
2 #define __ASM_POWERPC_IMC_PMU_H
3 
4 /*
5  * IMC Nest Performance Monitor counter support.
6  *
7  * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation.
8  *           (C) 2017 Anju T Sudhakar, IBM Corporation.
9  *           (C) 2017 Hemant K Shaw, IBM Corporation.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version
14  * 2 of the License, or later version.
15  */
16 
17 #include <linux/perf_event.h>
18 #include <linux/slab.h>
19 #include <linux/of.h>
20 #include <linux/io.h>
21 #include <asm/opal.h>
22 
23 /*
24  * Compatibility macros for IMC devices
25  */
26 #define IMC_DTB_COMPAT			"ibm,opal-in-memory-counters"
27 #define IMC_DTB_UNIT_COMPAT		"ibm,imc-counters"
28 
29 
30 /*
31  * LDBAR: Counter address and Enable/Disable macro.
32  * perf/imc-pmu.c has the LDBAR layout information.
33  */
34 #define THREAD_IMC_LDBAR_MASK           0x0003ffffffffe000ULL
35 #define THREAD_IMC_ENABLE               0x8000000000000000ULL
36 #define TRACE_IMC_ENABLE		0x4000000000000000ULL
37 
38 /*
39  * For debugfs interface for imc-mode and imc-command
40  */
41 #define IMC_CNTL_BLK_OFFSET		0x3FC00
42 #define IMC_CNTL_BLK_CMD_OFFSET		8
43 #define IMC_CNTL_BLK_MODE_OFFSET	32
44 
45 /*
46  * Structure to hold memory address information for imc units.
47  */
48 struct imc_mem_info {
49 	u64 *vbase;
50 	u32 id;
51 };
52 
53 /*
54  * Place holder for nest pmu events and values.
55  */
56 struct imc_events {
57 	u32 value;
58 	char *name;
59 	char *unit;
60 	char *scale;
61 };
62 
63 /*
64  * Trace IMC hardware updates a 64bytes record on
65  * Core Performance Monitoring Counter (CPMC)
66  * overflow. Here is the layout for the trace imc record
67  *
68  * DW 0 : Timebase
69  * DW 1 : Program Counter
70  * DW 2 : PIDR information
71  * DW 3 : CPMC1
72  * DW 4 : CPMC2
73  * DW 5 : CPMC3
74  * Dw 6 : CPMC4
75  * DW 7 : Timebase
76  * .....
77  *
78  * The following is the data structure to hold trace imc data.
79  */
80 struct trace_imc_data {
81 	u64 tb1;
82 	u64 ip;
83 	u64 val;
84 	u64 cpmc1;
85 	u64 cpmc2;
86 	u64 cpmc3;
87 	u64 cpmc4;
88 	u64 tb2;
89 };
90 
91 /* Event attribute array index */
92 #define IMC_FORMAT_ATTR		0
93 #define IMC_EVENT_ATTR		1
94 #define IMC_CPUMASK_ATTR	2
95 #define IMC_NULL_ATTR		3
96 
97 /* PMU Format attribute macros */
98 #define IMC_EVENT_OFFSET_MASK	0xffffffffULL
99 
100 /*
101  * Macro to mask bits 0:21 of first double word(which is the timebase) to
102  * compare with 8th double word (timebase) of trace imc record data.
103  */
104 #define IMC_TRACE_RECORD_TB1_MASK      0x3ffffffffffULL
105 
106 
107 /*
108  * Device tree parser code detects IMC pmu support and
109  * registers new IMC pmus. This structure will hold the
110  * pmu functions, events, counter memory information
111  * and attrs for each imc pmu and will be referenced at
112  * the time of pmu registration.
113  */
114 struct imc_pmu {
115 	struct pmu pmu;
116 	struct imc_mem_info *mem_info;
117 	struct imc_events *events;
118 	/*
119 	 * Attribute groups for the PMU. Slot 0 used for
120 	 * format attribute, slot 1 used for cpusmask attribute,
121 	 * slot 2 used for event attribute. Slot 3 keep as
122 	 * NULL.
123 	 */
124 	const struct attribute_group *attr_groups[4];
125 	u32 counter_mem_size;
126 	int domain;
127 	/*
128 	 * flag to notify whether the memory is mmaped
129 	 * or allocated by kernel.
130 	 */
131 	bool imc_counter_mmaped;
132 };
133 
134 /*
135  * Structure to hold id, lock and reference count for the imc events which
136  * are inited.
137  */
138 struct imc_pmu_ref {
139 	struct mutex lock;
140 	unsigned int id;
141 	int refc;
142 };
143 
144 /*
145  * In-Memory Collection Counters type.
146  * Data comes from Device tree.
147  * Three device type are supported.
148  */
149 
150 enum {
151 	IMC_TYPE_THREAD		= 0x1,
152 	IMC_TYPE_TRACE		= 0x2,
153 	IMC_TYPE_CORE		= 0x4,
154 	IMC_TYPE_CHIP           = 0x10,
155 };
156 
157 /*
158  * Domains for IMC PMUs
159  */
160 #define IMC_DOMAIN_NEST		1
161 #define IMC_DOMAIN_CORE		2
162 #define IMC_DOMAIN_THREAD	3
163 /* For trace-imc the domain is still thread but it operates in trace-mode */
164 #define IMC_DOMAIN_TRACE	4
165 
166 extern int init_imc_pmu(struct device_node *parent,
167 				struct imc_pmu *pmu_ptr, int pmu_id);
168 extern void thread_imc_disable(void);
169 extern int get_max_nest_dev(void);
170 extern void unregister_thread_imc(void);
171 #endif /* __ASM_POWERPC_IMC_PMU_H */
172