~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/linux/firmware/cirrus/cs_dsp.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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  */
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  */
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  */
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  */
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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php