diff mbox series

[v3,06/17] ASoC: Intel: avs: Add pipeline management requests

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

Commit Message

Cezary Rojewski March 4, 2022, 2:57 p.m. UTC
Pipeline represents a scheduling entity. Their existence as well as
their state machine is controlled through CREATE_PIPELINE,
DELETE_PIPELINE and SET_PIPELINE_STATE IPCs.

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/messages.c | 76 ++++++++++++++++++++++++++++++++++
 sound/soc/intel/avs/messages.h | 48 +++++++++++++++++++++
 2 files changed, 124 insertions(+)

Comments

Ranjani Sridharan March 4, 2022, 4:13 p.m. UTC | #1
On Fri, 2022-03-04 at 15:57 +0100, Cezary Rojewski wrote:
> Pipeline represents a scheduling entity. Their existence as well as
> their state machine is controlled through CREATE_PIPELINE,
> DELETE_PIPELINE and SET_PIPELINE_STATE IPCs.
> 
> 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/messages.c | 76
> ++++++++++++++++++++++++++++++++++
>  sound/soc/intel/avs/messages.h | 48 +++++++++++++++++++++
>  2 files changed, 124 insertions(+)
> 
> diff --git a/sound/soc/intel/avs/messages.c
> b/sound/soc/intel/avs/messages.c
> index d568338b0737..de2d50f8c6b4 100644
> --- a/sound/soc/intel/avs/messages.c
> +++ b/sound/soc/intel/avs/messages.c
> @@ -63,3 +63,79 @@ int avs_ipc_load_library(struct avs_dev *adev, u32
> dma_id, u32 lib_id)
>  
>  	return ret;
>  }
> +
> +int avs_ipc_create_pipeline(struct avs_dev *adev, u16 req_size, u8
> priority,
> +			    u8 instance_id, bool lp, u16 attributes)
> +{
> +	union avs_global_msg msg = AVS_GLOBAL_REQUEST(CREATE_PIPELINE);
> +	struct avs_ipc_msg request = {{0}};
> +	int ret;
> +
> +	msg.create_ppl.ppl_mem_size = req_size;
> +	msg.create_ppl.ppl_priority = priority;
> +	msg.create_ppl.instance_id = instance_id;
> +	msg.ext.create_ppl.lp = lp;
> +	msg.ext.create_ppl.attributes = attributes;
> +	request.header = msg.val;
> +
> +	ret = avs_dsp_send_msg(adev, &request, NULL);
> +	if (ret)
> +		avs_ipc_err(adev, &request, "create pipeline", ret);
> +
> +	return ret;
> +}
> +
> +int avs_ipc_delete_pipeline(struct avs_dev *adev, u8 instance_id)
> +{
> +	union avs_global_msg msg = AVS_GLOBAL_REQUEST(DELETE_PIPELINE);
> +	struct avs_ipc_msg request = {{0}};
> +	int ret;
> +
> +	msg.ppl.instance_id = instance_id;
> +	request.header = msg.val;
> +
> +	ret = avs_dsp_send_msg(adev, &request, NULL);
> +	if (ret)
> +		avs_ipc_err(adev, &request, "delete pipeline", ret);
> +
> +	return ret;
> +}
> +
> +int avs_ipc_set_pipeline_state(struct avs_dev *adev, u8 instance_id,
> +			       enum avs_pipeline_state state)
> +{
> +	union avs_global_msg msg =
> AVS_GLOBAL_REQUEST(SET_PIPELINE_STATE);
> +	struct avs_ipc_msg request = {{0}};
> +	int ret;
> +
> +	msg.set_ppl_state.ppl_id = instance_id;
> +	msg.set_ppl_state.state = state;
> +	request.header = msg.val;
> +
> +	ret = avs_dsp_send_msg(adev, &request, NULL);
> +	if (ret)
> +		avs_ipc_err(adev, &request, "set pipeline state", ret);
> +
> +	return ret;
> +}
> +
> +int avs_ipc_get_pipeline_state(struct avs_dev *adev, u8 instance_id,
> +			       enum avs_pipeline_state *state)
Can the pipeline state in the firmware change without the driver's
knowledge? When should the driver use this get_pipeline_state()?

Thanks,Ranjani
Cezary Rojewski March 4, 2022, 5:15 p.m. UTC | #2
On 2022-03-04 5:13 PM, Ranjani Sridharan wrote:
> On Fri, 2022-03-04 at 15:57 +0100, Cezary Rojewski wrote:
>> Pipeline represents a scheduling entity. Their existence as well as
>> their state machine is controlled through CREATE_PIPELINE,
>> DELETE_PIPELINE and SET_PIPELINE_STATE IPCs.

...

>> +int avs_ipc_set_pipeline_state(struct avs_dev *adev, u8 instance_id,
>> +			       enum avs_pipeline_state state)
>> +{
>> +	union avs_global_msg msg =
>> AVS_GLOBAL_REQUEST(SET_PIPELINE_STATE);
>> +	struct avs_ipc_msg request = {{0}};
>> +	int ret;
>> +
>> +	msg.set_ppl_state.ppl_id = instance_id;
>> +	msg.set_ppl_state.state = state;
>> +	request.header = msg.val;
>> +
>> +	ret = avs_dsp_send_msg(adev, &request, NULL);
>> +	if (ret)
>> +		avs_ipc_err(adev, &request, "set pipeline state", ret);
>> +
>> +	return ret;
>> +}
>> +
>> +int avs_ipc_get_pipeline_state(struct avs_dev *adev, u8 instance_id,
>> +			       enum avs_pipeline_state *state)
> Can the pipeline state in the firmware change without the driver's
> knowledge? When should the driver use this get_pipeline_state()?


Thanks for feedback! Consider dropping the unnecessary bits so it is 
easier to navigate through your responses.

Please note: kernel mailing list is not for explaining SW <-> FW 
communication details. Feel free to contact my colleagues from firmware 
team if in need of any FW-iface details.

-

Actual state machine is found in the firmware, not in the driver. Driver 
may use such information when profiling and also during debug.


Regards,
Czarek
diff mbox series

Patch

diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c
index d568338b0737..de2d50f8c6b4 100644
--- a/sound/soc/intel/avs/messages.c
+++ b/sound/soc/intel/avs/messages.c
@@ -63,3 +63,79 @@  int avs_ipc_load_library(struct avs_dev *adev, u32 dma_id, u32 lib_id)
 
 	return ret;
 }
+
+int avs_ipc_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority,
+			    u8 instance_id, bool lp, u16 attributes)
+{
+	union avs_global_msg msg = AVS_GLOBAL_REQUEST(CREATE_PIPELINE);
+	struct avs_ipc_msg request = {{0}};
+	int ret;
+
+	msg.create_ppl.ppl_mem_size = req_size;
+	msg.create_ppl.ppl_priority = priority;
+	msg.create_ppl.instance_id = instance_id;
+	msg.ext.create_ppl.lp = lp;
+	msg.ext.create_ppl.attributes = attributes;
+	request.header = msg.val;
+
+	ret = avs_dsp_send_msg(adev, &request, NULL);
+	if (ret)
+		avs_ipc_err(adev, &request, "create pipeline", ret);
+
+	return ret;
+}
+
+int avs_ipc_delete_pipeline(struct avs_dev *adev, u8 instance_id)
+{
+	union avs_global_msg msg = AVS_GLOBAL_REQUEST(DELETE_PIPELINE);
+	struct avs_ipc_msg request = {{0}};
+	int ret;
+
+	msg.ppl.instance_id = instance_id;
+	request.header = msg.val;
+
+	ret = avs_dsp_send_msg(adev, &request, NULL);
+	if (ret)
+		avs_ipc_err(adev, &request, "delete pipeline", ret);
+
+	return ret;
+}
+
+int avs_ipc_set_pipeline_state(struct avs_dev *adev, u8 instance_id,
+			       enum avs_pipeline_state state)
+{
+	union avs_global_msg msg = AVS_GLOBAL_REQUEST(SET_PIPELINE_STATE);
+	struct avs_ipc_msg request = {{0}};
+	int ret;
+
+	msg.set_ppl_state.ppl_id = instance_id;
+	msg.set_ppl_state.state = state;
+	request.header = msg.val;
+
+	ret = avs_dsp_send_msg(adev, &request, NULL);
+	if (ret)
+		avs_ipc_err(adev, &request, "set pipeline state", ret);
+
+	return ret;
+}
+
+int avs_ipc_get_pipeline_state(struct avs_dev *adev, u8 instance_id,
+			       enum avs_pipeline_state *state)
+{
+	union avs_global_msg msg = AVS_GLOBAL_REQUEST(GET_PIPELINE_STATE);
+	struct avs_ipc_msg request = {{0}};
+	struct avs_ipc_msg reply = {{0}};
+	int ret;
+
+	msg.get_ppl_state.ppl_id = instance_id;
+	request.header = msg.val;
+
+	ret = avs_dsp_send_msg(adev, &request, &reply);
+	if (ret) {
+		avs_ipc_err(adev, &request, "get pipeline state", ret);
+		return ret;
+	}
+
+	*state = reply.rsp.ext.get_ppl_state.state;
+	return ret;
+}
diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h
index b9ec1c64179b..c1bf1cff54d9 100644
--- a/sound/soc/intel/avs/messages.h
+++ b/sound/soc/intel/avs/messages.h
@@ -26,6 +26,10 @@  enum avs_msg_direction {
 enum avs_global_msg_type {
 	AVS_GLB_LOAD_MULTIPLE_MODULES = 15,
 	AVS_GLB_UNLOAD_MULTIPLE_MODULES = 16,
+	AVS_GLB_CREATE_PIPELINE = 17,
+	AVS_GLB_DELETE_PIPELINE = 18,
+	AVS_GLB_SET_PIPELINE_STATE = 19,
+	AVS_GLB_GET_PIPELINE_STATE = 20,
 	AVS_GLB_LOAD_LIBRARY = 24,
 	AVS_GLB_NOTIFICATION = 27,
 };
@@ -45,6 +49,23 @@  union avs_global_msg {
 			struct {
 				u32 mod_cnt:8;
 			} load_multi_mods;
+			/* pipeline management */
+			struct {
+				u32 ppl_mem_size:11;
+				u32 ppl_priority:5;
+				u32 instance_id:8;
+			} create_ppl;
+			struct {
+				u32 rsvd:16;
+				u32 instance_id:8;
+			} ppl; /* generic ppl request */
+			struct {
+				u32 state:16;
+				u32 ppl_id:8;
+			} set_ppl_state;
+			struct {
+				u32 ppl_id:8;
+			} get_ppl_state;
 			/* library loading */
 			struct {
 				u32 dma_id:5;
@@ -54,6 +75,12 @@  union avs_global_msg {
 		};
 		union {
 			u32 val;
+			/* pipeline management */
+			struct {
+				u32 lp:1; /* low power flag */
+				u32 rsvd:3;
+				u32 attributes:16; /* additional scheduling flags */
+			} create_ppl;
 		} ext;
 	};
 } __packed;
@@ -101,6 +128,10 @@  union avs_reply_msg {
 			struct {
 				u32 err_mod_id:16;
 			} load_multi_mods;
+			/* pipeline management */
+			struct {
+				u32 state:5;
+			} get_ppl_state;
 		} ext;
 	};
 } __packed;
@@ -189,4 +220,21 @@  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);
 
+/* Pipeline management messages */
+enum avs_pipeline_state {
+	AVS_PPL_STATE_INVALID,
+	AVS_PPL_STATE_UNINITIALIZED,
+	AVS_PPL_STATE_RESET,
+	AVS_PPL_STATE_PAUSED,
+	AVS_PPL_STATE_RUNNING,
+};
+
+int avs_ipc_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority,
+			    u8 instance_id, bool lp, u16 attributes);
+int avs_ipc_delete_pipeline(struct avs_dev *adev, u8 instance_id);
+int avs_ipc_set_pipeline_state(struct avs_dev *adev, u8 instance_id,
+			       enum avs_pipeline_state state);
+int avs_ipc_get_pipeline_state(struct avs_dev *adev, u8 instance_id,
+			       enum avs_pipeline_state *state);
+
 #endif /* __SOUND_SOC_INTEL_AVS_MSGS_H */