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 | ||
175 | /* | |
176 | * Audio DSP Generic Module. | |
177 | * | |
178 | * Each Firmware file can consist of 1..N modules. A module can span multiple | |
e9600bc1 LG |
179 | * ADSP memory blocks. The simplest FW will be a file with 1 module. A module |
180 | * can be instanciated multiple times in the DSP. | |
a4b12990 MB |
181 | */ |
182 | struct sst_module { | |
183 | struct sst_dsp *dsp; | |
184 | struct sst_fw *sst_fw; /* parent FW we belong too */ | |
185 | ||
186 | /* module configuration */ | |
187 | u32 id; | |
188 | u32 entry; /* module entry point */ | |
e9600bc1 | 189 | s32 offset; /* module offset in firmware file */ |
a4b12990 | 190 | u32 size; /* module size */ |
e9600bc1 LG |
191 | u32 scratch_size; /* global scratch memory required */ |
192 | u32 persistent_size; /* private memory required */ | |
193 | enum sst_mem_type type; /* destination memory type */ | |
194 | u32 data_offset; /* offset in ADSP memory space */ | |
195 | void *data; /* module data */ | |
a4b12990 MB |
196 | |
197 | /* runtime */ | |
198 | u32 usage_count; /* can be unloaded if count == 0 */ | |
199 | void *private; /* core doesn't touch this */ | |
200 | ||
201 | /* lists */ | |
202 | struct list_head block_list; /* Module list of blocks in use */ | |
203 | struct list_head list; /* DSP list of modules */ | |
204 | struct list_head list_fw; /* FW list of modules */ | |
e9600bc1 | 205 | struct list_head runtime_list; /* list of runtime module objects*/ |
a4b12990 MB |
206 | }; |
207 | ||
208 | /* | |
209 | * SST Memory Block operations. | |
210 | */ | |
211 | struct sst_block_ops { | |
212 | int (*enable)(struct sst_mem_block *block); | |
213 | int (*disable)(struct sst_mem_block *block); | |
214 | }; | |
215 | ||
216 | /* | |
217 | * SST Generic Memory Block. | |
218 | * | |
219 | * SST ADP memory has multiple IRAM and DRAM blocks. Some ADSP blocks can be | |
220 | * power gated. | |
221 | */ | |
222 | struct sst_mem_block { | |
223 | struct sst_dsp *dsp; | |
224 | struct sst_module *module; /* module that uses this block */ | |
225 | ||
226 | /* block config */ | |
227 | u32 offset; /* offset from base */ | |
228 | u32 size; /* block size */ | |
229 | u32 index; /* block index 0..N */ | |
230 | enum sst_mem_type type; /* block memory type IRAM/DRAM */ | |
231 | struct sst_block_ops *ops; /* block operations, if any */ | |
232 | ||
233 | /* block status */ | |
a4b12990 MB |
234 | u32 bytes_used; /* bytes in use by modules */ |
235 | void *private; /* generic core does not touch this */ | |
236 | int users; /* number of modules using this block */ | |
237 | ||
238 | /* block lists */ | |
239 | struct list_head module_list; /* Module list of blocks */ | |
240 | struct list_head list; /* Map list of free/used blocks */ | |
241 | }; | |
242 | ||
243 | /* | |
244 | * Generic SST Shim Interface. | |
245 | */ | |
246 | struct sst_dsp { | |
247 | ||
248 | /* runtime */ | |
249 | struct sst_dsp_device *sst_dev; | |
250 | spinlock_t spinlock; /* IPC locking */ | |
251 | struct mutex mutex; /* DSP FW lock */ | |
252 | struct device *dev; | |
10df3509 | 253 | struct device *dma_dev; |
a4b12990 MB |
254 | void *thread_context; |
255 | int irq; | |
256 | u32 id; | |
257 | ||
258 | /* list of free and used ADSP memory blocks */ | |
259 | struct list_head used_block_list; | |
260 | struct list_head free_block_list; | |
261 | ||
262 | /* operations */ | |
263 | struct sst_ops *ops; | |
264 | ||
265 | /* debug FS */ | |
266 | struct dentry *debugfs_root; | |
267 | ||
268 | /* base addresses */ | |
269 | struct sst_addr addr; | |
270 | ||
271 | /* mailbox */ | |
272 | struct sst_mailbox mailbox; | |
273 | ||
274 | /* SST FW files loaded and their modules */ | |
275 | struct list_head module_list; | |
276 | struct list_head fw_list; | |
277 | ||
e9600bc1 LG |
278 | /* scratch buffer */ |
279 | struct list_head scratch_block_list; | |
280 | u32 scratch_offset; | |
281 | u32 scratch_size; | |
282 | ||
a4b12990 MB |
283 | /* platform data */ |
284 | struct sst_pdata *pdata; | |
285 | ||
286 | /* DMA FW loading */ | |
287 | struct sst_dma *dma; | |
288 | bool fw_use_dma; | |
289 | }; | |
290 | ||
291 | /* Size optimised DRAM/IRAM memcpy */ | |
292 | static inline void sst_dsp_write(struct sst_dsp *sst, void *src, | |
293 | u32 dest_offset, size_t bytes) | |
294 | { | |
295 | sst->ops->ram_write(sst, sst->addr.lpe + dest_offset, src, bytes); | |
296 | } | |
297 | ||
298 | static inline void sst_dsp_read(struct sst_dsp *sst, void *dest, | |
299 | u32 src_offset, size_t bytes) | |
300 | { | |
301 | sst->ops->ram_read(sst, dest, sst->addr.lpe + src_offset, bytes); | |
302 | } | |
303 | ||
304 | static inline void *sst_dsp_get_thread_context(struct sst_dsp *sst) | |
305 | { | |
306 | return sst->thread_context; | |
307 | } | |
308 | ||
309 | /* Create/Free FW files - can contain multiple modules */ | |
310 | struct sst_fw *sst_fw_new(struct sst_dsp *dsp, | |
311 | const struct firmware *fw, void *private); | |
312 | void sst_fw_free(struct sst_fw *sst_fw); | |
313 | void sst_fw_free_all(struct sst_dsp *dsp); | |
555f8a80 LG |
314 | int sst_fw_reload(struct sst_fw *sst_fw); |
315 | void sst_fw_unload(struct sst_fw *sst_fw); | |
a4b12990 MB |
316 | |
317 | /* Create/Free firmware modules */ | |
318 | struct sst_module *sst_module_new(struct sst_fw *sst_fw, | |
319 | struct sst_module_template *template, void *private); | |
e9600bc1 | 320 | void sst_module_free(struct sst_module *module); |
a4b12990 | 321 | struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id); |
e9600bc1 LG |
322 | int sst_module_alloc_blocks(struct sst_module *module); |
323 | int sst_module_free_blocks(struct sst_module *module); | |
324 | ||
325 | /* Create/Free firmware module runtime instances */ | |
326 | struct sst_module_runtime *sst_module_runtime_new(struct sst_module *module, | |
327 | int id, void *private); | |
328 | void sst_module_runtime_free(struct sst_module_runtime *runtime); | |
329 | struct sst_module_runtime *sst_module_runtime_get_from_id( | |
330 | struct sst_module *module, u32 id); | |
331 | int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime, | |
332 | int offset); | |
333 | int sst_module_runtime_free_blocks(struct sst_module_runtime *runtime); | |
334 | int sst_module_runtime_save(struct sst_module_runtime *runtime, | |
335 | struct sst_module_runtime_context *context); | |
336 | int sst_module_runtime_restore(struct sst_module_runtime *runtime, | |
337 | struct sst_module_runtime_context *context); | |
338 | ||
339 | /* generic block allocation */ | |
340 | int sst_alloc_blocks(struct sst_dsp *dsp, struct sst_block_allocator *ba, | |
341 | struct list_head *block_list); | |
342 | int sst_free_blocks(struct sst_dsp *dsp, struct list_head *block_list); | |
343 | ||
344 | /* scratch allocation */ | |
345 | int sst_block_alloc_scratch(struct sst_dsp *dsp); | |
346 | void sst_block_free_scratch(struct sst_dsp *dsp); | |
a4b12990 MB |
347 | |
348 | /* Register the DSPs memory blocks - would be nice to read from ACPI */ | |
349 | struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset, | |
350 | u32 size, enum sst_mem_type type, struct sst_block_ops *ops, u32 index, | |
351 | void *private); | |
352 | void sst_mem_block_unregister_all(struct sst_dsp *dsp); | |
353 | ||
e9600bc1 LG |
354 | /* Create/Free DMA resources */ |
355 | int sst_dma_new(struct sst_dsp *sst); | |
356 | void sst_dma_free(struct sst_dma *dma); | |
357 | ||
358 | u32 sst_dsp_get_offset(struct sst_dsp *dsp, u32 offset, | |
359 | enum sst_mem_type type); | |
a4b12990 | 360 | #endif |