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 #define CS_ADSP2_REGION_0 BIT(0) 15 #define CS_ADSP2_REGION_1 BIT(1) 16 #define CS_ADSP2_REGION_2 BIT(2) 17 #define CS_ADSP2_REGION_3 BIT(3) 18 #define CS_ADSP2_REGION_4 BIT(4) 19 #define CS_ADSP2_REGION_5 BIT(5) 20 #define CS_ADSP2_REGION_6 BIT(6) 21 #define CS_ADSP2_REGION_7 BIT(7) 22 #define CS_ADSP2_REGION_8 BIT(8) 23 #define CS_ADSP2_REGION_9 BIT(9) 24 #define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \ 25 CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \ 26 CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \ 27 CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \ 28 CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9) 29 #define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9) 30 31 #define CS_DSP_DATA_WORD_SIZE 3 32 33 #define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 34 #define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 35 #define CS_DSP_ACKED_CTL_MIN_VALUE 0 36 #define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF 37 38 /** 39 * struct cs_dsp_region - Describes a logical memory region in DSP address space 40 * @type: Memory region type 41 * @base: Address of region 42 */ 43 struct cs_dsp_region { 44 int type; 45 unsigned int base; 46 }; 47 48 /** 49 * struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space 50 * @list: List node for internal use 51 * @alg: Algorithm id 52 * @type: Memory region type 53 * @base: Address of region 54 */ 55 struct cs_dsp_alg_region { 56 struct list_head list; 57 unsigned int alg; 58 int type; 59 unsigned int base; 60 }; 61 62 /** 63 * struct cs_dsp_coeff_ctl - Describes a coefficient control 64 * @fw_name: Name of the firmware 65 * @subname: Name of the control parsed from the WMFW 66 * @subname_len: Length of subname 67 * @alg_region: Logical region associated with this control 68 * @dsp: DSP instance associated with this control 69 * @enabled: Flag indicating whether control is enabled 70 * @list: List node for internal use 71 * @cache: Cached value of the control 72 * @offset: Offset of control within alg_region 73 * @len: Length of the cached value 74 * @set: Flag indicating the value has been written by the user 75 * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h 76 * @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h 77 * @priv: For use by the client 78 */ 79 struct cs_dsp_coeff_ctl { 80 const char *fw_name; 81 /* Subname is needed to match with firmware */ 82 const char *subname; 83 unsigned int subname_len; 84 struct cs_dsp_alg_region alg_region; 85 struct cs_dsp *dsp; 86 unsigned int enabled:1; 87 struct list_head list; 88 void *cache; 89 unsigned int offset; 90 size_t len; 91 unsigned int set:1; 92 unsigned int flags; 93 unsigned int type; 94 95 void *priv; 96 }; 97 98 struct cs_dsp_ops; 99 struct cs_dsp_client_ops; 100 101 /** 102 * struct cs_dsp - Configuration and state of a Cirrus Logic DSP 103 * @name: The name of the DSP instance 104 * @rev: Revision of the DSP 105 * @num: DSP instance number 106 * @type: Type of DSP 107 * @dev: Driver model representation of the device 108 * @regmap: Register map of the device 109 * @ops: Function pointers for internal callbacks 110 * @client_ops: Function pointers for client callbacks 111 * @base: Address of the DSP registers 112 * @base_sysinfo: Address of the sysinfo register (Halo only) 113 * @sysclk_reg: Address of the sysclk register (ADSP1 only) 114 * @sysclk_mask: Mask of frequency bits within sysclk register (ADSP1 only) 115 * @sysclk_shift: Shift of frequency bits within sysclk register (ADSP1 only) 116 * @alg_regions: List of currently loaded algorithm regions 117 * @fw_file_name: Filename of the current firmware 118 * @fw_name: Name of the current firmware 119 * @fw_id: ID of the current firmware, obtained from the wmfw 120 * @fw_id_version: Version of the firmware, obtained from the wmfw 121 * @fw_vendor_id: Vendor of the firmware, obtained from the wmfw 122 * @mem: DSP memory region descriptions 123 * @num_mems: Number of memory regions in this DSP 124 * @fw_ver: Version of the wmfw file format 125 * @booted: Flag indicating DSP has been configured 126 * @running: Flag indicating DSP is executing firmware 127 * @ctl_list: Controls defined within the loaded DSP firmware 128 * @lock_regions: Enable MPU traps on specified memory regions 129 * @pwr_lock: Lock used to serialize accesses 130 * @debugfs_root: Debugfs directory for this DSP instance 131 * @wmfw_file_name: Filename of the currently loaded firmware 132 * @bin_file_name: Filename of the currently loaded coefficients 133 */ 134 struct cs_dsp { 135 const char *name; 136 int rev; 137 int num; 138 int type; 139 struct device *dev; 140 struct regmap *regmap; 141 142 const struct cs_dsp_ops *ops; 143 const struct cs_dsp_client_ops *client_ops; 144 145 unsigned int base; 146 unsigned int base_sysinfo; 147 unsigned int sysclk_reg; 148 unsigned int sysclk_mask; 149 unsigned int sysclk_shift; 150 151 struct list_head alg_regions; 152 153 const char *fw_name; 154 unsigned int fw_id; 155 unsigned int fw_id_version; 156 unsigned int fw_vendor_id; 157 158 const struct cs_dsp_region *mem; 159 int num_mems; 160 161 int fw_ver; 162 163 bool booted; 164 bool running; 165 166 struct list_head ctl_list; 167 168 struct mutex pwr_lock; 169 170 unsigned int lock_regions; 171 172 #ifdef CONFIG_DEBUG_FS 173 struct dentry *debugfs_root; 174 char *wmfw_file_name; 175 char *bin_file_name; 176 #endif 177 }; 178 179 /** 180 * struct cs_dsp_client_ops - client callbacks 181 * @control_add: Called under the pwr_lock when a control is created 182 * @control_remove: Called under the pwr_lock when a control is destroyed 183 * @post_run: Called under the pwr_lock by cs_dsp_run() 184 * @post_stop: Called under the pwr_lock by cs_dsp_stop() 185 * @watchdog_expired: Called when a watchdog expiry is detected 186 * 187 * These callbacks give the cs_dsp client an opportunity to respond to events 188 * or to perform actions atomically. 189 */ 190 struct cs_dsp_client_ops { 191 int (*control_add)(struct cs_dsp_coeff_ctl *ctl); 192 void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); 193 int (*post_run)(struct cs_dsp *dsp); 194 void (*post_stop)(struct cs_dsp *dsp); 195 void (*watchdog_expired)(struct cs_dsp *dsp); 196 }; 197 198 int cs_dsp_adsp1_init(struct cs_dsp *dsp); 199 int cs_dsp_adsp2_init(struct cs_dsp *dsp); 200 int cs_dsp_halo_init(struct cs_dsp *dsp); 201 202 int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, 203 const struct firmware *wmfw_firmware, char *wmfw_filename, 204 const struct firmware *coeff_firmware, char *coeff_filename, 205 const char *fw_name); 206 void cs_dsp_adsp1_power_down(struct cs_dsp *dsp); 207 int cs_dsp_power_up(struct cs_dsp *dsp, 208 const struct firmware *wmfw_firmware, char *wmfw_filename, 209 const struct firmware *coeff_firmware, char *coeff_filename, 210 const char *fw_name); 211 void cs_dsp_power_down(struct cs_dsp *dsp); 212 int cs_dsp_run(struct cs_dsp *dsp); 213 void cs_dsp_stop(struct cs_dsp *dsp); 214 215 void cs_dsp_remove(struct cs_dsp *dsp); 216 217 int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq); 218 void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp); 219 void cs_dsp_halo_bus_error(struct cs_dsp *dsp); 220 void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp); 221 222 void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root); 223 void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp); 224 225 int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id); 226 int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len); 227 int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len); 228 struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, 229 unsigned int alg); 230 231 int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, 232 unsigned int num_words, __be32 *data); 233 int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data); 234 int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data); 235 void cs_dsp_remove_padding(u32 *buf, int nwords); 236 237 struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, 238 int type, unsigned int id); 239 240 const char *cs_dsp_mem_region_name(unsigned int type); 241 242 #endif 243