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/copier.h 20 * \brief IPC4 copier definitions. 21 * NOTE: This ABI uses bit fields and is non portable. 22 */ 23 24 #ifndef __SOF_IPC4_COPIER_H__ 25 #define __SOF_IPC4_COPIER_H__ 26 27 #include <stdint.h> 28 #include <ipc4/base-config.h> 29 #include <ipc4/gateway.h> 30 31 #include <sof/compiler_attributes.h> 32 #include <sof/audio/buffer.h> 33 #include <sof/audio/pcm_converter.h> 34 35 #define COPIER_GENERIC 36 37 #if defined(__XCC__) 38 #include <xtensa/config/core-isa.h> 39 40 #if XCHAL_HAVE_HIFI3 || XCHAL_HAVE_HIFI4 41 #undef COPIER_GENERIC 42 #endif 43 44 #endif 45 46 static const uint32_t INVALID_QUEUE_ID = 0xFFFFFFFF; 47 48 /* copier Module Configuration & Interface 49 * UUID: 9BA00C83-CA12-4A83-943C-1FA2E82F9DDA 50 * 51 * Copier may be instantiated and bound in one of following configurations: 52 * 53 * - case 1: 54 * digraph Module_Copier_Module { 55 * InputGateway 56 * InputGateway -> Copier 57 * 58 * DestinationMod 59 * Copier -> DestinationMod 60 * } 61 * 62 * digraph Module_Copier_Gateways { 63 * SourceMod 64 * SourceMod -> Copier 65 * 66 * OutputGateway 67 * Copier -> OutputGateway 68 * } 69 * - case 3: 70 * digraph Module_Copier_Module { 71 * SourceMod 72 * SourceMod -> Copier 73 * 74 * DestinationMod 75 * Copier -> DestinationMod 76 * } 77 * 78 * - case 4: 79 * digraph Module_Copier_Module { 80 * SourceMod 81 * 82 * SourceMod -> Copier 83 * 84 * DestinationMod 85 * OutputGateway 86 * 87 * Copier -> OutputGateway 88 * Copier -> DestinationMod 89 * } 90 * 91 * In cases 1 and 2, the initial configuration must include Gateway Configuration 92 * data along with valid Node ID of the gateway to be connected on either 93 * Copier's end. 94 * 95 * Gateway can only be connected to input pin "0" or output pin "0". 96 * 97 * Initial configuration data allows setup audio format of main Copier's pins, 98 * input pin "0" and output pin "0" and prepare PCM conversion routine if any is 99 * required. However Copier supports up to #COPIER_MODULE_OUTPUT_PINS_COUNT 100 * output pins. Before any additional output pin is used in binding operation, 101 * the host driver has to send run-time parameter to setup sink formwat 102 * (#COPIER_MODULE_CFG_PARAM_SET_SINK_FORMAT) first to setup a PCM conversion 103 * routine if any is required. 104 */ 105 106 #define IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT 4 107 108 /* 109 * Gateway can only be connected to input pin "0" or output pin "0". 110 */ 111 #define IPC4_COPIER_GATEWAY_PIN 0 112 113 enum ipc4_copier_features { 114 /* ff FAST_MODE bit is set in CopierModuleCfg::copier_feature_mask then 115 * copier is able to transfer more than ibs. This bit shall be set only if 116 * all sinks are connected to data processing queue. 117 */ 118 IPC4_COPIER_FAST_MODE = 0 119 }; 120 121 struct ipc4_copier_gateway_cfg { 122 /* ID of Gateway Node. If node_id is valid, i.e. != -1, copier instance is connected to the 123 * specified gateway using either input pin 0 or output pin 0 depending on 124 * the node's direction, otherwise the data in this structure is ignored. 125 */ 126 union ipc4_connector_node_id node_id; 127 /* preferred Gateway DMA buffer size (in bytes). 128 * FW attempts to allocate DMA buffer according to this value, however it may 129 * fall back to IBS/OBS * 2 in case there is no memory available for deeper 130 * buffering. 131 */ 132 uint32_t dma_buffer_size; 133 /* length of gateway node configuration blob specified in #config_data. 134 * Length must be specified in number of dwords. 135 * Refer to the specific gateway documentation for details on the node 136 * configuration blob requirements. 137 */ 138 uint32_t config_length; 139 /* gateway node configuration blob */ 140 uint32_t config_data[1]; 141 } __attribute__((packed, aligned(4))); 142 143 struct ipc4_copier_module_cfg { 144 struct ipc4_base_module_cfg base; 145 146 /* audio format for output pin 0 */ 147 struct ipc4_audio_format out_fmt; 148 uint32_t copier_feature_mask; 149 struct ipc4_copier_gateway_cfg gtw_cfg; 150 } __attribute__((packed, aligned(4))); 151 152 enum ipc4_copier_module_config_params { 153 /* Use LARGE_CONFIG_SET to initialize timestamp event. Ipc mailbox must 154 * contain properly built CopierConfigTimestampInitData struct. 155 */ 156 IPC4_COPIER_MODULE_CFG_PARAM_TIMESTAMP_INIT = 1, 157 /* Use LARGE_CONFIG_SET to initialize copier sink. Ipc mailbox must contain 158 * properly built CopierConfigSetSinkFormat struct. 159 */ 160 IPC4_COPIER_MODULE_CFG_PARAM_SET_SINK_FORMAT = 2, 161 /* Use LARGE_CONFIG_SET to initialize and enable on Copier data segment 162 * event. Ipc mailbox must contain properly built DataSegmentEnabled struct. 163 */ 164 IPC4_COPIER_MODULE_CFG_PARAM_DATA_SEGMENT_ENABLED = 3, 165 /* Use LARGE_CONFIG_GET to retrieve Linear Link Position (LLP) value for non 166 * HD-A gateways. 167 */ 168 IPC4_COPIER_MODULE_CFG_PARAM_LLP_READING = 4, 169 /* Use LARGE_CONFIG_GET to retrieve Linear Link Position (LLP) value for non 170 * HD-A gateways and corresponding total processed data 171 * Sample code to retrieve LlpReadingExtended: 172 * Message::LargeConfigOp message(true, COPIER_MODULE_ID, KPB_INSTANCE_ID); 173 * message.GetBits().large_param_id = COPIER_MODULE_CFG_PARAM_LLP_READING_EXTENDED; 174 * message.GetBits().init_block = true; 175 * message.GetBits().final_block = true; 176 * message.GetBits().data_off_size = IPC_OUTPUT_MAILBOX; 177 * LlpReadingExtended* output_mailbox = NULL; 178 * send_ipc(message, input_mailbox, (uint8_t**)&output_mailbox); 179 */ 180 IPC4_COPIER_MODULE_CFG_PARAM_LLP_READING_EXTENDED = 5, 181 /* Use LARGE_CONFIG_SET to setup attenuation on output pins. Data is just 182 * uint32_t. Config is only allowed when output pin is set up for 32bit and 183 * source is connected to Gateway 184 */ 185 IPC4_COPIER_MODULE_CFG_ATTENUATION = 6 186 }; 187 188 struct ipc4_copier_config_timestamp_init_data { 189 /* Contains low-level configuration for timestamp init. 190 * Passed-through directly into ifc _LOCAL_TS_Control Register of 191 * corresponding HW i/f from DSP Timestamping Registers. 192 */ 193 uint32_t tsctrl_reg; 194 } __attribute__((packed, aligned(4))); 195 196 struct ipc4_copier_config_set_sink_format { 197 uint32_t sink_id; 198 /* Input format used by the source. Must be the same as present 199 * if already initialized. 200 */ 201 struct ipc4_audio_format source_fmt; 202 /* Output format used by the sink */ 203 struct ipc4_audio_format sink_fmt; 204 } __attribute__((packed, aligned(4))); 205 206 #define IPC4_COPIER_DATA_SEGMENT_DISABLE (0 << 0) 207 #define IPC4_COPIER_DATA_SEGMENT_ENABLE (1 << 0) 208 #define IPC4_COPIER_DATA_SEGMENT_RESTART (1 << 1) 209 210 struct ipc4_data_segment_enabled { 211 /* Gateway node id */ 212 uint32_t node_id; 213 /* Indicates whether notification should be enabled (!=0) or disabled (=0). 214 * Carries additional information. If bit 1 is set DS will be restarted 215 * immediately. 216 * Use only as logic or of COPIER_DATA_SEGMENT_*. 217 * To disable: 218 * COPIER_DATA_SEGMENT_DISABLE 219 * To enable, but finish previous: 220 * COPIER_DATA_SEGMENT_ENABLE 221 * To enable, and apply right away: 222 * COPIER_DATA_SEGMENT_ENABLE | COPIER_DATA_SEGMENT_RESTART 223 */ 224 uint32_t enabled; 225 /* Data segment size (in bytes) */ 226 uint32_t data_seg_size; 227 } __attribute__((packed, aligned(4))); 228 229 /* One of copy_single_channel_cXX() to mux/demux channels into/from copier multi_endpoint_buffer */ 230 typedef void (* channel_copy_func)(struct audio_stream __sparse_cache *dst, 231 int dst_channel, 232 const struct audio_stream __sparse_cache *src, 233 int src_channel, int frame_count); 234 235 struct copier_data { 236 /* 237 * struct ipc4_copier_module_cfg actually has variable size, but we 238 * don't need the variable size array at the end, we won't be copying it 239 * from the IPC data. 240 */ 241 struct ipc4_copier_module_cfg config; 242 struct comp_dev *endpoint[IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT]; 243 struct comp_buffer *endpoint_buffer[IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT]; 244 uint32_t endpoint_num; 245 246 /* buffer to mux/demux data from/to multiple endpoint buffers for ALH multi-gateway case */ 247 struct comp_buffer *multi_endpoint_buffer; 248 channel_copy_func copy_single_channel; 249 250 bool bsource_buffer; 251 252 int direction; 253 /* sample data >> attenuation in range of [1 - 31] */ 254 uint32_t attenuation; 255 256 /* pipeline register offset in memory windows 0 */ 257 uint32_t pipeline_reg_offset; 258 uint64_t host_position; 259 260 struct ipc4_audio_format out_fmt[IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT]; 261 pcm_converter_func converter[IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT]; 262 uint64_t input_total_data_processed; 263 uint64_t output_total_data_processed; 264 struct host_data *hd; 265 bool ipc_gtw; 266 }; 267 268 int apply_attenuation(struct comp_dev *dev, struct copier_data *cd, 269 struct comp_buffer __sparse_cache *sink, int frame); 270 271 #endif 272