xref: /openbmc/linux/sound/soc/sof/intel/hda-loader-skl.c (revision e2379d4a83da44816009971e932db31e665d41a1)
1c712be34SPierre-Louis Bossart // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2c712be34SPierre-Louis Bossart //
3c712be34SPierre-Louis Bossart // This file is provided under a dual BSD/GPLv2 license.  When using or
4c712be34SPierre-Louis Bossart // redistributing this file, you may do so under either license.
5c712be34SPierre-Louis Bossart //
6c712be34SPierre-Louis Bossart // Copyright(c) 2018-2022 Intel Corporation. All rights reserved.
7c712be34SPierre-Louis Bossart //
8c712be34SPierre-Louis Bossart 
9c712be34SPierre-Louis Bossart #include <linux/delay.h>
10c712be34SPierre-Louis Bossart #include <linux/device.h>
11c712be34SPierre-Louis Bossart #include <linux/dma-mapping.h>
12c712be34SPierre-Louis Bossart #include <linux/firmware.h>
13c712be34SPierre-Louis Bossart #include <linux/fs.h>
14c712be34SPierre-Louis Bossart #include <linux/interrupt.h>
15c712be34SPierre-Louis Bossart #include <linux/mm.h>
16c712be34SPierre-Louis Bossart #include <linux/module.h>
17c712be34SPierre-Louis Bossart #include <linux/pci.h>
18c712be34SPierre-Louis Bossart #include <linux/pm_runtime.h>
19c712be34SPierre-Louis Bossart #include <linux/slab.h>
20c712be34SPierre-Louis Bossart #include <sound/hdaudio_ext.h>
21c712be34SPierre-Louis Bossart #include <sound/sof.h>
22c712be34SPierre-Louis Bossart #include <sound/pcm_params.h>
23c712be34SPierre-Louis Bossart 
24c712be34SPierre-Louis Bossart #include "../sof-priv.h"
25c712be34SPierre-Louis Bossart #include "../ops.h"
26c712be34SPierre-Louis Bossart #include "hda.h"
27c712be34SPierre-Louis Bossart 
28c712be34SPierre-Louis Bossart #define HDA_SKL_WAIT_TIMEOUT		500	/* 500 msec */
29c712be34SPierre-Louis Bossart #define HDA_SKL_CLDMA_MAX_BUFFER_SIZE	(32 * PAGE_SIZE)
30c712be34SPierre-Louis Bossart 
31c712be34SPierre-Louis Bossart /* Stream Reset */
32c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_SRST_SHIFT	0
33c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_SRST(x)		(((x) & 0x1) << \
34c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_SRST_SHIFT)
35c712be34SPierre-Louis Bossart 
36c712be34SPierre-Louis Bossart /* Stream Run */
37c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_RUN_SHIFT		1
38c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_RUN(x)		(((x) & 0x1) << \
39c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_RUN_SHIFT)
40c712be34SPierre-Louis Bossart 
41c712be34SPierre-Louis Bossart /* Interrupt On Completion Enable */
42c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_IOCE_SHIFT	2
43c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_IOCE(x)		(((x) & 0x1) << \
44c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_IOCE_SHIFT)
45c712be34SPierre-Louis Bossart 
46c712be34SPierre-Louis Bossart /* FIFO Error Interrupt Enable */
47c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_FEIE_SHIFT	3
48c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_FEIE(x)		(((x) & 0x1) << \
49c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_FEIE_SHIFT)
50c712be34SPierre-Louis Bossart 
51c712be34SPierre-Louis Bossart /* Descriptor Error Interrupt Enable */
52c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_DEIE_SHIFT	4
53c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_DEIE(x)		(((x) & 0x1) << \
54c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_DEIE_SHIFT)
55c712be34SPierre-Louis Bossart 
56c712be34SPierre-Louis Bossart /* FIFO Limit Change */
57c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_FIFOLC_SHIFT	5
58c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_FIFOLC(x)		(((x) & 0x1) << \
59c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_FIFOLC_SHIFT)
60c712be34SPierre-Louis Bossart 
61c712be34SPierre-Louis Bossart /* Stripe Control */
62c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_STRIPE_SHIFT	16
63c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_STRIPE(x)		(((x) & 0x3) << \
64c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_STRIPE_SHIFT)
65c712be34SPierre-Louis Bossart 
66c712be34SPierre-Louis Bossart /* Traffic Priority */
67c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_TP_SHIFT		18
68c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_TP(x)		(((x) & 0x1) << \
69c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_TP_SHIFT)
70c712be34SPierre-Louis Bossart 
71c712be34SPierre-Louis Bossart /* Bidirectional Direction Control */
72c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_DIR_SHIFT		19
73c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_DIR(x)		(((x) & 0x1) << \
74c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_DIR_SHIFT)
75c712be34SPierre-Louis Bossart 
76c712be34SPierre-Louis Bossart /* Stream Number */
77c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_STRM_SHIFT	20
78c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_STRM(x)		(((x) & 0xf) << \
79c712be34SPierre-Louis Bossart 					HDA_CL_SD_CTL_STRM_SHIFT)
80c712be34SPierre-Louis Bossart 
81c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_INT(x)	\
82c712be34SPierre-Louis Bossart 		(HDA_CL_SD_CTL_IOCE(x) | \
83c712be34SPierre-Louis Bossart 		HDA_CL_SD_CTL_FEIE(x) | \
84c712be34SPierre-Louis Bossart 		HDA_CL_SD_CTL_DEIE(x))
85c712be34SPierre-Louis Bossart 
86c712be34SPierre-Louis Bossart #define HDA_CL_SD_CTL_INT_MASK	\
87c712be34SPierre-Louis Bossart 		(HDA_CL_SD_CTL_IOCE(1) | \
88c712be34SPierre-Louis Bossart 		HDA_CL_SD_CTL_FEIE(1) | \
89c712be34SPierre-Louis Bossart 		HDA_CL_SD_CTL_DEIE(1))
90c712be34SPierre-Louis Bossart 
91c712be34SPierre-Louis Bossart #define DMA_ADDRESS_128_BITS_ALIGNMENT	7
92c712be34SPierre-Louis Bossart #define BDL_ALIGN(x)			((x) >> DMA_ADDRESS_128_BITS_ALIGNMENT)
93c712be34SPierre-Louis Bossart 
94c712be34SPierre-Louis Bossart /* Buffer Descriptor List Lower Base Address */
95c712be34SPierre-Louis Bossart #define HDA_CL_SD_BDLPLBA_SHIFT		7
96*e2379d4aSPierre-Louis Bossart #define HDA_CL_SD_BDLPLBA_MASK		GENMASK(31, 7)
97c712be34SPierre-Louis Bossart #define HDA_CL_SD_BDLPLBA(x)		\
98c712be34SPierre-Louis Bossart 	((BDL_ALIGN(lower_32_bits(x)) << HDA_CL_SD_BDLPLBA_SHIFT) & \
99c712be34SPierre-Louis Bossart 	 HDA_CL_SD_BDLPLBA_MASK)
100c712be34SPierre-Louis Bossart 
101c712be34SPierre-Louis Bossart /* Buffer Descriptor List Upper Base Address */
102c712be34SPierre-Louis Bossart #define HDA_CL_SD_BDLPUBA(x)		\
103*e2379d4aSPierre-Louis Bossart 			(upper_32_bits(x))
104c712be34SPierre-Louis Bossart 
105c712be34SPierre-Louis Bossart /* Software Position in Buffer Enable */
106c712be34SPierre-Louis Bossart #define HDA_CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT	0
107c712be34SPierre-Louis Bossart #define HDA_CL_SPBFIFO_SPBFCCTL_SPIBE_MASK	\
108c712be34SPierre-Louis Bossart 			(1 << HDA_CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT)
109c712be34SPierre-Louis Bossart 
110c712be34SPierre-Louis Bossart #define HDA_CL_SPBFIFO_SPBFCCTL_SPIBE(x)	\
111c712be34SPierre-Louis Bossart 			(((x) << HDA_CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT) & \
112c712be34SPierre-Louis Bossart 			 HDA_CL_SPBFIFO_SPBFCCTL_SPIBE_MASK)
113c712be34SPierre-Louis Bossart 
114c712be34SPierre-Louis Bossart #define HDA_CL_DMA_SD_INT_COMPLETE		0x4
115c712be34SPierre-Louis Bossart 
116c712be34SPierre-Louis Bossart static int cl_skl_cldma_setup_bdle(struct snd_sof_dev *sdev,
117c712be34SPierre-Louis Bossart 				   struct snd_dma_buffer *dmab_data,
118c712be34SPierre-Louis Bossart 				   __le32 **bdlp, int size, int with_ioc)
119c712be34SPierre-Louis Bossart {
120c712be34SPierre-Louis Bossart 	phys_addr_t addr = virt_to_phys(dmab_data->area);
121c712be34SPierre-Louis Bossart 	__le32 *bdl = *bdlp;
122c712be34SPierre-Louis Bossart 
123c712be34SPierre-Louis Bossart 	/*
124c712be34SPierre-Louis Bossart 	 * This code is simplified by using one fragment of physical memory and assuming
125c712be34SPierre-Louis Bossart 	 * all the code fits. This could be improved with scatter-gather but the firmware
126c712be34SPierre-Louis Bossart 	 * size is limited by DSP memory anyways
127c712be34SPierre-Louis Bossart 	 */
128c712be34SPierre-Louis Bossart 	bdl[0] = cpu_to_le32(lower_32_bits(addr));
129c712be34SPierre-Louis Bossart 	bdl[1] = cpu_to_le32(upper_32_bits(addr));
130c712be34SPierre-Louis Bossart 	bdl[2] = cpu_to_le32(size);
131c712be34SPierre-Louis Bossart 	bdl[3] = (!with_ioc) ? 0 : cpu_to_le32(0x01);
132c712be34SPierre-Louis Bossart 
133c712be34SPierre-Louis Bossart 	return 1; /* one fragment */
134c712be34SPierre-Louis Bossart }
135c712be34SPierre-Louis Bossart 
136c712be34SPierre-Louis Bossart static void cl_skl_cldma_stream_run(struct snd_sof_dev *sdev, bool enable)
137c712be34SPierre-Louis Bossart {
138c712be34SPierre-Louis Bossart 	int sd_offset = SOF_HDA_ADSP_LOADER_BASE;
139c712be34SPierre-Louis Bossart 	unsigned char val;
140c712be34SPierre-Louis Bossart 	int retries;
141c712be34SPierre-Louis Bossart 	u32 run = enable ? 0x1 : 0;
142c712be34SPierre-Louis Bossart 
143c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
144c712be34SPierre-Louis Bossart 				sd_offset + SOF_HDA_ADSP_REG_CL_SD_CTL,
145c712be34SPierre-Louis Bossart 				HDA_CL_SD_CTL_RUN(1), HDA_CL_SD_CTL_RUN(run));
146c712be34SPierre-Louis Bossart 
147c712be34SPierre-Louis Bossart 	retries = 300;
148c712be34SPierre-Louis Bossart 	do {
149c712be34SPierre-Louis Bossart 		udelay(3);
150c712be34SPierre-Louis Bossart 
151c712be34SPierre-Louis Bossart 		/* waiting for hardware to report the stream Run bit set */
152c712be34SPierre-Louis Bossart 		val = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
153c712be34SPierre-Louis Bossart 				       sd_offset + SOF_HDA_ADSP_REG_CL_SD_CTL);
154c712be34SPierre-Louis Bossart 		val &= HDA_CL_SD_CTL_RUN(1);
155c712be34SPierre-Louis Bossart 		if (enable && val)
156c712be34SPierre-Louis Bossart 			break;
157c712be34SPierre-Louis Bossart 		else if (!enable && !val)
158c712be34SPierre-Louis Bossart 			break;
159c712be34SPierre-Louis Bossart 	} while (--retries);
160c712be34SPierre-Louis Bossart 
161c712be34SPierre-Louis Bossart 	if (retries == 0)
162c712be34SPierre-Louis Bossart 		dev_err(sdev->dev, "%s: failed to set Run bit=%d enable=%d\n",
163c712be34SPierre-Louis Bossart 			__func__, val, enable);
164c712be34SPierre-Louis Bossart }
165c712be34SPierre-Louis Bossart 
166c712be34SPierre-Louis Bossart static void cl_skl_cldma_stream_clear(struct snd_sof_dev *sdev)
167c712be34SPierre-Louis Bossart {
168c712be34SPierre-Louis Bossart 	int sd_offset = SOF_HDA_ADSP_LOADER_BASE;
169c712be34SPierre-Louis Bossart 
170c712be34SPierre-Louis Bossart 	/* make sure Run bit is cleared before setting stream register */
171c712be34SPierre-Louis Bossart 	cl_skl_cldma_stream_run(sdev, 0);
172c712be34SPierre-Louis Bossart 
173c712be34SPierre-Louis Bossart 	/* Disable the Interrupt On Completion, FIFO Error Interrupt,
174c712be34SPierre-Louis Bossart 	 * Descriptor Error Interrupt and set the cldma stream number to 0.
175c712be34SPierre-Louis Bossart 	 */
176c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
177c712be34SPierre-Louis Bossart 				sd_offset + SOF_HDA_ADSP_REG_CL_SD_CTL,
178c712be34SPierre-Louis Bossart 				HDA_CL_SD_CTL_INT_MASK, HDA_CL_SD_CTL_INT(0));
179c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
180c712be34SPierre-Louis Bossart 				sd_offset + SOF_HDA_ADSP_REG_CL_SD_CTL,
181c712be34SPierre-Louis Bossart 				HDA_CL_SD_CTL_STRM(0xf), HDA_CL_SD_CTL_STRM(0));
182c712be34SPierre-Louis Bossart 
183c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
184c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL, HDA_CL_SD_BDLPLBA(0));
185c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
186c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU, 0);
187c712be34SPierre-Louis Bossart 
188c712be34SPierre-Louis Bossart 	/* Set the Cyclic Buffer Length to 0. */
189c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
190c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL, 0);
191c712be34SPierre-Louis Bossart 	/* Set the Last Valid Index. */
192c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
193c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI, 0);
194c712be34SPierre-Louis Bossart }
195c712be34SPierre-Louis Bossart 
196c712be34SPierre-Louis Bossart static void cl_skl_cldma_setup_spb(struct snd_sof_dev *sdev,
197c712be34SPierre-Louis Bossart 				   unsigned int size, bool enable)
198c712be34SPierre-Louis Bossart {
199c712be34SPierre-Louis Bossart 	int sd_offset = SOF_DSP_REG_CL_SPBFIFO;
200c712be34SPierre-Louis Bossart 
201c712be34SPierre-Louis Bossart 	if (enable)
202c712be34SPierre-Louis Bossart 		snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
203c712be34SPierre-Louis Bossart 					sd_offset + SOF_HDA_ADSP_REG_CL_SPBFIFO_SPBFCCTL,
204c712be34SPierre-Louis Bossart 					HDA_CL_SPBFIFO_SPBFCCTL_SPIBE_MASK,
205c712be34SPierre-Louis Bossart 					HDA_CL_SPBFIFO_SPBFCCTL_SPIBE(1));
206c712be34SPierre-Louis Bossart 
207c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
208c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SPBFIFO_SPIB, size);
209c712be34SPierre-Louis Bossart }
210c712be34SPierre-Louis Bossart 
211c712be34SPierre-Louis Bossart static void cl_skl_cldma_set_intr(struct snd_sof_dev *sdev, bool enable)
212c712be34SPierre-Louis Bossart {
213c712be34SPierre-Louis Bossart 	u32 val = enable ? HDA_DSP_ADSPIC_CL_DMA : 0;
214c712be34SPierre-Louis Bossart 
215c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
216c712be34SPierre-Louis Bossart 				HDA_DSP_ADSPIC_CL_DMA, val);
217c712be34SPierre-Louis Bossart }
218c712be34SPierre-Louis Bossart 
219c712be34SPierre-Louis Bossart static void cl_skl_cldma_cleanup_spb(struct snd_sof_dev *sdev)
220c712be34SPierre-Louis Bossart {
221c712be34SPierre-Louis Bossart 	int sd_offset = SOF_DSP_REG_CL_SPBFIFO;
222c712be34SPierre-Louis Bossart 
223c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
224c712be34SPierre-Louis Bossart 				sd_offset + SOF_HDA_ADSP_REG_CL_SPBFIFO_SPBFCCTL,
225c712be34SPierre-Louis Bossart 				HDA_CL_SPBFIFO_SPBFCCTL_SPIBE_MASK,
226c712be34SPierre-Louis Bossart 				HDA_CL_SPBFIFO_SPBFCCTL_SPIBE(0));
227c712be34SPierre-Louis Bossart 
228c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
229c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SPBFIFO_SPIB, 0);
230c712be34SPierre-Louis Bossart }
231c712be34SPierre-Louis Bossart 
232c712be34SPierre-Louis Bossart static void cl_skl_cldma_setup_controller(struct snd_sof_dev *sdev,
233c712be34SPierre-Louis Bossart 					  struct snd_dma_buffer *dmab_bdl,
234c712be34SPierre-Louis Bossart 					  unsigned int max_size, u32 count)
235c712be34SPierre-Louis Bossart {
236c712be34SPierre-Louis Bossart 	int sd_offset = SOF_HDA_ADSP_LOADER_BASE;
237c712be34SPierre-Louis Bossart 
238c712be34SPierre-Louis Bossart 	/* Clear the stream first and then set it. */
239c712be34SPierre-Louis Bossart 	cl_skl_cldma_stream_clear(sdev);
240c712be34SPierre-Louis Bossart 
241c712be34SPierre-Louis Bossart 	/* setting the stream register */
242c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
243c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
244c712be34SPierre-Louis Bossart 			  HDA_CL_SD_BDLPLBA(dmab_bdl->addr));
245c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
246c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
247c712be34SPierre-Louis Bossart 			  HDA_CL_SD_BDLPUBA(dmab_bdl->addr));
248c712be34SPierre-Louis Bossart 
249c712be34SPierre-Louis Bossart 	/* Set the Cyclic Buffer Length. */
250c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
251c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL, max_size);
252c712be34SPierre-Louis Bossart 	/* Set the Last Valid Index. */
253c712be34SPierre-Louis Bossart 	snd_sof_dsp_write(sdev, HDA_DSP_BAR,
254c712be34SPierre-Louis Bossart 			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI, count - 1);
255c712be34SPierre-Louis Bossart 
256c712be34SPierre-Louis Bossart 	/* Set the Interrupt On Completion, FIFO Error Interrupt,
257c712be34SPierre-Louis Bossart 	 * Descriptor Error Interrupt and the cldma stream number.
258c712be34SPierre-Louis Bossart 	 */
259c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
260c712be34SPierre-Louis Bossart 				sd_offset + SOF_HDA_ADSP_REG_CL_SD_CTL,
261c712be34SPierre-Louis Bossart 				HDA_CL_SD_CTL_INT_MASK, HDA_CL_SD_CTL_INT(1));
262c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
263c712be34SPierre-Louis Bossart 				sd_offset + SOF_HDA_ADSP_REG_CL_SD_CTL,
264c712be34SPierre-Louis Bossart 				HDA_CL_SD_CTL_STRM(0xf),
265c712be34SPierre-Louis Bossart 				HDA_CL_SD_CTL_STRM(1));
266c712be34SPierre-Louis Bossart }
267c712be34SPierre-Louis Bossart 
268c712be34SPierre-Louis Bossart static int cl_stream_prepare_skl(struct snd_sof_dev *sdev,
269c712be34SPierre-Louis Bossart 				 struct snd_dma_buffer *dmab,
270c712be34SPierre-Louis Bossart 				 struct snd_dma_buffer *dmab_bdl)
271c712be34SPierre-Louis Bossart 
272c712be34SPierre-Louis Bossart {
273c712be34SPierre-Louis Bossart 	unsigned int bufsize = HDA_SKL_CLDMA_MAX_BUFFER_SIZE;
274c712be34SPierre-Louis Bossart 	__le32 *bdl;
275c712be34SPierre-Louis Bossart 	int frags;
276c712be34SPierre-Louis Bossart 	int ret;
277c712be34SPierre-Louis Bossart 
278c712be34SPierre-Louis Bossart 	ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, bufsize, dmab);
279c712be34SPierre-Louis Bossart 	if (ret < 0) {
280c712be34SPierre-Louis Bossart 		dev_err(sdev->dev, "%s: failed to alloc fw buffer: %x\n", __func__, ret);
281c712be34SPierre-Louis Bossart 		return ret;
282c712be34SPierre-Louis Bossart 	}
283c712be34SPierre-Louis Bossart 
284c712be34SPierre-Louis Bossart 	ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, bufsize, dmab_bdl);
285c712be34SPierre-Louis Bossart 	if (ret < 0) {
286c712be34SPierre-Louis Bossart 		dev_err(sdev->dev, "%s: failed to alloc blde: %x\n", __func__, ret);
287c712be34SPierre-Louis Bossart 		snd_dma_free_pages(dmab);
288c712be34SPierre-Louis Bossart 		return ret;
289c712be34SPierre-Louis Bossart 	}
290c712be34SPierre-Louis Bossart 
291c712be34SPierre-Louis Bossart 	bdl = (__le32 *)dmab_bdl->area;
292c712be34SPierre-Louis Bossart 	frags = cl_skl_cldma_setup_bdle(sdev, dmab, &bdl, bufsize, 1);
293c712be34SPierre-Louis Bossart 	cl_skl_cldma_setup_controller(sdev, dmab_bdl, bufsize, frags);
294c712be34SPierre-Louis Bossart 
295c712be34SPierre-Louis Bossart 	return ret;
296c712be34SPierre-Louis Bossart }
297c712be34SPierre-Louis Bossart 
298c712be34SPierre-Louis Bossart static void cl_cleanup_skl(struct snd_sof_dev *sdev,
299c712be34SPierre-Louis Bossart 			   struct snd_dma_buffer *dmab,
300c712be34SPierre-Louis Bossart 			   struct snd_dma_buffer *dmab_bdl)
301c712be34SPierre-Louis Bossart {
302c712be34SPierre-Louis Bossart 	cl_skl_cldma_cleanup_spb(sdev);
303c712be34SPierre-Louis Bossart 	cl_skl_cldma_stream_clear(sdev);
304c712be34SPierre-Louis Bossart 	snd_dma_free_pages(dmab);
305c712be34SPierre-Louis Bossart 	snd_dma_free_pages(dmab_bdl);
306c712be34SPierre-Louis Bossart }
307c712be34SPierre-Louis Bossart 
308c712be34SPierre-Louis Bossart static int cl_dsp_init_skl(struct snd_sof_dev *sdev,
309c712be34SPierre-Louis Bossart 			   struct snd_dma_buffer *dmab,
310c712be34SPierre-Louis Bossart 			   struct snd_dma_buffer *dmab_bdl)
311c712be34SPierre-Louis Bossart {
312c712be34SPierre-Louis Bossart 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
313c712be34SPierre-Louis Bossart 	const struct sof_intel_dsp_desc *chip = hda->desc;
314c712be34SPierre-Louis Bossart 	unsigned int status;
315c712be34SPierre-Louis Bossart 	u32 flags;
316c712be34SPierre-Louis Bossart 	int ret;
317c712be34SPierre-Louis Bossart 
318c712be34SPierre-Louis Bossart 	/* check if the init_core is already enabled, if yes, reset and make it run,
319c712be34SPierre-Louis Bossart 	 * if not, powerdown and enable it again.
320c712be34SPierre-Louis Bossart 	 */
321c712be34SPierre-Louis Bossart 	if (hda_dsp_core_is_enabled(sdev, chip->init_core_mask)) {
322c712be34SPierre-Louis Bossart 		/* if enabled, reset it, and run the init_core. */
323c712be34SPierre-Louis Bossart 		ret = hda_dsp_core_stall_reset(sdev, chip->init_core_mask);
324c712be34SPierre-Louis Bossart 		if (ret < 0)
325c712be34SPierre-Louis Bossart 			goto err;
326c712be34SPierre-Louis Bossart 
327c712be34SPierre-Louis Bossart 		ret = hda_dsp_core_run(sdev, chip->init_core_mask);
328c712be34SPierre-Louis Bossart 		if (ret < 0) {
329c712be34SPierre-Louis Bossart 			dev_err(sdev->dev, "%s: dsp core start failed %d\n", __func__, ret);
330c712be34SPierre-Louis Bossart 			goto err;
331c712be34SPierre-Louis Bossart 		}
332c712be34SPierre-Louis Bossart 	} else {
333c712be34SPierre-Louis Bossart 		/* if not enabled, power down it first and then powerup and run
334c712be34SPierre-Louis Bossart 		 * the init_core.
335c712be34SPierre-Louis Bossart 		 */
336c712be34SPierre-Louis Bossart 		ret = hda_dsp_core_reset_power_down(sdev, chip->init_core_mask);
337c712be34SPierre-Louis Bossart 		if (ret < 0) {
338c712be34SPierre-Louis Bossart 			dev_err(sdev->dev, "%s: dsp core0 disable fail: %d\n", __func__, ret);
339c712be34SPierre-Louis Bossart 			goto err;
340c712be34SPierre-Louis Bossart 		}
341c712be34SPierre-Louis Bossart 		ret = hda_dsp_enable_core(sdev, chip->init_core_mask);
342c712be34SPierre-Louis Bossart 		if (ret < 0) {
343c712be34SPierre-Louis Bossart 			dev_err(sdev->dev, "%s: dsp core0 enable fail: %d\n", __func__, ret);
344c712be34SPierre-Louis Bossart 			goto err;
345c712be34SPierre-Louis Bossart 		}
346c712be34SPierre-Louis Bossart 	}
347c712be34SPierre-Louis Bossart 
348c712be34SPierre-Louis Bossart 	/* prepare DMA for code loader stream */
349c712be34SPierre-Louis Bossart 	ret = cl_stream_prepare_skl(sdev, dmab, dmab_bdl);
350c712be34SPierre-Louis Bossart 	if (ret < 0) {
351c712be34SPierre-Louis Bossart 		dev_err(sdev->dev, "%s: dma prepare fw loading err: %x\n", __func__, ret);
352c712be34SPierre-Louis Bossart 		return ret;
353c712be34SPierre-Louis Bossart 	}
354c712be34SPierre-Louis Bossart 
355c712be34SPierre-Louis Bossart 	/* enable the interrupt */
356c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
357c712be34SPierre-Louis Bossart 				HDA_DSP_ADSPIC_IPC, HDA_DSP_ADSPIC_IPC);
358c712be34SPierre-Louis Bossart 
359c712be34SPierre-Louis Bossart 	/* enable IPC DONE interrupt */
360c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
361c712be34SPierre-Louis Bossart 				HDA_DSP_REG_HIPCCTL_DONE,
362c712be34SPierre-Louis Bossart 				HDA_DSP_REG_HIPCCTL_DONE);
363c712be34SPierre-Louis Bossart 
364c712be34SPierre-Louis Bossart 	/* enable IPC BUSY interrupt */
365c712be34SPierre-Louis Bossart 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
366c712be34SPierre-Louis Bossart 				HDA_DSP_REG_HIPCCTL_BUSY,
367c712be34SPierre-Louis Bossart 				HDA_DSP_REG_HIPCCTL_BUSY);
368c712be34SPierre-Louis Bossart 
369c712be34SPierre-Louis Bossart 	/* polling the ROM init status information. */
370c712be34SPierre-Louis Bossart 	ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
371c712be34SPierre-Louis Bossart 					    chip->rom_status_reg, status,
372c712be34SPierre-Louis Bossart 					    (FSR_TO_STATE_CODE(status)
373c712be34SPierre-Louis Bossart 					     == FSR_STATE_INIT_DONE),
374c712be34SPierre-Louis Bossart 					    HDA_DSP_REG_POLL_INTERVAL_US,
375c712be34SPierre-Louis Bossart 					    chip->rom_init_timeout *
376c712be34SPierre-Louis Bossart 					    USEC_PER_MSEC);
377c712be34SPierre-Louis Bossart 	if (ret < 0)
378c712be34SPierre-Louis Bossart 		goto err;
379c712be34SPierre-Louis Bossart 
380c712be34SPierre-Louis Bossart 	return ret;
381c712be34SPierre-Louis Bossart 
382c712be34SPierre-Louis Bossart err:
383c712be34SPierre-Louis Bossart 	flags = SOF_DBG_DUMP_PCI | SOF_DBG_DUMP_MBOX;
384c712be34SPierre-Louis Bossart 
385c712be34SPierre-Louis Bossart 	snd_sof_dsp_dbg_dump(sdev, "Boot failed\n", flags);
386c712be34SPierre-Louis Bossart 	cl_cleanup_skl(sdev, dmab, dmab_bdl);
387c712be34SPierre-Louis Bossart 	hda_dsp_core_reset_power_down(sdev, chip->init_core_mask);
388c712be34SPierre-Louis Bossart 	return ret;
389c712be34SPierre-Louis Bossart }
390c712be34SPierre-Louis Bossart 
391c712be34SPierre-Louis Bossart static void cl_skl_cldma_fill_buffer(struct snd_sof_dev *sdev,
392c712be34SPierre-Louis Bossart 				     struct snd_dma_buffer *dmab,
393c712be34SPierre-Louis Bossart 				     unsigned int bufsize,
394c712be34SPierre-Louis Bossart 				     unsigned int copysize,
395c712be34SPierre-Louis Bossart 				     const void *curr_pos,
396c712be34SPierre-Louis Bossart 				     bool intr_enable)
397c712be34SPierre-Louis Bossart {
398c712be34SPierre-Louis Bossart 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
399c712be34SPierre-Louis Bossart 
400c712be34SPierre-Louis Bossart 	/* copy the image into the buffer with the maximum buffer size. */
401c712be34SPierre-Louis Bossart 	unsigned int size = (bufsize == copysize) ? bufsize : copysize;
402c712be34SPierre-Louis Bossart 
403c712be34SPierre-Louis Bossart 	memcpy(dmab->area, curr_pos, size);
404c712be34SPierre-Louis Bossart 
405c712be34SPierre-Louis Bossart 	/* Set the wait condition for every load. */
406c712be34SPierre-Louis Bossart 	hda->code_loading = 1;
407c712be34SPierre-Louis Bossart 
408c712be34SPierre-Louis Bossart 	/* Set the interrupt. */
409c712be34SPierre-Louis Bossart 	if (intr_enable)
410c712be34SPierre-Louis Bossart 		cl_skl_cldma_set_intr(sdev, true);
411c712be34SPierre-Louis Bossart 
412c712be34SPierre-Louis Bossart 	/* Set the SPB. */
413c712be34SPierre-Louis Bossart 	cl_skl_cldma_setup_spb(sdev, size, true);
414c712be34SPierre-Louis Bossart 
415c712be34SPierre-Louis Bossart 	/* Trigger the code loading stream. */
416c712be34SPierre-Louis Bossart 	cl_skl_cldma_stream_run(sdev, true);
417c712be34SPierre-Louis Bossart }
418c712be34SPierre-Louis Bossart 
419c712be34SPierre-Louis Bossart static int cl_skl_cldma_wait_interruptible(struct snd_sof_dev *sdev,
420c712be34SPierre-Louis Bossart 					   bool intr_wait)
421c712be34SPierre-Louis Bossart {
422c712be34SPierre-Louis Bossart 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
423c712be34SPierre-Louis Bossart 	const struct sof_intel_dsp_desc *chip = hda->desc;
424c712be34SPierre-Louis Bossart 	int sd_offset = SOF_HDA_ADSP_LOADER_BASE;
425c712be34SPierre-Louis Bossart 	u8 cl_dma_intr_status;
426c712be34SPierre-Louis Bossart 
427c712be34SPierre-Louis Bossart 	/*
428c712be34SPierre-Louis Bossart 	 * Wait for CLDMA interrupt to inform the binary segment transfer is
429c712be34SPierre-Louis Bossart 	 * complete.
430c712be34SPierre-Louis Bossart 	 */
431c712be34SPierre-Louis Bossart 	if (!wait_event_timeout(hda->waitq, !hda->code_loading,
432c712be34SPierre-Louis Bossart 				msecs_to_jiffies(HDA_SKL_WAIT_TIMEOUT))) {
433c712be34SPierre-Louis Bossart 		dev_err(sdev->dev, "cldma copy timeout\n");
434c712be34SPierre-Louis Bossart 		dev_err(sdev->dev, "ROM code=%#x: FW status=%#x\n",
435c712be34SPierre-Louis Bossart 			snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_ROM_ERROR),
436c712be34SPierre-Louis Bossart 			snd_sof_dsp_read(sdev, HDA_DSP_BAR, chip->rom_status_reg));
437c712be34SPierre-Louis Bossart 		return -EIO;
438c712be34SPierre-Louis Bossart 	}
439c712be34SPierre-Louis Bossart 
440c712be34SPierre-Louis Bossart 	/* now check DMA interrupt status */
441c712be34SPierre-Louis Bossart 	cl_dma_intr_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
442c712be34SPierre-Louis Bossart 					      sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS);
443c712be34SPierre-Louis Bossart 
444c712be34SPierre-Louis Bossart 	if (!(cl_dma_intr_status & HDA_CL_DMA_SD_INT_COMPLETE)) {
445c712be34SPierre-Louis Bossart 		dev_err(sdev->dev, "cldma copy failed\n");
446c712be34SPierre-Louis Bossart 		return -EIO;
447c712be34SPierre-Louis Bossart 	}
448c712be34SPierre-Louis Bossart 
449c712be34SPierre-Louis Bossart 	dev_dbg(sdev->dev, "cldma buffer copy complete\n");
450c712be34SPierre-Louis Bossart 	return 0;
451c712be34SPierre-Louis Bossart }
452c712be34SPierre-Louis Bossart 
453c712be34SPierre-Louis Bossart static int
454c712be34SPierre-Louis Bossart cl_skl_cldma_copy_to_buf(struct snd_sof_dev *sdev,
455c712be34SPierre-Louis Bossart 			 struct snd_dma_buffer *dmab,
456c712be34SPierre-Louis Bossart 			 const void *bin,
457c712be34SPierre-Louis Bossart 			 u32 total_size, u32 bufsize)
458c712be34SPierre-Louis Bossart {
459c712be34SPierre-Louis Bossart 	unsigned int bytes_left = total_size;
460c712be34SPierre-Louis Bossart 	const void *curr_pos = bin;
461c712be34SPierre-Louis Bossart 	int ret;
462c712be34SPierre-Louis Bossart 
463c712be34SPierre-Louis Bossart 	if (total_size <= 0)
464c712be34SPierre-Louis Bossart 		return -EINVAL;
465c712be34SPierre-Louis Bossart 
466c712be34SPierre-Louis Bossart 	while (bytes_left > 0) {
467c712be34SPierre-Louis Bossart 		if (bytes_left > bufsize) {
468c712be34SPierre-Louis Bossart 			dev_dbg(sdev->dev, "cldma copy %#x bytes\n", bufsize);
469c712be34SPierre-Louis Bossart 
470c712be34SPierre-Louis Bossart 			cl_skl_cldma_fill_buffer(sdev, dmab, bufsize, bufsize, curr_pos, true);
471c712be34SPierre-Louis Bossart 
472c712be34SPierre-Louis Bossart 			ret = cl_skl_cldma_wait_interruptible(sdev, false);
473c712be34SPierre-Louis Bossart 			if (ret < 0) {
474c712be34SPierre-Louis Bossart 				dev_err(sdev->dev, "%s: fw failed to load. %#x bytes remaining\n",
475c712be34SPierre-Louis Bossart 					__func__, bytes_left);
476c712be34SPierre-Louis Bossart 				return ret;
477c712be34SPierre-Louis Bossart 			}
478c712be34SPierre-Louis Bossart 
479c712be34SPierre-Louis Bossart 			bytes_left -= bufsize;
480c712be34SPierre-Louis Bossart 			curr_pos += bufsize;
481c712be34SPierre-Louis Bossart 		} else {
482c712be34SPierre-Louis Bossart 			dev_dbg(sdev->dev, "cldma copy %#x bytes\n", bytes_left);
483c712be34SPierre-Louis Bossart 
484c712be34SPierre-Louis Bossart 			cl_skl_cldma_set_intr(sdev, false);
485c712be34SPierre-Louis Bossart 			cl_skl_cldma_fill_buffer(sdev, dmab, bufsize, bytes_left, curr_pos, false);
486c712be34SPierre-Louis Bossart 			return 0;
487c712be34SPierre-Louis Bossart 		}
488c712be34SPierre-Louis Bossart 	}
489c712be34SPierre-Louis Bossart 
490c712be34SPierre-Louis Bossart 	return bytes_left;
491c712be34SPierre-Louis Bossart }
492c712be34SPierre-Louis Bossart 
493c712be34SPierre-Louis Bossart static int cl_copy_fw_skl(struct snd_sof_dev *sdev,
494c712be34SPierre-Louis Bossart 			  struct snd_dma_buffer *dmab)
495c712be34SPierre-Louis Bossart 
496c712be34SPierre-Louis Bossart {
497c712be34SPierre-Louis Bossart 	struct snd_sof_pdata *plat_data = sdev->pdata;
498c712be34SPierre-Louis Bossart 	const struct firmware *fw =  plat_data->fw;
499c712be34SPierre-Louis Bossart 	struct firmware stripped_firmware;
500c712be34SPierre-Louis Bossart 	unsigned int bufsize = HDA_SKL_CLDMA_MAX_BUFFER_SIZE;
501c712be34SPierre-Louis Bossart 	int ret;
502c712be34SPierre-Louis Bossart 
503c712be34SPierre-Louis Bossart 	stripped_firmware.data = plat_data->fw->data + plat_data->fw_offset;
504c712be34SPierre-Louis Bossart 	stripped_firmware.size = plat_data->fw->size - plat_data->fw_offset;
505c712be34SPierre-Louis Bossart 
506c712be34SPierre-Louis Bossart 	dev_dbg(sdev->dev, "firmware size: %#zx buffer size %#x\n", fw->size, bufsize);
507c712be34SPierre-Louis Bossart 
508c712be34SPierre-Louis Bossart 	ret = cl_skl_cldma_copy_to_buf(sdev, dmab, stripped_firmware.data,
509c712be34SPierre-Louis Bossart 				       stripped_firmware.size, bufsize);
510c712be34SPierre-Louis Bossart 	if (ret < 0)
511c712be34SPierre-Louis Bossart 		dev_err(sdev->dev, "%s: fw copy failed %d\n", __func__, ret);
512c712be34SPierre-Louis Bossart 
513c712be34SPierre-Louis Bossart 	return ret;
514c712be34SPierre-Louis Bossart }
515c712be34SPierre-Louis Bossart 
516c712be34SPierre-Louis Bossart int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev)
517c712be34SPierre-Louis Bossart {
518c712be34SPierre-Louis Bossart 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
519c712be34SPierre-Louis Bossart 	const struct sof_intel_dsp_desc *chip = hda->desc;
520c712be34SPierre-Louis Bossart 	struct snd_dma_buffer dmab_bdl;
521c712be34SPierre-Louis Bossart 	struct snd_dma_buffer dmab;
522c712be34SPierre-Louis Bossart 	unsigned int reg;
523c712be34SPierre-Louis Bossart 	u32 flags;
524c712be34SPierre-Louis Bossart 	int ret;
525c712be34SPierre-Louis Bossart 
526c712be34SPierre-Louis Bossart 	ret = cl_dsp_init_skl(sdev, &dmab, &dmab_bdl);
527c712be34SPierre-Louis Bossart 
528c712be34SPierre-Louis Bossart 	/* retry enabling core and ROM load. seemed to help */
529c712be34SPierre-Louis Bossart 	if (ret < 0) {
530c712be34SPierre-Louis Bossart 		ret = cl_dsp_init_skl(sdev, &dmab, &dmab_bdl);
531c712be34SPierre-Louis Bossart 		if (ret < 0) {
532c712be34SPierre-Louis Bossart 			dev_err(sdev->dev, "Error code=%#x: FW status=%#x\n",
533c712be34SPierre-Louis Bossart 				snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_ROM_ERROR),
534c712be34SPierre-Louis Bossart 				snd_sof_dsp_read(sdev, HDA_DSP_BAR, chip->rom_status_reg));
535c712be34SPierre-Louis Bossart 			dev_err(sdev->dev, "Core En/ROM load fail:%d\n", ret);
536c712be34SPierre-Louis Bossart 			return ret;
537c712be34SPierre-Louis Bossart 		}
538c712be34SPierre-Louis Bossart 	}
539c712be34SPierre-Louis Bossart 
540c712be34SPierre-Louis Bossart 	dev_dbg(sdev->dev, "ROM init successful\n");
541c712be34SPierre-Louis Bossart 
542c712be34SPierre-Louis Bossart 	/* at this point DSP ROM has been initialized and should be ready for
543c712be34SPierre-Louis Bossart 	 * code loading and firmware boot
544c712be34SPierre-Louis Bossart 	 */
545c712be34SPierre-Louis Bossart 	ret = cl_copy_fw_skl(sdev, &dmab);
546c712be34SPierre-Louis Bossart 	if (ret < 0) {
547c712be34SPierre-Louis Bossart 		dev_err(sdev->dev, "%s: load firmware failed : %d\n", __func__, ret);
548c712be34SPierre-Louis Bossart 		goto err;
549c712be34SPierre-Louis Bossart 	}
550c712be34SPierre-Louis Bossart 
551c712be34SPierre-Louis Bossart 	ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
552c712be34SPierre-Louis Bossart 					    chip->rom_status_reg, reg,
553c712be34SPierre-Louis Bossart 					    (FSR_TO_STATE_CODE(reg)
554c712be34SPierre-Louis Bossart 					     == FSR_STATE_ROM_BASEFW_ENTERED),
555c712be34SPierre-Louis Bossart 					    HDA_DSP_REG_POLL_INTERVAL_US,
556c712be34SPierre-Louis Bossart 					    HDA_DSP_BASEFW_TIMEOUT_US);
557c712be34SPierre-Louis Bossart 
558c712be34SPierre-Louis Bossart 	dev_dbg(sdev->dev, "Firmware download successful, booting...\n");
559c712be34SPierre-Louis Bossart 
560c712be34SPierre-Louis Bossart 	cl_skl_cldma_stream_run(sdev, false);
561c712be34SPierre-Louis Bossart 	cl_cleanup_skl(sdev, &dmab, &dmab_bdl);
562c712be34SPierre-Louis Bossart 
563c712be34SPierre-Louis Bossart 	if (!ret)
564c712be34SPierre-Louis Bossart 		return chip->init_core_mask;
565c712be34SPierre-Louis Bossart 
566c712be34SPierre-Louis Bossart 	return ret;
567c712be34SPierre-Louis Bossart 
568c712be34SPierre-Louis Bossart err:
569c712be34SPierre-Louis Bossart 	flags = SOF_DBG_DUMP_PCI | SOF_DBG_DUMP_MBOX;
570c712be34SPierre-Louis Bossart 
571c712be34SPierre-Louis Bossart 	snd_sof_dsp_dbg_dump(sdev, "Boot failed\n", flags);
572c712be34SPierre-Louis Bossart 
573c712be34SPierre-Louis Bossart 	/* power down DSP */
574c712be34SPierre-Louis Bossart 	hda_dsp_core_reset_power_down(sdev, chip->init_core_mask);
575c712be34SPierre-Louis Bossart 	cl_skl_cldma_stream_run(sdev, false);
576c712be34SPierre-Louis Bossart 	cl_cleanup_skl(sdev, &dmab, &dmab_bdl);
577c712be34SPierre-Louis Bossart 
578c712be34SPierre-Louis Bossart 	dev_err(sdev->dev, "%s: load fw failed err: %d\n", __func__, ret);
579c712be34SPierre-Louis Bossart 	return ret;
580c712be34SPierre-Louis Bossart }
581