diff options
-rw-r--r-- | sound/soc/sof/intel/byt.c | 164 | ||||
-rw-r--r-- | sound/soc/sof/loader.c | 168 | ||||
-rw-r--r-- | sound/soc/sof/sof-priv.h | 2 |
3 files changed, 189 insertions, 145 deletions
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index cb8f02ee09f2..5e7a6aaa627a 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c | |||
@@ -110,148 +110,6 @@ static void byt_dsp_done(struct snd_sof_dev *sdev); | |||
110 | static void byt_get_reply(struct snd_sof_dev *sdev); | 110 | static void byt_get_reply(struct snd_sof_dev *sdev); |
111 | 111 | ||
112 | /* | 112 | /* |
113 | * IPC Firmware ready. | ||
114 | */ | ||
115 | static void byt_get_windows(struct snd_sof_dev *sdev) | ||
116 | { | ||
117 | struct sof_ipc_window_elem *elem; | ||
118 | u32 outbox_offset = 0; | ||
119 | u32 stream_offset = 0; | ||
120 | u32 inbox_offset = 0; | ||
121 | u32 outbox_size = 0; | ||
122 | u32 stream_size = 0; | ||
123 | u32 inbox_size = 0; | ||
124 | int i; | ||
125 | |||
126 | if (!sdev->info_window) { | ||
127 | dev_err(sdev->dev, "error: have no window info\n"); | ||
128 | return; | ||
129 | } | ||
130 | |||
131 | for (i = 0; i < sdev->info_window->num_windows; i++) { | ||
132 | elem = &sdev->info_window->window[i]; | ||
133 | |||
134 | switch (elem->type) { | ||
135 | case SOF_IPC_REGION_UPBOX: | ||
136 | inbox_offset = elem->offset + MBOX_OFFSET; | ||
137 | inbox_size = elem->size; | ||
138 | snd_sof_debugfs_io_item(sdev, | ||
139 | sdev->bar[BYT_DSP_BAR] + | ||
140 | inbox_offset, | ||
141 | elem->size, "inbox", | ||
142 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
143 | break; | ||
144 | case SOF_IPC_REGION_DOWNBOX: | ||
145 | outbox_offset = elem->offset + MBOX_OFFSET; | ||
146 | outbox_size = elem->size; | ||
147 | snd_sof_debugfs_io_item(sdev, | ||
148 | sdev->bar[BYT_DSP_BAR] + | ||
149 | outbox_offset, | ||
150 | elem->size, "outbox", | ||
151 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
152 | break; | ||
153 | case SOF_IPC_REGION_TRACE: | ||
154 | snd_sof_debugfs_io_item(sdev, | ||
155 | sdev->bar[BYT_DSP_BAR] + | ||
156 | elem->offset + | ||
157 | MBOX_OFFSET, | ||
158 | elem->size, "etrace", | ||
159 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
160 | break; | ||
161 | case SOF_IPC_REGION_DEBUG: | ||
162 | snd_sof_debugfs_io_item(sdev, | ||
163 | sdev->bar[BYT_DSP_BAR] + | ||
164 | elem->offset + | ||
165 | MBOX_OFFSET, | ||
166 | elem->size, "debug", | ||
167 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
168 | break; | ||
169 | case SOF_IPC_REGION_STREAM: | ||
170 | stream_offset = elem->offset + MBOX_OFFSET; | ||
171 | stream_size = elem->size; | ||
172 | snd_sof_debugfs_io_item(sdev, | ||
173 | sdev->bar[BYT_DSP_BAR] + | ||
174 | stream_offset, | ||
175 | elem->size, "stream", | ||
176 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
177 | break; | ||
178 | case SOF_IPC_REGION_REGS: | ||
179 | snd_sof_debugfs_io_item(sdev, | ||
180 | sdev->bar[BYT_DSP_BAR] + | ||
181 | elem->offset + | ||
182 | MBOX_OFFSET, | ||
183 | elem->size, "regs", | ||
184 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
185 | break; | ||
186 | case SOF_IPC_REGION_EXCEPTION: | ||
187 | sdev->dsp_oops_offset = elem->offset + MBOX_OFFSET; | ||
188 | snd_sof_debugfs_io_item(sdev, | ||
189 | sdev->bar[BYT_DSP_BAR] + | ||
190 | elem->offset + | ||
191 | MBOX_OFFSET, | ||
192 | elem->size, "exception", | ||
193 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
194 | break; | ||
195 | default: | ||
196 | dev_err(sdev->dev, "error: get illegal window info\n"); | ||
197 | return; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | if (outbox_size == 0 || inbox_size == 0) { | ||
202 | dev_err(sdev->dev, "error: get illegal mailbox window\n"); | ||
203 | return; | ||
204 | } | ||
205 | |||
206 | snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size, | ||
207 | outbox_offset, outbox_size); | ||
208 | sdev->stream_box.offset = stream_offset; | ||
209 | sdev->stream_box.size = stream_size; | ||
210 | |||
211 | dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n", | ||
212 | inbox_offset, inbox_size); | ||
213 | dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n", | ||
214 | outbox_offset, outbox_size); | ||
215 | dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n", | ||
216 | stream_offset, stream_size); | ||
217 | } | ||
218 | |||
219 | /* check for ABI compatibility and create memory windows on first boot */ | ||
220 | static int byt_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) | ||
221 | { | ||
222 | struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready; | ||
223 | u32 offset; | ||
224 | int ret; | ||
225 | |||
226 | /* mailbox must be on 4k boundary */ | ||
227 | offset = MBOX_OFFSET; | ||
228 | |||
229 | dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n", | ||
230 | msg_id, offset); | ||
231 | |||
232 | /* no need to re-check version/ABI for subsequent boots */ | ||
233 | if (!sdev->first_boot) | ||
234 | return 0; | ||
235 | |||
236 | /* copy data from the DSP FW ready offset */ | ||
237 | sof_block_read(sdev, sdev->mmio_bar, offset, fw_ready, | ||
238 | sizeof(*fw_ready)); | ||
239 | |||
240 | /* make sure ABI version is compatible */ | ||
241 | ret = snd_sof_ipc_valid(sdev); | ||
242 | if (ret < 0) | ||
243 | return ret; | ||
244 | |||
245 | /* now check for extended data */ | ||
246 | snd_sof_fw_parse_ext_data(sdev, sdev->mmio_bar, MBOX_OFFSET + | ||
247 | sizeof(struct sof_ipc_fw_ready)); | ||
248 | |||
249 | byt_get_windows(sdev); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * Debug | 113 | * Debug |
256 | */ | 114 | */ |
257 | 115 | ||
@@ -418,6 +276,16 @@ static void byt_get_reply(struct snd_sof_dev *sdev) | |||
418 | msg->reply_error = ret; | 276 | msg->reply_error = ret; |
419 | } | 277 | } |
420 | 278 | ||
279 | static int byt_get_mailbox_offset(struct snd_sof_dev *sdev) | ||
280 | { | ||
281 | return MBOX_OFFSET; | ||
282 | } | ||
283 | |||
284 | static int byt_get_window_offset(struct snd_sof_dev *sdev, u32 id) | ||
285 | { | ||
286 | return MBOX_OFFSET; | ||
287 | } | ||
288 | |||
421 | static void byt_host_done(struct snd_sof_dev *sdev) | 289 | static void byt_host_done(struct snd_sof_dev *sdev) |
422 | { | 290 | { |
423 | /* clear BUSY bit and set DONE bit - accept new messages */ | 291 | /* clear BUSY bit and set DONE bit - accept new messages */ |
@@ -612,7 +480,9 @@ const struct snd_sof_dsp_ops sof_tng_ops = { | |||
612 | 480 | ||
613 | /* ipc */ | 481 | /* ipc */ |
614 | .send_msg = byt_send_msg, | 482 | .send_msg = byt_send_msg, |
615 | .fw_ready = byt_fw_ready, | 483 | .fw_ready = sof_fw_ready, |
484 | .get_mailbox_offset = byt_get_mailbox_offset, | ||
485 | .get_window_offset = byt_get_window_offset, | ||
616 | 486 | ||
617 | .ipc_msg_data = intel_ipc_msg_data, | 487 | .ipc_msg_data = intel_ipc_msg_data, |
618 | .ipc_pcm_params = intel_ipc_pcm_params, | 488 | .ipc_pcm_params = intel_ipc_pcm_params, |
@@ -771,7 +641,9 @@ const struct snd_sof_dsp_ops sof_byt_ops = { | |||
771 | 641 | ||
772 | /* ipc */ | 642 | /* ipc */ |
773 | .send_msg = byt_send_msg, | 643 | .send_msg = byt_send_msg, |
774 | .fw_ready = byt_fw_ready, | 644 | .fw_ready = sof_fw_ready, |
645 | .get_mailbox_offset = byt_get_mailbox_offset, | ||
646 | .get_window_offset = byt_get_window_offset, | ||
775 | 647 | ||
776 | .ipc_msg_data = intel_ipc_msg_data, | 648 | .ipc_msg_data = intel_ipc_msg_data, |
777 | .ipc_pcm_params = intel_ipc_pcm_params, | 649 | .ipc_pcm_params = intel_ipc_pcm_params, |
@@ -828,7 +700,9 @@ const struct snd_sof_dsp_ops sof_cht_ops = { | |||
828 | 700 | ||
829 | /* ipc */ | 701 | /* ipc */ |
830 | .send_msg = byt_send_msg, | 702 | .send_msg = byt_send_msg, |
831 | .fw_ready = byt_fw_ready, | 703 | .fw_ready = sof_fw_ready, |
704 | .get_mailbox_offset = byt_get_mailbox_offset, | ||
705 | .get_window_offset = byt_get_window_offset, | ||
832 | 706 | ||
833 | .ipc_msg_data = intel_ipc_msg_data, | 707 | .ipc_msg_data = intel_ipc_msg_data, |
834 | .ipc_pcm_params = intel_ipc_pcm_params, | 708 | .ipc_pcm_params = intel_ipc_pcm_params, |
diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index 93cb8fd0844f..d7f32745fefe 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c | |||
@@ -87,6 +87,174 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset) | |||
87 | } | 87 | } |
88 | EXPORT_SYMBOL(snd_sof_fw_parse_ext_data); | 88 | EXPORT_SYMBOL(snd_sof_fw_parse_ext_data); |
89 | 89 | ||
90 | /* | ||
91 | * IPC Firmware ready. | ||
92 | */ | ||
93 | static void sof_get_windows(struct snd_sof_dev *sdev) | ||
94 | { | ||
95 | struct sof_ipc_window_elem *elem; | ||
96 | u32 outbox_offset = 0; | ||
97 | u32 stream_offset = 0; | ||
98 | u32 inbox_offset = 0; | ||
99 | u32 outbox_size = 0; | ||
100 | u32 stream_size = 0; | ||
101 | u32 inbox_size = 0; | ||
102 | int window_offset; | ||
103 | int bar; | ||
104 | int i; | ||
105 | |||
106 | if (!sdev->info_window) { | ||
107 | dev_err(sdev->dev, "error: have no window info\n"); | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | bar = snd_sof_dsp_get_bar_index(sdev, SOF_FW_BLK_TYPE_SRAM); | ||
112 | if (bar < 0) { | ||
113 | dev_err(sdev->dev, "error: have no bar mapping\n"); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | for (i = 0; i < sdev->info_window->num_windows; i++) { | ||
118 | elem = &sdev->info_window->window[i]; | ||
119 | |||
120 | window_offset = snd_sof_dsp_get_window_offset(sdev, elem->id); | ||
121 | if (window_offset < 0) { | ||
122 | dev_warn(sdev->dev, "warn: no offset for window %d\n", | ||
123 | elem->id); | ||
124 | continue; | ||
125 | } | ||
126 | |||
127 | switch (elem->type) { | ||
128 | case SOF_IPC_REGION_UPBOX: | ||
129 | inbox_offset = window_offset + elem->offset; | ||
130 | inbox_size = elem->size; | ||
131 | snd_sof_debugfs_io_item(sdev, | ||
132 | sdev->bar[bar] + | ||
133 | inbox_offset, | ||
134 | elem->size, "inbox", | ||
135 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
136 | break; | ||
137 | case SOF_IPC_REGION_DOWNBOX: | ||
138 | outbox_offset = window_offset + elem->offset; | ||
139 | outbox_size = elem->size; | ||
140 | snd_sof_debugfs_io_item(sdev, | ||
141 | sdev->bar[bar] + | ||
142 | outbox_offset, | ||
143 | elem->size, "outbox", | ||
144 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
145 | break; | ||
146 | case SOF_IPC_REGION_TRACE: | ||
147 | snd_sof_debugfs_io_item(sdev, | ||
148 | sdev->bar[bar] + | ||
149 | window_offset + | ||
150 | elem->offset, | ||
151 | elem->size, "etrace", | ||
152 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
153 | break; | ||
154 | case SOF_IPC_REGION_DEBUG: | ||
155 | snd_sof_debugfs_io_item(sdev, | ||
156 | sdev->bar[bar] + | ||
157 | window_offset + | ||
158 | elem->offset, | ||
159 | elem->size, "debug", | ||
160 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
161 | break; | ||
162 | case SOF_IPC_REGION_STREAM: | ||
163 | stream_offset = window_offset + elem->offset; | ||
164 | stream_size = elem->size; | ||
165 | snd_sof_debugfs_io_item(sdev, | ||
166 | sdev->bar[bar] + | ||
167 | stream_offset, | ||
168 | elem->size, "stream", | ||
169 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
170 | break; | ||
171 | case SOF_IPC_REGION_REGS: | ||
172 | snd_sof_debugfs_io_item(sdev, | ||
173 | sdev->bar[bar] + | ||
174 | window_offset + | ||
175 | elem->offset, | ||
176 | elem->size, "regs", | ||
177 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
178 | break; | ||
179 | case SOF_IPC_REGION_EXCEPTION: | ||
180 | sdev->dsp_oops_offset = window_offset + elem->offset; | ||
181 | snd_sof_debugfs_io_item(sdev, | ||
182 | sdev->bar[bar] + | ||
183 | window_offset + | ||
184 | elem->offset, | ||
185 | elem->size, "exception", | ||
186 | SOF_DEBUGFS_ACCESS_D0_ONLY); | ||
187 | break; | ||
188 | default: | ||
189 | dev_err(sdev->dev, "error: get illegal window info\n"); | ||
190 | return; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | if (outbox_size == 0 || inbox_size == 0) { | ||
195 | dev_err(sdev->dev, "error: get illegal mailbox window\n"); | ||
196 | return; | ||
197 | } | ||
198 | |||
199 | snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size, | ||
200 | outbox_offset, outbox_size); | ||
201 | sdev->stream_box.offset = stream_offset; | ||
202 | sdev->stream_box.size = stream_size; | ||
203 | |||
204 | dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n", | ||
205 | inbox_offset, inbox_size); | ||
206 | dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n", | ||
207 | outbox_offset, outbox_size); | ||
208 | dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n", | ||
209 | stream_offset, stream_size); | ||
210 | } | ||
211 | |||
212 | /* check for ABI compatibility and create memory windows on first boot */ | ||
213 | int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) | ||
214 | { | ||
215 | struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready; | ||
216 | int offset; | ||
217 | int bar; | ||
218 | int ret; | ||
219 | |||
220 | /* mailbox must be on 4k boundary */ | ||
221 | offset = snd_sof_dsp_get_mailbox_offset(sdev); | ||
222 | if (offset < 0) { | ||
223 | dev_err(sdev->dev, "error: have no mailbox offset\n"); | ||
224 | return offset; | ||
225 | } | ||
226 | |||
227 | bar = snd_sof_dsp_get_bar_index(sdev, SOF_FW_BLK_TYPE_SRAM); | ||
228 | if (bar < 0) { | ||
229 | dev_err(sdev->dev, "error: have no bar mapping\n"); | ||
230 | return -EINVAL; | ||
231 | } | ||
232 | |||
233 | dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n", | ||
234 | msg_id, offset); | ||
235 | |||
236 | /* no need to re-check version/ABI for subsequent boots */ | ||
237 | if (!sdev->first_boot) | ||
238 | return 0; | ||
239 | |||
240 | /* copy data from the DSP FW ready offset */ | ||
241 | sof_block_read(sdev, bar, offset, fw_ready, sizeof(*fw_ready)); | ||
242 | |||
243 | /* make sure ABI version is compatible */ | ||
244 | ret = snd_sof_ipc_valid(sdev); | ||
245 | if (ret < 0) | ||
246 | return ret; | ||
247 | |||
248 | /* now check for extended data */ | ||
249 | snd_sof_fw_parse_ext_data(sdev, bar, offset + | ||
250 | sizeof(struct sof_ipc_fw_ready)); | ||
251 | |||
252 | sof_get_windows(sdev); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | EXPORT_SYMBOL(sof_fw_ready); | ||
257 | |||
90 | /* generic module parser for mmaped DSPs */ | 258 | /* generic module parser for mmaped DSPs */ |
91 | int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, | 259 | int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, |
92 | struct snd_sof_mod_hdr *module) | 260 | struct snd_sof_mod_hdr *module) |
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index de11f28bae3a..730f3259dd02 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h | |||
@@ -642,6 +642,8 @@ void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src, | |||
642 | void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest, | 642 | void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest, |
643 | size_t size); | 643 | size_t size); |
644 | 644 | ||
645 | int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id); | ||
646 | |||
645 | void intel_ipc_msg_data(struct snd_sof_dev *sdev, | 647 | void intel_ipc_msg_data(struct snd_sof_dev *sdev, |
646 | struct snd_pcm_substream *substream, | 648 | struct snd_pcm_substream *substream, |
647 | void *p, size_t sz); | 649 | void *p, size_t sz); |