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