File Index
Files and directories
Sign in
FILE

cs_dsp.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/firmware/cirrus/cs_dsp.h C
  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 */
 60struct 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 */
 72struct 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 */
 96struct 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
115struct cs_dsp_ops;
116struct 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 */
150struct 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 */
209struct 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
219int cs_dsp_adsp1_init(struct cs_dsp *dsp);
220int cs_dsp_adsp2_init(struct cs_dsp *dsp);
221int cs_dsp_halo_init(struct cs_dsp *dsp);
222
223int 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);
227void cs_dsp_adsp1_power_down(struct cs_dsp *dsp);
228int 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);
232void cs_dsp_power_down(struct cs_dsp *dsp);
233int cs_dsp_run(struct cs_dsp *dsp);
234void cs_dsp_stop(struct cs_dsp *dsp);
235
236void cs_dsp_remove(struct cs_dsp *dsp);
237
238int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq);
239void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp);
240void cs_dsp_halo_bus_error(struct cs_dsp *dsp);
241void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp);
242
243void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root);
244void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp);
245
246int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id);
247int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off,
248			    const void *buf, size_t len);
249int cs_dsp_coeff_lock_and_write_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off,
250				     const void *buf, size_t len);
251int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off,
252			   void *buf, size_t len);
253int cs_dsp_coeff_lock_and_read_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off,
254				    void *buf, size_t len);
255struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type,
256					unsigned int alg);
257
258int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr,
259			       unsigned int num_words, __be32 *data);
260int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data);
261int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data);
262void cs_dsp_remove_padding(u32 *buf, int nwords);
263
264struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp,
265						 int type, unsigned int id);
266
267const 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 */
274struct cs_dsp_wseq {
275	struct cs_dsp_coeff_ctl *ctl;
276	struct list_head ops;
277};
278
279int cs_dsp_wseq_init(struct cs_dsp *dsp, struct cs_dsp_wseq *wseqs, unsigned int num_wseqs);
280int cs_dsp_wseq_write(struct cs_dsp *dsp, struct cs_dsp_wseq *wseq, u32 addr, u32 data,
281		      u8 op_code, bool update);
282int 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 */
294struct 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 */
310static 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 */
326static 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 */
337static 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 */
348static 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
353int cs_dsp_chunk_write(struct cs_dsp_chunk *ch, int nbits, u32 val);
354int cs_dsp_chunk_flush(struct cs_dsp_chunk *ch);
355int cs_dsp_chunk_read(struct cs_dsp_chunk *ch, int nbits);
356
357#endif
~/ Read-only file preview.