Lines Matching +full:machine +full:- +full:level
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
15 #include "sof-priv.h"
16 #include "sof-of-dev.h"
43 static int override_ipc_type = -1;
45 MODULE_PARM_DESC(ipc_type, "Force SOF IPC type. 0 - IPC3, 1 - IPC4");
68 * sof_debug_check_flag - check if a given flag(s) is set in sof_core_debug
109 * sof_print_oops_and_stack - Handle the printing of DSP oops and stack trace
111 * @level: prink log level to use for the printing
123 void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level, in sof_print_oops_and_stack() argument
133 dev_printk(level, sdev->dev, "unexpected fault %#010x trace %#010x\n", in sof_print_oops_and_stack()
142 dev_printk(level, sdev->dev, "reason: %s (%#x)\n", in sof_print_oops_and_stack()
144 dev_printk(level, sdev->dev, "trace point: %#010x\n", tracep_code); in sof_print_oops_and_stack()
150 dev_printk(level, sdev->dev, "unknown panic code: %#x\n", in sof_print_oops_and_stack()
152 dev_printk(level, sdev->dev, "trace point: %#010x\n", tracep_code); in sof_print_oops_and_stack()
155 dev_printk(level, sdev->dev, "panic at %s:%d\n", panic_info->filename, in sof_print_oops_and_stack()
156 panic_info->linenum); in sof_print_oops_and_stack()
157 sof_oops(sdev, level, oops); in sof_print_oops_and_stack()
158 sof_stack(sdev, level, oops, stack, stack_words); in sof_print_oops_and_stack()
165 if (sdev->fw_state == new_state) in sof_set_fw_state()
168 dev_dbg(sdev->dev, "fw_state change: %d -> %d\n", sdev->fw_state, new_state); in sof_set_fw_state()
169 sdev->fw_state = new_state; in sof_set_fw_state()
185 struct snd_sof_pdata *sof_pdata = sdev->pdata; in sof_of_machine_select()
186 const struct sof_dev_desc *desc = sof_pdata->desc; in sof_of_machine_select()
187 struct snd_sof_of_mach *mach = desc->of_machines; in sof_of_machine_select()
192 for (; mach->compatible; mach++) { in sof_of_machine_select()
193 if (of_machine_is_compatible(mach->compatible)) { in sof_of_machine_select()
194 sof_pdata->tplg_filename = mach->sof_tplg_filename; in sof_of_machine_select()
195 if (mach->fw_filename) in sof_of_machine_select()
196 sof_pdata->fw_filename = mach->fw_filename; in sof_of_machine_select()
208 struct snd_sof_pdata *sof_pdata = sdev->pdata; in sof_machine_check()
209 const struct sof_dev_desc *desc = sof_pdata->desc; in sof_machine_check()
219 /* find machine */ in sof_machine_check()
222 sof_pdata->machine = mach; in sof_machine_check()
224 if (sof_pdata->subsystem_id_set) { in sof_machine_check()
225 mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor; in sof_machine_check()
226 mach->mach_params.subsystem_device = sof_pdata->subsystem_device; in sof_machine_check()
227 mach->mach_params.subsystem_id_set = true; in sof_machine_check()
236 sof_pdata->of_machine = of_mach; in sof_machine_check()
241 dev_err(sdev->dev, "error: no matching ASoC machine driver found - aborting probe\n"); in sof_machine_check()
242 return -ENODEV; in sof_machine_check()
245 dev_warn(sdev->dev, "Force to use nocodec mode\n"); in sof_machine_check()
250 dev_warn(sdev->dev, "Using nocodec machine driver\n"); in sof_machine_check()
251 mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL); in sof_machine_check()
253 return -ENOMEM; in sof_machine_check()
255 mach->drv_name = "sof-nocodec"; in sof_machine_check()
256 if (!sof_pdata->tplg_filename) in sof_machine_check()
257 sof_pdata->tplg_filename = desc->nocodec_tplg_filename; in sof_machine_check()
259 sof_pdata->machine = mach; in sof_machine_check()
267 struct snd_sof_pdata *plat_data = sdev->pdata; in sof_select_ipc_and_paths()
268 struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; in sof_select_ipc_and_paths()
270 struct device *dev = sdev->dev; in sof_select_ipc_and_paths()
273 if (base_profile->ipc_type != plat_data->desc->ipc_default) in sof_select_ipc_and_paths()
276 plat_data->desc->ipc_default, base_profile->ipc_type); in sof_select_ipc_and_paths()
278 if (base_profile->fw_path) in sof_select_ipc_and_paths()
280 base_profile->fw_path); in sof_select_ipc_and_paths()
281 else if (base_profile->fw_path_postfix) in sof_select_ipc_and_paths()
283 base_profile->fw_path_postfix); in sof_select_ipc_and_paths()
285 if (base_profile->fw_lib_path) in sof_select_ipc_and_paths()
287 base_profile->fw_lib_path); in sof_select_ipc_and_paths()
288 else if (base_profile->fw_lib_path_postfix) in sof_select_ipc_and_paths()
290 base_profile->fw_lib_path_postfix); in sof_select_ipc_and_paths()
292 if (base_profile->fw_name) in sof_select_ipc_and_paths()
294 base_profile->fw_name); in sof_select_ipc_and_paths()
296 if (base_profile->tplg_path) in sof_select_ipc_and_paths()
298 base_profile->tplg_path); in sof_select_ipc_and_paths()
300 if (base_profile->tplg_name) in sof_select_ipc_and_paths()
302 base_profile->tplg_name); in sof_select_ipc_and_paths()
308 plat_data->ipc_type = out_profile.ipc_type; in sof_select_ipc_and_paths()
309 plat_data->fw_filename = out_profile.fw_name; in sof_select_ipc_and_paths()
310 plat_data->fw_filename_prefix = out_profile.fw_path; in sof_select_ipc_and_paths()
311 plat_data->fw_lib_prefix = out_profile.fw_lib_path; in sof_select_ipc_and_paths()
312 plat_data->tplg_filename_prefix = out_profile.tplg_path; in sof_select_ipc_and_paths()
327 if (!sof_ops(sdev) || !sof_ops(sdev)->probe) { in validate_sof_ops()
328 dev_err(sdev->dev, "missing mandatory ops\n"); in validate_sof_ops()
330 return -EINVAL; in validate_sof_ops()
333 if (!sdev->dspless_mode_selected && in validate_sof_ops()
334 (!sof_ops(sdev)->run || !sof_ops(sdev)->block_read || in validate_sof_ops()
335 !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg || in validate_sof_ops()
336 !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data)) { in validate_sof_ops()
337 dev_err(sdev->dev, "missing mandatory DSP ops\n"); in validate_sof_ops()
339 return -EINVAL; in validate_sof_ops()
347 struct snd_sof_pdata *plat_data = sdev->pdata; in sof_init_sof_ops()
348 struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; in sof_init_sof_ops()
351 if (!(BIT(base_profile->ipc_type) & plat_data->desc->ipc_supported_mask)) { in sof_init_sof_ops()
352 dev_err(sdev->dev, in sof_init_sof_ops()
354 base_profile->ipc_type, plat_data->desc->ipc_supported_mask); in sof_init_sof_ops()
355 return -EINVAL; in sof_init_sof_ops()
362 plat_data->ipc_type = base_profile->ipc_type; in sof_init_sof_ops()
363 plat_data->tplg_filename = base_profile->tplg_name; in sof_init_sof_ops()
370 struct snd_sof_pdata *plat_data = sdev->pdata; in sof_init_environment()
371 struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; in sof_init_environment()
377 dev_err(sdev->dev, "failed to probe DSP %d\n", ret); in sof_init_environment()
381 /* check machine info */ in sof_init_environment()
384 dev_err(sdev->dev, "failed to get machine info %d\n", ret); in sof_init_environment()
391 } else if (plat_data->ipc_type != base_profile->ipc_type) { in sof_init_environment()
392 /* IPC type changed, re-initialize the ops */ in sof_init_environment()
417 * +----------------------------------------------------------------------+
419 * ------------------ ------------------ |
421 * | BOOT_FAILED |<-------| READY_FAILED | |
422 * | |<--+ | | ------------------ |
423 * ------------------ | ------------------ | | |
424 * ^ | ^ | CRASHED |---+ |
426 * (FW Boot Timeout) | (FW_READY FAIL) ------------------ | |
429 * ------------------ | | ------------------ | |
431 * | IN_PROGRESS |---------------+------------->| COMPLETE | | |
433 * ------------------ | ------------------ | |
439 * ------------------ | ------------------ | | |
440 * | | | | |<-----+ | |
441 * | PREPARE |---+ | NOT_STARTED |<---------------------+ |
442 * | | | |<--------------------------+
443 * ------------------ ------------------
446 * | +-----------------------+ |
450 * +------------------------------------+
456 struct snd_sof_pdata *plat_data = sdev->pdata; in sof_probe_continue()
469 if (sdev->dspless_mode_selected) { in sof_probe_continue()
482 dev_err(sdev->dev, "error: failed to init DSP trace/debug %d\n", in sof_probe_continue()
488 sdev->ipc = snd_sof_ipc_init(sdev); in sof_probe_continue()
489 if (!sdev->ipc) { in sof_probe_continue()
490 ret = -ENOMEM; in sof_probe_continue()
491 dev_err(sdev->dev, "error: failed to init DSP IPC %d\n", ret); in sof_probe_continue()
498 dev_err(sdev->dev, "error: failed to load DSP firmware %d\n", in sof_probe_continue()
512 dev_err(sdev->dev, "error: failed to boot DSP firmware %d\n", in sof_probe_continue()
519 sdev->fw_trace_is_supported = true; in sof_probe_continue()
525 dev_warn(sdev->dev, "failed to initialize firmware tracing %d\n", in sof_probe_continue()
529 dev_dbg(sdev->dev, "SOF firmware trace disabled\n"); in sof_probe_continue()
534 sdev->first_boot = false; in sof_probe_continue()
537 ret = devm_snd_soc_register_component(sdev->dev, &sdev->plat_drv, in sof_probe_continue()
538 sof_ops(sdev)->drv, in sof_probe_continue()
539 sof_ops(sdev)->num_drv); in sof_probe_continue()
541 dev_err(sdev->dev, in sof_probe_continue()
548 dev_err(sdev->dev, in sof_probe_continue()
549 "error: failed to register machine driver %d\n", ret); in sof_probe_continue()
555 dev_err(sdev->dev, "failed to register clients %d\n", ret); in sof_probe_continue()
564 if (!sof_ops(sdev)->runtime_suspend || !sof_ops(sdev)->runtime_resume) in sof_probe_continue()
565 pm_runtime_get_noresume(sdev->dev); in sof_probe_continue()
567 if (plat_data->sof_probe_complete) in sof_probe_continue()
568 plat_data->sof_probe_complete(sdev->dev); in sof_probe_continue()
570 sdev->probe_completed = true; in sof_probe_continue()
591 sdev->first_boot = true; in sof_probe_continue()
605 dev_err(sdev->dev, "error: %s failed err: %d\n", __func__, ret); in sof_probe_work()
613 path_override->ipc_type = override_ipc_type; in sof_apply_profile_override()
615 path_override->fw_path = override_fw_path; in sof_apply_profile_override()
617 path_override->fw_name = override_fw_filename; in sof_apply_profile_override()
619 path_override->fw_lib_path = override_lib_path; in sof_apply_profile_override()
621 path_override->tplg_path = override_tplg_path; in sof_apply_profile_override()
623 path_override->tplg_name = override_tplg_filename; in sof_apply_profile_override()
633 return -ENOMEM; in snd_sof_device_probe()
636 sdev->dev = dev; in snd_sof_device_probe()
639 sdev->dsp_power_state.state = SOF_DSP_PM_D0; in snd_sof_device_probe()
641 sdev->pdata = plat_data; in snd_sof_device_probe()
642 sdev->first_boot = true; in snd_sof_device_probe()
649 if (plat_data->desc->dspless_mode_supported) { in snd_sof_device_probe()
651 sdev->dspless_mode_selected = true; in snd_sof_device_probe()
657 sof_apply_profile_override(&plat_data->ipc_file_profile_base); in snd_sof_device_probe()
664 INIT_LIST_HEAD(&sdev->pcm_list); in snd_sof_device_probe()
665 INIT_LIST_HEAD(&sdev->kcontrol_list); in snd_sof_device_probe()
666 INIT_LIST_HEAD(&sdev->widget_list); in snd_sof_device_probe()
667 INIT_LIST_HEAD(&sdev->pipeline_list); in snd_sof_device_probe()
668 INIT_LIST_HEAD(&sdev->dai_list); in snd_sof_device_probe()
669 INIT_LIST_HEAD(&sdev->dai_link_list); in snd_sof_device_probe()
670 INIT_LIST_HEAD(&sdev->route_list); in snd_sof_device_probe()
671 INIT_LIST_HEAD(&sdev->ipc_client_list); in snd_sof_device_probe()
672 INIT_LIST_HEAD(&sdev->ipc_rx_handler_list); in snd_sof_device_probe()
673 INIT_LIST_HEAD(&sdev->fw_state_handler_list); in snd_sof_device_probe()
674 spin_lock_init(&sdev->ipc_lock); in snd_sof_device_probe()
675 spin_lock_init(&sdev->hw_lock); in snd_sof_device_probe()
676 mutex_init(&sdev->power_state_access); in snd_sof_device_probe()
677 mutex_init(&sdev->ipc_client_mutex); in snd_sof_device_probe()
678 mutex_init(&sdev->client_event_handler_mutex); in snd_sof_device_probe()
681 if (plat_data->desc->ipc_timeout == 0) in snd_sof_device_probe()
682 sdev->ipc_timeout = TIMEOUT_DEFAULT_IPC_MS; in snd_sof_device_probe()
684 sdev->ipc_timeout = plat_data->desc->ipc_timeout; in snd_sof_device_probe()
685 if (plat_data->desc->boot_timeout == 0) in snd_sof_device_probe()
686 sdev->boot_timeout = TIMEOUT_DEFAULT_BOOT_MS; in snd_sof_device_probe()
688 sdev->boot_timeout = plat_data->desc->boot_timeout; in snd_sof_device_probe()
693 sdev->ipc_timeout = sof_ipc_timeout_ms; in snd_sof_device_probe()
696 sdev->boot_timeout = sof_boot_timeout_ms; in snd_sof_device_probe()
702 * first pass of probe which isn't allowed to run in a work-queue, in snd_sof_device_probe()
703 * typically to rely on -EPROBE_DEFER dependencies in snd_sof_device_probe()
710 INIT_WORK(&sdev->probe_work, sof_probe_work); in snd_sof_device_probe()
711 schedule_work(&sdev->probe_work); in snd_sof_device_probe()
723 return sdev->probe_completed; in snd_sof_device_probe_completed()
730 struct snd_sof_pdata *pdata = sdev->pdata; in snd_sof_device_remove()
735 aborted = cancel_work_sync(&sdev->probe_work); in snd_sof_device_remove()
744 * Unregister machine driver. This will unbind the snd_card which in snd_sof_device_remove()
755 if (sdev->d3_prevented) { in snd_sof_device_remove()
756 sdev->d3_prevented = false; in snd_sof_device_remove()
757 pm_runtime_put_noidle(sdev->dev); in snd_sof_device_remove()
760 if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) { in snd_sof_device_remove()
790 cancel_work_sync(&sdev->probe_work); in snd_sof_device_shutdown()
792 if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) { in snd_sof_device_shutdown()
801 /* Machine driver registering and unregistering */
809 drv_name = plat_data->machine->drv_name; in sof_machine_register()
810 mach = plat_data->machine; in sof_machine_register()
811 size = sizeof(*plat_data->machine); in sof_machine_register()
813 /* register machine driver, pass machine info as pdata */ in sof_machine_register()
814 plat_data->pdev_mach = in sof_machine_register()
815 platform_device_register_data(sdev->dev, drv_name, in sof_machine_register()
817 if (IS_ERR(plat_data->pdev_mach)) in sof_machine_register()
818 return PTR_ERR(plat_data->pdev_mach); in sof_machine_register()
820 dev_dbg(sdev->dev, "created machine %s\n", in sof_machine_register()
821 dev_name(&plat_data->pdev_mach->dev)); in sof_machine_register()
831 platform_device_unregister(plat_data->pdev_mach); in sof_machine_unregister()
838 MODULE_ALIAS("platform:sof-audio");