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