Lines Matching +full:ipc +full:- +full:3
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
13 #include "sof-priv.h"
14 #include "sof-audio.h"
15 #include "ipc4-priv.h"
34 {3, "Not enough space in the IPC reply buffer to complete the request"},
36 {5, "Replaced ADSP IPC PENDING (unused)"},
98 dev_err(sdev->dev, "FW reported error: %u - %s\n", in sof_ipc4_check_reply_status()
105 dev_err(sdev->dev, "FW reported error: %u - Unknown\n", status); in sof_ipc4_check_reply_status()
115 ret = -ENOENT; in sof_ipc4_check_reply_status()
120 ret = -EBUSY; in sof_ipc4_check_reply_status()
123 ret = -EINVAL; in sof_ipc4_check_reply_status()
188 val = msg->primary & SOF_IPC4_MSG_TARGET_MASK; in sof_ipc4_log_header()
189 type = SOF_IPC4_MSG_TYPE_GET(msg->primary); in sof_ipc4_log_header()
206 u32 notif = SOF_IPC4_NOTIFICATION_TYPE_GET(msg->primary); in sof_ipc4_log_header()
221 if (data_size_valid && msg->data_size) in sof_ipc4_log_header()
223 text, msg->primary, msg->extension, str, str2, in sof_ipc4_log_header()
224 msg->data_size); in sof_ipc4_log_header()
226 dev_dbg(dev, "%s: %#x|%#x: %s|%s\n", text, msg->primary, in sof_ipc4_log_header()
227 msg->extension, str, str2); in sof_ipc4_log_header()
229 if (data_size_valid && msg->data_size) in sof_ipc4_log_header()
231 text, msg->primary, msg->extension, str, in sof_ipc4_log_header()
232 msg->data_size); in sof_ipc4_log_header()
234 dev_dbg(dev, "%s: %#x|%#x: %s\n", text, msg->primary, in sof_ipc4_log_header()
235 msg->extension, str); in sof_ipc4_log_header()
244 !SOF_IPC4_MSG_IS_MODULE_MSG(msg->primary) && in sof_ipc4_log_header()
245 SOF_IPC4_MSG_TYPE_GET(msg->primary) == SOF_IPC4_GLB_NOTIFICATION && in sof_ipc4_log_header()
246 SOF_IPC4_NOTIFICATION_TYPE_GET(msg->primary) == SOF_IPC4_NOTIFY_LOG_BUFFER_STATUS) in sof_ipc4_log_header()
249 if (data_size_valid && msg->data_size) in sof_ipc4_log_header()
251 msg->primary, msg->extension, msg->data_size); in sof_ipc4_log_header()
253 dev_dbg(dev, "%s: %#x|%#x\n", text, msg->primary, msg->extension); in sof_ipc4_log_header()
259 struct snd_sof_ipc_msg *msg = sdev->msg; in sof_ipc4_get_reply()
264 ipc4_reply = msg->reply_data; in sof_ipc4_get_reply()
266 sof_ipc4_log_header(sdev->dev, "ipc tx reply", ipc4_reply, false); in sof_ipc4_get_reply()
268 ret = sof_ipc4_check_reply_status(sdev, ipc4_reply->primary); in sof_ipc4_get_reply()
273 if (!msg->reply_size || !SOF_IPC4_MSG_IS_MODULE_MSG(ipc4_reply->primary) || in sof_ipc4_get_reply()
274 (SOF_IPC4_MSG_TYPE_GET(ipc4_reply->primary) != SOF_IPC4_MOD_LARGE_CONFIG_GET)) in sof_ipc4_get_reply()
278 snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, ipc4_reply->data_ptr, in sof_ipc4_get_reply()
279 msg->reply_size); in sof_ipc4_get_reply()
284 /* wait for IPC message reply */
285 static int ipc4_wait_tx_done(struct snd_sof_ipc *ipc, void *reply_data) in ipc4_wait_tx_done() argument
287 struct snd_sof_ipc_msg *msg = &ipc->msg; in ipc4_wait_tx_done()
288 struct sof_ipc4_msg *ipc4_msg = msg->msg_data; in ipc4_wait_tx_done()
289 struct snd_sof_dev *sdev = ipc->sdev; in ipc4_wait_tx_done()
292 /* wait for DSP IPC completion */ in ipc4_wait_tx_done()
293 ret = wait_event_timeout(msg->waitq, msg->ipc_complete, in ipc4_wait_tx_done()
294 msecs_to_jiffies(sdev->ipc_timeout)); in ipc4_wait_tx_done()
296 dev_err(sdev->dev, "ipc timed out for %#x|%#x\n", in ipc4_wait_tx_done()
297 ipc4_msg->primary, ipc4_msg->extension); in ipc4_wait_tx_done()
298 snd_sof_handle_fw_exception(ipc->sdev, "IPC timeout"); in ipc4_wait_tx_done()
299 return -ETIMEDOUT; in ipc4_wait_tx_done()
302 if (msg->reply_error) { in ipc4_wait_tx_done()
303 dev_err(sdev->dev, "ipc error for msg %#x|%#x\n", in ipc4_wait_tx_done()
304 ipc4_msg->primary, ipc4_msg->extension); in ipc4_wait_tx_done()
305 ret = msg->reply_error; in ipc4_wait_tx_done()
308 struct sof_ipc4_msg *ipc4_reply = msg->reply_data; in ipc4_wait_tx_done()
312 ipc4_reply_data->header_u64 = ipc4_reply->header_u64; in ipc4_wait_tx_done()
313 if (msg->reply_size && ipc4_reply_data->data_ptr) { in ipc4_wait_tx_done()
315 memcpy(ipc4_reply_data->data_ptr, ipc4_reply->data_ptr, in ipc4_wait_tx_done()
316 msg->reply_size); in ipc4_wait_tx_done()
317 ipc4_reply_data->data_size = msg->reply_size; in ipc4_wait_tx_done()
322 sof_ipc4_log_header(sdev->dev, "ipc tx done ", ipc4_msg, true); in ipc4_wait_tx_done()
325 /* re-enable dumps after successful IPC tx */ in ipc4_wait_tx_done()
326 if (sdev->ipc_dump_printed) { in ipc4_wait_tx_done()
327 sdev->dbg_dump_printed = false; in ipc4_wait_tx_done()
328 sdev->ipc_dump_printed = false; in ipc4_wait_tx_done()
334 static int ipc4_tx_msg_unlocked(struct snd_sof_ipc *ipc, in ipc4_tx_msg_unlocked() argument
339 struct snd_sof_dev *sdev = ipc->sdev; in ipc4_tx_msg_unlocked()
342 if (msg_bytes > ipc->max_payload_size || reply_bytes > ipc->max_payload_size) in ipc4_tx_msg_unlocked()
343 return -EINVAL; in ipc4_tx_msg_unlocked()
347 dev_err_ratelimited(sdev->dev, in ipc4_tx_msg_unlocked()
348 "%s: ipc message send for %#x|%#x failed: %d\n", in ipc4_tx_msg_unlocked()
349 __func__, ipc4_msg->primary, ipc4_msg->extension, ret); in ipc4_tx_msg_unlocked()
353 sof_ipc4_log_header(sdev->dev, "ipc tx ", msg_data, true); in ipc4_tx_msg_unlocked()
356 return ipc4_wait_tx_done(ipc, reply_data); in ipc4_tx_msg_unlocked()
362 struct snd_sof_ipc *ipc = sdev->ipc; in sof_ipc4_tx_msg() local
369 return -EINVAL; in sof_ipc4_tx_msg()
371 /* Serialise IPC TX */ in sof_ipc4_tx_msg()
372 mutex_lock(&ipc->tx_mutex); in sof_ipc4_tx_msg()
374 ret = ipc4_tx_msg_unlocked(ipc, msg_data, msg_bytes, reply_data, reply_bytes); in sof_ipc4_tx_msg()
376 mutex_unlock(&ipc->tx_mutex); in sof_ipc4_tx_msg()
386 sof_ipc4_dump_payload(sdev, msg->data_ptr, msg->data_size); in sof_ipc4_tx_msg()
395 size_t payload_limit = sdev->ipc->max_payload_size; in sof_ipc4_set_get_data()
405 return -EINVAL; in sof_ipc4_set_get_data()
407 if ((ipc4_msg->primary & SOF_IPC4_MSG_TARGET_MASK) != in sof_ipc4_set_get_data()
409 return -EINVAL; in sof_ipc4_set_get_data()
411 ipc4_msg->primary &= ~SOF_IPC4_MSG_TYPE_MASK; in sof_ipc4_set_get_data()
412 tx.primary = ipc4_msg->primary; in sof_ipc4_set_get_data()
413 tx.extension = ipc4_msg->extension; in sof_ipc4_set_get_data()
425 /* Serialise IPC TX */ in sof_ipc4_set_get_data()
426 mutex_lock(&sdev->ipc->tx_mutex); in sof_ipc4_set_get_data()
447 tx.data_ptr = ipc4_msg->data_ptr + offset; in sof_ipc4_set_get_data()
455 rx.data_ptr = ipc4_msg->data_ptr + offset; in sof_ipc4_set_get_data()
462 ret = ipc4_tx_msg_unlocked(sdev->ipc, &tx, tx_size, &rx, rx_size); in sof_ipc4_set_get_data()
464 dev_err(sdev->dev, in sof_ipc4_set_get_data()
475 dev_err(sdev->dev, in sof_ipc4_set_get_data()
478 ret = -ENOMEM; in sof_ipc4_set_get_data()
491 remaining -= chunk_size; in sof_ipc4_set_get_data()
496 ipc4_msg->data_size = offset; in sof_ipc4_set_get_data()
498 sof_ipc4_dump_payload(sdev, ipc4_msg->data_ptr, ipc4_msg->data_size); in sof_ipc4_set_get_data()
501 mutex_unlock(&sdev->ipc->tx_mutex); in sof_ipc4_set_get_data()
509 struct snd_sof_ipc_msg *msg = &sdev->ipc->msg; in sof_ipc4_init_msg_memory()
512 sdev->ipc->max_payload_size = SOF_IPC4_MSG_MAX_SIZE; in sof_ipc4_init_msg_memory()
515 msg->reply_data = devm_kzalloc(sdev->dev, sdev->ipc->max_payload_size + in sof_ipc4_init_msg_memory()
517 if (!msg->reply_data) in sof_ipc4_init_msg_memory()
518 return -ENOMEM; in sof_ipc4_init_msg_memory()
520 ipc4_msg = msg->reply_data; in sof_ipc4_init_msg_memory()
521 ipc4_msg->data_ptr = msg->reply_data + sizeof(struct sof_ipc4_msg); in sof_ipc4_init_msg_memory()
530 /* no need to re-check version/ABI for subsequent boots */ in ipc4_fw_ready()
531 if (!sdev->first_boot) in ipc4_fw_ready()
534 /* Set up the windows for IPC communication */ in ipc4_fw_ready()
537 dev_err(sdev->dev, "%s: No mailbox offset\n", __func__); in ipc4_fw_ready()
544 sdev->dsp_box.offset = inbox_offset; in ipc4_fw_ready()
545 sdev->dsp_box.size = inbox_size; in ipc4_fw_ready()
546 sdev->host_box.offset = outbox_offset; in ipc4_fw_ready()
547 sdev->host_box.size = outbox_size; in ipc4_fw_ready()
549 sdev->debug_box.offset = snd_sof_dsp_get_window_offset(sdev, in ipc4_fw_ready()
552 dev_dbg(sdev->dev, "mailbox upstream 0x%x - size 0x%x\n", in ipc4_fw_ready()
554 dev_dbg(sdev->dev, "mailbox downstream 0x%x - size 0x%x\n", in ipc4_fw_ready()
556 dev_dbg(sdev->dev, "debug box 0x%x\n", sdev->debug_box.offset); in ipc4_fw_ready()
563 struct sof_ipc4_msg *ipc4_msg = sdev->ipc->msg.rx_data; in sof_ipc4_rx_msg()
567 if (!ipc4_msg || !SOF_IPC4_MSG_IS_NOTIFICATION(ipc4_msg->primary)) in sof_ipc4_rx_msg()
570 ipc4_msg->data_ptr = NULL; in sof_ipc4_rx_msg()
571 ipc4_msg->data_size = 0; in sof_ipc4_rx_msg()
573 sof_ipc4_log_header(sdev->dev, "ipc rx ", ipc4_msg, false); in sof_ipc4_rx_msg()
575 switch (SOF_IPC4_NOTIFICATION_TYPE_GET(ipc4_msg->primary)) { in sof_ipc4_rx_msg()
578 if (sdev->fw_state == SOF_FW_BOOT_IN_PROGRESS) { in sof_ipc4_rx_msg()
586 wake_up(&sdev->boot_wait); in sof_ipc4_rx_msg()
594 sof_ipc4_mtrace_update_pos(sdev, SOF_IPC4_LOG_CORE_GET(ipc4_msg->primary)); in sof_ipc4_rx_msg()
597 dev_dbg(sdev->dev, "Unhandled DSP message: %#x|%#x\n", in sof_ipc4_rx_msg()
598 ipc4_msg->primary, ipc4_msg->extension); in sof_ipc4_rx_msg()
603 ipc4_msg->data_ptr = kmalloc(data_size, GFP_KERNEL); in sof_ipc4_rx_msg()
604 if (!ipc4_msg->data_ptr) in sof_ipc4_rx_msg()
607 ipc4_msg->data_size = data_size; in sof_ipc4_rx_msg()
608 snd_sof_ipc_msg_data(sdev, NULL, ipc4_msg->data_ptr, ipc4_msg->data_size); in sof_ipc4_rx_msg()
611 sof_ipc4_log_header(sdev->dev, "ipc rx done ", ipc4_msg, true); in sof_ipc4_rx_msg()
614 kfree(ipc4_msg->data_ptr); in sof_ipc4_rx_msg()
615 ipc4_msg->data_ptr = NULL; in sof_ipc4_rx_msg()
616 ipc4_msg->data_size = 0; in sof_ipc4_rx_msg()