Lines Matching full:ipc
2 * skl-sst-ipc.c - Intel skl IPC Support
21 #include "skl-sst-ipc.h"
185 /* Set D0ix IPC extension register */
302 static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) in skl_ipc_tx_msg() argument
307 sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); in skl_ipc_tx_msg()
308 sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE, in skl_ipc_tx_msg()
310 sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI, in skl_ipc_tx_msg()
331 static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc, in skl_ipc_reply_get_msg() argument
337 if (list_empty(&ipc->rx_list)) { in skl_ipc_reply_get_msg()
338 dev_err(ipc->dev, "ipc: rx list is empty but received 0x%x\n", in skl_ipc_reply_get_msg()
343 msg = list_first_entry(&ipc->rx_list, struct ipc_message, list); in skl_ipc_reply_get_msg()
350 int skl_ipc_process_notification(struct sst_generic_ipc *ipc, in skl_ipc_process_notification() argument
353 struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); in skl_ipc_process_notification()
359 dev_err(ipc->dev, "FW Underrun %x\n", header.primary); in skl_ipc_process_notification()
363 dev_err(ipc->dev, "MCPS Budget Violation: %x\n", in skl_ipc_process_notification()
373 dev_dbg(ipc->dev, "***** Phrase Detected **********\n"); in skl_ipc_process_notification()
381 skl->enable_miscbdcge(ipc->dev, false); in skl_ipc_process_notification()
386 dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n", in skl_ipc_process_notification()
409 void skl_ipc_process_reply(struct sst_generic_ipc *ipc, in skl_ipc_process_reply() argument
415 struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); in skl_ipc_process_reply()
418 spin_lock_irqsave(&ipc->dsp->spinlock, flags); in skl_ipc_process_reply()
419 msg = skl_ipc_reply_get_msg(ipc, *ipc_header); in skl_ipc_process_reply()
420 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in skl_ipc_process_reply()
422 dev_dbg(ipc->dev, "ipc: rx list is empty\n"); in skl_ipc_process_reply()
428 dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary); in skl_ipc_process_reply()
430 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size); in skl_ipc_process_reply()
445 dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply); in skl_ipc_process_reply()
446 dev_err(ipc->dev, "FW Error Code: %u\n", in skl_ipc_process_reply()
447 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); in skl_ipc_process_reply()
462 spin_lock_irqsave(&ipc->dsp->spinlock, flags); in skl_ipc_process_reply()
464 sst_ipc_tx_msg_reply_complete(ipc, msg); in skl_ipc_process_reply()
465 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in skl_ipc_process_reply()
472 struct sst_generic_ipc *ipc = &skl->ipc; in skl_dsp_irq_thread_handler() local
480 /* Here we handle IPC interrupts only */ in skl_dsp_irq_thread_handler()
508 dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n", in skl_dsp_irq_thread_handler()
510 dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n", in skl_dsp_irq_thread_handler()
515 skl_ipc_process_reply(ipc, header); in skl_dsp_irq_thread_handler()
517 dev_dbg(dsp->dev, "IPC irq: Notification from firmware\n"); in skl_dsp_irq_thread_handler()
518 skl_ipc_process_notification(ipc, header); in skl_dsp_irq_thread_handler()
532 schedule_work(&ipc->kwork); in skl_dsp_irq_thread_handler()
551 /* enable IPC DONE interrupt */ in skl_ipc_op_int_enable()
555 /* Enable IPC BUSY interrupt */ in skl_ipc_op_int_enable()
562 /* disable IPC DONE interrupt */ in skl_ipc_op_int_disable()
566 /* Disable IPC BUSY interrupt */ in skl_ipc_op_int_disable()
580 struct sst_generic_ipc *ipc; in skl_ipc_init() local
583 ipc = &skl->ipc; in skl_ipc_init()
584 ipc->dsp = skl->dsp; in skl_ipc_init()
585 ipc->dev = dev; in skl_ipc_init()
587 ipc->tx_data_max_size = SKL_ADSP_W1_SZ; in skl_ipc_init()
588 ipc->rx_data_max_size = SKL_ADSP_W0_UP_SZ; in skl_ipc_init()
590 err = sst_ipc_init(ipc); in skl_ipc_init()
594 ipc->ops.tx_msg = skl_ipc_tx_msg; in skl_ipc_init()
595 ipc->ops.tx_data_copy = skl_ipc_tx_data_copy; in skl_ipc_init()
596 ipc->ops.is_dsp_busy = skl_ipc_is_dsp_busy; in skl_ipc_init()
601 void skl_ipc_free(struct sst_generic_ipc *ipc) in skl_ipc_free() argument
603 /* Disable IPC DONE interrupt */ in skl_ipc_free()
604 sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL, in skl_ipc_free()
607 /* Disable IPC BUSY interrupt */ in skl_ipc_free()
608 sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL, in skl_ipc_free()
611 sst_ipc_fini(ipc); in skl_ipc_free()
614 int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc, in skl_ipc_create_pipeline() argument
630 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); in skl_ipc_create_pipeline()
631 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); in skl_ipc_create_pipeline()
633 dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret); in skl_ipc_create_pipeline()
641 int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) in skl_ipc_delete_pipeline() argument
652 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); in skl_ipc_delete_pipeline()
653 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); in skl_ipc_delete_pipeline()
655 dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret); in skl_ipc_delete_pipeline()
663 int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc, in skl_ipc_set_pipeline_state() argument
676 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); in skl_ipc_set_pipeline_state()
677 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); in skl_ipc_set_pipeline_state()
679 dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret); in skl_ipc_set_pipeline_state()
687 skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id) in skl_ipc_save_pipeline() argument
699 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); in skl_ipc_save_pipeline()
700 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); in skl_ipc_save_pipeline()
702 dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret); in skl_ipc_save_pipeline()
710 int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) in skl_ipc_restore_pipeline() argument
721 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); in skl_ipc_restore_pipeline()
722 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); in skl_ipc_restore_pipeline()
724 dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret); in skl_ipc_restore_pipeline()
732 int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id, in skl_ipc_set_dx() argument
745 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, in skl_ipc_set_dx()
747 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, in skl_ipc_set_dx()
750 dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret); in skl_ipc_set_dx()
758 int skl_ipc_init_instance(struct sst_generic_ipc *ipc, in skl_ipc_init_instance() argument
782 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, in skl_ipc_init_instance()
784 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, param_data, in skl_ipc_init_instance()
788 dev_err(ipc->dev, "ipc: init instance failed\n"); in skl_ipc_init_instance()
796 int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc, in skl_ipc_bind_unbind() argument
815 dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary, in skl_ipc_bind_unbind()
817 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); in skl_ipc_bind_unbind()
819 dev_err(ipc->dev, "ipc: bind/unbind failed\n"); in skl_ipc_bind_unbind()
828 * In order to load a module we need to send IPC to initiate that. DMA will
830 * at single shot, so we can send IPC with N modules represented by
833 int skl_ipc_load_modules(struct sst_generic_ipc *ipc, in skl_ipc_load_modules() argument
845 ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data, in skl_ipc_load_modules()
848 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret); in skl_ipc_load_modules()
854 int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt, in skl_ipc_unload_modules() argument
866 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data, in skl_ipc_unload_modules()
869 dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret); in skl_ipc_unload_modules()
875 int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, in skl_ipc_set_large_config() argument
902 dev_dbg(ipc->dev, "In %s primary=%#x ext=%#x\n", __func__, in skl_ipc_set_large_config()
904 dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n", in skl_ipc_set_large_config()
906 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, in skl_ipc_set_large_config()
910 dev_err(ipc->dev, in skl_ipc_set_large_config()
911 "ipc: set large config fail, err: %d\n", ret); in skl_ipc_set_large_config()
929 int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, in skl_ipc_get_large_config() argument
957 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, in skl_ipc_get_large_config()
961 dev_err(ipc->dev, in skl_ipc_get_large_config()
962 "ipc: get large config fail, err: %d\n", ret); in skl_ipc_get_large_config()
980 int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, in skl_sst_ipc_load_library() argument
994 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, in skl_sst_ipc_load_library()
997 ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0); in skl_sst_ipc_load_library()
1000 dev_err(ipc->dev, "ipc: load lib failed\n"); in skl_sst_ipc_load_library()
1006 int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) in skl_ipc_set_d0ix() argument
1021 dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__, in skl_ipc_set_d0ix()
1025 * Use the nopm IPC here as we dont want it checking for D0iX in skl_ipc_set_d0ix()
1027 ret = sst_ipc_tx_message_nopm(ipc, *ipc_header, NULL, 0, NULL, 0); in skl_ipc_set_d0ix()
1029 dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret); in skl_ipc_set_d0ix()