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 | ||
25 | struct sst_mem_block; | |
26 | struct sst_module; | |
27 | struct sst_fw; | |
28 | ||
e9600bc1 LG |
29 | /* do we need to remove or keep */ |
30 | #define DSP_DRAM_ADDR_OFFSET 0x400000 | |
31 | ||
a4b12990 MB |
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 *); | |
d96c53a1 LG |
39 | int (*wake)(struct sst_dsp *); |
40 | void (*sleep)(struct sst_dsp *); | |
41 | void (*stall)(struct sst_dsp *); | |
a4b12990 MB |
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; | |
e9600bc1 LG |
76 | u32 dsp_iram_offset; |
77 | u32 dsp_dram_offset; | |
a4b12990 MB |
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 | ||
a4b12990 MB |
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 | ||
a4b12990 MB |
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 */ | |
e9600bc1 LG |
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; | |
a4b12990 MB |
173 | }; |
174 | ||
9449d39b LH |
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 | ||
a4b12990 MB |
185 | /* |
186 | * Audio DSP Generic Module. | |
187 | * | |
188 | * Each Firmware file can consist of 1..N modules. A module can span multiple | |
e9600bc1 LG |
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. | |
a4b12990 MB |
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 */ | |
e9600bc1 | 199 | s32 offset; /* module offset in firmware file */ |
a4b12990 | 200 | u32 size; /* module size */ |
e9600bc1 LG |
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 */ | |
a4b12990 MB |
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 */ | |
e9600bc1 | 215 | struct list_head runtime_list; /* list of runtime module objects*/ |
9449d39b LH |
216 | |
217 | /* state */ | |
218 | enum sst_module_state state; | |
a4b12990 MB |
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 */ | |
a4b12990 MB |
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; | |
10df3509 | 266 | struct device *dma_dev; |
a4b12990 MB |
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 | ||
e9600bc1 LG |
291 | /* scratch buffer */ |
292 | struct list_head scratch_block_list; | |
293 | u32 scratch_offset; | |
294 | u32 scratch_size; | |
295 | ||
a4b12990 MB |
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); | |
555f8a80 LG |
327 | int sst_fw_reload(struct sst_fw *sst_fw); |
328 | void sst_fw_unload(struct sst_fw *sst_fw); | |
a4b12990 MB |
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); | |
e9600bc1 | 333 | void sst_module_free(struct sst_module *module); |
a4b12990 | 334 | struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id); |
e9600bc1 LG |
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); | |
a4b12990 MB |
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 | ||
e9600bc1 LG |
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); | |
a4b12990 | 373 | #endif |