xref: /openbmc/linux/sound/soc/intel/skylake/bxt-sst.c (revision 7bcae826)
1 /*
2  *  bxt-sst.c - DSP library functions for BXT platform
3  *
4  *  Copyright (C) 2015-16 Intel Corp
5  *  Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
6  *	   Jeeja KP <jeeja.kp@intel.com>
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; version 2 of the License.
11  *
12  *  This program is distributed in the hope that it will be useful, but
13  *  WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  General Public License for more details.
16  */
17 
18 #include <linux/module.h>
19 #include <linux/delay.h>
20 #include <linux/firmware.h>
21 #include <linux/device.h>
22 
23 #include "../common/sst-dsp.h"
24 #include "../common/sst-dsp-priv.h"
25 #include "skl-sst-ipc.h"
26 
27 #define BXT_BASEFW_TIMEOUT	3000
28 #define BXT_INIT_TIMEOUT	500
29 #define BXT_IPC_PURGE_FW	0x01004000
30 
31 #define BXT_ROM_INIT		0x5
32 #define BXT_ADSP_SRAM0_BASE	0x80000
33 
34 /* Firmware status window */
35 #define BXT_ADSP_FW_STATUS	BXT_ADSP_SRAM0_BASE
36 #define BXT_ADSP_ERROR_CODE     (BXT_ADSP_FW_STATUS + 0x4)
37 
38 #define BXT_ADSP_SRAM1_BASE	0xA0000
39 
40 #define BXT_INSTANCE_ID 0
41 #define BXT_BASE_FW_MODULE_ID 0
42 
43 #define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
44 
45 /* Delay before scheduling D0i3 entry */
46 #define BXT_D0I3_DELAY 5000
47 
48 static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
49 {
50 	 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
51 }
52 
53 static int
54 bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
55 {
56 	struct snd_dma_buffer dmab;
57 	struct skl_sst *skl = ctx->thread_context;
58 	const struct firmware *fw = NULL;
59 	struct firmware stripped_fw;
60 	int ret = 0, i, dma_id, stream_tag;
61 
62 	/* library indices start from 1 to N. 0 represents base FW */
63 	for (i = 1; i < lib_count; i++) {
64 		ret = request_firmware(&fw, linfo[i].name, ctx->dev);
65 		if (ret < 0) {
66 			dev_err(ctx->dev, "Request lib %s failed:%d\n",
67 					linfo[i].name, ret);
68 			return ret;
69 		}
70 
71 		if (skl->is_first_boot) {
72 			ret = snd_skl_parse_uuids(ctx, fw,
73 					BXT_ADSP_FW_BIN_HDR_OFFSET, i);
74 			if (ret < 0)
75 				goto load_library_failed;
76 		}
77 
78 		stripped_fw.data = fw->data;
79 		stripped_fw.size = fw->size;
80 		skl_dsp_strip_extended_manifest(&stripped_fw);
81 
82 		stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
83 					stripped_fw.size, &dmab);
84 		if (stream_tag <= 0) {
85 			dev_err(ctx->dev, "Lib prepare DMA err: %x\n",
86 					stream_tag);
87 			ret = stream_tag;
88 			goto load_library_failed;
89 		}
90 
91 		dma_id = stream_tag - 1;
92 		memcpy(dmab.area, stripped_fw.data, stripped_fw.size);
93 
94 		ctx->dsp_ops.trigger(ctx->dev, true, stream_tag);
95 		ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i);
96 		if (ret < 0)
97 			dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n",
98 					linfo[i].name, ret);
99 
100 		ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
101 		ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
102 		release_firmware(fw);
103 		fw = NULL;
104 	}
105 
106 	return ret;
107 
108 load_library_failed:
109 	release_firmware(fw);
110 	return ret;
111 }
112 
113 /*
114  * First boot sequence has some extra steps. Core 0 waits for power
115  * status on core 1, so power up core 1 also momentarily, keep it in
116  * reset/stall and then turn it off
117  */
118 static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
119 			const void *fwdata, u32 fwsize)
120 {
121 	int stream_tag, ret;
122 
123 	stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab);
124 	if (stream_tag <= 0) {
125 		dev_err(ctx->dev, "Failed to prepare DMA FW loading err: %x\n",
126 				stream_tag);
127 		return stream_tag;
128 	}
129 
130 	ctx->dsp_ops.stream_tag = stream_tag;
131 	memcpy(ctx->dmab.area, fwdata, fwsize);
132 
133 	/* Step 1: Power up core 0 and core1 */
134 	ret = skl_dsp_core_power_up(ctx, SKL_DSP_CORE0_MASK |
135 				SKL_DSP_CORE_MASK(1));
136 	if (ret < 0) {
137 		dev_err(ctx->dev, "dsp core0/1 power up failed\n");
138 		goto base_fw_load_failed;
139 	}
140 
141 	/* Step 2: Purge FW request */
142 	sst_dsp_shim_write(ctx, SKL_ADSP_REG_HIPCI, SKL_ADSP_REG_HIPCI_BUSY |
143 				(BXT_IPC_PURGE_FW | ((stream_tag - 1) << 9)));
144 
145 	/* Step 3: Unset core0 reset state & unstall/run core0 */
146 	ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK);
147 	if (ret < 0) {
148 		dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret);
149 		ret = -EIO;
150 		goto base_fw_load_failed;
151 	}
152 
153 	/* Step 4: Wait for DONE Bit */
154 	ret = sst_dsp_register_poll(ctx, SKL_ADSP_REG_HIPCIE,
155 					SKL_ADSP_REG_HIPCIE_DONE,
156 					SKL_ADSP_REG_HIPCIE_DONE,
157 					BXT_INIT_TIMEOUT, "HIPCIE Done");
158 	if (ret < 0) {
159 		dev_err(ctx->dev, "Timout for Purge Request%d\n", ret);
160 		goto base_fw_load_failed;
161 	}
162 
163 	/* Step 5: power down core1 */
164 	ret = skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1));
165 	if (ret < 0) {
166 		dev_err(ctx->dev, "dsp core1 power down failed\n");
167 		goto base_fw_load_failed;
168 	}
169 
170 	/* Step 6: Enable Interrupt */
171 	skl_ipc_int_enable(ctx);
172 	skl_ipc_op_int_enable(ctx);
173 
174 	/* Step 7: Wait for ROM init */
175 	ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK,
176 			SKL_FW_INIT, BXT_INIT_TIMEOUT, "ROM Load");
177 	if (ret < 0) {
178 		dev_err(ctx->dev, "Timeout for ROM init, ret:%d\n", ret);
179 		goto base_fw_load_failed;
180 	}
181 
182 	return ret;
183 
184 base_fw_load_failed:
185 	ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag);
186 	skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1));
187 	skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
188 	return ret;
189 }
190 
191 static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
192 {
193 	int ret;
194 
195 	ctx->dsp_ops.trigger(ctx->dev, true, ctx->dsp_ops.stream_tag);
196 	ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK,
197 			BXT_ROM_INIT, BXT_BASEFW_TIMEOUT, "Firmware boot");
198 
199 	ctx->dsp_ops.trigger(ctx->dev, false, ctx->dsp_ops.stream_tag);
200 	ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, ctx->dsp_ops.stream_tag);
201 
202 	return ret;
203 }
204 
205 static int bxt_load_base_firmware(struct sst_dsp *ctx)
206 {
207 	struct firmware stripped_fw;
208 	struct skl_sst *skl = ctx->thread_context;
209 	int ret;
210 
211 	ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
212 	if (ret < 0) {
213 		dev_err(ctx->dev, "Request firmware failed %d\n", ret);
214 		goto sst_load_base_firmware_failed;
215 	}
216 
217 	/* check for extended manifest */
218 	if (ctx->fw == NULL)
219 		goto sst_load_base_firmware_failed;
220 
221 	/* prase uuids on first boot */
222 	if (skl->is_first_boot) {
223 		ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
224 		if (ret < 0)
225 			goto sst_load_base_firmware_failed;
226 	}
227 
228 	stripped_fw.data = ctx->fw->data;
229 	stripped_fw.size = ctx->fw->size;
230 	skl_dsp_strip_extended_manifest(&stripped_fw);
231 
232 	ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
233 	/* Retry Enabling core and ROM load. Retry seemed to help */
234 	if (ret < 0) {
235 		ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
236 		if (ret < 0) {
237 			dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
238 			sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
239 			sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
240 
241 			dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret);
242 			goto sst_load_base_firmware_failed;
243 		}
244 	}
245 
246 	ret = sst_transfer_fw_host_dma(ctx);
247 	if (ret < 0) {
248 		dev_err(ctx->dev, "Transfer firmware failed %d\n", ret);
249 		dev_info(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
250 			sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
251 			sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
252 
253 		skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
254 	} else {
255 		dev_dbg(ctx->dev, "Firmware download successful\n");
256 		ret = wait_event_timeout(skl->boot_wait, skl->boot_complete,
257 					msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
258 		if (ret == 0) {
259 			dev_err(ctx->dev, "DSP boot fail, FW Ready timeout\n");
260 			skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
261 			ret = -EIO;
262 		} else {
263 			ret = 0;
264 			skl->fw_loaded = true;
265 		}
266 	}
267 
268 sst_load_base_firmware_failed:
269 	release_firmware(ctx->fw);
270 	return ret;
271 }
272 
273 /*
274  * Decide the D0i3 state that can be targeted based on the usecase
275  * ref counts and DSP state
276  *
277  * Decision Matrix:  (X= dont care; state = target state)
278  *
279  * DSP state != SKL_DSP_RUNNING ; state = no d0i3
280  *
281  * DSP state == SKL_DSP_RUNNING , the following matrix applies
282  * non_d0i3 >0; streaming =X; non_streaming =X; state = no d0i3
283  * non_d0i3 =X; streaming =0; non_streaming =0; state = no d0i3
284  * non_d0i3 =0; streaming >0; non_streaming =X; state = streaming d0i3
285  * non_d0i3 =0; streaming =0; non_streaming =X; state = non-streaming d0i3
286  */
287 static int bxt_d0i3_target_state(struct sst_dsp *ctx)
288 {
289 	struct skl_sst *skl = ctx->thread_context;
290 	struct skl_d0i3_data *d0i3 = &skl->d0i3;
291 
292 	if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING)
293 		return SKL_DSP_D0I3_NONE;
294 
295 	if (d0i3->non_d0i3)
296 		return SKL_DSP_D0I3_NONE;
297 	else if (d0i3->streaming)
298 		return SKL_DSP_D0I3_STREAMING;
299 	else if (d0i3->non_streaming)
300 		return SKL_DSP_D0I3_NON_STREAMING;
301 	else
302 		return SKL_DSP_D0I3_NONE;
303 }
304 
305 static void bxt_set_dsp_D0i3(struct work_struct *work)
306 {
307 	int ret;
308 	struct skl_ipc_d0ix_msg msg;
309 	struct skl_sst *skl = container_of(work,
310 			struct skl_sst, d0i3.work.work);
311 	struct sst_dsp *ctx = skl->dsp;
312 	struct skl_d0i3_data *d0i3 = &skl->d0i3;
313 	int target_state;
314 
315 	dev_dbg(ctx->dev, "In %s:\n", __func__);
316 
317 	/* D0i3 entry allowed only if core 0 alone is running */
318 	if (skl_dsp_get_enabled_cores(ctx) !=  SKL_DSP_CORE0_MASK) {
319 		dev_warn(ctx->dev,
320 				"D0i3 allowed when only core0 running:Exit\n");
321 		return;
322 	}
323 
324 	target_state = bxt_d0i3_target_state(ctx);
325 	if (target_state == SKL_DSP_D0I3_NONE)
326 		return;
327 
328 	msg.instance_id = 0;
329 	msg.module_id = 0;
330 	msg.wake = 1;
331 	msg.streaming = 0;
332 	if (target_state == SKL_DSP_D0I3_STREAMING)
333 		msg.streaming = 1;
334 
335 	ret =  skl_ipc_set_d0ix(&skl->ipc, &msg);
336 
337 	if (ret < 0) {
338 		dev_err(ctx->dev, "Failed to set DSP to D0i3 state\n");
339 		return;
340 	}
341 
342 	/* Set Vendor specific register D0I3C.I3 to enable D0i3*/
343 	if (skl->update_d0i3c)
344 		skl->update_d0i3c(skl->dev, true);
345 
346 	d0i3->state = target_state;
347 	skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING_D0I3;
348 }
349 
350 static int bxt_schedule_dsp_D0i3(struct sst_dsp *ctx)
351 {
352 	struct skl_sst *skl = ctx->thread_context;
353 	struct skl_d0i3_data *d0i3 = &skl->d0i3;
354 
355 	/* Schedule D0i3 only if the usecase ref counts are appropriate */
356 	if (bxt_d0i3_target_state(ctx) != SKL_DSP_D0I3_NONE) {
357 
358 		dev_dbg(ctx->dev, "%s: Schedule D0i3\n", __func__);
359 
360 		schedule_delayed_work(&d0i3->work,
361 				msecs_to_jiffies(BXT_D0I3_DELAY));
362 	}
363 
364 	return 0;
365 }
366 
367 static int bxt_set_dsp_D0i0(struct sst_dsp *ctx)
368 {
369 	int ret;
370 	struct skl_ipc_d0ix_msg msg;
371 	struct skl_sst *skl = ctx->thread_context;
372 
373 	dev_dbg(ctx->dev, "In %s:\n", __func__);
374 
375 	/* First Cancel any pending attempt to put DSP to D0i3 */
376 	cancel_delayed_work_sync(&skl->d0i3.work);
377 
378 	/* If DSP is currently in D0i3, bring it to D0i0 */
379 	if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING_D0I3)
380 		return 0;
381 
382 	dev_dbg(ctx->dev, "Set DSP to D0i0\n");
383 
384 	msg.instance_id = 0;
385 	msg.module_id = 0;
386 	msg.streaming = 0;
387 	msg.wake = 0;
388 
389 	if (skl->d0i3.state == SKL_DSP_D0I3_STREAMING)
390 		msg.streaming = 1;
391 
392 	/* Clear Vendor specific register D0I3C.I3 to disable D0i3*/
393 	if (skl->update_d0i3c)
394 		skl->update_d0i3c(skl->dev, false);
395 
396 	ret =  skl_ipc_set_d0ix(&skl->ipc, &msg);
397 	if (ret < 0) {
398 		dev_err(ctx->dev, "Failed to set DSP to D0i0\n");
399 		return ret;
400 	}
401 
402 	skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING;
403 	skl->d0i3.state = SKL_DSP_D0I3_NONE;
404 
405 	return 0;
406 }
407 
408 static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
409 {
410 	struct skl_sst *skl = ctx->thread_context;
411 	int ret;
412 	struct skl_ipc_dxstate_info dx;
413 	unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
414 
415 	if (skl->fw_loaded == false) {
416 		skl->boot_complete = false;
417 		ret = bxt_load_base_firmware(ctx);
418 		if (ret < 0) {
419 			dev_err(ctx->dev, "reload fw failed: %d\n", ret);
420 			return ret;
421 		}
422 
423 		if (skl->lib_count > 1) {
424 			ret = bxt_load_library(ctx, skl->lib_info,
425 						skl->lib_count);
426 			if (ret < 0) {
427 				dev_err(ctx->dev, "reload libs failed: %d\n", ret);
428 				return ret;
429 			}
430 		}
431 		return ret;
432 	}
433 
434 	/* If core 0 is being turned on, turn on core 1 as well */
435 	if (core_id == SKL_DSP_CORE0_ID)
436 		ret = skl_dsp_core_power_up(ctx, core_mask |
437 				SKL_DSP_CORE_MASK(1));
438 	else
439 		ret = skl_dsp_core_power_up(ctx, core_mask);
440 
441 	if (ret < 0)
442 		goto err;
443 
444 	if (core_id == SKL_DSP_CORE0_ID) {
445 
446 		/*
447 		 * Enable interrupt after SPA is set and before
448 		 * DSP is unstalled
449 		 */
450 		skl_ipc_int_enable(ctx);
451 		skl_ipc_op_int_enable(ctx);
452 		skl->boot_complete = false;
453 	}
454 
455 	ret = skl_dsp_start_core(ctx, core_mask);
456 	if (ret < 0)
457 		goto err;
458 
459 	if (core_id == SKL_DSP_CORE0_ID) {
460 		ret = wait_event_timeout(skl->boot_wait,
461 				skl->boot_complete,
462 				msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
463 
464 	/* If core 1 was turned on for booting core 0, turn it off */
465 		skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1));
466 		if (ret == 0) {
467 			dev_err(ctx->dev, "%s: DSP boot timeout\n", __func__);
468 			dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
469 				sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
470 				sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
471 			dev_err(ctx->dev, "Failed to set core0 to D0 state\n");
472 			ret = -EIO;
473 			goto err;
474 		}
475 	}
476 
477 	/* Tell FW if additional core in now On */
478 
479 	if (core_id != SKL_DSP_CORE0_ID) {
480 		dx.core_mask = core_mask;
481 		dx.dx_mask = core_mask;
482 
483 		ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID,
484 					BXT_BASE_FW_MODULE_ID, &dx);
485 		if (ret < 0) {
486 			dev_err(ctx->dev, "IPC set_dx for core %d fail: %d\n",
487 								core_id, ret);
488 			goto err;
489 		}
490 	}
491 
492 	skl->cores.state[core_id] = SKL_DSP_RUNNING;
493 	return 0;
494 err:
495 	if (core_id == SKL_DSP_CORE0_ID)
496 		core_mask |= SKL_DSP_CORE_MASK(1);
497 	skl_dsp_disable_core(ctx, core_mask);
498 
499 	return ret;
500 }
501 
502 static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
503 {
504 	int ret;
505 	struct skl_ipc_dxstate_info dx;
506 	struct skl_sst *skl = ctx->thread_context;
507 	unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
508 
509 	dx.core_mask = core_mask;
510 	dx.dx_mask = SKL_IPC_D3_MASK;
511 
512 	dev_dbg(ctx->dev, "core mask=%x dx_mask=%x\n",
513 			dx.core_mask, dx.dx_mask);
514 
515 	ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID,
516 				BXT_BASE_FW_MODULE_ID, &dx);
517 	if (ret < 0)
518 		dev_err(ctx->dev,
519 		"Failed to set DSP to D3:core id = %d;Continue reset\n",
520 		core_id);
521 
522 	ret = skl_dsp_disable_core(ctx, core_mask);
523 	if (ret < 0) {
524 		dev_err(ctx->dev, "Failed to disable core %d\n", ret);
525 		return ret;
526 	}
527 	skl->cores.state[core_id] = SKL_DSP_RESET;
528 	return 0;
529 }
530 
531 static struct skl_dsp_fw_ops bxt_fw_ops = {
532 	.set_state_D0 = bxt_set_dsp_D0,
533 	.set_state_D3 = bxt_set_dsp_D3,
534 	.set_state_D0i3 = bxt_schedule_dsp_D0i3,
535 	.set_state_D0i0 = bxt_set_dsp_D0i0,
536 	.load_fw = bxt_load_base_firmware,
537 	.get_fw_errcode = bxt_get_errorcode,
538 	.load_library = bxt_load_library,
539 };
540 
541 static struct sst_ops skl_ops = {
542 	.irq_handler = skl_dsp_sst_interrupt,
543 	.write = sst_shim32_write,
544 	.read = sst_shim32_read,
545 	.ram_read = sst_memcpy_fromio_32,
546 	.ram_write = sst_memcpy_toio_32,
547 	.free = skl_dsp_free,
548 };
549 
550 static struct sst_dsp_device skl_dev = {
551 	.thread = skl_dsp_irq_thread_handler,
552 	.ops = &skl_ops,
553 };
554 
555 int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
556 			const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
557 			struct skl_sst **dsp)
558 {
559 	struct skl_sst *skl;
560 	struct sst_dsp *sst;
561 	int ret;
562 
563 	skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL);
564 	if (skl == NULL)
565 		return -ENOMEM;
566 
567 	skl->dev = dev;
568 	skl_dev.thread_context = skl;
569 	INIT_LIST_HEAD(&skl->uuid_list);
570 
571 	skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq);
572 	if (!skl->dsp) {
573 		dev_err(skl->dev, "skl_dsp_ctx_init failed\n");
574 		return -ENODEV;
575 	}
576 
577 	sst = skl->dsp;
578 	sst->fw_name = fw_name;
579 	sst->dsp_ops = dsp_ops;
580 	sst->fw_ops = bxt_fw_ops;
581 	sst->addr.lpe = mmio_base;
582 	sst->addr.shim = mmio_base;
583 
584 	sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
585 			SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
586 
587 	INIT_LIST_HEAD(&sst->module_list);
588 	ret = skl_ipc_init(dev, skl);
589 	if (ret)
590 		return ret;
591 
592 	/* set the D0i3 check */
593 	skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0;
594 
595 	skl->cores.count = 2;
596 	skl->boot_complete = false;
597 	init_waitqueue_head(&skl->boot_wait);
598 	skl->is_first_boot = true;
599 	INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3);
600 	skl->d0i3.state = SKL_DSP_D0I3_NONE;
601 
602 	if (dsp)
603 		*dsp = skl;
604 
605 	return 0;
606 }
607 EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
608 
609 int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
610 {
611 	int ret;
612 	struct sst_dsp *sst = ctx->dsp;
613 
614 	ret = sst->fw_ops.load_fw(sst);
615 	if (ret < 0) {
616 		dev_err(dev, "Load base fw failed: %x\n", ret);
617 		return ret;
618 	}
619 
620 	skl_dsp_init_core_state(sst);
621 
622 	if (ctx->lib_count > 1) {
623 		ret = sst->fw_ops.load_library(sst, ctx->lib_info,
624 						ctx->lib_count);
625 		if (ret < 0) {
626 			dev_err(dev, "Load Library failed : %x\n", ret);
627 			return ret;
628 		}
629 	}
630 	ctx->is_first_boot = false;
631 
632 	return 0;
633 }
634 EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
635 
636 void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
637 {
638 	skl_freeup_uuid_list(ctx);
639 	skl_ipc_free(&ctx->ipc);
640 	ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);
641 
642 	if (ctx->dsp->addr.lpe)
643 		iounmap(ctx->dsp->addr.lpe);
644 
645 	ctx->dsp->ops->free(ctx->dsp);
646 }
647 EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup);
648 
649 MODULE_LICENSE("GPL v2");
650 MODULE_DESCRIPTION("Intel Broxton IPC driver");
651