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 * Write sequence operation codes 47 */ 48 #define CS_DSP_WSEQ_FULL 0x00 49 #define CS_DSP_WSEQ_ADDR8 0x02 50 #define CS_DSP_WSEQ_L16 0x04 51 #define CS_DSP_WSEQ_H16 0x05 52 #define CS_DSP_WSEQ_UNLOCK 0xFD 53 #define CS_DSP_WSEQ_END 0xFF 54 55 /** 56 * struct cs_dsp_region - Describes a logical memory region in DSP address space 57 * @type: Memory region type 58 * @base: Address of region 59 */ 60 struct cs_dsp_region { 61 int type; 62 unsigned int base; 63 }; 64 65 /** 66 * struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space 67 * @alg: Algorithm id 68 * @ver: Expected algorithm version 69 * @type: Memory region type 70 * @base: Address of region 71 */ 72 struct cs_dsp_alg_region { 73 unsigned int alg; 74 unsigned int ver; 75 int type; 76 unsigned int base; 77 }; 78 79 /** 80 * struct cs_dsp_coeff_ctl - Describes a coefficient control 81 * @list: List node for internal use 82 * @dsp: DSP instance associated with this control 83 * @cache: Cached value of the control 84 * @fw_name: Name of the firmware 85 * @subname: Name of the control parsed from the WMFW 86 * @subname_len: Length of subname 87 * @offset: Offset of control within alg_region in words 88 * @len: Length of the cached value in bytes 89 * @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h 90 * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h 91 * @set: Flag indicating the value has been written by the user 92 * @enabled: Flag indicating whether control is enabled 93 * @alg_region: Logical region associated with this control 94 * @priv: For use by the client 95 */ 96 struct cs_dsp_coeff_ctl { 97 struct list_head list; 98 struct cs_dsp *dsp; 99 void *cache; 100 const char *fw_name; 101 /* Subname is needed to match with firmware */ 102 const char *subname; 103 unsigned int subname_len; 104 unsigned int offset; 105 unsigned int len; 106 unsigned int type; 107 unsigned int flags; 108 unsigned int set:1; 109 unsigned int enabled:1; 110 struct cs_dsp_alg_region alg_region; 111 112 void *priv; 113 }; 114 115 struct cs_dsp_ops; 116 struct cs_dsp_client_ops; 117 118 /** 119 * struct cs_dsp - Configuration and state of a Cirrus Logic DSP 120 * @name: The name of the DSP instance 121 * @rev: Revision of the DSP 122 * @num: DSP instance number 123 * @type: Type of DSP 124 * @dev: Driver model representation of the device 125 * @regmap: Register map of the device 126 * @ops: Function pointers for internal callbacks 127 * @client_ops: Function pointers for client callbacks 128 * @base: Address of the DSP registers 129 * @base_sysinfo: Address of the sysinfo register (Halo only) 130 * @sysclk_reg: Address of the sysclk register (ADSP1 only) 131 * @sysclk_mask: Mask of frequency bits within sysclk register (ADSP1 only) 132 * @sysclk_shift: Shift of frequency bits within sysclk register (ADSP1 only) 133 * @alg_regions: List of currently loaded algorithm regions 134 * @fw_name: Name of the current firmware 135 * @fw_id: ID of the current firmware, obtained from the wmfw 136 * @fw_id_version: Version of the firmware, obtained from the wmfw 137 * @fw_vendor_id: Vendor of the firmware, obtained from the wmfw 138 * @mem: DSP memory region descriptions 139 * @num_mems: Number of memory regions in this DSP 140 * @fw_ver: Version of the wmfw file format 141 * @booted: Flag indicating DSP has been configured 142 * @running: Flag indicating DSP is executing firmware 143 * @ctl_list: Controls defined within the loaded DSP firmware 144 * @lock_regions: Enable MPU traps on specified memory regions 145 * @pwr_lock: Lock used to serialize accesses 146 * @debugfs_root: Debugfs directory for this DSP instance 147 * @wmfw_file_name: Filename of the currently loaded firmware 148 * @bin_file_name: Filename of the currently loaded coefficients 149 */ 150 struct cs_dsp { 151 const char *name; 152 int rev; 153 int num; 154 int type; 155 struct device *dev; 156 struct regmap *regmap; 157 158 const struct cs_dsp_ops *ops; 159 const struct cs_dsp_client_ops *client_ops; 160 161 unsigned int base; 162 unsigned int base_sysinfo; 163 unsigned int sysclk_reg; 164 unsigned int sysclk_mask; 165 unsigned int sysclk_shift; 166 bool no_core_startstop; 167 168 struct list_head alg_regions; 169 170 const char *fw_name; 171 unsigned int fw_id; 172 unsigned int fw_id_version; 173 unsigned int fw_vendor_id; 174 175 const struct cs_dsp_region *mem; 176 int num_mems; 177 178 int wmfw_ver; 179 180 bool booted; 181 bool running; 182 183 struct list_head ctl_list; 184 185 struct mutex pwr_lock; 186 187 unsigned int lock_regions; 188 189 #ifdef CONFIG_DEBUG_FS 190 struct dentry *debugfs_root; 191 const char *wmfw_file_name; 192 const char *bin_file_name; 193 #endif 194 }; 195 196 /** 197 * struct cs_dsp_client_ops - client callbacks 198 * @control_add: Called under the pwr_lock when a control is created 199 * @control_remove: Called under the pwr_lock when a control is destroyed 200 * @pre_run: Called under the pwr_lock by cs_dsp_run() before the core is started 201 * @post_run: Called under the pwr_lock by cs_dsp_run() after the core is started 202 * @pre_stop: Called under the pwr_lock by cs_dsp_stop() before the core is stopped 203 * @post_stop: Called under the pwr_lock by cs_dsp_stop() after the core is stopped 204 * @watchdog_expired: Called when a watchdog expiry is detected 205 * 206 * These callbacks give the cs_dsp client an opportunity to respond to events 207 * or to perform actions atomically. 208 */ 209 struct cs_dsp_client_ops { 210 int (*control_add)(struct cs_dsp_coeff_ctl *ctl); 211 void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); 212 int (*pre_run)(struct cs_dsp *dsp); 213 int (*post_run)(struct cs_dsp *dsp); 214 void (*pre_stop)(struct cs_dsp *dsp); 215 void (*post_stop)(struct cs_dsp *dsp); 216 void (*watchdog_expired)(struct cs_dsp *dsp); 217 }; 218 219 int cs_dsp_adsp1_init(struct cs_dsp *dsp); 220 int cs_dsp_adsp2_init(struct cs_dsp *dsp); 221 int cs_dsp_halo_init(struct cs_dsp *dsp); 222 223 int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, 224 const struct firmware *wmfw_firmware, const char *wmfw_filename, 225 const struct firmware *coeff_firmware, const char *coeff_filename, 226 const char *fw_name); 227 void cs_dsp_adsp1_power_down(struct cs_dsp *dsp); 228 int cs_dsp_power_up(struct cs_dsp *dsp, 229 const struct firmware *wmfw_firmware, const char *wmfw_filename, 230 const struct firmware *coeff_firmware, const char *coeff_filename, 231 const char *fw_name); 232 void cs_dsp_power_down(struct cs_dsp *dsp); 233 int cs_dsp_run(struct cs_dsp *dsp); 234 void cs_dsp_stop(struct cs_dsp *dsp); 235 236 void cs_dsp_remove(struct cs_dsp *dsp); 237 238 int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq); 239 void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp); 240 void cs_dsp_halo_bus_error(struct cs_dsp *dsp); 241 void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp); 242 243 void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root); 244 void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp); 245 246 int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id); 247 int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, 248 const void *buf, size_t len); 249 int cs_dsp_coeff_lock_and_write_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, 250 const void *buf, size_t len); 251 int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, 252 void *buf, size_t len); 253 int cs_dsp_coeff_lock_and_read_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, 254 void *buf, size_t len); 255 struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, 256 unsigned int alg); 257 258 int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, 259 unsigned int num_words, __be32 *data); 260 int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data); 261 int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data); 262 void cs_dsp_remove_padding(u32 *buf, int nwords); 263 264 struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, 265 int type, unsigned int id); 266 267 const char *cs_dsp_mem_region_name(unsigned int type); 268 269 /** 270 * struct cs_dsp_wseq - Describes a write sequence 271 * @ctl: Write sequence cs_dsp control 272 * @ops: Operations contained within 273 */ 274 struct cs_dsp_wseq { 275 struct cs_dsp_coeff_ctl *ctl; 276 struct list_head ops; 277 }; 278 279 int cs_dsp_wseq_init(struct cs_dsp *dsp, struct cs_dsp_wseq *wseqs, unsigned int num_wseqs); 280 int cs_dsp_wseq_write(struct cs_dsp *dsp, struct cs_dsp_wseq *wseq, u32 addr, u32 data, 281 u8 op_code, bool update); 282 int cs_dsp_wseq_multi_write(struct cs_dsp *dsp, struct cs_dsp_wseq *wseq, 283 const struct reg_sequence *reg_seq, int num_regs, 284 u8 op_code, bool update); 285 286 /** 287 * struct cs_dsp_chunk - Describes a buffer holding data formatted for the DSP 288 * @data: Pointer to underlying buffer memory 289 * @max: Pointer to end of the buffer memory 290 * @bytes: Number of bytes read/written into the memory chunk 291 * @cache: Temporary holding data as it is formatted 292 * @cachebits: Number of bits of data currently in cache 293 */ 294 struct cs_dsp_chunk { 295 u8 *data; 296 u8 *max; 297 int bytes; 298 299 u32 cache; 300 int cachebits; 301 }; 302 303 /** 304 * cs_dsp_chunk() - Create a DSP memory chunk 305 * @data: Pointer to the buffer that will be used to store data 306 * @size: Size of the buffer in bytes 307 * 308 * Return: A cs_dsp_chunk structure 309 */ 310 static inline struct cs_dsp_chunk cs_dsp_chunk(void *data, int size) 311 { 312 struct cs_dsp_chunk ch = { 313 .data = data, 314 .max = data + size, 315 }; 316 317 return ch; 318 } 319 320 /** 321 * cs_dsp_chunk_end() - Check if a DSP memory chunk is full 322 * @ch: Pointer to the chunk structure 323 * 324 * Return: True if the whole buffer has been read/written 325 */ 326 static inline bool cs_dsp_chunk_end(struct cs_dsp_chunk *ch) 327 { 328 return ch->data == ch->max; 329 } 330 331 /** 332 * cs_dsp_chunk_bytes() - Number of bytes written/read from a DSP memory chunk 333 * @ch: Pointer to the chunk structure 334 * 335 * Return: Number of bytes read/written to the buffer 336 */ 337 static inline int cs_dsp_chunk_bytes(struct cs_dsp_chunk *ch) 338 { 339 return ch->bytes; 340 } 341 342 /** 343 * cs_dsp_chunk_valid_addr() - Check if an address is in a DSP memory chunk 344 * @ch: Pointer to the chunk structure 345 * 346 * Return: True if the given address is within the buffer 347 */ 348 static inline bool cs_dsp_chunk_valid_addr(struct cs_dsp_chunk *ch, void *addr) 349 { 350 return (u8 *)addr >= ch->data && (u8 *)addr < ch->max; 351 } 352 353 int cs_dsp_chunk_write(struct cs_dsp_chunk *ch, int nbits, u32 val); 354 int cs_dsp_chunk_flush(struct cs_dsp_chunk *ch); 355 int cs_dsp_chunk_read(struct cs_dsp_chunk *ch, int nbits); 356 357 #endif 358