arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / sound / soc / intel / avs / loader.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
4 //
5 // Authors: Cezary Rojewski <cezary.rojewski@intel.com>
6 //          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
7 //
8
9 #include <linux/firmware.h>
10 #include <linux/module.h>
11 #include <linux/slab.h>
12 #include <sound/hdaudio.h>
13 #include <sound/hdaudio_ext.h>
14 #include "avs.h"
15 #include "cldma.h"
16 #include "messages.h"
17 #include "registers.h"
18 #include "topology.h"
19
20 #define AVS_ROM_STS_MASK                0xFF
21 #define AVS_ROM_INIT_DONE               0x1
22 #define SKL_ROM_BASEFW_ENTERED          0xF
23 #define APL_ROM_FW_ENTERED              0x5
24 #define AVS_ROM_INIT_POLLING_US         5
25 #define SKL_ROM_INIT_TIMEOUT_US         1000000
26 #define APL_ROM_INIT_TIMEOUT_US         300000
27 #define APL_ROM_INIT_RETRIES            3
28
29 #define AVS_FW_INIT_POLLING_US          500
30 #define AVS_FW_INIT_TIMEOUT_MS          3000
31 #define AVS_FW_INIT_TIMEOUT_US          (AVS_FW_INIT_TIMEOUT_MS * 1000)
32
33 #define AVS_CLDMA_START_DELAY_MS        100
34
35 #define AVS_ROOT_DIR                    "intel/avs"
36 #define AVS_BASEFW_FILENAME             "/*(DEBLOBBED)*/"
37 #define AVS_EXT_MANIFEST_MAGIC          0x31454124
38 #define SKL_MANIFEST_MAGIC              0x00000006
39 #define SKL_ADSPFW_OFFSET               0x284
40 #define APL_MANIFEST_MAGIC              0x44504324
41 #define APL_ADSPFW_OFFSET               0x2000
42
43 /* Occasionally, engineering (release candidate) firmware is provided for testing. */
44 static bool debug_ignore_fw_version;
45 module_param_named(ignore_fw_version, debug_ignore_fw_version, bool, 0444);
46 MODULE_PARM_DESC(ignore_fw_version, "Ignore firmware version check 0=no (default), 1=yes");
47
48 #define AVS_LIB_NAME_SIZE       8
49
50 struct avs_fw_manifest {
51         u32 id;
52         u32 len;
53         char name[AVS_LIB_NAME_SIZE];
54         u32 preload_page_count;
55         u32 img_flags;
56         u32 feature_mask;
57         struct avs_fw_version version;
58 } __packed;
59
60 struct avs_fw_ext_manifest {
61         u32 id;
62         u32 len;
63         u16 version_major;
64         u16 version_minor;
65         u32 entries;
66 } __packed;
67
68 static int avs_fw_ext_manifest_strip(struct firmware *fw)
69 {
70         struct avs_fw_ext_manifest *man;
71
72         if (fw->size < sizeof(*man))
73                 return -EINVAL;
74
75         man = (struct avs_fw_ext_manifest *)fw->data;
76         if (man->id == AVS_EXT_MANIFEST_MAGIC) {
77                 fw->data += man->len;
78                 fw->size -= man->len;
79         }
80
81         return 0;
82 }
83
84 static int avs_fw_manifest_offset(struct firmware *fw)
85 {
86         /* Header type found in first DWORD of fw binary. */
87         u32 magic = *(u32 *)fw->data;
88
89         switch (magic) {
90         case SKL_MANIFEST_MAGIC:
91                 return SKL_ADSPFW_OFFSET;
92         case APL_MANIFEST_MAGIC:
93                 return APL_ADSPFW_OFFSET;
94         default:
95                 return -EINVAL;
96         }
97 }
98
99 static int avs_fw_manifest_strip_verify(struct avs_dev *adev, struct firmware *fw,
100                                         const struct avs_fw_version *min)
101 {
102         struct avs_fw_manifest *man;
103         int offset, ret;
104
105         ret = avs_fw_ext_manifest_strip(fw);
106         if (ret)
107                 return ret;
108
109         offset = avs_fw_manifest_offset(fw);
110         if (offset < 0)
111                 return offset;
112
113         if (fw->size < offset + sizeof(*man))
114                 return -EINVAL;
115         if (!min)
116                 return 0;
117
118         man = (struct avs_fw_manifest *)(fw->data + offset);
119         if (man->version.major != min->major ||
120             man->version.minor != min->minor ||
121             man->version.hotfix != min->hotfix ||
122             man->version.build < min->build) {
123                 dev_warn(adev->dev, "bad FW version %d.%d.%d.%d, expected %d.%d.%d.%d or newer\n",
124                          man->version.major, man->version.minor,
125                          man->version.hotfix, man->version.build,
126                          min->major, min->minor, min->hotfix, min->build);
127
128                 if (!debug_ignore_fw_version)
129                         return -EINVAL;
130         }
131
132         return 0;
133 }
134
135 int avs_cldma_load_basefw(struct avs_dev *adev, struct firmware *fw)
136 {
137         struct hda_cldma *cl = &code_loader;
138         unsigned int reg;
139         int ret;
140
141         ret = avs_dsp_op(adev, power, AVS_MAIN_CORE_MASK, true);
142         if (ret < 0)
143                 return ret;
144
145         ret = avs_dsp_op(adev, reset, AVS_MAIN_CORE_MASK, false);
146         if (ret < 0)
147                 return ret;
148
149         ret = hda_cldma_reset(cl);
150         if (ret < 0) {
151                 dev_err(adev->dev, "cldma reset failed: %d\n", ret);
152                 return ret;
153         }
154         hda_cldma_setup(cl);
155
156         ret = avs_dsp_op(adev, stall, AVS_MAIN_CORE_MASK, false);
157         if (ret < 0)
158                 return ret;
159
160         reinit_completion(&adev->fw_ready);
161         avs_dsp_op(adev, int_control, true);
162
163         /* await ROM init */
164         ret = snd_hdac_adsp_readl_poll(adev, AVS_FW_REG_STATUS(adev), reg,
165                                        (reg & AVS_ROM_INIT_DONE) == AVS_ROM_INIT_DONE,
166                                        AVS_ROM_INIT_POLLING_US, SKL_ROM_INIT_TIMEOUT_US);
167         if (ret < 0) {
168                 dev_err(adev->dev, "rom init timeout: %d\n", ret);
169                 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
170                 return ret;
171         }
172
173         hda_cldma_set_data(cl, (void *)fw->data, fw->size);
174         /* transfer firmware */
175         hda_cldma_transfer(cl, 0);
176         ret = snd_hdac_adsp_readl_poll(adev, AVS_FW_REG_STATUS(adev), reg,
177                                        (reg & AVS_ROM_STS_MASK) == SKL_ROM_BASEFW_ENTERED,
178                                        AVS_FW_INIT_POLLING_US, AVS_FW_INIT_TIMEOUT_US);
179         hda_cldma_stop(cl);
180         if (ret < 0) {
181                 dev_err(adev->dev, "transfer fw failed: %d\n", ret);
182                 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
183                 return ret;
184         }
185
186         return 0;
187 }
188
189 int avs_cldma_load_library(struct avs_dev *adev, struct firmware *lib, u32 id)
190 {
191         struct hda_cldma *cl = &code_loader;
192         int ret;
193
194         hda_cldma_set_data(cl, (void *)lib->data, lib->size);
195         /* transfer modules manifest */
196         hda_cldma_transfer(cl, msecs_to_jiffies(AVS_CLDMA_START_DELAY_MS));
197
198         /* DMA id ignored as there is only ever one code-loader DMA */
199         ret = avs_ipc_load_library(adev, 0, id);
200         hda_cldma_stop(cl);
201
202         if (ret) {
203                 ret = AVS_IPC_RET(ret);
204                 dev_err(adev->dev, "transfer lib %d failed: %d\n", id, ret);
205         }
206
207         return ret;
208 }
209
210 static int avs_cldma_load_module(struct avs_dev *adev, struct avs_module_entry *mentry)
211 {
212         struct hda_cldma *cl = &code_loader;
213         const struct firmware *mod;
214         char *mod_name;
215         int ret;
216
217         mod_name = kasprintf(GFP_KERNEL, "/*(DEBLOBBED)*/", AVS_ROOT_DIR,
218                              adev->spec->name, mentry->uuid.b);
219         if (!mod_name)
220                 return -ENOMEM;
221
222         ret = avs_request_firmware(adev, &mod, mod_name);
223         kfree(mod_name);
224         if (ret < 0)
225                 return ret;
226
227         avs_hda_power_gating_enable(adev, false);
228         avs_hda_clock_gating_enable(adev, false);
229         avs_hda_l1sen_enable(adev, false);
230
231         hda_cldma_set_data(cl, (void *)mod->data, mod->size);
232         hda_cldma_transfer(cl, msecs_to_jiffies(AVS_CLDMA_START_DELAY_MS));
233         ret = avs_ipc_load_modules(adev, &mentry->module_id, 1);
234         hda_cldma_stop(cl);
235
236         avs_hda_l1sen_enable(adev, true);
237         avs_hda_clock_gating_enable(adev, true);
238         avs_hda_power_gating_enable(adev, true);
239
240         if (ret) {
241                 dev_err(adev->dev, "load module %d failed: %d\n", mentry->module_id, ret);
242                 avs_release_last_firmware(adev);
243                 return AVS_IPC_RET(ret);
244         }
245
246         return 0;
247 }
248
249 int avs_cldma_transfer_modules(struct avs_dev *adev, bool load,
250                                struct avs_module_entry *mods, u32 num_mods)
251 {
252         u16 *mod_ids;
253         int ret, i;
254
255         /* Either load to DSP or unload them to free space. */
256         if (load) {
257                 for (i = 0; i < num_mods; i++) {
258                         ret = avs_cldma_load_module(adev, &mods[i]);
259                         if (ret)
260                                 return ret;
261                 }
262
263                 return 0;
264         }
265
266         mod_ids = kcalloc(num_mods, sizeof(u16), GFP_KERNEL);
267         if (!mod_ids)
268                 return -ENOMEM;
269
270         for (i = 0; i < num_mods; i++)
271                 mod_ids[i] = mods[i].module_id;
272
273         ret = avs_ipc_unload_modules(adev, mod_ids, num_mods);
274         kfree(mod_ids);
275         if (ret)
276                 return AVS_IPC_RET(ret);
277
278         return 0;
279 }
280
281 static int
282 avs_hda_init_rom(struct avs_dev *adev, unsigned int dma_id, bool purge)
283 {
284         const struct avs_spec *const spec = adev->spec;
285         unsigned int corex_mask, reg;
286         int ret;
287
288         corex_mask = spec->core_init_mask & ~AVS_MAIN_CORE_MASK;
289
290         ret = avs_dsp_op(adev, power, spec->core_init_mask, true);
291         if (ret < 0)
292                 goto err;
293
294         ret = avs_dsp_op(adev, reset, AVS_MAIN_CORE_MASK, false);
295         if (ret < 0)
296                 goto err;
297
298         reinit_completion(&adev->fw_ready);
299         avs_dsp_op(adev, int_control, true);
300
301         /* set boot config */
302         ret = avs_ipc_set_boot_config(adev, dma_id, purge);
303         if (ret) {
304                 ret = AVS_IPC_RET(ret);
305                 goto err;
306         }
307
308         /* await ROM init */
309         ret = snd_hdac_adsp_readq_poll(adev, spec->rom_status, reg,
310                                        (reg & 0xF) == AVS_ROM_INIT_DONE ||
311                                        (reg & 0xF) == APL_ROM_FW_ENTERED,
312                                        AVS_ROM_INIT_POLLING_US, APL_ROM_INIT_TIMEOUT_US);
313         if (ret < 0) {
314                 dev_err(adev->dev, "rom init timeout: %d\n", ret);
315                 goto err;
316         }
317
318         /* power down non-main cores */
319         if (corex_mask) {
320                 ret = avs_dsp_op(adev, power, corex_mask, false);
321                 if (ret < 0)
322                         goto err;
323         }
324
325         return 0;
326
327 err:
328         avs_dsp_core_disable(adev, spec->core_init_mask);
329         return ret;
330 }
331
332 static int avs_imr_load_basefw(struct avs_dev *adev)
333 {
334         int ret;
335
336         /* DMA id ignored when flashing from IMR as no transfer occurs. */
337         ret = avs_hda_init_rom(adev, 0, false);
338         if (ret < 0) {
339                 dev_err(adev->dev, "rom init failed: %d\n", ret);
340                 return ret;
341         }
342
343         ret = wait_for_completion_timeout(&adev->fw_ready,
344                                           msecs_to_jiffies(AVS_FW_INIT_TIMEOUT_MS));
345         if (!ret) {
346                 dev_err(adev->dev, "firmware ready timeout\n");
347                 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
348                 return -ETIMEDOUT;
349         }
350
351         return 0;
352 }
353
354 int avs_hda_load_basefw(struct avs_dev *adev, struct firmware *fw)
355 {
356         struct snd_pcm_substream substream;
357         struct snd_dma_buffer dmab;
358         struct hdac_ext_stream *estream;
359         struct hdac_stream *hstream;
360         struct hdac_bus *bus = &adev->base.core;
361         unsigned int sdfmt, reg;
362         int ret, i;
363
364         /* configure hda dma */
365         memset(&substream, 0, sizeof(substream));
366         substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
367         estream = snd_hdac_ext_stream_assign(bus, &substream,
368                                              HDAC_EXT_STREAM_TYPE_HOST);
369         if (!estream)
370                 return -ENODEV;
371         hstream = hdac_stream(estream);
372
373         /* code loading performed with default format */
374         sdfmt = snd_hdac_calc_stream_format(48000, 1, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
375         ret = snd_hdac_dsp_prepare(hstream, sdfmt, fw->size, &dmab);
376         if (ret < 0)
377                 goto release_stream;
378
379         /* enable SPIB for hda stream */
380         snd_hdac_stream_spbcap_enable(bus, true, hstream->index);
381         ret = snd_hdac_stream_set_spib(bus, hstream, fw->size);
382         if (ret)
383                 goto cleanup_resources;
384
385         memcpy(dmab.area, fw->data, fw->size);
386
387         for (i = 0; i < APL_ROM_INIT_RETRIES; i++) {
388                 unsigned int dma_id = hstream->stream_tag - 1;
389
390                 ret = avs_hda_init_rom(adev, dma_id, true);
391                 if (!ret)
392                         break;
393                 dev_info(adev->dev, "#%d rom init fail: %d\n", i + 1, ret);
394         }
395         if (ret < 0)
396                 goto cleanup_resources;
397
398         /* transfer firmware */
399         snd_hdac_dsp_trigger(hstream, true);
400         ret = snd_hdac_adsp_readl_poll(adev, AVS_FW_REG_STATUS(adev), reg,
401                                        (reg & AVS_ROM_STS_MASK) == APL_ROM_FW_ENTERED,
402                                        AVS_FW_INIT_POLLING_US, AVS_FW_INIT_TIMEOUT_US);
403         snd_hdac_dsp_trigger(hstream, false);
404         if (ret < 0) {
405                 dev_err(adev->dev, "transfer fw failed: %d\n", ret);
406                 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
407         }
408
409 cleanup_resources:
410         /* disable SPIB for hda stream */
411         snd_hdac_stream_spbcap_enable(bus, false, hstream->index);
412         snd_hdac_stream_set_spib(bus, hstream, 0);
413
414         snd_hdac_dsp_cleanup(hstream, &dmab);
415 release_stream:
416         snd_hdac_ext_stream_release(estream, HDAC_EXT_STREAM_TYPE_HOST);
417
418         return ret;
419 }
420
421 int avs_hda_load_library(struct avs_dev *adev, struct firmware *lib, u32 id)
422 {
423         struct snd_pcm_substream substream;
424         struct snd_dma_buffer dmab;
425         struct hdac_ext_stream *estream;
426         struct hdac_stream *stream;
427         struct hdac_bus *bus = &adev->base.core;
428         unsigned int sdfmt;
429         int ret;
430
431         /* configure hda dma */
432         memset(&substream, 0, sizeof(substream));
433         substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
434         estream = snd_hdac_ext_stream_assign(bus, &substream,
435                                              HDAC_EXT_STREAM_TYPE_HOST);
436         if (!estream)
437                 return -ENODEV;
438         stream = hdac_stream(estream);
439
440         /* code loading performed with default format */
441         sdfmt = snd_hdac_calc_stream_format(48000, 1, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
442         ret = snd_hdac_dsp_prepare(stream, sdfmt, lib->size, &dmab);
443         if (ret < 0)
444                 goto release_stream;
445
446         /* enable SPIB for hda stream */
447         snd_hdac_stream_spbcap_enable(bus, true, stream->index);
448         snd_hdac_stream_set_spib(bus, stream, lib->size);
449
450         memcpy(dmab.area, lib->data, lib->size);
451
452         /* transfer firmware */
453         snd_hdac_dsp_trigger(stream, true);
454         ret = avs_ipc_load_library(adev, stream->stream_tag - 1, id);
455         snd_hdac_dsp_trigger(stream, false);
456         if (ret) {
457                 dev_err(adev->dev, "transfer lib %d failed: %d\n", id, ret);
458                 ret = AVS_IPC_RET(ret);
459         }
460
461         /* disable SPIB for hda stream */
462         snd_hdac_stream_spbcap_enable(bus, false, stream->index);
463         snd_hdac_stream_set_spib(bus, stream, 0);
464
465         snd_hdac_dsp_cleanup(stream, &dmab);
466 release_stream:
467         snd_hdac_ext_stream_release(estream, HDAC_EXT_STREAM_TYPE_HOST);
468
469         return ret;
470 }
471
472 int avs_hda_transfer_modules(struct avs_dev *adev, bool load,
473                              struct avs_module_entry *mods, u32 num_mods)
474 {
475         /*
476          * All platforms without CLDMA are equipped with IMR,
477          * and thus the module transferring is offloaded to DSP.
478          */
479         return 0;
480 }
481
482 int avs_dsp_load_libraries(struct avs_dev *adev, struct avs_tplg_library *libs, u32 num_libs)
483 {
484         int start, id, i = 0;
485         int ret;
486
487         /* Calculate the id to assign for the next lib. */
488         for (id = 0; id < adev->fw_cfg.max_libs_count; id++)
489                 if (adev->lib_names[id][0] == '\0')
490                         break;
491         if (id + num_libs >= adev->fw_cfg.max_libs_count)
492                 return -EINVAL;
493
494         start = id;
495         while (i < num_libs) {
496                 struct avs_fw_manifest *man;
497                 const struct firmware *fw;
498                 struct firmware stripped_fw;
499                 char *filename;
500                 int j;
501
502                 filename = kasprintf(GFP_KERNEL, "%s/%s/%s", AVS_ROOT_DIR, adev->spec->name,
503                                      libs[i].name);
504                 if (!filename)
505                         return -ENOMEM;
506
507                 /*
508                  * If any call after this one fails, requested firmware is not released with
509                  * avs_release_last_firmware() as failing to load code results in need for reload
510                  * of entire driver module. And then avs_release_firmwares() is in place already.
511                  */
512                 ret = avs_request_firmware(adev, &fw, filename);
513                 kfree(filename);
514                 if (ret < 0)
515                         return ret;
516
517                 stripped_fw = *fw;
518                 ret = avs_fw_manifest_strip_verify(adev, &stripped_fw, NULL);
519                 if (ret) {
520                         dev_err(adev->dev, "invalid library data: %d\n", ret);
521                         return ret;
522                 }
523
524                 ret = avs_fw_manifest_offset(&stripped_fw);
525                 if (ret < 0)
526                         return ret;
527                 man = (struct avs_fw_manifest *)(stripped_fw.data + ret);
528
529                 /* Don't load anything that's already in DSP memory. */
530                 for (j = 0; j < id; j++)
531                         if (!strncmp(adev->lib_names[j], man->name, AVS_LIB_NAME_SIZE))
532                                 goto next_lib;
533
534                 ret = avs_dsp_op(adev, load_lib, &stripped_fw, id);
535                 if (ret)
536                         return ret;
537
538                 strncpy(adev->lib_names[id], man->name, AVS_LIB_NAME_SIZE);
539                 id++;
540 next_lib:
541                 i++;
542         }
543
544         return start == id ? 1 : 0;
545 }
546
547 static int avs_dsp_load_basefw(struct avs_dev *adev)
548 {
549         const struct avs_fw_version *min_req;
550         const struct avs_spec *const spec = adev->spec;
551         const struct firmware *fw;
552         struct firmware stripped_fw;
553         char *filename;
554         int ret;
555
556         filename = kasprintf(GFP_KERNEL, "%s/%s/%s", AVS_ROOT_DIR, spec->name, AVS_BASEFW_FILENAME);
557         if (!filename)
558                 return -ENOMEM;
559
560         ret = avs_request_firmware(adev, &fw, filename);
561         kfree(filename);
562         if (ret < 0) {
563                 dev_err(adev->dev, "request firmware failed: %d\n", ret);
564                 return ret;
565         }
566
567         stripped_fw = *fw;
568         min_req = &adev->spec->min_fw_version;
569
570         ret = avs_fw_manifest_strip_verify(adev, &stripped_fw, min_req);
571         if (ret < 0) {
572                 dev_err(adev->dev, "invalid firmware data: %d\n", ret);
573                 goto release_fw;
574         }
575
576         ret = avs_dsp_op(adev, load_basefw, &stripped_fw);
577         if (ret < 0) {
578                 dev_err(adev->dev, "basefw load failed: %d\n", ret);
579                 goto release_fw;
580         }
581
582         ret = wait_for_completion_timeout(&adev->fw_ready,
583                                           msecs_to_jiffies(AVS_FW_INIT_TIMEOUT_MS));
584         if (!ret) {
585                 dev_err(adev->dev, "firmware ready timeout\n");
586                 avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
587                 ret = -ETIMEDOUT;
588                 goto release_fw;
589         }
590
591         return 0;
592
593 release_fw:
594         avs_release_last_firmware(adev);
595         return ret;
596 }
597
598 int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge)
599 {
600         struct avs_soc_component *acomp;
601         int ret, i;
602
603         /* Forgo full boot if flash from IMR succeeds. */
604         if (!purge && avs_platattr_test(adev, IMR)) {
605                 ret = avs_imr_load_basefw(adev);
606                 if (!ret)
607                         return 0;
608
609                 dev_dbg(adev->dev, "firmware flash from imr failed: %d\n", ret);
610         }
611
612         /* Full boot, clear cached data except for basefw (slot 0). */
613         for (i = 1; i < adev->fw_cfg.max_libs_count; i++)
614                 memset(adev->lib_names[i], 0, AVS_LIB_NAME_SIZE);
615
616         avs_hda_power_gating_enable(adev, false);
617         avs_hda_clock_gating_enable(adev, false);
618         avs_hda_l1sen_enable(adev, false);
619
620         ret = avs_dsp_load_basefw(adev);
621         if (ret)
622                 goto reenable_gating;
623
624         mutex_lock(&adev->comp_list_mutex);
625         list_for_each_entry(acomp, &adev->comp_list, node) {
626                 struct avs_tplg *tplg = acomp->tplg;
627
628                 ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
629                 if (ret < 0)
630                         break;
631         }
632         mutex_unlock(&adev->comp_list_mutex);
633
634 reenable_gating:
635         avs_hda_l1sen_enable(adev, true);
636         avs_hda_clock_gating_enable(adev, true);
637         avs_hda_power_gating_enable(adev, true);
638
639         if (ret < 0)
640                 return ret;
641
642         /* With all code loaded, refresh module information. */
643         ret = avs_module_info_init(adev, true);
644         if (ret) {
645                 dev_err(adev->dev, "init module info failed: %d\n", ret);
646                 return ret;
647         }
648
649         return 0;
650 }
651
652 int avs_dsp_first_boot_firmware(struct avs_dev *adev)
653 {
654         int ret, i;
655
656         if (avs_platattr_test(adev, CLDMA)) {
657                 ret = hda_cldma_init(&code_loader, &adev->base.core,
658                                      adev->dsp_ba, AVS_CL_DEFAULT_BUFFER_SIZE);
659                 if (ret < 0) {
660                         dev_err(adev->dev, "cldma init failed: %d\n", ret);
661                         return ret;
662                 }
663         }
664
665         ret = avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
666         if (ret < 0)
667                 return ret;
668
669         ret = avs_dsp_boot_firmware(adev, true);
670         if (ret < 0) {
671                 dev_err(adev->dev, "firmware boot failed: %d\n", ret);
672                 return ret;
673         }
674
675         ret = avs_ipc_get_hw_config(adev, &adev->hw_cfg);
676         if (ret) {
677                 dev_err(adev->dev, "get hw cfg failed: %d\n", ret);
678                 return AVS_IPC_RET(ret);
679         }
680
681         ret = avs_ipc_get_fw_config(adev, &adev->fw_cfg);
682         if (ret) {
683                 dev_err(adev->dev, "get fw cfg failed: %d\n", ret);
684                 return AVS_IPC_RET(ret);
685         }
686
687         adev->core_refs = devm_kcalloc(adev->dev, adev->hw_cfg.dsp_cores,
688                                        sizeof(*adev->core_refs), GFP_KERNEL);
689         adev->lib_names = devm_kcalloc(adev->dev, adev->fw_cfg.max_libs_count,
690                                        sizeof(*adev->lib_names), GFP_KERNEL);
691         if (!adev->core_refs || !adev->lib_names)
692                 return -ENOMEM;
693
694         for (i = 0; i < adev->fw_cfg.max_libs_count; i++) {
695                 adev->lib_names[i] = devm_kzalloc(adev->dev, AVS_LIB_NAME_SIZE, GFP_KERNEL);
696                 if (!adev->lib_names[i])
697                         return -ENOMEM;
698         }
699
700         /* basefw always occupies slot 0 */
701         strcpy(&adev->lib_names[0][0], "BASEFW");
702
703         ida_init(&adev->ppl_ida);
704
705         return 0;
706 }