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