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