diff mbox series

[05/17] ASoC: Intel: avs: Add code loading requests

Message ID 20220207122108.3780926-6-cezary.rojewski@intel.com (mailing list archive)
State Superseded
Headers show
Series ASoC: Intel: AVS - Audio DSP for cAVS | expand

Commit Message

Cezary Rojewski Feb. 7, 2022, 12:20 p.m. UTC
Before firmware and its modules can be used, they have to be loaded.
Code loading process is complex and is a combination of DMA and IPC
operations. Here, IPC part is being added and accounts for CLDMA and HDA
mechanisms both.

Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/Makefile   |  2 +-
 sound/soc/intel/avs/messages.c | 65 ++++++++++++++++++++++++++++++++++
 sound/soc/intel/avs/messages.h | 22 ++++++++++++
 3 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 sound/soc/intel/avs/messages.c

Comments

Pierre-Louis Bossart Feb. 25, 2022, 1:02 a.m. UTC | #1
> +#define AVS_CL_TIMEOUT_MS	5000

it's not clear where this comes from, and it's also unclear why both
types of code loading would have the same timeout when the hardware is
so fundamentally different.

> +
> +int avs_ipc_load_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids)
> +{
> +	union avs_global_msg msg = AVS_GLOBAL_REQUEST(LOAD_MULTIPLE_MODULES);
> +	struct avs_ipc_msg request;
> +	int ret;
> +
> +	msg.load_multi_mods.mod_cnt = num_mod_ids;
> +	request.header = msg.val;
> +	request.data = mod_ids;
> +	request.size = sizeof(*mod_ids) * num_mod_ids;
> +
> +	ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS);
> +	if (ret)
> +		avs_ipc_err(adev, &request, "load multiple modules", ret);
> +
> +	return ret;
> +}
> +
> +int avs_ipc_unload_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids)
> +{
> +	union avs_global_msg msg = AVS_GLOBAL_REQUEST(UNLOAD_MULTIPLE_MODULES);
> +	struct avs_ipc_msg request;
> +	int ret;
> +
> +	msg.load_multi_mods.mod_cnt = num_mod_ids;
> +	request.header = msg.val;
> +	request.data = mod_ids;
> +	request.size = sizeof(*mod_ids) * num_mod_ids;
> +
> +	ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS);
> +	if (ret)
> +		avs_ipc_err(adev, &request, "unload multiple modules", ret);
> +
> +	return ret;
> +}
> +
> +int avs_ipc_load_library(struct avs_dev *adev, u32 dma_id, u32 lib_id)
> +{
> +	union avs_global_msg msg = AVS_GLOBAL_REQUEST(LOAD_LIBRARY);
> +	struct avs_ipc_msg request = {0};

I've asked this before and I don't recall by this case requires an
initialization to zero?

> +	int ret;
> +
> +	msg.load_lib.dma_id = dma_id;
> +	msg.load_lib.lib_id = lib_id;
> +	request.header = msg.val;
> +
> +	ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS);
> +	if (ret)
> +		avs_ipc_err(adev, &request, "load library", ret);
> +
> +	return ret;
Cezary Rojewski Feb. 25, 2022, 6:08 p.m. UTC | #2
On 2022-02-25 2:02 AM, Pierre-Louis Bossart wrote:
> 
>> +#define AVS_CL_TIMEOUT_MS	5000
> 
> it's not clear where this comes from, and it's also unclear why both
> types of code loading would have the same timeout when the hardware is
> so fundamentally different.


I can re-check but most often than not, I'm basing these on proven, 
working, close-source equivalent.

>> +int avs_ipc_load_library(struct avs_dev *adev, u32 dma_id, u32 lib_id)
>> +{
>> +	union avs_global_msg msg = AVS_GLOBAL_REQUEST(LOAD_LIBRARY);
>> +	struct avs_ipc_msg request = {0};
> 
> I've asked this before and I don't recall by this case requires an
> initialization to zero?


Fields 'data' and 'size' are also part of struct avs_ipc_msg. We zero 
them out here as there is no payload to be sent for LOAD_LIBRARY IPC.

>> +	int ret;
>> +
>> +	msg.load_lib.dma_id = dma_id;
>> +	msg.load_lib.lib_id = lib_id;
>> +	request.header = msg.val;
>> +
>> +	ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS);
>> +	if (ret)
>> +		avs_ipc_err(adev, &request, "load library", ret);
>> +
>> +	return ret;
>
diff mbox series

Patch

diff --git a/sound/soc/intel/avs/Makefile b/sound/soc/intel/avs/Makefile
index e243806dd38a..c0824f30fd3b 100644
--- a/sound/soc/intel/avs/Makefile
+++ b/sound/soc/intel/avs/Makefile
@@ -1,5 +1,5 @@ 
 # SPDX-License-Identifier: GPL-2.0-only
 
-snd-soc-avs-objs := dsp.o ipc.o
+snd-soc-avs-objs := dsp.o ipc.o messages.o
 
 obj-$(CONFIG_SND_SOC_INTEL_AVS) += snd-soc-avs.o
diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c
new file mode 100644
index 000000000000..8dac946dd8dd
--- /dev/null
+++ b/sound/soc/intel/avs/messages.c
@@ -0,0 +1,65 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2021 Intel Corporation. All rights reserved.
+//
+// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+//          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+//
+
+#include "avs.h"
+#include "messages.h"
+
+#define AVS_CL_TIMEOUT_MS	5000
+
+int avs_ipc_load_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids)
+{
+	union avs_global_msg msg = AVS_GLOBAL_REQUEST(LOAD_MULTIPLE_MODULES);
+	struct avs_ipc_msg request;
+	int ret;
+
+	msg.load_multi_mods.mod_cnt = num_mod_ids;
+	request.header = msg.val;
+	request.data = mod_ids;
+	request.size = sizeof(*mod_ids) * num_mod_ids;
+
+	ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS);
+	if (ret)
+		avs_ipc_err(adev, &request, "load multiple modules", ret);
+
+	return ret;
+}
+
+int avs_ipc_unload_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids)
+{
+	union avs_global_msg msg = AVS_GLOBAL_REQUEST(UNLOAD_MULTIPLE_MODULES);
+	struct avs_ipc_msg request;
+	int ret;
+
+	msg.load_multi_mods.mod_cnt = num_mod_ids;
+	request.header = msg.val;
+	request.data = mod_ids;
+	request.size = sizeof(*mod_ids) * num_mod_ids;
+
+	ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS);
+	if (ret)
+		avs_ipc_err(adev, &request, "unload multiple modules", ret);
+
+	return ret;
+}
+
+int avs_ipc_load_library(struct avs_dev *adev, u32 dma_id, u32 lib_id)
+{
+	union avs_global_msg msg = AVS_GLOBAL_REQUEST(LOAD_LIBRARY);
+	struct avs_ipc_msg request = {0};
+	int ret;
+
+	msg.load_lib.dma_id = dma_id;
+	msg.load_lib.lib_id = lib_id;
+	request.header = msg.val;
+
+	ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS);
+	if (ret)
+		avs_ipc_err(adev, &request, "load library", ret);
+
+	return ret;
+}
diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h
index 003e634f5547..b9ec1c64179b 100644
--- a/sound/soc/intel/avs/messages.h
+++ b/sound/soc/intel/avs/messages.h
@@ -24,6 +24,9 @@  enum avs_msg_direction {
 };
 
 enum avs_global_msg_type {
+	AVS_GLB_LOAD_MULTIPLE_MODULES = 15,
+	AVS_GLB_UNLOAD_MULTIPLE_MODULES = 16,
+	AVS_GLB_LOAD_LIBRARY = 24,
 	AVS_GLB_NOTIFICATION = 27,
 };
 
@@ -38,6 +41,16 @@  union avs_global_msg {
 				u32 msg_direction:1;
 				u32 msg_target:1;
 			};
+			/* module loading */
+			struct {
+				u32 mod_cnt:8;
+			} load_multi_mods;
+			/* library loading */
+			struct {
+				u32 dma_id:5;
+				u32 rsvd:11;
+				u32 lib_id:4;
+			} load_lib;
 		};
 		union {
 			u32 val;
@@ -84,6 +97,10 @@  union avs_reply_msg {
 		};
 		union {
 			u32 val;
+			/* module loading */
+			struct {
+				u32 err_mod_id:16;
+			} load_multi_mods;
 		} ext;
 	};
 } __packed;
@@ -167,4 +184,9 @@  struct avs_notify_mod_data {
 	u32 data[];
 } __packed;
 
+/* Code loading messages */
+int avs_ipc_load_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids);
+int avs_ipc_unload_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids);
+int avs_ipc_load_library(struct avs_dev *adev, u32 dma_id, u32 lib_id);
+
 #endif /* __SOUND_SOC_INTEL_AVS_MSGS_H */