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