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