1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * cs_dsp.h -- Cirrus Logic DSP firmware support 4 * 5 * Based on sound/soc/codecs/wm_adsp.h 6 * 7 * Copyright 2012 Wolfson Microelectronics plc 8 * Copyright (C) 2015-2021 Cirrus Logic, Inc. and 9 * Cirrus Logic International Semiconductor Ltd. 10 */ 11 #ifndef __CS_DSP_H 12 #define __CS_DSP_H 13 14 #include <linux/bits.h> 15 #include <linux/device.h> 16 #include <linux/firmware.h> 17 #include <linux/list.h> 18 #include <linux/regmap.h> 19 20 #define CS_ADSP2_REGION_0 BIT(0) 21 #define CS_ADSP2_REGION_1 BIT(1) 22 #define CS_ADSP2_REGION_2 BIT(2) 23 #define CS_ADSP2_REGION_3 BIT(3) 24 #define CS_ADSP2_REGION_4 BIT(4) 25 #define CS_ADSP2_REGION_5 BIT(5) 26 #define CS_ADSP2_REGION_6 BIT(6) 27 #define CS_ADSP2_REGION_7 BIT(7) 28 #define CS_ADSP2_REGION_8 BIT(8) 29 #define CS_ADSP2_REGION_9 BIT(9) 30 #define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \ 31 CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \ 32 CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \ 33 CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \ 34 CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9) 35 #define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9) 36 37 #define CS_DSP_DATA_WORD_SIZE 3 38 #define CS_DSP_DATA_WORD_BITS (3 * BITS_PER_BYTE) 39 40 #define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 41 #define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 42 #define CS_DSP_ACKED_CTL_MIN_VALUE 0 43 #define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF 44 45 /** 46 * struct cs_dsp_region - Describes a logical memory region in DSP address space 47 * @type: Memory region type 48 * @base: Address of region 49 */ 50 struct cs_dsp_region { 51 int type; 52 unsigned int base; 53 }; 54 55 /** 56 * struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space 57 * @list: List node for internal use 58 * @alg: Algorithm id 59 * @ver: Expected algorithm version 60 * @type: Memory region type 61 * @base: Address of region 62 */ 63 struct cs_dsp_alg_region { 64 struct list_head list; 65 unsigned int alg; 66 unsigned int ver; 67 int type; 68 unsigned int base; 69 }; 70 71 /** 72 * struct cs_dsp_coeff_ctl - Describes a coefficient control 73 * @list: List node for internal use 74 * @dsp: DSP instance associated with this control 75 * @cache: Cached value of the control 76 * @fw_name: Name of the firmware 77 * @subname: Name of the control parsed from the WMFW 78 * @subname_len: Length of subname 79 * @offset: Offset of control within alg_region in words 80 * @len: Length of the cached value in bytes 81 * @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h 82 * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h 83 * @set: Flag indicating the value has been written by the user 84 * @enabled: Flag indicating whether control is enabled 85 * @alg_region: Logical region associated with this control 86 * @priv: For use by the client 87 */ 88 struct cs_dsp_coeff_ctl { 89 struct list_head list; 90 struct cs_dsp *dsp; 91 void *cache; 92 const char *fw_name; 93 /* Subname is needed to match with firmware */ 94 const char *subname; 95 unsigned int subname_len; 96 unsigned int offset; 97 size_t len; 98 unsigned int type; 99 unsigned int flags; 100 unsigned int set:1; 101 unsigned int enabled:1; 102 struct cs_dsp_alg_region alg_region; 103 104 void *priv; 105 }; 106 107 struct cs_dsp_ops; 108 struct cs_dsp_client_ops; 109 110 /** 111 * struct cs_dsp - Configuration and state of a Cirrus Logic DSP 112 * @name: The name of the DSP instance 113 * @rev: Revision of the DSP 114 * @num: DSP instance number 115 * @type: Type of DSP 116 * @dev: Driver model representation of the device 117 * @regmap: Register map of the device 118 * @ops: Function pointers for internal callbacks 119 * @client_ops: Function pointers for client callbacks 120 * @base: Address of the DSP registers 121 * @base_sysinfo: Address of the sysinfo register (Halo only) 122 * @sysclk_reg: Address of the sysclk register (ADSP1 only) 123 * @sysclk_mask: Mask of frequency bits within sysclk register (ADSP1 only) 124 * @sysclk_shift: Shift of frequency bits within sysclk register (ADSP1 only) 125 * @alg_regions: List of currently loaded algorithm regions 126 * @fw_file_name: Filename of the current firmware 127 * @fw_name: Name of the current firmware 128 * @fw_id: ID of the current firmware, obtained from the wmfw 129 * @fw_id_version: Version of the firmware, obtained from the wmfw 130 * @fw_vendor_id: Vendor of the firmware, obtained from the wmfw 131 * @mem: DSP memory region descriptions 132 * @num_mems: Number of memory regions in this DSP 133 * @fw_ver: Version of the wmfw file format 134 * @booted: Flag indicating DSP has been configured 135 * @running: Flag indicating DSP is executing firmware 136 * @ctl_list: Controls defined within the loaded DSP firmware 137 * @lock_regions: Enable MPU traps on specified memory regions 138 * @pwr_lock: Lock used to serialize accesses 139 * @debugfs_root: Debugfs directory for this DSP instance 140 * @wmfw_file_name: Filename of the currently loaded firmware 141 * @bin_file_name: Filename of the currently loaded coefficients 142 */ 143 struct cs_dsp { 144 const char *name; 145 int rev; 146 int num; 147 int type; 148 struct device *dev; 149 struct regmap *regmap; 150 151 const struct cs_dsp_ops *ops; 152 const struct cs_dsp_client_ops *client_ops; 153 154 unsigned int base; 155 unsigned int base_sysinfo; 156 unsigned int sysclk_reg; 157 unsigned int sysclk_mask; 158 unsigned int sysclk_shift; 159 bool no_core_startstop; 160 161 struct list_head alg_regions; 162 163 const char *fw_name; 164 unsigned int fw_id; 165 unsigned int fw_id_version; 166 unsigned int fw_vendor_id; 167 168 const struct cs_dsp_region *mem; 169 int num_mems; 170 171 int fw_ver; 172 173 bool booted; 174 bool running; 175 176 struct list_head ctl_list; 177 178 struct mutex pwr_lock; 179 180 unsigned int lock_regions; 181 182 #ifdef CONFIG_DEBUG_FS 183 struct dentry *debugfs_root; 184 char *wmfw_file_name; 185 char *bin_file_name; 186 #endif 187 }; 188 189 /** 190 * struct cs_dsp_client_ops - client callbacks 191 * @control_add: Called under the pwr_lock when a control is created 192 * @control_remove: Called under the pwr_lock when a control is destroyed 193 * @pre_run: Called under the pwr_lock by cs_dsp_run() before the core is started 194 * @post_run: Called under the pwr_lock by cs_dsp_run() after the core is started 195 * @pre_stop: Called under the pwr_lock by cs_dsp_stop() before the core is stopped 196 * @post_stop: Called under the pwr_lock by cs_dsp_stop() after the core is stopped 197 * @watchdog_expired: Called when a watchdog expiry is detected 198 * 199 * These callbacks give the cs_dsp client an opportunity to respond to events 200 * or to perform actions atomically. 201 */ 202 struct cs_dsp_client_ops { 203 int (*control_add)(struct cs_dsp_coeff_ctl *ctl); 204 void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); 205 int (*pre_run)(struct cs_dsp *dsp); 206 int (*post_run)(struct cs_dsp *dsp); 207 void (*pre_stop)(struct cs_dsp *dsp); 208 void (*post_stop)(struct cs_dsp *dsp); 209 void (*watchdog_expired)(struct cs_dsp *dsp); 210 }; 211 212 int cs_dsp_adsp1_init(struct cs_dsp *dsp); 213 int cs_dsp_adsp2_init(struct cs_dsp *dsp); 214 int cs_dsp_halo_init(struct cs_dsp *dsp); 215 216 int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, 217 const struct firmware *wmfw_firmware, char *wmfw_filename, 218 const struct firmware *coeff_firmware, char *coeff_filename, 219 const char *fw_name); 220 void cs_dsp_adsp1_power_down(struct cs_dsp *dsp); 221 int cs_dsp_power_up(struct cs_dsp *dsp, 222 const struct firmware *wmfw_firmware, char *wmfw_filename, 223 const struct firmware *coeff_firmware, char *coeff_filename, 224 const char *fw_name); 225 void cs_dsp_power_down(struct cs_dsp *dsp); 226 int cs_dsp_run(struct cs_dsp *dsp); 227 void cs_dsp_stop(struct cs_dsp *dsp); 228 229 void cs_dsp_remove(struct cs_dsp *dsp); 230 231 int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq); 232 void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp); 233 void cs_dsp_halo_bus_error(struct cs_dsp *dsp); 234 void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp); 235 236 void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root); 237 void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp); 238 239 int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id); 240 int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, 241 const void *buf, size_t len); 242 int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, 243 void *buf, size_t len); 244 struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, 245 unsigned int alg); 246 247 int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, 248 unsigned int num_words, __be32 *data); 249 int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data); 250 int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data); 251 void cs_dsp_remove_padding(u32 *buf, int nwords); 252 253 struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, 254 int type, unsigned int id); 255 256 const char *cs_dsp_mem_region_name(unsigned int type); 257 258 /** 259 * struct cs_dsp_chunk - Describes a buffer holding data formatted for the DSP 260 * @data: Pointer to underlying buffer memory 261 * @max: Pointer to end of the buffer memory 262 * @bytes: Number of bytes read/written into the memory chunk 263 * @cache: Temporary holding data as it is formatted 264 * @cachebits: Number of bits of data currently in cache 265 */ 266 struct cs_dsp_chunk { 267 u8 *data; 268 u8 *max; 269 int bytes; 270 271 u32 cache; 272 int cachebits; 273 }; 274 275 /** 276 * cs_dsp_chunk() - Create a DSP memory chunk 277 * @data: Pointer to the buffer that will be used to store data 278 * @size: Size of the buffer in bytes 279 * 280 * Return: A cs_dsp_chunk structure 281 */ 282 static inline struct cs_dsp_chunk cs_dsp_chunk(void *data, int size) 283 { 284 struct cs_dsp_chunk ch = { 285 .data = data, 286 .max = data + size, 287 }; 288 289 return ch; 290 } 291 292 /** 293 * cs_dsp_chunk_end() - Check if a DSP memory chunk is full 294 * @ch: Pointer to the chunk structure 295 * 296 * Return: True if the whole buffer has been read/written 297 */ 298 static inline bool cs_dsp_chunk_end(struct cs_dsp_chunk *ch) 299 { 300 return ch->data == ch->max; 301 } 302 303 /** 304 * cs_dsp_chunk_bytes() - Number of bytes written/read from a DSP memory chunk 305 * @ch: Pointer to the chunk structure 306 * 307 * Return: Number of bytes read/written to the buffer 308 */ 309 static inline int cs_dsp_chunk_bytes(struct cs_dsp_chunk *ch) 310 { 311 return ch->bytes; 312 } 313 314 /** 315 * cs_dsp_chunk_valid_addr() - Check if an address is in a DSP memory chunk 316 * @ch: Pointer to the chunk structure 317 * 318 * Return: True if the given address is within the buffer 319 */ 320 static inline bool cs_dsp_chunk_valid_addr(struct cs_dsp_chunk *ch, void *addr) 321 { 322 return (u8 *)addr >= ch->data && (u8 *)addr < ch->max; 323 } 324 325 int cs_dsp_chunk_write(struct cs_dsp_chunk *ch, int nbits, u32 val); 326 int cs_dsp_chunk_flush(struct cs_dsp_chunk *ch); 327 int cs_dsp_chunk_read(struct cs_dsp_chunk *ch, int nbits); 328 329 #endif 330