aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/skylake/skl-sst-ipc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/skylake/skl-sst-ipc.c')
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 96f2f6889b18..0bd01e62622c 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -114,6 +114,11 @@
114#define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \ 114#define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \
115 << IPC_CORE_ID_SHIFT) 115 << IPC_CORE_ID_SHIFT)
116 116
117#define IPC_DOMAIN_SHIFT 28
118#define IPC_DOMAIN_MASK 0x1
119#define IPC_DOMAIN(x) (((x) & IPC_DOMAIN_MASK) \
120 << IPC_DOMAIN_SHIFT)
121
117/* Bind/Unbind message extension register */ 122/* Bind/Unbind message extension register */
118#define IPC_DST_MOD_ID_SHIFT 0 123#define IPC_DST_MOD_ID_SHIFT 0
119#define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \ 124#define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \
@@ -190,6 +195,7 @@ enum skl_ipc_glb_type {
190 IPC_GLB_GET_PPL_CONTEXT_SIZE = 21, 195 IPC_GLB_GET_PPL_CONTEXT_SIZE = 21,
191 IPC_GLB_SAVE_PPL = 22, 196 IPC_GLB_SAVE_PPL = 22,
192 IPC_GLB_RESTORE_PPL = 23, 197 IPC_GLB_RESTORE_PPL = 23,
198 IPC_GLB_LOAD_LIBRARY = 24,
193 IPC_GLB_NOTIFY = 26, 199 IPC_GLB_NOTIFY = 26,
194 IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */ 200 IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */
195}; 201};
@@ -338,7 +344,7 @@ static int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
338 break; 344 break;
339 345
340 default: 346 default:
341 dev_err(ipc->dev, "ipc: Unhandled error msg=%x", 347 dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n",
342 header.primary); 348 header.primary);
343 break; 349 break;
344 } 350 }
@@ -379,13 +385,13 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
379 break; 385 break;
380 386
381 default: 387 default:
382 dev_err(ipc->dev, "Unknown ipc reply: 0x%x", reply); 388 dev_err(ipc->dev, "Unknown ipc reply: 0x%x\n", reply);
383 msg->errno = -EINVAL; 389 msg->errno = -EINVAL;
384 break; 390 break;
385 } 391 }
386 392
387 if (reply != IPC_GLB_REPLY_SUCCESS) { 393 if (reply != IPC_GLB_REPLY_SUCCESS) {
388 dev_err(ipc->dev, "ipc FW reply: reply=%d", reply); 394 dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply);
389 dev_err(ipc->dev, "FW Error Code: %u\n", 395 dev_err(ipc->dev, "FW Error Code: %u\n",
390 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); 396 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
391 } 397 }
@@ -434,9 +440,9 @@ irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
434 hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE); 440 hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE);
435 header.primary = hipct; 441 header.primary = hipct;
436 header.extension = hipcte; 442 header.extension = hipcte;
437 dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x", 443 dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n",
438 header.primary); 444 header.primary);
439 dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x", 445 dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n",
440 header.extension); 446 header.extension);
441 447
442 if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) { 448 if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) {
@@ -704,6 +710,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
704 header.extension = IPC_CORE_ID(msg->core_id); 710 header.extension = IPC_CORE_ID(msg->core_id);
705 header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id); 711 header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id);
706 header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); 712 header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
713 header.extension |= IPC_DOMAIN(msg->domain);
707 714
708 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, 715 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
709 header.primary, header.extension); 716 header.primary, header.extension);
@@ -742,7 +749,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
742 header.extension); 749 header.extension);
743 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 750 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
744 if (ret < 0) { 751 if (ret < 0) {
745 dev_err(ipc->dev, "ipc: bind/unbind faileden"); 752 dev_err(ipc->dev, "ipc: bind/unbind failed\n");
746 return ret; 753 return ret;
747 } 754 }
748 755
@@ -902,3 +909,25 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
902 return ret; 909 return ret;
903} 910}
904EXPORT_SYMBOL_GPL(skl_ipc_get_large_config); 911EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
912
913int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
914 u8 dma_id, u8 table_id)
915{
916 struct skl_ipc_header header = {0};
917 u64 *ipc_header = (u64 *)(&header);
918 int ret = 0;
919
920 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
921 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
922 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
923 header.primary |= IPC_MOD_INSTANCE_ID(table_id);
924 header.primary |= IPC_MOD_ID(dma_id);
925
926 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
927
928 if (ret < 0)
929 dev_err(ipc->dev, "ipc: load lib failed\n");
930
931 return ret;
932}
933EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);