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