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