1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2021 Intel Corporation. All rights reserved.
4  */
5 
6 /*
7  * This file contains structures that are exact copies of an existing ABI used
8  * by IOT middleware. They are Intel specific and will be used by one middleware.
9  *
10  * Some of the structures may contain programming implementations that makes them
11  * unsuitable for generic use and general usage.
12  *
13  * This code is mostly copied "as-is" from existing C++ interface files hence the use of
14  * different style in places. The intention is to keep the interface as close as possible to
15  * original so it's easier to track changes with IPC host code.
16  */
17 
18 /**
19  * \file include/ipc4/pipeline.h
20  * \brief IPC4 pipeline definitions
21  * NOTE: This ABI uses bit fields and is non portable.
22  */
23 
24 #ifndef __SOF_IPC4_PIPELINE_H__
25 #define __SOF_IPC4_PIPELINE_H__
26 
27 #include <stdint.h>
28 #include <ipc4/error_status.h>
29 
30 /**< Pipeline priority */
31 enum ipc4_pipeline_priority {
32 	/**< Priority 0 (run first) */
33 	SOF_IPC4_PIPELINE_PRIORITY_0 = 0,
34 	/**< Priority 1 */
35 	SOF_IPC4_PIPELINE_PRIORITY_1,
36 	/**< Priority 2 */
37 	SOF_IPC4_PIPELINE_PRIORITY_2,
38 	/**< Priority 3 */
39 	SOF_IPC4_PIPELINE_PRIORITY_3,
40 	/**< Priority 4 */
41 	SOF_IPC4_PIPELINE_PRIORITY_4,
42 	/**< Priority 5 */
43 	SOF_IPC4_PIPELINE_PRIORITY_5,
44 	/**< Priority 6 */
45 	SOF_IPC4_PIPELINE_PRIORITY_6,
46 	/**< Priority 7 */
47 	SOF_IPC4_PIPELINE_PRIORITY_7,
48 	/**< Max (and lowest) priority */
49 	SOF_IPC4_MAX_PIPELINE_PRIORITY = SOF_IPC4_PIPELINE_PRIORITY_7
50 };
51 
52 /**< Pipeline State */
53 enum ipc4_pipeline_state {
54 	/**< Invalid value */
55 	SOF_IPC4_PIPELINE_STATE_INVALID = 0,
56 	/**< Created but initialization incomplete */
57 	SOF_IPC4_PIPELINE_STATE_UNINITIALIZED = 1,
58 	/**< Resets pipeline */
59 	SOF_IPC4_PIPELINE_STATE_RESET = 2,
60 	/**< Pauses pipeline */
61 	SOF_IPC4_PIPELINE_STATE_PAUSED = 3,
62 	/**< Starts pipeline */
63 	SOF_IPC4_PIPELINE_STATE_RUNNING = 4,
64 	/**< Marks pipeline as expecting End Of Stream */
65 	SOF_IPC4_PIPELINE_STATE_EOS = 5,
66 	/**< Stopped on error */
67 	SOF_IPC4_PIPELINE_STATE_ERROR_STOP,
68 	/**< Saved to the host memory */
69 	SOF_IPC4_PIPELINE_STATE_SAVED
70 };
71 
72 /*!
73  * lp - indicates whether the pipeline should be kept on running in low power
74  * mode. On BXT the driver should set this flag to 1 for WoV pipeline.
75  *
76  * \remark hide_methods
77  */
78 struct ipc4_pipeline_create {
79 
80 	union {
81 		uint32_t dat;
82 
83 		struct {
84 			/**< # pages for pipeline */
85 			uint32_t ppl_mem_size   : 11;
86 			/**< priority - uses enum ipc4_pipeline_priority */
87 			uint32_t ppl_priority   : 5;
88 			/**< pipeline id */
89 			uint32_t instance_id    : 8;
90 			/**< Global::CREATE_PIPELINE */
91 			uint32_t type           : 5;
92 			/**< Msg::MSG_REQUEST */
93 			uint32_t rsp            : 1;
94 			/**< Msg::FW_GEN_MSG */
95 			uint32_t msg_tgt        : 1;
96 			uint32_t _reserved_0    : 1;
97 		} r;
98 	} primary;
99 
100 	union{
101 		uint32_t dat;
102 
103 		struct {
104 			/**< 1 - is low power */
105 			uint32_t lp             : 1;
106 			uint32_t rsvd1          : 3;
107 			uint32_t attributes     : 16;
108 			uint32_t core_id        : 4;
109 			uint32_t rsvd2          : 6;
110 			uint32_t _reserved_2    : 2;
111 		} r;
112 	} extension;
113 } __attribute__((packed, aligned(4)));
114 
115 /*!
116  * SW Driver sends this IPC message to delete a pipeline from ADSP memory.
117  *
118  * All module instances and tasks that are associated with the pipeline are
119  * deleted too.
120  *
121  * There must be no existing binding from any pipeline's module instance
122  * to another pipeline to complete the command successfully.
123  *
124  * \remark hide_methods
125  */
126 struct ipc4_pipeline_delete {
127 	union {
128 		uint32_t dat;
129 
130 		struct {
131 			uint32_t rsvd0          : 16;
132 			/**< Ppl instance id */
133 			uint32_t instance_id    : 8;
134 			/**< Global::DELETE_PIPELINE */
135 			uint32_t type           : 5;
136 			/**< Msg::MSG_REQUEST */
137 			uint32_t rsp            : 1;
138 			/**< Msg::FW_GEN_MSG */
139 			uint32_t msg_tgt        : 1;
140 			uint32_t _reserved_0    : 1;
141 		} r;
142 	} primary;
143 
144 	union{
145 		uint32_t dat;
146 
147 		struct {
148 			uint32_t rsvd1          : 30;
149 			uint32_t _reserved_2    : 2;
150 		} r;
151 	} extension;
152 } __attribute__((packed, aligned(4)));
153 
154 /*!
155  * Host SW sends this message to set a pipeline to the specified state.
156  *
157  * If there are multiple pipelines, from FW input to FW output, connected
158  * in a data processing stream, the driver should start them in reverse order,
159  * beginning with pipeline connected to the output gateway, in order to avoid
160  * overruns (FW protects the output gateway against underruns in this scenario).
161  *
162  * If driver starts multiple pipelines using a single Set Pipeline State
163  * command, it should take care of the pipeline ID order in the command payload
164  * to follow the above rule.
165  *
166  * sync_stop_start indicates whether all specified pipelines' gateways should
167  * be started with a minimal delay possible. If this flag is set to 0 while
168  * multiple pipelines are specified, the target pipelines' state is adjusted
169  * pipeline by pipeline meaning that internal propagation to all child modules
170  * may take more time between reaching state of attached gateways. Output and
171  * input gateways are grouped separately, and started/stopped separately.
172  *
173  * NOTE: Task Creation/Registration is part of the first state transition.
174  * There is no other dedicated call for this.
175  *
176  * \remark hide_methods
177  */
178 struct ipc4_pipeline_set_state_data {
179 	/**< Number of items in ppl_id[] */
180 	uint32_t pipelines_count;
181 	/**< Pipeline ids */
182 	uint32_t ppl_id[];
183 } __attribute__((packed, aligned(4)));
184 
185 struct ipc4_pipeline_set_state {
186 	union {
187 		uint32_t dat;
188 
189 		struct {
190 			/**< new state, one of enum ipc4_pipeline_state */
191 			uint32_t ppl_state  : 16;
192 			/**< pipeline instance id (ignored if multi_ppl =1) */
193 			uint32_t ppl_id     : 8;
194 			/**< Global::SET_PIPELINE_STATE */
195 			uint32_t type       : 5;
196 			/**< Msg::MSG_REQUEST */
197 			uint32_t rsp        : 1;
198 
199 			/**< Msg::FW_GEN_MSG */
200 			uint32_t msg_tgt    : 1;
201 			uint32_t _reserved_0: 1;
202 		} r;
203 	} primary;
204 
205 	union{
206 		uint32_t dat;
207 
208 		struct {
209 			/**< = 1 if there are more pipeline ids in payload */
210 			uint32_t multi_ppl  : 1;
211 			/**< = 1 if FW should sync state change across multiple ppls */
212 			uint32_t sync_stop_start : 1;
213 			uint32_t rsvd1      : 28;
214 			uint32_t _reserved_2: 2;
215 		} r;
216 	} extension;
217 
218 	/* multiple pipeline states */
219 	struct ipc4_pipeline_set_state_data s_data;
220 } __attribute__((packed, aligned(4)));
221 
222 /**< Reply to Set Pipeline State */
223 /*!
224  * In case of error, there is failed pipeline id reported back.
225  *
226   \remark hide_methods
227 */
228 struct ipc4_pipeline_set_state_reply {
229 	union {
230 		uint32_t dat;
231 
232 		struct {
233 			/**< status */
234 			uint32_t status     : IPC4_IXC_STATUS_BITS;
235 			/**< Global::SET_PIPELINE_STATE */
236 			uint32_t type       : 5;
237 			/**< Msg::MSG_REPLY */
238 			uint32_t rsp        : 1;
239 			/**< Msg::FW_GEN_MSG */
240 			uint32_t msg_tgt    : 1;
241 			uint32_t _reserved_0: 1;
242 		} r;
243 	} primary;
244 
245 	union{
246 		uint32_t dat;
247 
248 		struct {
249 			/**< id of failed pipeline on error */
250 			uint32_t ppl_id     : 30;
251 			uint32_t _reserved_2: 2;
252 		} r;
253 	} extension;
254 } __attribute__((packed, aligned(4)));
255 
256 /**< This IPC message is sent to the FW in order to retrieve a pipeline state. */
257 /*! \remark hide_methods */
258 struct ipc4_pipeline_get_state {
259 	union {
260 		uint32_t dat;
261 
262 		struct {
263 			/**< pipeline id */
264 			uint32_t ppl_id     : 8;
265 			uint32_t rsvd       : 16;
266 			/**< Global::GET_PIPELINE_STATE */
267 			uint32_t type       : 5;
268 			/**< Msg::MSG_REQUEST */
269 			uint32_t rsp        : 1;
270 			/**< Msg::FW_GEN_MSG */
271 			uint32_t msg_tgt    : 1;
272 			uint32_t _reserved_0: 1;
273 			} r;
274 	} primary;
275 
276 	union{
277 		uint32_t dat;
278 
279 		struct {
280 			uint32_t rsvd1      : 30;
281 			uint32_t _reserved_2: 2;
282 		} r;
283 	} extension;
284 } __attribute__((packed, aligned(4)));
285 
286 /**< Sent by the FW in response to GetPipelineState. */
287 /*! \remark hide_methods */
288 struct ipc4_pipeline_get_state_reply {
289 	union {
290 		uint32_t dat;
291 
292 		struct {
293 			/**< status */
294 			uint32_t status      :IPC4_IXC_STATUS_BITS;
295 			/**< Global::GET_PIPELINE_STATE */
296 			uint32_t type       : 5;
297 			/**< Msg::MSG_REPLY */
298 			uint32_t rsp        : 1;
299 			/**< Msg::FW_GEN_MSG */
300 			uint32_t msg_tgt    : 1;
301 			uint32_t _reserved_0: 1;
302 		} r;
303 	} primary;
304 
305 	union{
306 		uint32_t dat;
307 
308 		struct {
309 			/**< one of PipelineState */
310 			uint32_t state      : 5;
311 			uint32_t rsvd1      : 25;
312 			uint32_t _reserved_2: 2;
313 		} r;
314 	} extension;
315 } __attribute__((packed, aligned(4)));
316 
317 /*!
318  * The size is expressed in number of pages. It is a total number of memory pages
319  * allocated for pipeline memory buffer and all separately allocated child
320  * module instances.
321  *
322  *  \remark hide_methods
323  */
324 struct ipc4_pipeline_get_context_size {
325 	union {
326 		uint32_t dat;
327 
328 		struct {
329 			uint32_t rsvd0          : 16;
330 			/**< pipeline id */
331 			uint32_t instance_id    : 8;
332 			/**< Global::GET_PIPELINE_CONTEXT_SIZE */
333 			uint32_t type           : 5;
334 			/**< Msg::MSG_REQUEST */
335 			uint32_t rsp            : 1;
336 			/**< Msg::FW_GEN_MSG */
337 			uint32_t msg_tgt        : 1;
338 			uint32_t _reserved_0    : 1;
339 		} r;
340 	} primary;
341 
342 	union{
343 		uint32_t dat;
344 
345 		struct {
346 			uint32_t rsvd1          : 30;
347 			uint32_t _reserved_2    : 2;
348 		} r;
349 	} extension;
350 } __attribute__((packed, aligned(4)));
351 
352 /**< Reply to Get Pipeline Context Size. */
353 /*! \remark hide_methods */
354 struct ipc4_pipeline_get_context_size_reply {
355 	union {
356 		uint32_t dat;
357 
358 		struct {
359 			/**< status */
360 			uint32_t status :IPC4_IXC_STATUS_BITS;
361 			/**< Global::GET_PIPELINE_CONTEXT_SIZE */
362 			uint32_t type       : 5;
363 			/**< Msg::MSG_REPLY */
364 			uint32_t rsp        : 1;
365 			/**< Msg::FW_GEN_MSG */
366 			uint32_t msg_tgt    : 1;
367 			uint32_t _reserved_0: 1;
368 		} r;
369 	} primary;
370 
371 	union{
372 		uint32_t dat;
373 
374 		struct {
375 			/**< size of pipeline context (in number of pages) */
376 			uint32_t ctx_size   : 16;
377 			uint32_t rsvd1      : 14;
378 			uint32_t _reserved_2: 2;
379 		} r;
380 	} extension;
381 } __attribute__((packed, aligned(4)));
382 
383 struct ipc4_chain_dma {
384 	union {
385 		uint32_t dat;
386 
387 		struct {
388 		uint32_t host_dma_id		: 5;
389 		uint32_t rsvd4		: 3;
390 		uint32_t link_dma_id		: 5;
391 		uint32_t rsvd3		: 3;
392 		/* allocate buffer specified by FIFO size */
393 		uint32_t allocate		: 1;
394 		uint32_t enable			: 1;
395 		/* controls SCS bit in both Host and Link gateway */
396 		uint32_t scs		: 1;
397 		uint32_t rsvd2		: 5;
398 		/* Global::CHAIN_DMA */
399 		uint32_t type		: 5;
400 		/* Msg::MSG_REQUEST */
401 		uint32_t rsp		: 1;
402 		/* Msg::FW_GEN_MSG */
403 		uint32_t msg_tgt		: 1;
404 		uint32_t _reserved_0		: 1;
405 		} r;
406 	} primary;
407 
408 	union {
409 		uint32_t dat;
410 
411 		struct {
412 			/* size of FIFO (bytes) */
413 			uint32_t fifo_size		: 24;
414 			uint32_t rsvd1		: 6;
415 			uint32_t _reserved_2		: 2;
416 		} r;
417 	} extension;
418 } __attribute__((packed, aligned(4)));
419 
420 #endif
421