Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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/device.h>
15#include <linux/firmware.h>
16#include <linux/list.h>
17#include <linux/regmap.h>
18
19#define CS_ADSP2_REGION_0 BIT(0)
20#define CS_ADSP2_REGION_1 BIT(1)
21#define CS_ADSP2_REGION_2 BIT(2)
22#define CS_ADSP2_REGION_3 BIT(3)
23#define CS_ADSP2_REGION_4 BIT(4)
24#define CS_ADSP2_REGION_5 BIT(5)
25#define CS_ADSP2_REGION_6 BIT(6)
26#define CS_ADSP2_REGION_7 BIT(7)
27#define CS_ADSP2_REGION_8 BIT(8)
28#define CS_ADSP2_REGION_9 BIT(9)
29#define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \
30 CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \
31 CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \
32 CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \
33 CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9)
34#define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9)
35
36#define CS_DSP_DATA_WORD_SIZE 3
37
38#define CS_DSP_ACKED_CTL_TIMEOUT_MS 100
39#define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10
40#define CS_DSP_ACKED_CTL_MIN_VALUE 0
41#define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF
42
43/**
44 * struct cs_dsp_region - Describes a logical memory region in DSP address space
45 * @type: Memory region type
46 * @base: Address of region
47 */
48struct cs_dsp_region {
49 int type;
50 unsigned int base;
51};
52
53/**
54 * struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space
55 * @list: List node for internal use
56 * @alg: Algorithm id
57 * @ver: Expected algorithm version
58 * @type: Memory region type
59 * @base: Address of region
60 */
61struct cs_dsp_alg_region {
62 struct list_head list;
63 unsigned int alg;
64 unsigned int ver;
65 int type;
66 unsigned int base;
67};
68
69/**
70 * struct cs_dsp_coeff_ctl - Describes a coefficient control
71 * @fw_name: Name of the firmware
72 * @subname: Name of the control parsed from the WMFW
73 * @subname_len: Length of subname
74 * @alg_region: Logical region associated with this control
75 * @dsp: DSP instance associated with this control
76 * @enabled: Flag indicating whether control is enabled
77 * @list: List node for internal use
78 * @cache: Cached value of the control
79 * @offset: Offset of control within alg_region in words
80 * @len: Length of the cached value in bytes
81 * @set: Flag indicating the value has been written by the user
82 * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h
83 * @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h
84 * @priv: For use by the client
85 */
86struct cs_dsp_coeff_ctl {
87 const char *fw_name;
88 /* Subname is needed to match with firmware */
89 const char *subname;
90 unsigned int subname_len;
91 struct cs_dsp_alg_region alg_region;
92 struct cs_dsp *dsp;
93 unsigned int enabled:1;
94 struct list_head list;
95 void *cache;
96 unsigned int offset;
97 size_t len;
98 unsigned int set:1;
99 unsigned int flags;
100 unsigned int type;
101
102 void *priv;
103};
104
105struct cs_dsp_ops;
106struct cs_dsp_client_ops;
107
108/**
109 * struct cs_dsp - Configuration and state of a Cirrus Logic DSP
110 * @name: The name of the DSP instance
111 * @rev: Revision of the DSP
112 * @num: DSP instance number
113 * @type: Type of DSP
114 * @dev: Driver model representation of the device
115 * @regmap: Register map of the device
116 * @ops: Function pointers for internal callbacks
117 * @client_ops: Function pointers for client callbacks
118 * @base: Address of the DSP registers
119 * @base_sysinfo: Address of the sysinfo register (Halo only)
120 * @sysclk_reg: Address of the sysclk register (ADSP1 only)
121 * @sysclk_mask: Mask of frequency bits within sysclk register (ADSP1 only)
122 * @sysclk_shift: Shift of frequency bits within sysclk register (ADSP1 only)
123 * @alg_regions: List of currently loaded algorithm regions
124 * @fw_file_name: Filename of the current firmware
125 * @fw_name: Name of the current firmware
126 * @fw_id: ID of the current firmware, obtained from the wmfw
127 * @fw_id_version: Version of the firmware, obtained from the wmfw
128 * @fw_vendor_id: Vendor of the firmware, obtained from the wmfw
129 * @mem: DSP memory region descriptions
130 * @num_mems: Number of memory regions in this DSP
131 * @fw_ver: Version of the wmfw file format
132 * @booted: Flag indicating DSP has been configured
133 * @running: Flag indicating DSP is executing firmware
134 * @ctl_list: Controls defined within the loaded DSP firmware
135 * @lock_regions: Enable MPU traps on specified memory regions
136 * @pwr_lock: Lock used to serialize accesses
137 * @debugfs_root: Debugfs directory for this DSP instance
138 * @wmfw_file_name: Filename of the currently loaded firmware
139 * @bin_file_name: Filename of the currently loaded coefficients
140 */
141struct cs_dsp {
142 const char *name;
143 int rev;
144 int num;
145 int type;
146 struct device *dev;
147 struct regmap *regmap;
148
149 const struct cs_dsp_ops *ops;
150 const struct cs_dsp_client_ops *client_ops;
151
152 unsigned int base;
153 unsigned int base_sysinfo;
154 unsigned int sysclk_reg;
155 unsigned int sysclk_mask;
156 unsigned int sysclk_shift;
157
158 struct list_head alg_regions;
159
160 const char *fw_name;
161 unsigned int fw_id;
162 unsigned int fw_id_version;
163 unsigned int fw_vendor_id;
164
165 const struct cs_dsp_region *mem;
166 int num_mems;
167
168 int fw_ver;
169
170 bool booted;
171 bool running;
172
173 struct list_head ctl_list;
174
175 struct mutex pwr_lock;
176
177 unsigned int lock_regions;
178
179#ifdef CONFIG_DEBUG_FS
180 struct dentry *debugfs_root;
181 char *wmfw_file_name;
182 char *bin_file_name;
183#endif
184};
185
186/**
187 * struct cs_dsp_client_ops - client callbacks
188 * @control_add: Called under the pwr_lock when a control is created
189 * @control_remove: Called under the pwr_lock when a control is destroyed
190 * @pre_run: Called under the pwr_lock by cs_dsp_run() before the core is started
191 * @post_run: Called under the pwr_lock by cs_dsp_run() after the core is started
192 * @post_stop: Called under the pwr_lock by cs_dsp_stop()
193 * @watchdog_expired: Called when a watchdog expiry is detected
194 *
195 * These callbacks give the cs_dsp client an opportunity to respond to events
196 * or to perform actions atomically.
197 */
198struct cs_dsp_client_ops {
199 int (*control_add)(struct cs_dsp_coeff_ctl *ctl);
200 void (*control_remove)(struct cs_dsp_coeff_ctl *ctl);
201 int (*pre_run)(struct cs_dsp *dsp);
202 int (*post_run)(struct cs_dsp *dsp);
203 void (*post_stop)(struct cs_dsp *dsp);
204 void (*watchdog_expired)(struct cs_dsp *dsp);
205};
206
207int cs_dsp_adsp1_init(struct cs_dsp *dsp);
208int cs_dsp_adsp2_init(struct cs_dsp *dsp);
209int cs_dsp_halo_init(struct cs_dsp *dsp);
210
211int cs_dsp_adsp1_power_up(struct cs_dsp *dsp,
212 const struct firmware *wmfw_firmware, char *wmfw_filename,
213 const struct firmware *coeff_firmware, char *coeff_filename,
214 const char *fw_name);
215void cs_dsp_adsp1_power_down(struct cs_dsp *dsp);
216int cs_dsp_power_up(struct cs_dsp *dsp,
217 const struct firmware *wmfw_firmware, char *wmfw_filename,
218 const struct firmware *coeff_firmware, char *coeff_filename,
219 const char *fw_name);
220void cs_dsp_power_down(struct cs_dsp *dsp);
221int cs_dsp_run(struct cs_dsp *dsp);
222void cs_dsp_stop(struct cs_dsp *dsp);
223
224void cs_dsp_remove(struct cs_dsp *dsp);
225
226int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq);
227void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp);
228void cs_dsp_halo_bus_error(struct cs_dsp *dsp);
229void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp);
230
231void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root);
232void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp);
233
234int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id);
235int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off,
236 const void *buf, size_t len);
237int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off,
238 void *buf, size_t len);
239struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type,
240 unsigned int alg);
241
242int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr,
243 unsigned int num_words, __be32 *data);
244int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data);
245int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data);
246void cs_dsp_remove_padding(u32 *buf, int nwords);
247
248struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp,
249 int type, unsigned int id);
250
251const char *cs_dsp_mem_region_name(unsigned int type);
252
253#endif