1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
6 // Copyright(c) 2018 Intel Corporation. All rights reserved.
8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
11 #include <linux/firmware.h>
12 #include <linux/module.h>
13 #include <asm/unaligned.h>
14 #include <sound/soc.h>
15 #include <sound/sof.h>
19 /* SOF defaults if not provided by the platform in ms */
20 #define TIMEOUT_DEFAULT_IPC_MS 500
21 #define TIMEOUT_DEFAULT_BOOT_MS 2000
24 * Generic object lookup APIs.
27 struct snd_sof_pcm
*snd_sof_find_spcm_name(struct snd_sof_dev
*sdev
,
30 struct snd_sof_pcm
*spcm
;
32 list_for_each_entry(spcm
, &sdev
->pcm_list
, list
) {
33 /* match with PCM dai name */
34 if (strcmp(spcm
->pcm
.dai_name
, name
) == 0)
37 /* match with playback caps name if set */
38 if (*spcm
->pcm
.caps
[0].name
&&
39 !strcmp(spcm
->pcm
.caps
[0].name
, name
))
42 /* match with capture caps name if set */
43 if (*spcm
->pcm
.caps
[1].name
&&
44 !strcmp(spcm
->pcm
.caps
[1].name
, name
))
51 struct snd_sof_pcm
*snd_sof_find_spcm_comp(struct snd_sof_dev
*sdev
,
55 struct snd_sof_pcm
*spcm
;
57 list_for_each_entry(spcm
, &sdev
->pcm_list
, list
) {
58 if (spcm
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].comp_id
== comp_id
) {
59 *direction
= SNDRV_PCM_STREAM_PLAYBACK
;
62 if (spcm
->stream
[SNDRV_PCM_STREAM_CAPTURE
].comp_id
== comp_id
) {
63 *direction
= SNDRV_PCM_STREAM_CAPTURE
;
71 struct snd_sof_pcm
*snd_sof_find_spcm_pcm_id(struct snd_sof_dev
*sdev
,
74 struct snd_sof_pcm
*spcm
;
76 list_for_each_entry(spcm
, &sdev
->pcm_list
, list
) {
77 if (le32_to_cpu(spcm
->pcm
.pcm_id
) == pcm_id
)
84 struct snd_sof_widget
*snd_sof_find_swidget(struct snd_sof_dev
*sdev
,
87 struct snd_sof_widget
*swidget
;
89 list_for_each_entry(swidget
, &sdev
->widget_list
, list
) {
90 if (strcmp(name
, swidget
->widget
->name
) == 0)
97 /* find widget by stream name and direction */
98 struct snd_sof_widget
*snd_sof_find_swidget_sname(struct snd_sof_dev
*sdev
,
99 const char *pcm_name
, int dir
)
101 struct snd_sof_widget
*swidget
;
102 enum snd_soc_dapm_type type
;
104 if (dir
== SNDRV_PCM_STREAM_PLAYBACK
)
105 type
= snd_soc_dapm_aif_in
;
107 type
= snd_soc_dapm_aif_out
;
109 list_for_each_entry(swidget
, &sdev
->widget_list
, list
) {
110 if (!strcmp(pcm_name
, swidget
->widget
->sname
) && swidget
->id
== type
)
117 struct snd_sof_dai
*snd_sof_find_dai(struct snd_sof_dev
*sdev
,
120 struct snd_sof_dai
*dai
;
122 list_for_each_entry(dai
, &sdev
->dai_list
, list
) {
123 if (dai
->name
&& (strcmp(name
, dai
->name
) == 0))
131 * FW Panic/fault handling.
134 struct sof_panic_msg
{
139 /* standard FW panic types */
140 static const struct sof_panic_msg panic_msg
[] = {
141 {SOF_IPC_PANIC_MEM
, "out of memory"},
142 {SOF_IPC_PANIC_WORK
, "work subsystem init failed"},
143 {SOF_IPC_PANIC_IPC
, "IPC subsystem init failed"},
144 {SOF_IPC_PANIC_ARCH
, "arch init failed"},
145 {SOF_IPC_PANIC_PLATFORM
, "platform init failed"},
146 {SOF_IPC_PANIC_TASK
, "scheduler init failed"},
147 {SOF_IPC_PANIC_EXCEPTION
, "runtime exception"},
148 {SOF_IPC_PANIC_DEADLOCK
, "deadlock"},
149 {SOF_IPC_PANIC_STACK
, "stack overflow"},
150 {SOF_IPC_PANIC_IDLE
, "can't enter idle"},
151 {SOF_IPC_PANIC_WFI
, "invalid wait state"},
152 {SOF_IPC_PANIC_ASSERT
, "assertion failed"},
156 * helper to be called from .dbg_dump callbacks. No error code is
157 * provided, it's left as an exercise for the caller of .dbg_dump
158 * (typically IPC or loader)
160 void snd_sof_get_status(struct snd_sof_dev
*sdev
, u32 panic_code
,
161 u32 tracep_code
, void *oops
,
162 struct sof_ipc_panic_info
*panic_info
,
163 void *stack
, size_t stack_words
)
168 /* is firmware dead ? */
169 if ((panic_code
& SOF_IPC_PANIC_MAGIC_MASK
) != SOF_IPC_PANIC_MAGIC
) {
170 dev_err(sdev
->dev
, "error: unexpected fault 0x%8.8x trace 0x%8.8x\n",
171 panic_code
, tracep_code
);
172 return; /* no fault ? */
175 code
= panic_code
& (SOF_IPC_PANIC_MAGIC_MASK
| SOF_IPC_PANIC_CODE_MASK
);
177 for (i
= 0; i
< ARRAY_SIZE(panic_msg
); i
++) {
178 if (panic_msg
[i
].id
== code
) {
179 dev_err(sdev
->dev
, "error: %s\n", panic_msg
[i
].msg
);
180 dev_err(sdev
->dev
, "error: trace point %8.8x\n",
187 dev_err(sdev
->dev
, "error: unknown reason %8.8x\n", panic_code
);
188 dev_err(sdev
->dev
, "error: trace point %8.8x\n", tracep_code
);
191 dev_err(sdev
->dev
, "error: panic at %s:%d\n",
192 panic_info
->filename
, panic_info
->linenum
);
193 sof_oops(sdev
, oops
);
194 sof_stack(sdev
, oops
, stack
, stack_words
);
196 EXPORT_SYMBOL(snd_sof_get_status
);
199 * Generic buffer page table creation.
200 * Take the each physical page address and drop the least significant unused
201 * bits from each (based on PAGE_SIZE). Then pack valid page address bits
202 * into compressed page table.
205 int snd_sof_create_page_table(struct snd_sof_dev
*sdev
,
206 struct snd_dma_buffer
*dmab
,
207 unsigned char *page_table
, size_t size
)
211 pages
= snd_sgbuf_aligned_pages(size
);
213 dev_dbg(sdev
->dev
, "generating page table for %p size 0x%zx pages %d\n",
214 dmab
->area
, size
, pages
);
216 for (i
= 0; i
< pages
; i
++) {
218 * The number of valid address bits for each page is 20.
219 * idx determines the byte position within page_table
220 * where the current page's address is stored
221 * in the compressed page_table.
222 * This can be calculated by multiplying the page number by 2.5.
224 u32 idx
= (5 * i
) >> 1;
225 u32 pfn
= snd_sgbuf_get_addr(dmab
, i
* PAGE_SIZE
) >> PAGE_SHIFT
;
228 dev_vdbg(sdev
->dev
, "pfn i %i idx %d pfn %x\n", i
, idx
, pfn
);
230 pg_table
= (u8
*)(page_table
+ idx
);
233 * pagetable compression:
234 * byte 0 byte 1 byte 2 byte 3 byte 4 byte 5
235 * ___________pfn 0__________ __________pfn 1___________ _pfn 2...
236 * .... .... .... .... .... .... .... .... .... .... ....
238 * 1. set current location to 0, PFN index i to 0
239 * 2. put pfn[i] at current location in Little Endian byte order
240 * 3. calculate an intermediate value as
241 * x = (pfn[i+1] << 4) | (pfn[i] & 0xf)
242 * 4. put x at offset (current location + 2) in LE byte order
243 * 5. increment current location by 5 bytes, increment i by 2
247 put_unaligned_le32((pg_table
[0] & 0xf) | pfn
<< 4,
250 put_unaligned_le32(pfn
, pg_table
);
257 * SOF Driver enumeration.
259 static int sof_machine_check(struct snd_sof_dev
*sdev
)
261 struct snd_sof_pdata
*plat_data
= sdev
->pdata
;
262 #if IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)
263 struct snd_soc_acpi_mach
*machine
;
267 if (plat_data
->machine
)
270 #if !IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)
271 dev_err(sdev
->dev
, "error: no matching ASoC machine driver found - aborting probe\n");
274 /* fallback to nocodec mode */
275 dev_warn(sdev
->dev
, "No ASoC machine driver found - using nocodec\n");
276 machine
= devm_kzalloc(sdev
->dev
, sizeof(*machine
), GFP_KERNEL
);
280 ret
= sof_nocodec_setup(sdev
->dev
, plat_data
, machine
,
281 plat_data
->desc
, plat_data
->desc
->ops
);
285 plat_data
->machine
= machine
;
291 static int sof_probe_continue(struct snd_sof_dev
*sdev
)
293 struct snd_sof_pdata
*plat_data
= sdev
->pdata
;
294 const char *drv_name
;
299 /* probe the DSP hardware */
300 ret
= snd_sof_probe(sdev
);
302 dev_err(sdev
->dev
, "error: failed to probe DSP %d\n", ret
);
306 /* check machine info */
307 ret
= sof_machine_check(sdev
);
309 dev_err(sdev
->dev
, "error: failed to get machine info %d\n",
314 /* set up platform component driver */
315 snd_sof_new_platform_drv(sdev
);
317 /* register any debug/trace capabilities */
318 ret
= snd_sof_dbg_init(sdev
);
321 * debugfs issues are suppressed in snd_sof_dbg_init() since
322 * we cannot rely on debugfs
323 * here we trap errors due to memory allocation only.
325 dev_err(sdev
->dev
, "error: failed to init DSP trace/debug %d\n",
331 sdev
->ipc
= snd_sof_ipc_init(sdev
);
333 dev_err(sdev
->dev
, "error: failed to init DSP IPC %d\n", ret
);
337 /* load the firmware */
338 ret
= snd_sof_load_firmware(sdev
);
340 dev_err(sdev
->dev
, "error: failed to load DSP firmware %d\n",
345 /* boot the firmware */
346 ret
= snd_sof_run_firmware(sdev
);
348 dev_err(sdev
->dev
, "error: failed to boot DSP firmware %d\n",
354 ret
= snd_sof_init_trace(sdev
);
358 "warning: failed to initialize trace %d\n", ret
);
361 /* hereafter all FW boot flows are for PM reasons */
362 sdev
->first_boot
= false;
364 /* now register audio DSP platform driver and dai */
365 ret
= devm_snd_soc_register_component(sdev
->dev
, &sdev
->plat_drv
,
367 sof_ops(sdev
)->num_drv
);
370 "error: failed to register DSP DAI driver %d\n", ret
);
374 drv_name
= plat_data
->machine
->drv_name
;
375 mach
= (const void *)plat_data
->machine
;
376 size
= sizeof(*plat_data
->machine
);
378 /* register machine driver, pass machine info as pdata */
379 plat_data
->pdev_mach
=
380 platform_device_register_data(sdev
->dev
, drv_name
,
381 PLATFORM_DEVID_NONE
, mach
, size
);
383 if (IS_ERR(plat_data
->pdev_mach
)) {
384 ret
= PTR_ERR(plat_data
->pdev_mach
);
388 dev_dbg(sdev
->dev
, "created machine %s\n",
389 dev_name(&plat_data
->pdev_mach
->dev
));
391 if (plat_data
->sof_probe_complete
)
392 plat_data
->sof_probe_complete(sdev
->dev
);
396 #if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
398 snd_sof_fw_unload(sdev
);
400 snd_sof_ipc_free(sdev
);
402 snd_sof_free_debug(sdev
);
404 snd_sof_remove(sdev
);
408 * when the probe_continue is handled in a work queue, the
409 * probe does not fail so we don't release resources here.
410 * They will be released with an explicit call to
411 * snd_sof_device_remove() when the PCI/ACPI device is removed
424 static void sof_probe_work(struct work_struct
*work
)
426 struct snd_sof_dev
*sdev
=
427 container_of(work
, struct snd_sof_dev
, probe_work
);
430 ret
= sof_probe_continue(sdev
);
432 /* errors cannot be propagated, log */
433 dev_err(sdev
->dev
, "error: %s failed err: %d\n", __func__
, ret
);
437 int snd_sof_device_probe(struct device
*dev
, struct snd_sof_pdata
*plat_data
)
439 struct snd_sof_dev
*sdev
;
441 sdev
= devm_kzalloc(dev
, sizeof(*sdev
), GFP_KERNEL
);
445 /* initialize sof device */
448 sdev
->pdata
= plat_data
;
449 sdev
->first_boot
= true;
450 dev_set_drvdata(dev
, sdev
);
452 /* check all mandatory ops */
453 if (!sof_ops(sdev
) || !sof_ops(sdev
)->probe
|| !sof_ops(sdev
)->run
||
454 !sof_ops(sdev
)->block_read
|| !sof_ops(sdev
)->block_write
||
455 !sof_ops(sdev
)->send_msg
|| !sof_ops(sdev
)->load_firmware
||
456 !sof_ops(sdev
)->ipc_msg_data
|| !sof_ops(sdev
)->ipc_pcm_params
)
459 INIT_LIST_HEAD(&sdev
->pcm_list
);
460 INIT_LIST_HEAD(&sdev
->kcontrol_list
);
461 INIT_LIST_HEAD(&sdev
->widget_list
);
462 INIT_LIST_HEAD(&sdev
->dai_list
);
463 INIT_LIST_HEAD(&sdev
->route_list
);
464 spin_lock_init(&sdev
->ipc_lock
);
465 spin_lock_init(&sdev
->hw_lock
);
467 if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE
))
468 INIT_WORK(&sdev
->probe_work
, sof_probe_work
);
470 /* set default timeouts if none provided */
471 if (plat_data
->desc
->ipc_timeout
== 0)
472 sdev
->ipc_timeout
= TIMEOUT_DEFAULT_IPC_MS
;
474 sdev
->ipc_timeout
= plat_data
->desc
->ipc_timeout
;
475 if (plat_data
->desc
->boot_timeout
== 0)
476 sdev
->boot_timeout
= TIMEOUT_DEFAULT_BOOT_MS
;
478 sdev
->boot_timeout
= plat_data
->desc
->boot_timeout
;
480 if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE
)) {
481 schedule_work(&sdev
->probe_work
);
485 return sof_probe_continue(sdev
);
487 EXPORT_SYMBOL(snd_sof_device_probe
);
489 int snd_sof_device_remove(struct device
*dev
)
491 struct snd_sof_dev
*sdev
= dev_get_drvdata(dev
);
492 struct snd_sof_pdata
*pdata
= sdev
->pdata
;
494 if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE
))
495 cancel_work_sync(&sdev
->probe_work
);
497 snd_sof_fw_unload(sdev
);
498 snd_sof_ipc_free(sdev
);
499 snd_sof_free_debug(sdev
);
500 snd_sof_free_trace(sdev
);
503 * Unregister machine driver. This will unbind the snd_card which
504 * will remove the component driver and unload the topology
505 * before freeing the snd_card.
507 if (!IS_ERR_OR_NULL(pdata
->pdev_mach
))
508 platform_device_unregister(pdata
->pdev_mach
);
511 * Unregistering the machine driver results in unloading the topology.
512 * Some widgets, ex: scheduler, attempt to power down the core they are
513 * scheduled on, when they are unloaded. Therefore, the DSP must be
514 * removed only after the topology has been unloaded.
516 snd_sof_remove(sdev
);
518 /* release firmware */
519 release_firmware(pdata
->fw
);
524 EXPORT_SYMBOL(snd_sof_device_remove
);
526 MODULE_AUTHOR("Liam Girdwood");
527 MODULE_DESCRIPTION("Sound Open Firmware (SOF) Core");
528 MODULE_LICENSE("Dual BSD/GPL");
529 MODULE_ALIAS("platform:sof-audio");