xref: /linux/drivers/hwtracing/coresight/coresight-config.h (revision b2131cff722479bb4e6db3e4d5d8014421c6c97f)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2020 Linaro Limited, All rights reserved.
4  * Author: Mike Leach <mike.leach@linaro.org>
5  */
6 
7 #ifndef _CORESIGHT_CORESIGHT_CONFIG_H
8 #define _CORESIGHT_CORESIGHT_CONFIG_H
9 
10 #include <linux/cleanup.h>
11 #include <linux/coresight.h>
12 #include <linux/types.h>
13 
14 /* CoreSight Configuration Management - component and system wide configuration */
15 
16 /*
17  * Register type flags for register value descriptor:
18  * describe how the value is interpreted, and handled.
19  */
20 #define CS_CFG_REG_TYPE_STD		0x80	/* reg is standard reg */
21 #define CS_CFG_REG_TYPE_RESOURCE	0x40	/* reg is a resource */
22 #define CS_CFG_REG_TYPE_VAL_PARAM	0x08	/* reg value uses param */
23 #define CS_CFG_REG_TYPE_VAL_MASK	0x04	/* reg value bit masked */
24 #define CS_CFG_REG_TYPE_VAL_64BIT	0x02	/* reg value 64 bit */
25 #define CS_CFG_REG_TYPE_VAL_SAVE	0x01	/* reg value save on disable */
26 
27 /*
28  * flags defining what device class a feature will match to when processing a
29  * system configuration - used by config data and devices.
30  */
31 #define CS_CFG_MATCH_CLASS_SRC_ALL	0x0001	/* match any source */
32 #define CS_CFG_MATCH_CLASS_SRC_ETM4	0x0002	/* match any ETMv4 device */
33 
34 /* flags defining device instance matching - used in config match desc data. */
35 #define CS_CFG_MATCH_INST_ANY		0x80000000 /* any instance of a class */
36 
37 /*
38  * Limit number of presets in a configuration
39  * This is related to the number of bits (4) we use to select the preset on
40  * the perf command line. Preset 0 is always none selected.
41  * See PMU_FORMAT_ATTR(preset, "config:0-3") in coresight-etm-perf.c
42  */
43 #define CS_CFG_CONFIG_PRESET_MAX 15
44 
45 /**
46  * Parameter descriptor for a device feature.
47  *
48  * @name:  Name of parameter.
49  * @value: Initial or default value.
50  */
51 struct cscfg_parameter_desc {
52 	const char *name;
53 	u64 value;
54 };
55 
56 /**
57  * Representation of register value and a descriptor of register usage.
58  *
59  * Used as a descriptor in the feature descriptors.
60  * Used as a value in when in a feature loading into a csdev.
61  *
62  * Supports full 64 bit register value, or 32 bit value with optional mask
63  * value.
64  *
65  * @type:	define register usage and interpretation.
66  * @offset:	the address offset for register in the hardware device (per device specification).
67  * @hw_info:	optional hardware device type specific information. (ETM / CTI specific etc)
68  * @val64:	64 bit value.
69  * @val32:	32 bit value.
70  * @mask32:	32 bit mask when using 32 bit value to access device register - if mask type.
71  * @param_idx:	parameter index value into parameter array if param type.
72  */
73 struct cscfg_regval_desc {
74 	struct {
75 		u32 type:8;
76 		u32 offset:12;
77 		u32 hw_info:12;
78 	};
79 	union {
80 		u64 val64;
81 		struct {
82 			u32 val32;
83 			u32 mask32;
84 		};
85 		u32 param_idx;
86 	};
87 };
88 
89 /**
90  * Device feature descriptor - combination of registers and parameters to
91  * program a device to implement a specific complex function.
92  *
93  * @name:	 feature name.
94  * @description: brief description of the feature.
95  * @item:	 List entry.
96  * @match_flags: matching information if loading into a device
97  * @nr_params:   number of parameters used.
98  * @params_desc: array of parameters used.
99  * @nr_regs:	 number of registers used.
100  * @regs_desc:	 array of registers used.
101  * @load_owner:	 handle to load owner for dynamic load and unload of features.
102  * @fs_group:	 reference to configfs group for dynamic unload.
103  */
104 struct cscfg_feature_desc {
105 	const char *name;
106 	const char *description;
107 	struct list_head item;
108 	u32 match_flags;
109 	int nr_params;
110 	struct cscfg_parameter_desc *params_desc;
111 	int nr_regs;
112 	struct cscfg_regval_desc *regs_desc;
113 	void *load_owner;
114 	struct config_group *fs_group;
115 };
116 
117 /**
118  * Configuration descriptor - describes selectable system configuration.
119  *
120  * A configuration describes device features in use, and may provide preset
121  * values for the parameters in those features.
122  *
123  * A single set of presets is the sum of the parameters declared by
124  * all the features in use - this value is @nr_total_params.
125  *
126  * @name:		name of the configuration - used for selection.
127  * @description:	description of the purpose of the configuration.
128  * @item:		list entry.
129  * @nr_feat_refs:	Number of features used in this configuration.
130  * @feat_ref_names:	references to features used in this configuration.
131  * @nr_presets:		Number of sets of presets supplied by this configuration.
132  * @nr_total_params:	Sum of all parameters declared by used features
133  * @presets:		Array of preset values.
134  * @event_ea:		Extended attribute for perf event value
135  * @active_cnt:		ref count for activate on this configuration.
136  * @load_owner:		handle to load owner for dynamic load and unload of configs.
137  * @fs_group:		reference to configfs group for dynamic unload.
138  * @available:		config can be activated - multi-stage load sets true on completion.
139  */
140 struct cscfg_config_desc {
141 	const char *name;
142 	const char *description;
143 	struct list_head item;
144 	int nr_feat_refs;
145 	const char **feat_ref_names;
146 	int nr_presets;
147 	int nr_total_params;
148 	const u64 *presets; /* nr_presets * nr_total_params */
149 	struct dev_ext_attribute *event_ea;
150 	atomic_t active_cnt;
151 	void *load_owner;
152 	struct config_group *fs_group;
153 	bool available;
154 };
155 
156 /**
157  * config register instance - part of a loaded feature.
158  *                            maps register values to csdev driver structures
159  *
160  * @reg_desc:		value to use when setting feature on device / store for
161  *			readback of volatile values.
162  * @driver_regval:	pointer to internal driver element used to set the value
163  *			in hardware.
164  */
165 struct cscfg_regval_csdev {
166 	struct cscfg_regval_desc reg_desc;
167 	void *driver_regval;
168 };
169 
170 /**
171  * config parameter instance - part of a loaded feature.
172  *
173  * @feat_csdev:		parent feature
174  * @reg_csdev:		register value updated by this parameter.
175  * @current_value:	current value of parameter - may be set by user via
176  *			sysfs, or modified during device operation.
177  * @val64:		true if 64 bit value
178  */
179 struct cscfg_parameter_csdev {
180 	struct cscfg_feature_csdev *feat_csdev;
181 	struct cscfg_regval_csdev *reg_csdev;
182 	u64 current_value;
183 	bool val64;
184 };
185 
186 /**
187  * Feature instance loaded into a CoreSight device.
188  *
189  * When a feature is loaded into a specific device, then this structure holds
190  * the connections between the register / parameter values used and the
191  * internal data structures that are written when the feature is enabled.
192  *
193  * Since applying a feature modifies internal data structures in the device,
194  * then we have a reference to the device spinlock to protect access to these
195  * structures (@drv_spinlock).
196  *
197  * @feat_desc:		pointer to the static descriptor for this feature.
198  * @csdev:		parent CoreSight device instance.
199  * @node:		list entry into feature list for this device.
200  * @drv_spinlock:	device spinlock for access to driver register data.
201  * @nr_params:		number of parameters.
202  * @params_csdev:	current parameter values on this device
203  * @nr_regs:		number of registers to be programmed.
204  * @regs_csdev:		Programming details for the registers
205  */
206 struct cscfg_feature_csdev {
207 	const struct cscfg_feature_desc *feat_desc;
208 	struct coresight_device *csdev;
209 	struct list_head node;
210 	raw_spinlock_t *drv_spinlock;
211 	int nr_params;
212 	struct cscfg_parameter_csdev *params_csdev;
213 	int nr_regs;
214 	struct cscfg_regval_csdev *regs_csdev;
215 };
216 
217 /**
218  * Configuration instance when loaded into a CoreSight device.
219  *
220  * The instance contains references to loaded features on this device that are
221  * used by the configuration.
222  *
223  * @config_desc:reference to the descriptor for this configuration
224  * @csdev:	parent coresight device for this configuration instance.
225  * @enabled:	true if configuration is enabled on this device.
226  * @node:	list entry within the coresight device
227  * @nr_feat:	Number of features on this device that are used in the
228  *		configuration.
229  * @feats_csdev:references to the device features to enable.
230  */
231 struct cscfg_config_csdev {
232 	struct cscfg_config_desc *config_desc;
233 	struct coresight_device *csdev;
234 	bool enabled;
235 	struct list_head node;
236 	int nr_feat;
237 	struct cscfg_feature_csdev *feats_csdev[];
238 };
239 
240 /**
241  * Coresight device operations.
242  *
243  * Registered coresight devices provide these operations to manage feature
244  * instances compatible with the device hardware and drivers
245  *
246  * @load_feat:	Pass a feature descriptor into the device and create the
247  *		loaded feature instance (struct cscfg_feature_csdev).
248  */
249 struct cscfg_csdev_feat_ops {
250 	int (*load_feat)(struct coresight_device *csdev,
251 			 struct cscfg_feature_csdev *feat_csdev);
252 };
253 
254 /* coresight config helper functions*/
255 
256 /* enable / disable config on a device - called with appropriate locks set.*/
257 int cscfg_csdev_enable_config(struct cscfg_config_csdev *config_csdev, int preset);
258 void cscfg_csdev_disable_config(struct cscfg_config_csdev *config_csdev);
259 
260 /* reset a feature to default values */
261 void cscfg_reset_feat(struct cscfg_feature_csdev *feat_csdev);
262 
263 #define feat_csdev_lock(feat_csdev, flags)				\
264 	do {								\
265 		raw_spinlock_t *__lock = feat_csdev->drv_spinlock;	\
266 		typecheck(unsigned long, flags);			\
267 		if (__lock)						\
268 			raw_spin_lock_irqsave(__lock, flags);		\
269 	} while (0)
270 
271 #define feat_csdev_unlock(feat_csdev, flags)				\
272 	do {								\
273 		raw_spinlock_t *__lock = feat_csdev->drv_spinlock;	\
274 		typecheck(unsigned long, flags);			\
275 		if (__lock)						\
276 			raw_spin_unlock_irqrestore(__lock, flags);	\
277 	} while (0)
278 
279 DEFINE_LOCK_GUARD_1(feat_csdev_lock, struct cscfg_feature_csdev,
280 		    feat_csdev_lock(_T->lock, _T->flags),
281 		    feat_csdev_unlock(_T->lock, _T->flags),
282 		    unsigned long flags)
283 
284 #endif /* _CORESIGHT_CORESIGHT_CONFIG_H */
285