diff options
Diffstat (limited to 'sound/soc/intel/common/sst-dsp-priv.h')
-rw-r--r-- | sound/soc/intel/common/sst-dsp-priv.h | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h new file mode 100644 index 000000000000..396d54510350 --- /dev/null +++ b/sound/soc/intel/common/sst-dsp-priv.h | |||
@@ -0,0 +1,373 @@ | |||
1 | /* | ||
2 | * Intel Smart Sound Technology | ||
3 | * | ||
4 | * Copyright (C) 2013, Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #ifndef __SOUND_SOC_SST_DSP_PRIV_H | ||
18 | #define __SOUND_SOC_SST_DSP_PRIV_H | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/firmware.h> | ||
24 | |||
25 | struct sst_mem_block; | ||
26 | struct sst_module; | ||
27 | struct sst_fw; | ||
28 | |||
29 | /* do we need to remove or keep */ | ||
30 | #define DSP_DRAM_ADDR_OFFSET 0x400000 | ||
31 | |||
32 | /* | ||
33 | * DSP Operations exported by platform Audio DSP driver. | ||
34 | */ | ||
35 | struct sst_ops { | ||
36 | /* DSP core boot / reset */ | ||
37 | void (*boot)(struct sst_dsp *); | ||
38 | void (*reset)(struct sst_dsp *); | ||
39 | int (*wake)(struct sst_dsp *); | ||
40 | void (*sleep)(struct sst_dsp *); | ||
41 | void (*stall)(struct sst_dsp *); | ||
42 | |||
43 | /* Shim IO */ | ||
44 | void (*write)(void __iomem *addr, u32 offset, u32 value); | ||
45 | u32 (*read)(void __iomem *addr, u32 offset); | ||
46 | void (*write64)(void __iomem *addr, u32 offset, u64 value); | ||
47 | u64 (*read64)(void __iomem *addr, u32 offset); | ||
48 | |||
49 | /* DSP I/DRAM IO */ | ||
50 | void (*ram_read)(struct sst_dsp *sst, void *dest, void __iomem *src, | ||
51 | size_t bytes); | ||
52 | void (*ram_write)(struct sst_dsp *sst, void __iomem *dest, void *src, | ||
53 | size_t bytes); | ||
54 | |||
55 | void (*dump)(struct sst_dsp *); | ||
56 | |||
57 | /* IRQ handlers */ | ||
58 | irqreturn_t (*irq_handler)(int irq, void *context); | ||
59 | |||
60 | /* SST init and free */ | ||
61 | int (*init)(struct sst_dsp *sst, struct sst_pdata *pdata); | ||
62 | void (*free)(struct sst_dsp *sst); | ||
63 | |||
64 | /* FW module parser/loader */ | ||
65 | int (*parse_fw)(struct sst_fw *sst_fw); | ||
66 | }; | ||
67 | |||
68 | /* | ||
69 | * Audio DSP memory offsets and addresses. | ||
70 | */ | ||
71 | struct sst_addr { | ||
72 | u32 lpe_base; | ||
73 | u32 shim_offset; | ||
74 | u32 iram_offset; | ||
75 | u32 dram_offset; | ||
76 | u32 dsp_iram_offset; | ||
77 | u32 dsp_dram_offset; | ||
78 | void __iomem *lpe; | ||
79 | void __iomem *shim; | ||
80 | void __iomem *pci_cfg; | ||
81 | void __iomem *fw_ext; | ||
82 | }; | ||
83 | |||
84 | /* | ||
85 | * Audio DSP Mailbox configuration. | ||
86 | */ | ||
87 | struct sst_mailbox { | ||
88 | void __iomem *in_base; | ||
89 | void __iomem *out_base; | ||
90 | size_t in_size; | ||
91 | size_t out_size; | ||
92 | }; | ||
93 | |||
94 | /* | ||
95 | * Audio DSP memory block types. | ||
96 | */ | ||
97 | enum sst_mem_type { | ||
98 | SST_MEM_IRAM = 0, | ||
99 | SST_MEM_DRAM = 1, | ||
100 | SST_MEM_ANY = 2, | ||
101 | SST_MEM_CACHE= 3, | ||
102 | }; | ||
103 | |||
104 | /* | ||
105 | * Audio DSP Generic Firmware File. | ||
106 | * | ||
107 | * SST Firmware files can consist of 1..N modules. This generic structure is | ||
108 | * used to manage each firmware file and it's modules regardless of SST firmware | ||
109 | * type. A SST driver may load multiple FW files. | ||
110 | */ | ||
111 | struct sst_fw { | ||
112 | struct sst_dsp *dsp; | ||
113 | |||
114 | /* base addresses of FW file data */ | ||
115 | dma_addr_t dmable_fw_paddr; /* physical address of fw data */ | ||
116 | void *dma_buf; /* virtual address of fw data */ | ||
117 | u32 size; /* size of fw data */ | ||
118 | |||
119 | /* lists */ | ||
120 | struct list_head list; /* DSP list of FW */ | ||
121 | struct list_head module_list; /* FW list of modules */ | ||
122 | |||
123 | void *private; /* core doesn't touch this */ | ||
124 | }; | ||
125 | |||
126 | /* | ||
127 | * Audio DSP Generic Module Template. | ||
128 | * | ||
129 | * Used to define and register a new FW module. This data is extracted from | ||
130 | * FW module header information. | ||
131 | */ | ||
132 | struct sst_module_template { | ||
133 | u32 id; | ||
134 | u32 entry; /* entry point */ | ||
135 | u32 scratch_size; | ||
136 | u32 persistent_size; | ||
137 | }; | ||
138 | |||
139 | /* | ||
140 | * Block Allocator - Used to allocate blocks of DSP memory. | ||
141 | */ | ||
142 | struct sst_block_allocator { | ||
143 | u32 id; | ||
144 | u32 offset; | ||
145 | int size; | ||
146 | enum sst_mem_type type; | ||
147 | }; | ||
148 | |||
149 | /* | ||
150 | * Runtime Module Instance - A module object can be instanciated multiple | ||
151 | * times within the DSP FW. | ||
152 | */ | ||
153 | struct sst_module_runtime { | ||
154 | struct sst_dsp *dsp; | ||
155 | int id; | ||
156 | struct sst_module *module; /* parent module we belong too */ | ||
157 | |||
158 | u32 persistent_offset; /* private memory offset */ | ||
159 | void *private; | ||
160 | |||
161 | struct list_head list; | ||
162 | struct list_head block_list; /* list of blocks used */ | ||
163 | }; | ||
164 | |||
165 | /* | ||
166 | * Runtime Module Context - The runtime context must be manually stored by the | ||
167 | * driver prior to enter S3 and restored after leaving S3. This should really be | ||
168 | * part of the memory context saved by the enter D3 message IPC ??? | ||
169 | */ | ||
170 | struct sst_module_runtime_context { | ||
171 | dma_addr_t dma_buffer; | ||
172 | u32 *buffer; | ||
173 | }; | ||
174 | |||
175 | /* | ||
176 | * Audio DSP Module State | ||
177 | */ | ||
178 | enum sst_module_state { | ||
179 | SST_MODULE_STATE_UNLOADED = 0, /* default state */ | ||
180 | SST_MODULE_STATE_LOADED, | ||
181 | SST_MODULE_STATE_INITIALIZED, /* and inactive */ | ||
182 | SST_MODULE_STATE_ACTIVE, | ||
183 | }; | ||
184 | |||
185 | /* | ||
186 | * Audio DSP Generic Module. | ||
187 | * | ||
188 | * Each Firmware file can consist of 1..N modules. A module can span multiple | ||
189 | * ADSP memory blocks. The simplest FW will be a file with 1 module. A module | ||
190 | * can be instanciated multiple times in the DSP. | ||
191 | */ | ||
192 | struct sst_module { | ||
193 | struct sst_dsp *dsp; | ||
194 | struct sst_fw *sst_fw; /* parent FW we belong too */ | ||
195 | |||
196 | /* module configuration */ | ||
197 | u32 id; | ||
198 | u32 entry; /* module entry point */ | ||
199 | s32 offset; /* module offset in firmware file */ | ||
200 | u32 size; /* module size */ | ||
201 | u32 scratch_size; /* global scratch memory required */ | ||
202 | u32 persistent_size; /* private memory required */ | ||
203 | enum sst_mem_type type; /* destination memory type */ | ||
204 | u32 data_offset; /* offset in ADSP memory space */ | ||
205 | void *data; /* module data */ | ||
206 | |||
207 | /* runtime */ | ||
208 | u32 usage_count; /* can be unloaded if count == 0 */ | ||
209 | void *private; /* core doesn't touch this */ | ||
210 | |||
211 | /* lists */ | ||
212 | struct list_head block_list; /* Module list of blocks in use */ | ||
213 | struct list_head list; /* DSP list of modules */ | ||
214 | struct list_head list_fw; /* FW list of modules */ | ||
215 | struct list_head runtime_list; /* list of runtime module objects*/ | ||
216 | |||
217 | /* state */ | ||
218 | enum sst_module_state state; | ||
219 | }; | ||
220 | |||
221 | /* | ||
222 | * SST Memory Block operations. | ||
223 | */ | ||
224 | struct sst_block_ops { | ||
225 | int (*enable)(struct sst_mem_block *block); | ||
226 | int (*disable)(struct sst_mem_block *block); | ||
227 | }; | ||
228 | |||
229 | /* | ||
230 | * SST Generic Memory Block. | ||
231 | * | ||
232 | * SST ADP memory has multiple IRAM and DRAM blocks. Some ADSP blocks can be | ||
233 | * power gated. | ||
234 | */ | ||
235 | struct sst_mem_block { | ||
236 | struct sst_dsp *dsp; | ||
237 | struct sst_module *module; /* module that uses this block */ | ||
238 | |||
239 | /* block config */ | ||
240 | u32 offset; /* offset from base */ | ||
241 | u32 size; /* block size */ | ||
242 | u32 index; /* block index 0..N */ | ||
243 | enum sst_mem_type type; /* block memory type IRAM/DRAM */ | ||
244 | struct sst_block_ops *ops; /* block operations, if any */ | ||
245 | |||
246 | /* block status */ | ||
247 | u32 bytes_used; /* bytes in use by modules */ | ||
248 | void *private; /* generic core does not touch this */ | ||
249 | int users; /* number of modules using this block */ | ||
250 | |||
251 | /* block lists */ | ||
252 | struct list_head module_list; /* Module list of blocks */ | ||
253 | struct list_head list; /* Map list of free/used blocks */ | ||
254 | }; | ||
255 | |||
256 | /* | ||
257 | * Generic SST Shim Interface. | ||
258 | */ | ||
259 | struct sst_dsp { | ||
260 | |||
261 | /* runtime */ | ||
262 | struct sst_dsp_device *sst_dev; | ||
263 | spinlock_t spinlock; /* IPC locking */ | ||
264 | struct mutex mutex; /* DSP FW lock */ | ||
265 | struct device *dev; | ||
266 | struct device *dma_dev; | ||
267 | void *thread_context; | ||
268 | int irq; | ||
269 | u32 id; | ||
270 | |||
271 | /* list of free and used ADSP memory blocks */ | ||
272 | struct list_head used_block_list; | ||
273 | struct list_head free_block_list; | ||
274 | |||
275 | /* operations */ | ||
276 | struct sst_ops *ops; | ||
277 | |||
278 | /* debug FS */ | ||
279 | struct dentry *debugfs_root; | ||
280 | |||
281 | /* base addresses */ | ||
282 | struct sst_addr addr; | ||
283 | |||
284 | /* mailbox */ | ||
285 | struct sst_mailbox mailbox; | ||
286 | |||
287 | /* SST FW files loaded and their modules */ | ||
288 | struct list_head module_list; | ||
289 | struct list_head fw_list; | ||
290 | |||
291 | /* scratch buffer */ | ||
292 | struct list_head scratch_block_list; | ||
293 | u32 scratch_offset; | ||
294 | u32 scratch_size; | ||
295 | |||
296 | /* platform data */ | ||
297 | struct sst_pdata *pdata; | ||
298 | |||
299 | /* DMA FW loading */ | ||
300 | struct sst_dma *dma; | ||
301 | bool fw_use_dma; | ||
302 | }; | ||
303 | |||
304 | /* Size optimised DRAM/IRAM memcpy */ | ||
305 | static inline void sst_dsp_write(struct sst_dsp *sst, void *src, | ||
306 | u32 dest_offset, size_t bytes) | ||
307 | { | ||
308 | sst->ops->ram_write(sst, sst->addr.lpe + dest_offset, src, bytes); | ||
309 | } | ||
310 | |||
311 | static inline void sst_dsp_read(struct sst_dsp *sst, void *dest, | ||
312 | u32 src_offset, size_t bytes) | ||
313 | { | ||
314 | sst->ops->ram_read(sst, dest, sst->addr.lpe + src_offset, bytes); | ||
315 | } | ||
316 | |||
317 | static inline void *sst_dsp_get_thread_context(struct sst_dsp *sst) | ||
318 | { | ||
319 | return sst->thread_context; | ||
320 | } | ||
321 | |||
322 | /* Create/Free FW files - can contain multiple modules */ | ||
323 | struct sst_fw *sst_fw_new(struct sst_dsp *dsp, | ||
324 | const struct firmware *fw, void *private); | ||
325 | void sst_fw_free(struct sst_fw *sst_fw); | ||
326 | void sst_fw_free_all(struct sst_dsp *dsp); | ||
327 | int sst_fw_reload(struct sst_fw *sst_fw); | ||
328 | void sst_fw_unload(struct sst_fw *sst_fw); | ||
329 | |||
330 | /* Create/Free firmware modules */ | ||
331 | struct sst_module *sst_module_new(struct sst_fw *sst_fw, | ||
332 | struct sst_module_template *template, void *private); | ||
333 | void sst_module_free(struct sst_module *module); | ||
334 | struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id); | ||
335 | int sst_module_alloc_blocks(struct sst_module *module); | ||
336 | int sst_module_free_blocks(struct sst_module *module); | ||
337 | |||
338 | /* Create/Free firmware module runtime instances */ | ||
339 | struct sst_module_runtime *sst_module_runtime_new(struct sst_module *module, | ||
340 | int id, void *private); | ||
341 | void sst_module_runtime_free(struct sst_module_runtime *runtime); | ||
342 | struct sst_module_runtime *sst_module_runtime_get_from_id( | ||
343 | struct sst_module *module, u32 id); | ||
344 | int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime, | ||
345 | int offset); | ||
346 | int sst_module_runtime_free_blocks(struct sst_module_runtime *runtime); | ||
347 | int sst_module_runtime_save(struct sst_module_runtime *runtime, | ||
348 | struct sst_module_runtime_context *context); | ||
349 | int sst_module_runtime_restore(struct sst_module_runtime *runtime, | ||
350 | struct sst_module_runtime_context *context); | ||
351 | |||
352 | /* generic block allocation */ | ||
353 | int sst_alloc_blocks(struct sst_dsp *dsp, struct sst_block_allocator *ba, | ||
354 | struct list_head *block_list); | ||
355 | int sst_free_blocks(struct sst_dsp *dsp, struct list_head *block_list); | ||
356 | |||
357 | /* scratch allocation */ | ||
358 | int sst_block_alloc_scratch(struct sst_dsp *dsp); | ||
359 | void sst_block_free_scratch(struct sst_dsp *dsp); | ||
360 | |||
361 | /* Register the DSPs memory blocks - would be nice to read from ACPI */ | ||
362 | struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset, | ||
363 | u32 size, enum sst_mem_type type, struct sst_block_ops *ops, u32 index, | ||
364 | void *private); | ||
365 | void sst_mem_block_unregister_all(struct sst_dsp *dsp); | ||
366 | |||
367 | /* Create/Free DMA resources */ | ||
368 | int sst_dma_new(struct sst_dsp *sst); | ||
369 | void sst_dma_free(struct sst_dma *dma); | ||
370 | |||
371 | u32 sst_dsp_get_offset(struct sst_dsp *dsp, u32 offset, | ||
372 | enum sst_mem_type type); | ||
373 | #endif | ||