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