/* SPDX-License-Identifier: BSD-3-Clause * * Copyright(c) 2021 Intel Corporation. All rights reserved. */ /* * This file contains structures that are exact copies of an existing ABI used * by IOT middleware. They are Intel specific and will be used by one middleware. * * Some of the structures may contain programming implementations that makes them * unsuitable for generic use and general usage. * * This code is mostly copied "as-is" from existing C++ interface files hence the use of * different style in places. The intention is to keep the interface as close as possible to * original so it's easier to track changes with IPC host code. */ /** * \file include/ipc4/pipeline.h * \brief IPC4 pipeline definitions * NOTE: This ABI uses bit fields and is non portable. */ #ifndef __SOF_IPC4_PIPELINE_H__ #define __SOF_IPC4_PIPELINE_H__ #include #include /**< Pipeline priority */ enum ipc4_pipeline_priority { /**< Priority 0 (run first) */ SOF_IPC4_PIPELINE_PRIORITY_0 = 0, /**< Priority 1 */ SOF_IPC4_PIPELINE_PRIORITY_1, /**< Priority 2 */ SOF_IPC4_PIPELINE_PRIORITY_2, /**< Priority 3 */ SOF_IPC4_PIPELINE_PRIORITY_3, /**< Priority 4 */ SOF_IPC4_PIPELINE_PRIORITY_4, /**< Priority 5 */ SOF_IPC4_PIPELINE_PRIORITY_5, /**< Priority 6 */ SOF_IPC4_PIPELINE_PRIORITY_6, /**< Priority 7 */ SOF_IPC4_PIPELINE_PRIORITY_7, /**< Max (and lowest) priority */ SOF_IPC4_MAX_PIPELINE_PRIORITY = SOF_IPC4_PIPELINE_PRIORITY_7 }; /**< Pipeline State */ enum ipc4_pipeline_state { /**< Invalid value */ SOF_IPC4_PIPELINE_STATE_INVALID = 0, /**< Created but initialization incomplete */ SOF_IPC4_PIPELINE_STATE_UNINITIALIZED = 1, /**< Resets pipeline */ SOF_IPC4_PIPELINE_STATE_RESET = 2, /**< Pauses pipeline */ SOF_IPC4_PIPELINE_STATE_PAUSED = 3, /**< Starts pipeline */ SOF_IPC4_PIPELINE_STATE_RUNNING = 4, /**< Marks pipeline as expecting End Of Stream */ SOF_IPC4_PIPELINE_STATE_EOS = 5, /**< Stopped on error */ SOF_IPC4_PIPELINE_STATE_ERROR_STOP, /**< Saved to the host memory */ SOF_IPC4_PIPELINE_STATE_SAVED }; /*! * lp - indicates whether the pipeline should be kept on running in low power * mode. On BXT the driver should set this flag to 1 for WoV pipeline. * * \remark hide_methods */ struct ipc4_pipeline_create { union { uint32_t dat; struct { /**< # pages for pipeline */ uint32_t ppl_mem_size : 11; /**< priority - uses enum ipc4_pipeline_priority */ uint32_t ppl_priority : 5; /**< pipeline id */ uint32_t instance_id : 8; /**< Global::CREATE_PIPELINE */ uint32_t type : 5; /**< Msg::MSG_REQUEST */ uint32_t rsp : 1; /**< Msg::FW_GEN_MSG */ uint32_t msg_tgt : 1; uint32_t _reserved_0 : 1; } r; } primary; union{ uint32_t dat; struct { /**< 1 - is low power */ uint32_t lp : 1; uint32_t rsvd1 : 3; uint32_t attributes : 16; uint32_t core_id : 4; uint32_t rsvd2 : 6; uint32_t _reserved_2 : 2; } r; } extension; } __attribute__((packed, aligned(4))); /*! * SW Driver sends this IPC message to delete a pipeline from ADSP memory. * * All module instances and tasks that are associated with the pipeline are * deleted too. * * There must be no existing binding from any pipeline's module instance * to another pipeline to complete the command successfully. * * \remark hide_methods */ struct ipc4_pipeline_delete { union { uint32_t dat; struct { uint32_t rsvd0 : 16; /**< Ppl instance id */ uint32_t instance_id : 8; /**< Global::DELETE_PIPELINE */ uint32_t type : 5; /**< Msg::MSG_REQUEST */ uint32_t rsp : 1; /**< Msg::FW_GEN_MSG */ uint32_t msg_tgt : 1; uint32_t _reserved_0 : 1; } r; } primary; union{ uint32_t dat; struct { uint32_t rsvd1 : 30; uint32_t _reserved_2 : 2; } r; } extension; } __attribute__((packed, aligned(4))); /*! * Host SW sends this message to set a pipeline to the specified state. * * If there are multiple pipelines, from FW input to FW output, connected * in a data processing stream, the driver should start them in reverse order, * beginning with pipeline connected to the output gateway, in order to avoid * overruns (FW protects the output gateway against underruns in this scenario). * * If driver starts multiple pipelines using a single Set Pipeline State * command, it should take care of the pipeline ID order in the command payload * to follow the above rule. * * sync_stop_start indicates whether all specified pipelines' gateways should * be started with a minimal delay possible. If this flag is set to 0 while * multiple pipelines are specified, the target pipelines' state is adjusted * pipeline by pipeline meaning that internal propagation to all child modules * may take more time between reaching state of attached gateways. Output and * input gateways are grouped separately, and started/stopped separately. * * NOTE: Task Creation/Registration is part of the first state transition. * There is no other dedicated call for this. * * \remark hide_methods */ struct ipc4_pipeline_set_state_data { /**< Number of items in ppl_id[] */ uint32_t pipelines_count; /**< Pipeline ids */ uint32_t ppl_id[]; } __attribute__((packed, aligned(4))); struct ipc4_pipeline_set_state { union { uint32_t dat; struct { /**< new state, one of enum ipc4_pipeline_state */ uint32_t ppl_state : 16; /**< pipeline instance id (ignored if multi_ppl =1) */ uint32_t ppl_id : 8; /**< Global::SET_PIPELINE_STATE */ uint32_t type : 5; /**< Msg::MSG_REQUEST */ uint32_t rsp : 1; /**< Msg::FW_GEN_MSG */ uint32_t msg_tgt : 1; uint32_t _reserved_0: 1; } r; } primary; union{ uint32_t dat; struct { /**< = 1 if there are more pipeline ids in payload */ uint32_t multi_ppl : 1; /**< = 1 if FW should sync state change across multiple ppls */ uint32_t sync_stop_start : 1; uint32_t rsvd1 : 28; uint32_t _reserved_2: 2; } r; } extension; /* multiple pipeline states */ struct ipc4_pipeline_set_state_data s_data; } __attribute__((packed, aligned(4))); /**< Reply to Set Pipeline State */ /*! * In case of error, there is failed pipeline id reported back. * \remark hide_methods */ struct ipc4_pipeline_set_state_reply { union { uint32_t dat; struct { /**< status */ uint32_t status : IPC4_IXC_STATUS_BITS; /**< Global::SET_PIPELINE_STATE */ uint32_t type : 5; /**< Msg::MSG_REPLY */ uint32_t rsp : 1; /**< Msg::FW_GEN_MSG */ uint32_t msg_tgt : 1; uint32_t _reserved_0: 1; } r; } primary; union{ uint32_t dat; struct { /**< id of failed pipeline on error */ uint32_t ppl_id : 30; uint32_t _reserved_2: 2; } r; } extension; } __attribute__((packed, aligned(4))); /**< This IPC message is sent to the FW in order to retrieve a pipeline state. */ /*! \remark hide_methods */ struct ipc4_pipeline_get_state { union { uint32_t dat; struct { /**< pipeline id */ uint32_t ppl_id : 8; uint32_t rsvd : 16; /**< Global::GET_PIPELINE_STATE */ uint32_t type : 5; /**< Msg::MSG_REQUEST */ uint32_t rsp : 1; /**< Msg::FW_GEN_MSG */ uint32_t msg_tgt : 1; uint32_t _reserved_0: 1; } r; } primary; union{ uint32_t dat; struct { uint32_t rsvd1 : 30; uint32_t _reserved_2: 2; } r; } extension; } __attribute__((packed, aligned(4))); /**< Sent by the FW in response to GetPipelineState. */ /*! \remark hide_methods */ struct ipc4_pipeline_get_state_reply { union { uint32_t dat; struct { /**< status */ uint32_t status :IPC4_IXC_STATUS_BITS; /**< Global::GET_PIPELINE_STATE */ uint32_t type : 5; /**< Msg::MSG_REPLY */ uint32_t rsp : 1; /**< Msg::FW_GEN_MSG */ uint32_t msg_tgt : 1; uint32_t _reserved_0: 1; } r; } primary; union{ uint32_t dat; struct { /**< one of PipelineState */ uint32_t state : 5; uint32_t rsvd1 : 25; uint32_t _reserved_2: 2; } r; } extension; } __attribute__((packed, aligned(4))); /*! * The size is expressed in number of pages. It is a total number of memory pages * allocated for pipeline memory buffer and all separately allocated child * module instances. * * \remark hide_methods */ struct ipc4_pipeline_get_context_size { union { uint32_t dat; struct { uint32_t rsvd0 : 16; /**< pipeline id */ uint32_t instance_id : 8; /**< Global::GET_PIPELINE_CONTEXT_SIZE */ uint32_t type : 5; /**< Msg::MSG_REQUEST */ uint32_t rsp : 1; /**< Msg::FW_GEN_MSG */ uint32_t msg_tgt : 1; uint32_t _reserved_0 : 1; } r; } primary; union{ uint32_t dat; struct { uint32_t rsvd1 : 30; uint32_t _reserved_2 : 2; } r; } extension; } __attribute__((packed, aligned(4))); /**< Reply to Get Pipeline Context Size. */ /*! \remark hide_methods */ struct ipc4_pipeline_get_context_size_reply { union { uint32_t dat; struct { /**< status */ uint32_t status :IPC4_IXC_STATUS_BITS; /**< Global::GET_PIPELINE_CONTEXT_SIZE */ uint32_t type : 5; /**< Msg::MSG_REPLY */ uint32_t rsp : 1; /**< Msg::FW_GEN_MSG */ uint32_t msg_tgt : 1; uint32_t _reserved_0: 1; } r; } primary; union{ uint32_t dat; struct { /**< size of pipeline context (in number of pages) */ uint32_t ctx_size : 16; uint32_t rsvd1 : 14; uint32_t _reserved_2: 2; } r; } extension; } __attribute__((packed, aligned(4))); struct ipc4_chain_dma { union { uint32_t dat; struct { uint32_t host_dma_id : 5; uint32_t rsvd4 : 3; uint32_t link_dma_id : 5; uint32_t rsvd3 : 3; /* allocate buffer specified by FIFO size */ uint32_t allocate : 1; uint32_t enable : 1; /* controls SCS bit in both Host and Link gateway */ uint32_t scs : 1; uint32_t rsvd2 : 5; /* Global::CHAIN_DMA */ uint32_t type : 5; /* Msg::MSG_REQUEST */ uint32_t rsp : 1; /* Msg::FW_GEN_MSG */ uint32_t msg_tgt : 1; uint32_t _reserved_0 : 1; } r; } primary; union { uint32_t dat; struct { /* size of FIFO (bytes) */ uint32_t fifo_size : 24; uint32_t rsvd1 : 6; uint32_t _reserved_2 : 2; } r; } extension; } __attribute__((packed, aligned(4))); #endif