Lines Matching +full:primary +full:- +full:device
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
14 #include "sof-priv.h"
15 #include "sof-audio.h"
16 #include "ipc4-fw-reg.h"
17 #include "ipc4-priv.h"
18 #include "ipc4-telemetry.h"
95 dev_err(sdev->dev, "FW reported error: %u - %s\n", in sof_ipc4_check_reply_status()
102 dev_err(sdev->dev, "FW reported error: %u - Unknown\n", status); in sof_ipc4_check_reply_status()
108 ret = -EOPNOTSUPP; in sof_ipc4_check_reply_status()
116 ret = -ENOENT; in sof_ipc4_check_reply_status()
121 ret = -EBUSY; in sof_ipc4_check_reply_status()
124 ret = -EINVAL; in sof_ipc4_check_reply_status()
183 static void sof_ipc4_log_header(struct device *dev, u8 *text, struct sof_ipc4_msg *msg, in sof_ipc4_log_header()
190 val = msg->primary & SOF_IPC4_MSG_TARGET_MASK; in sof_ipc4_log_header()
191 type = SOF_IPC4_MSG_TYPE_GET(msg->primary); in sof_ipc4_log_header()
208 u32 notif = SOF_IPC4_NOTIFICATION_TYPE_GET(msg->primary); in sof_ipc4_log_header()
223 if (data_size_valid && msg->data_size) in sof_ipc4_log_header()
225 text, msg->primary, msg->extension, str, str2, in sof_ipc4_log_header()
226 msg->data_size); in sof_ipc4_log_header()
228 dev_dbg(dev, "%s: %#x|%#x: %s|%s\n", text, msg->primary, in sof_ipc4_log_header()
229 msg->extension, str, str2); in sof_ipc4_log_header()
231 if (data_size_valid && msg->data_size) in sof_ipc4_log_header()
233 text, msg->primary, msg->extension, str, in sof_ipc4_log_header()
234 msg->data_size); in sof_ipc4_log_header()
236 dev_dbg(dev, "%s: %#x|%#x: %s\n", text, msg->primary, in sof_ipc4_log_header()
237 msg->extension, str); in sof_ipc4_log_header()
261 static void sof_ipc4_log_header(struct device *dev, u8 *text, struct sof_ipc4_msg *msg, in sof_ipc4_log_header()
266 !SOF_IPC4_MSG_IS_MODULE_MSG(msg->primary) && in sof_ipc4_log_header()
267 SOF_IPC4_MSG_TYPE_GET(msg->primary) == SOF_IPC4_GLB_NOTIFICATION && in sof_ipc4_log_header()
268 SOF_IPC4_NOTIFICATION_TYPE_GET(msg->primary) == SOF_IPC4_NOTIFY_LOG_BUFFER_STATUS) in sof_ipc4_log_header()
271 if (data_size_valid && msg->data_size) in sof_ipc4_log_header()
273 msg->primary, msg->extension, msg->data_size); in sof_ipc4_log_header()
275 dev_dbg(dev, "%s: %#x|%#x\n", text, msg->primary, msg->extension); in sof_ipc4_log_header()
293 struct snd_sof_ipc_msg *msg = sdev->msg; in sof_ipc4_get_reply()
298 ipc4_reply = msg->reply_data; in sof_ipc4_get_reply()
300 sof_ipc4_log_header(sdev->dev, "ipc tx reply", ipc4_reply, false); in sof_ipc4_get_reply()
302 ret = sof_ipc4_check_reply_status(sdev, ipc4_reply->primary); in sof_ipc4_get_reply()
307 if (!msg->reply_size || !SOF_IPC4_MSG_IS_MODULE_MSG(ipc4_reply->primary) || in sof_ipc4_get_reply()
308 (SOF_IPC4_MSG_TYPE_GET(ipc4_reply->primary) != SOF_IPC4_MOD_LARGE_CONFIG_GET)) in sof_ipc4_get_reply()
312 snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, ipc4_reply->data_ptr, in sof_ipc4_get_reply()
313 msg->reply_size); in sof_ipc4_get_reply()
321 struct snd_sof_ipc_msg *msg = &ipc->msg; in ipc4_wait_tx_done()
322 struct sof_ipc4_msg *ipc4_msg = msg->msg_data; in ipc4_wait_tx_done()
323 struct snd_sof_dev *sdev = ipc->sdev; in ipc4_wait_tx_done()
327 ret = wait_event_timeout(msg->waitq, msg->ipc_complete, in ipc4_wait_tx_done()
328 msecs_to_jiffies(sdev->ipc_timeout)); in ipc4_wait_tx_done()
330 dev_err(sdev->dev, "ipc timed out for %#x|%#x\n", in ipc4_wait_tx_done()
331 ipc4_msg->primary, ipc4_msg->extension); in ipc4_wait_tx_done()
332 snd_sof_handle_fw_exception(ipc->sdev, "IPC timeout"); in ipc4_wait_tx_done()
333 return -ETIMEDOUT; in ipc4_wait_tx_done()
336 if (msg->reply_error) { in ipc4_wait_tx_done()
337 dev_err(sdev->dev, "ipc error for msg %#x|%#x\n", in ipc4_wait_tx_done()
338 ipc4_msg->primary, ipc4_msg->extension); in ipc4_wait_tx_done()
339 ret = msg->reply_error; in ipc4_wait_tx_done()
342 struct sof_ipc4_msg *ipc4_reply = msg->reply_data; in ipc4_wait_tx_done()
346 ipc4_reply_data->header_u64 = ipc4_reply->header_u64; in ipc4_wait_tx_done()
347 if (msg->reply_size && ipc4_reply_data->data_ptr) { in ipc4_wait_tx_done()
349 memcpy(ipc4_reply_data->data_ptr, ipc4_reply->data_ptr, in ipc4_wait_tx_done()
350 msg->reply_size); in ipc4_wait_tx_done()
351 ipc4_reply_data->data_size = msg->reply_size; in ipc4_wait_tx_done()
356 sof_ipc4_log_header(sdev->dev, "ipc tx done ", ipc4_msg, true); in ipc4_wait_tx_done()
359 /* re-enable dumps after successful IPC tx */ in ipc4_wait_tx_done()
360 if (sdev->ipc_dump_printed) { in ipc4_wait_tx_done()
361 sdev->dbg_dump_printed = false; in ipc4_wait_tx_done()
362 sdev->ipc_dump_printed = false; in ipc4_wait_tx_done()
373 struct snd_sof_dev *sdev = ipc->sdev; in ipc4_tx_msg_unlocked()
376 if (msg_bytes > ipc->max_payload_size || reply_bytes > ipc->max_payload_size) in ipc4_tx_msg_unlocked()
377 return -EINVAL; in ipc4_tx_msg_unlocked()
379 sof_ipc4_log_header(sdev->dev, "ipc tx ", msg_data, true); in ipc4_tx_msg_unlocked()
383 dev_err_ratelimited(sdev->dev, in ipc4_tx_msg_unlocked()
385 __func__, ipc4_msg->primary, ipc4_msg->extension, ret); in ipc4_tx_msg_unlocked()
396 struct snd_sof_ipc *ipc = sdev->ipc; in sof_ipc4_tx_msg()
400 return -EINVAL; in sof_ipc4_tx_msg()
414 mutex_lock(&ipc->tx_mutex); in sof_ipc4_tx_msg()
428 sof_ipc4_dump_payload(sdev, msg->data_ptr, msg->data_size); in sof_ipc4_tx_msg()
431 mutex_unlock(&ipc->tx_mutex); in sof_ipc4_tx_msg()
442 size_t payload_limit = sdev->ipc->max_payload_size; in sof_ipc4_set_get_data()
452 return -EINVAL; in sof_ipc4_set_get_data()
454 if ((ipc4_msg->primary & SOF_IPC4_MSG_TARGET_MASK) != in sof_ipc4_set_get_data()
456 return -EINVAL; in sof_ipc4_set_get_data()
458 ipc4_msg->primary &= ~SOF_IPC4_MSG_TYPE_MASK; in sof_ipc4_set_get_data()
459 tx.primary = ipc4_msg->primary; in sof_ipc4_set_get_data()
460 tx.extension = ipc4_msg->extension; in sof_ipc4_set_get_data()
463 tx.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_set_get_data()
465 tx.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_GET); in sof_ipc4_set_get_data()
478 mutex_lock(&sdev->ipc->tx_mutex); in sof_ipc4_set_get_data()
499 tx.data_ptr = ipc4_msg->data_ptr + offset; in sof_ipc4_set_get_data()
504 rx.primary = 0; in sof_ipc4_set_get_data()
507 rx.data_ptr = ipc4_msg->data_ptr + offset; in sof_ipc4_set_get_data()
514 ret = ipc4_tx_msg_unlocked(sdev->ipc, &tx, tx_size, &rx, rx_size); in sof_ipc4_set_get_data()
516 dev_err(sdev->dev, in sof_ipc4_set_get_data()
527 dev_err(sdev->dev, in sof_ipc4_set_get_data()
530 ret = -ENOMEM; in sof_ipc4_set_get_data()
543 remaining -= chunk_size; in sof_ipc4_set_get_data()
548 ipc4_msg->data_size = offset; in sof_ipc4_set_get_data()
552 sof_ipc4_dump_payload(sdev, ipc4_msg->data_ptr, ipc4_msg->data_size); in sof_ipc4_set_get_data()
554 mutex_unlock(&sdev->ipc->tx_mutex); in sof_ipc4_set_get_data()
562 struct snd_sof_ipc_msg *msg = &sdev->ipc->msg; in sof_ipc4_init_msg_memory()
565 sdev->ipc->max_payload_size = SOF_IPC4_MSG_MAX_SIZE; in sof_ipc4_init_msg_memory()
568 msg->reply_data = devm_kzalloc(sdev->dev, sdev->ipc->max_payload_size + in sof_ipc4_init_msg_memory()
570 if (!msg->reply_data) in sof_ipc4_init_msg_memory()
571 return -ENOMEM; in sof_ipc4_init_msg_memory()
573 ipc4_msg = msg->reply_data; in sof_ipc4_init_msg_memory()
574 ipc4_msg->data_ptr = msg->reply_data + sizeof(struct sof_ipc4_msg); in sof_ipc4_init_msg_memory()
587 slot_desc_type_offset = sdev->debug_box.offset + sizeof(u32); in sof_ipc4_find_debug_slot_offset_by_type()
592 return sdev->debug_box.offset + (i + 1) * SOF_IPC4_DEBUG_SLOT_SIZE; in sof_ipc4_find_debug_slot_offset_by_type()
597 dev_dbg(sdev->dev, "Slot type %#x is not available in debug window\n", slot_type); in sof_ipc4_find_debug_slot_offset_by_type()
604 if (!sdev->first_boot) { in ipc4_fw_ready()
605 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in ipc4_fw_ready()
611 if (!ipc4_data->fw_context_save) in ipc4_fw_ready()
612 ipc4_data->libraries_restored = !!(ipc4_msg->primary & in ipc4_fw_ready()
626 struct sof_ipc4_notify_module_data *data = ipc4_msg->data_ptr; in sof_ipc4_module_notification_handler()
630 * we need to re-allocate the buffer and re-read the whole payload, in sof_ipc4_module_notification_handler()
633 if (data->event_data_size) { in sof_ipc4_module_notification_handler()
637 ipc4_msg->data_size += data->event_data_size; in sof_ipc4_module_notification_handler()
639 new = krealloc(ipc4_msg->data_ptr, ipc4_msg->data_size, GFP_KERNEL); in sof_ipc4_module_notification_handler()
641 ipc4_msg->data_size -= data->event_data_size; in sof_ipc4_module_notification_handler()
645 /* re-read the whole payload */ in sof_ipc4_module_notification_handler()
646 ipc4_msg->data_ptr = new; in sof_ipc4_module_notification_handler()
647 ret = snd_sof_ipc_msg_data(sdev, NULL, ipc4_msg->data_ptr, in sof_ipc4_module_notification_handler()
648 ipc4_msg->data_size); in sof_ipc4_module_notification_handler()
650 dev_err(sdev->dev, in sof_ipc4_module_notification_handler()
655 data = ipc4_msg->data_ptr; in sof_ipc4_module_notification_handler()
659 if ((data->event_id & SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_MASK) == in sof_ipc4_module_notification_handler()
661 const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; in sof_ipc4_module_notification_handler()
663 if (tplg_ops->control->update) in sof_ipc4_module_notification_handler()
664 tplg_ops->control->update(sdev, ipc4_msg); in sof_ipc4_module_notification_handler()
670 struct sof_ipc4_msg *ipc4_msg = sdev->ipc->msg.rx_data; in sof_ipc4_rx_msg()
675 if (!ipc4_msg || !SOF_IPC4_MSG_IS_NOTIFICATION(ipc4_msg->primary)) in sof_ipc4_rx_msg()
678 ipc4_msg->data_ptr = NULL; in sof_ipc4_rx_msg()
679 ipc4_msg->data_size = 0; in sof_ipc4_rx_msg()
681 sof_ipc4_log_header(sdev->dev, "ipc rx ", ipc4_msg, false); in sof_ipc4_rx_msg()
683 switch (SOF_IPC4_NOTIFICATION_TYPE_GET(ipc4_msg->primary)) { in sof_ipc4_rx_msg()
686 if (sdev->fw_state == SOF_FW_BOOT_IN_PROGRESS) { in sof_ipc4_rx_msg()
694 wake_up(&sdev->boot_wait); in sof_ipc4_rx_msg()
702 sof_ipc4_mtrace_update_pos(sdev, SOF_IPC4_LOG_CORE_GET(ipc4_msg->primary)); in sof_ipc4_rx_msg()
712 dev_dbg(sdev->dev, "Unhandled DSP message: %#x|%#x\n", in sof_ipc4_rx_msg()
713 ipc4_msg->primary, ipc4_msg->extension); in sof_ipc4_rx_msg()
718 ipc4_msg->data_ptr = kmalloc(data_size, GFP_KERNEL); in sof_ipc4_rx_msg()
719 if (!ipc4_msg->data_ptr) in sof_ipc4_rx_msg()
722 ipc4_msg->data_size = data_size; in sof_ipc4_rx_msg()
723 err = snd_sof_ipc_msg_data(sdev, NULL, ipc4_msg->data_ptr, ipc4_msg->data_size); in sof_ipc4_rx_msg()
725 dev_err(sdev->dev, "failed to read IPC notification data: %d\n", err); in sof_ipc4_rx_msg()
726 kfree(ipc4_msg->data_ptr); in sof_ipc4_rx_msg()
727 ipc4_msg->data_ptr = NULL; in sof_ipc4_rx_msg()
728 ipc4_msg->data_size = 0; in sof_ipc4_rx_msg()
737 sof_ipc4_log_header(sdev->dev, "ipc rx done ", ipc4_msg, true); in sof_ipc4_rx_msg()
741 sof_ipc4_dump_payload(sdev, ipc4_msg->data_ptr, in sof_ipc4_rx_msg()
742 ipc4_msg->data_size); in sof_ipc4_rx_msg()
744 kfree(ipc4_msg->data_ptr); in sof_ipc4_rx_msg()
745 ipc4_msg->data_ptr = NULL; in sof_ipc4_rx_msg()
746 ipc4_msg->data_size = 0; in sof_ipc4_rx_msg()
761 msg.primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_SET_DX); in sof_ipc4_set_core_state()
762 msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_set_core_state()
763 msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_set_core_state()
773 * it that the primary core is going to be turned off, which is used as an
789 msg.primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_SET_D0IX); in sof_ipc4_set_pm_gate()
790 msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_set_pm_gate()
791 msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_set_pm_gate()
805 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_init()
808 mutex_init(&ipc4_data->pipeline_state_mutex); in sof_ipc4_init()
810 xa_init_flags(&ipc4_data->fw_lib_xa, XA_FLAGS_ALLOC); in sof_ipc4_init()
815 dev_err(sdev->dev, "%s: No mailbox offset\n", __func__); in sof_ipc4_init()
819 sdev->dsp_box.offset = inbox_offset; in sof_ipc4_init()
820 sdev->dsp_box.size = SOF_IPC4_MSG_MAX_SIZE; in sof_ipc4_init()
821 sdev->host_box.offset = snd_sof_dsp_get_window_offset(sdev, in sof_ipc4_init()
823 sdev->host_box.size = SOF_IPC4_MSG_MAX_SIZE; in sof_ipc4_init()
825 sdev->debug_box.offset = snd_sof_dsp_get_window_offset(sdev, in sof_ipc4_init()
828 sdev->fw_info_box.offset = snd_sof_dsp_get_window_offset(sdev, in sof_ipc4_init()
830 sdev->fw_info_box.size = sizeof(struct sof_ipc4_fw_registers); in sof_ipc4_init()
832 dev_dbg(sdev->dev, "mailbox upstream %#x - size %#x\n", in sof_ipc4_init()
833 sdev->dsp_box.offset, SOF_IPC4_MSG_MAX_SIZE); in sof_ipc4_init()
834 dev_dbg(sdev->dev, "mailbox downstream %#x - size %#x\n", in sof_ipc4_init()
835 sdev->host_box.offset, SOF_IPC4_MSG_MAX_SIZE); in sof_ipc4_init()
836 dev_dbg(sdev->dev, "debug box %#x\n", sdev->debug_box.offset); in sof_ipc4_init()
843 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_exit()
847 xa_for_each(&ipc4_data->fw_lib_xa, lib_id, fw_lib) { in sof_ipc4_exit()
853 release_firmware(fw_lib->sof_fw.fw); in sof_ipc4_exit()
855 fw_lib->sof_fw.fw = NULL; in sof_ipc4_exit()
858 xa_destroy(&ipc4_data->fw_lib_xa); in sof_ipc4_exit()
863 if (sdev->first_boot) { in sof_ipc4_post_boot()
895 msg.primary = SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_mic_privacy_state_change()
896 msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_mic_privacy_state_change()
897 msg.primary |= SOF_IPC4_MOD_ID(SOF_IPC4_MOD_INIT_BASEFW_MOD_ID); in sof_ipc4_mic_privacy_state_change()
898 msg.primary |= SOF_IPC4_MOD_INSTANCE(SOF_IPC4_MOD_INIT_BASEFW_INSTANCE_ID); in sof_ipc4_mic_privacy_state_change()