blob: ffb308bd81cea684508a3ba1a21477b5f885fab8 [file] [log] [blame]
Mark Browna4b12992014-03-12 23:04:35 +00001/*
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
25struct sst_mem_block;
26struct sst_module;
27struct sst_fw;
28
29/*
30 * DSP Operations exported by platform Audio DSP driver.
31 */
32struct sst_ops {
33 /* DSP core boot / reset */
34 void (*boot)(struct sst_dsp *);
35 void (*reset)(struct sst_dsp *);
36
37 /* Shim IO */
38 void (*write)(void __iomem *addr, u32 offset, u32 value);
39 u32 (*read)(void __iomem *addr, u32 offset);
40 void (*write64)(void __iomem *addr, u32 offset, u64 value);
41 u64 (*read64)(void __iomem *addr, u32 offset);
42
43 /* DSP I/DRAM IO */
44 void (*ram_read)(struct sst_dsp *sst, void *dest, void __iomem *src,
45 size_t bytes);
46 void (*ram_write)(struct sst_dsp *sst, void __iomem *dest, void *src,
47 size_t bytes);
48
49 void (*dump)(struct sst_dsp *);
50
51 /* IRQ handlers */
52 irqreturn_t (*irq_handler)(int irq, void *context);
53
54 /* SST init and free */
55 int (*init)(struct sst_dsp *sst, struct sst_pdata *pdata);
56 void (*free)(struct sst_dsp *sst);
57
58 /* FW module parser/loader */
59 int (*parse_fw)(struct sst_fw *sst_fw);
60};
61
62/*
63 * Audio DSP memory offsets and addresses.
64 */
65struct sst_addr {
66 u32 lpe_base;
67 u32 shim_offset;
68 u32 iram_offset;
69 u32 dram_offset;
70 void __iomem *lpe;
71 void __iomem *shim;
72 void __iomem *pci_cfg;
73 void __iomem *fw_ext;
74};
75
76/*
77 * Audio DSP Mailbox configuration.
78 */
79struct sst_mailbox {
80 void __iomem *in_base;
81 void __iomem *out_base;
82 size_t in_size;
83 size_t out_size;
84};
85
86/*
87 * Audio DSP Firmware data types.
88 */
89enum sst_data_type {
90 SST_DATA_M = 0, /* module block data */
91 SST_DATA_P = 1, /* peristant data (text, data) */
92 SST_DATA_S = 2, /* scratch data (usually buffers) */
93};
94
95/*
96 * Audio DSP memory block types.
97 */
98enum sst_mem_type {
99 SST_MEM_IRAM = 0,
100 SST_MEM_DRAM = 1,
101 SST_MEM_ANY = 2,
102 SST_MEM_CACHE= 3,
103};
104
105/*
106 * Audio DSP Generic Firmware File.
107 *
108 * SST Firmware files can consist of 1..N modules. This generic structure is
109 * used to manage each firmware file and it's modules regardless of SST firmware
110 * type. A SST driver may load multiple FW files.
111 */
112struct sst_fw {
113 struct sst_dsp *dsp;
114
115 /* base addresses of FW file data */
116 dma_addr_t dmable_fw_paddr; /* physical address of fw data */
117 void *dma_buf; /* virtual address of fw data */
118 u32 size; /* size of fw data */
119
120 /* lists */
121 struct list_head list; /* DSP list of FW */
122 struct list_head module_list; /* FW list of modules */
123
124 void *private; /* core doesn't touch this */
125};
126
127/*
128 * Audio DSP Generic Module data.
129 *
130 * This is used to dsecribe any sections of persistent (text and data) and
131 * scratch (buffers) of module data in ADSP memory space.
132 */
133struct sst_module_data {
134
135 enum sst_mem_type type; /* destination memory type */
136 enum sst_data_type data_type; /* type of module data */
137
138 u32 size; /* size in bytes */
Wenkai Du95e9ee92014-04-22 16:38:54 +0300139 int32_t offset; /* offset in FW file */
Mark Browna4b12992014-03-12 23:04:35 +0000140 u32 data_offset; /* offset in ADSP memory space */
141 void *data; /* module data */
142};
143
144/*
145 * Audio DSP Generic Module Template.
146 *
147 * Used to define and register a new FW module. This data is extracted from
148 * FW module header information.
149 */
150struct sst_module_template {
151 u32 id;
152 u32 entry; /* entry point */
153 struct sst_module_data s; /* scratch data */
154 struct sst_module_data p; /* peristant data */
155};
156
157/*
158 * Audio DSP Generic Module.
159 *
160 * Each Firmware file can consist of 1..N modules. A module can span multiple
161 * ADSP memory blocks. The simplest FW will be a file with 1 module.
162 */
163struct sst_module {
164 struct sst_dsp *dsp;
165 struct sst_fw *sst_fw; /* parent FW we belong too */
166
167 /* module configuration */
168 u32 id;
169 u32 entry; /* module entry point */
170 u32 offset; /* module offset in firmware file */
171 u32 size; /* module size */
172 struct sst_module_data s; /* scratch data */
173 struct sst_module_data p; /* peristant data */
174
175 /* runtime */
176 u32 usage_count; /* can be unloaded if count == 0 */
177 void *private; /* core doesn't touch this */
178
179 /* lists */
180 struct list_head block_list; /* Module list of blocks in use */
181 struct list_head list; /* DSP list of modules */
182 struct list_head list_fw; /* FW list of modules */
183};
184
185/*
186 * SST Memory Block operations.
187 */
188struct sst_block_ops {
189 int (*enable)(struct sst_mem_block *block);
190 int (*disable)(struct sst_mem_block *block);
191};
192
193/*
194 * SST Generic Memory Block.
195 *
196 * SST ADP memory has multiple IRAM and DRAM blocks. Some ADSP blocks can be
197 * power gated.
198 */
199struct sst_mem_block {
200 struct sst_dsp *dsp;
201 struct sst_module *module; /* module that uses this block */
202
203 /* block config */
204 u32 offset; /* offset from base */
205 u32 size; /* block size */
206 u32 index; /* block index 0..N */
207 enum sst_mem_type type; /* block memory type IRAM/DRAM */
208 struct sst_block_ops *ops; /* block operations, if any */
209
210 /* block status */
211 enum sst_data_type data_type; /* data type held in this block */
212 u32 bytes_used; /* bytes in use by modules */
213 void *private; /* generic core does not touch this */
214 int users; /* number of modules using this block */
215
216 /* block lists */
217 struct list_head module_list; /* Module list of blocks */
218 struct list_head list; /* Map list of free/used blocks */
219};
220
221/*
222 * Generic SST Shim Interface.
223 */
224struct sst_dsp {
225
226 /* runtime */
227 struct sst_dsp_device *sst_dev;
228 spinlock_t spinlock; /* IPC locking */
229 struct mutex mutex; /* DSP FW lock */
230 struct device *dev;
Liam Girdwood10df3502014-05-02 16:56:31 +0100231 struct device *dma_dev;
Mark Browna4b12992014-03-12 23:04:35 +0000232 void *thread_context;
233 int irq;
234 u32 id;
235
236 /* list of free and used ADSP memory blocks */
237 struct list_head used_block_list;
238 struct list_head free_block_list;
239
240 /* operations */
241 struct sst_ops *ops;
242
243 /* debug FS */
244 struct dentry *debugfs_root;
245
246 /* base addresses */
247 struct sst_addr addr;
248
249 /* mailbox */
250 struct sst_mailbox mailbox;
251
252 /* SST FW files loaded and their modules */
253 struct list_head module_list;
254 struct list_head fw_list;
255
256 /* platform data */
257 struct sst_pdata *pdata;
258
259 /* DMA FW loading */
260 struct sst_dma *dma;
261 bool fw_use_dma;
262};
263
264/* Size optimised DRAM/IRAM memcpy */
265static inline void sst_dsp_write(struct sst_dsp *sst, void *src,
266 u32 dest_offset, size_t bytes)
267{
268 sst->ops->ram_write(sst, sst->addr.lpe + dest_offset, src, bytes);
269}
270
271static inline void sst_dsp_read(struct sst_dsp *sst, void *dest,
272 u32 src_offset, size_t bytes)
273{
274 sst->ops->ram_read(sst, dest, sst->addr.lpe + src_offset, bytes);
275}
276
277static inline void *sst_dsp_get_thread_context(struct sst_dsp *sst)
278{
279 return sst->thread_context;
280}
281
282/* Create/Free FW files - can contain multiple modules */
283struct sst_fw *sst_fw_new(struct sst_dsp *dsp,
284 const struct firmware *fw, void *private);
285void sst_fw_free(struct sst_fw *sst_fw);
286void sst_fw_free_all(struct sst_dsp *dsp);
Liam Girdwood555f8a802014-05-05 17:31:37 +0100287int sst_fw_reload(struct sst_fw *sst_fw);
288void sst_fw_unload(struct sst_fw *sst_fw);
Mark Browna4b12992014-03-12 23:04:35 +0000289
290/* Create/Free firmware modules */
291struct sst_module *sst_module_new(struct sst_fw *sst_fw,
292 struct sst_module_template *template, void *private);
293void sst_module_free(struct sst_module *sst_module);
294int sst_module_insert(struct sst_module *sst_module);
295int sst_module_remove(struct sst_module *sst_module);
296int sst_module_insert_fixed_block(struct sst_module *module,
297 struct sst_module_data *data);
298struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id);
299
300/* allocate/free pesistent/scratch memory regions managed by drv */
301struct sst_module *sst_mem_block_alloc_scratch(struct sst_dsp *dsp);
302void sst_mem_block_free_scratch(struct sst_dsp *dsp,
303 struct sst_module *scratch);
304int sst_block_module_remove(struct sst_module *module);
305
306/* Register the DSPs memory blocks - would be nice to read from ACPI */
307struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
308 u32 size, enum sst_mem_type type, struct sst_block_ops *ops, u32 index,
309 void *private);
310void sst_mem_block_unregister_all(struct sst_dsp *dsp);
311
312#endif