aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMousami Jana <mousami.janax@intel.com>2015-12-03 12:59:55 -0500
committerMark Brown <broonie@kernel.org>2015-12-08 12:57:51 -0500
commitcce1c7f383e829651e0729d4b0b2cb78ea5cb2d6 (patch)
treef931433dcb9001f9a2717cdd7457bc9cb6174362
parentc99b80564c1badfa0cd14f4ebf3193fd77e412e9 (diff)
ASoC: Intel: Skylake: add LARGE_CONFIG_GET IPC support
For messages which have larger payload than mailbox data, we need to split the payload using set of messages containing mailbox size as payload. For sending such payload we already support LARGE_CONFIG_SET IPCs and now to query such payload add LARGE_CONFIG_GET IPC Signed-off-by: Mousami Jana <mousami.janax@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c53
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h3
2 files changed, 56 insertions, 0 deletions
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 33860d2311c4..62e665a3b8f7 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -349,6 +349,8 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
349 switch (reply) { 349 switch (reply) {
350 case IPC_GLB_REPLY_SUCCESS: 350 case IPC_GLB_REPLY_SUCCESS:
351 dev_info(ipc->dev, "ipc FW reply %x: success\n", header.primary); 351 dev_info(ipc->dev, "ipc FW reply %x: success\n", header.primary);
352 /* copy the rx data from the mailbox */
353 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
352 break; 354 break;
353 355
354 case IPC_GLB_REPLY_OUT_OF_MEMORY: 356 case IPC_GLB_REPLY_OUT_OF_MEMORY:
@@ -834,3 +836,54 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
834 return ret; 836 return ret;
835} 837}
836EXPORT_SYMBOL_GPL(skl_ipc_set_large_config); 838EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
839
840int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
841 struct skl_ipc_large_config_msg *msg, u32 *param)
842{
843 struct skl_ipc_header header = {0};
844 u64 *ipc_header = (u64 *)(&header);
845 int ret = 0;
846 size_t sz_remaining, rx_size, data_offset;
847
848 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
849 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
850 header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_GET);
851 header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
852 header.primary |= IPC_MOD_ID(msg->module_id);
853
854 header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
855 header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
856 header.extension |= IPC_FINAL_BLOCK(1);
857 header.extension |= IPC_INITIAL_BLOCK(1);
858
859 sz_remaining = msg->param_data_size;
860 data_offset = 0;
861
862 while (sz_remaining != 0) {
863 rx_size = sz_remaining > SKL_ADSP_W1_SZ
864 ? SKL_ADSP_W1_SZ : sz_remaining;
865 if (rx_size == sz_remaining)
866 header.extension |= IPC_FINAL_BLOCK(1);
867
868 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0,
869 ((char *)param) + data_offset,
870 msg->param_data_size);
871 if (ret < 0) {
872 dev_err(ipc->dev,
873 "ipc: get large config fail, err: %d\n", ret);
874 return ret;
875 }
876 sz_remaining -= rx_size;
877 data_offset = msg->param_data_size - sz_remaining;
878
879 /* clear the fields */
880 header.extension &= IPC_INITIAL_BLOCK_CLEAR;
881 header.extension &= IPC_DATA_OFFSET_SZ_CLEAR;
882 /* fill the fields */
883 header.extension |= IPC_INITIAL_BLOCK(1);
884 header.extension |= IPC_DATA_OFFSET_SZ(data_offset);
885 }
886
887 return ret;
888}
889EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index e17012778560..1bbcdb471cf2 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -120,6 +120,9 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc,
120int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, 120int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
121 struct skl_ipc_large_config_msg *msg, u32 *param); 121 struct skl_ipc_large_config_msg *msg, u32 *param);
122 122
123int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
124 struct skl_ipc_large_config_msg *msg, u32 *param);
125
123void skl_ipc_int_enable(struct sst_dsp *dsp); 126void skl_ipc_int_enable(struct sst_dsp *dsp);
124void skl_ipc_op_int_enable(struct sst_dsp *ctx); 127void skl_ipc_op_int_enable(struct sst_dsp *ctx);
125void skl_ipc_op_int_disable(struct sst_dsp *ctx); 128void skl_ipc_op_int_disable(struct sst_dsp *ctx);