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