1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2021 Intel Corporation. All rights reserved. 4 */ 5 6 /* 7 * Some of the structures may contain programming implementations that makes them 8 * unsuitable for generic use and general usage. 9 * 10 * This code is mostly copied "as-is" from existing C++ interface files hence the use of 11 * different style in places. The intention is to keep the interface as close as possible to 12 * original so it's easier to track changes with IPC host code. 13 */ 14 15 /** 16 * \file include/ipc4/module.h 17 * \brief IPC4 module definitions 18 * NOTE: This ABI uses bit fields and is non portable. 19 */ 20 21 #ifndef __IPC4_MODULE_H__ 22 #define __IPC4_MODULE_H__ 23 24 #include <ipc4/error_status.h> 25 26 #include <stdint.h> 27 28 /* TODO: revisit it. Now it aligns with audio sdk 29 * and we will update this value and sdk when more 30 * libraries are supported 31 */ 32 #define IPC4_MAX_SUPPORTED_LIBRARIES 16 33 34 #define IPC4_MAX_MODULE_COUNT 128 35 36 #define SOF_IPC4_DST_QUEUE_ID_BITFIELD_SIZE 3 37 #define SOF_IPC4_SRC_QUEUE_ID_BITFIELD_SIZE 3 38 39 enum sof_ipc4_module_type { 40 SOF_IPC4_MOD_INIT_INSTANCE = 0, 41 SOF_IPC4_MOD_CONFIG_GET = 1, 42 SOF_IPC4_MOD_CONFIG_SET = 2, 43 SOF_IPC4_MOD_LARGE_CONFIG_GET = 3, 44 SOF_IPC4_MOD_LARGE_CONFIG_SET = 4, 45 SOF_IPC4_MOD_BIND = 5, 46 SOF_IPC4_MOD_UNBIND = 6, 47 SOF_IPC4_MOD_SET_DX = 7, 48 SOF_IPC4_MOD_SET_D0IX = 8, 49 SOF_IPC4_MOD_ENTER_MODULE_RESTORE = 9, 50 SOF_IPC4_MOD_EXIT_MODULE_RESTORE = 10, 51 SOF_IPC4_MOD_DELETE_INSTANCE = 11, 52 }; 53 54 /* 55 * Host Driver sends this message to create a new module instance. 56 */ 57 struct ipc4_module_init_ext_init { 58 /**< if it is set to 1, proc_domain should be ignored and processing */ 59 /* domain is RTOS scheduling */ 60 uint32_t rtos_domain : 1; 61 /**< Indicates that GNA is used by a module and additional information */ 62 /* (gna_config) is passed after ExtendedData. */ 63 uint32_t gna_used : 1; 64 uint32_t rsvd_0 : 30; 65 uint32_t rsvd_1[2]; 66 } __attribute__((packed, aligned(4))); 67 68 struct ipc4_module_init_ext_data { 69 struct ipc4_module_init_ext_init extended_init; 70 71 /**< Data (actual size set to param_block_size) */ 72 uint32_t param_data[]; 73 } __attribute__((packed, aligned(4))); 74 75 struct ipc4_module_init_gna_config { 76 /**< Number of GNA cycles required to process one input frame. */ 77 /* This information is used by DP scheduler to correctly schedule 78 * a DP module. 79 */ 80 uint32_t gna_cpc; 81 uint32_t rsvd; 82 } __attribute__((packed, aligned(4))); 83 84 struct ipc4_module_init_data { 85 /**< Data (actual size set to param_block_size) */ 86 uint32_t param_data[0]; 87 } __attribute__((packed, aligned(4))); 88 89 /*! 90 Created instance is a child element of pipeline identified by the ppl_id 91 specified by the driver. 92 93 The module_id should be set to an index of the module entry in the FW Image 94 Manifest. 95 96 The instance_id assigned by the driver should be in the 97 0..ModuleEntry.max_instance_count range defined in the FW Image Manifest. 98 99 Initial configuration of the module instance is provided by the driver in 100 the param_data array. Size of the array is specified in param_block_size 101 field of the message header. 102 103 Refer to Module Configuration section of FW I/F Specification for details on 104 module specific initial configuration parameters. 105 106 \remark hide_methods 107 */ 108 struct ipc4_module_init_instance { 109 110 union { 111 uint32_t dat; 112 113 struct { 114 /**< module id */ 115 uint32_t module_id : 16; 116 /**< instance id */ 117 uint32_t instance_id : 8; 118 /**< ModuleMsg::INIT_INSTANCE */ 119 uint32_t type : 5; 120 /**< Msg::MSG_REQUEST */ 121 uint32_t rsp : 1; 122 /**< Msg::MODULE_MSG */ 123 uint32_t msg_tgt : 1; 124 uint32_t _reserved_0 : 1; 125 } r; 126 } primary; 127 128 union { 129 uint32_t dat; 130 131 struct { 132 /**< Size of Data::param_data[] (in dwords) */ 133 uint32_t param_block_size : 16; 134 /**< ID of module instance's parent pipeline */ 135 uint32_t ppl_instance_id : 8; 136 /**< ID of core that instance will run on */ 137 uint32_t core_id : 4; 138 /**< Processing domain, 0-LL, 1-DP */ 139 uint32_t proc_domain : 1; 140 /* reserved in cAVS */ 141 uint32_t extended_init : 1; 142 uint32_t _hw_reserved_2 : 2; 143 } r; 144 } extension; 145 /* 146 * The following objects are optional and follow this structure in this 147 * order provided the respective object bit is set in preceding object. 148 * 149 * struct ipc4_module_init_ext_init ext_init; 150 * struct ipc4_module_init_ext_data ext_data; 151 * struct ipc4_module_init_gna_config gna_config; 152 * struct ipc4_module_init_data init_data; 153 */ 154 } __attribute__((packed, aligned(4))); 155 156 /*! 157 SW Driver sends Bind IPC message to connect two module instances together 158 creating data processing path between them. 159 160 Unbind IPC message is sent to destroy a connection between two module instances 161 (belonging to different pipelines) previously created with Bind call. 162 163 NOTE: when both module instances are parts of the same pipeline Unbind IPC would 164 be ignored by FW since FW does not support changing internal topology of pipeline 165 during run-time. The only way to change pipeline topology is to delete the whole 166 pipeline and create it in modified form. 167 168 \remark hide_methods 169 */ 170 struct ipc4_module_bind_unbind { 171 union { 172 uint32_t dat; 173 174 struct { 175 /**< module id */ 176 uint32_t module_id : 16; 177 /**< instance id */ 178 uint32_t instance_id : 8; 179 /**< ModuleMsg::BIND / UNBIND. */ 180 uint32_t type : 5; 181 /**< Msg::MSG_REQUEST */ 182 uint32_t rsp : 1; 183 /**< Msg::MODULE_MSG */ 184 uint32_t msg_tgt : 1; 185 uint32_t _reserved_0 : 1; 186 } r; 187 } primary; 188 189 union { 190 uint32_t dat; 191 192 struct { 193 /**< destination module id */ 194 uint32_t dst_module_id : 16; 195 /**< destination instance id */ 196 uint32_t dst_instance_id : 8; 197 /**< destination queue (pin) id */ 198 uint32_t dst_queue : SOF_IPC4_DST_QUEUE_ID_BITFIELD_SIZE; 199 /**< source queue (pin) id */ 200 uint32_t src_queue : SOF_IPC4_SRC_QUEUE_ID_BITFIELD_SIZE; 201 uint32_t _reserved_2 : 2; 202 } r; 203 } extension; 204 } __attribute__((packed, aligned(4))); 205 206 struct ipc4_module_large_config { 207 union { 208 uint32_t dat; 209 210 struct { 211 /**< module id */ 212 uint32_t module_id : 16; 213 /**< instance id */ 214 uint32_t instance_id : 8; 215 /**< ModuleMsg::LARGE_CONFIG_GET / LARGE_CONFIG_SET */ 216 uint32_t type : 5; 217 /**< Msg::MSG_REQUEST or Msg::MSG_REPLY */ 218 uint32_t rsp : 1; 219 /**< Msg::MODULE_MSG or Msg::FW_GEN_MSG */ 220 uint32_t msg_tgt : 1; 221 uint32_t _reserved_0 : 1; 222 } r; 223 } primary; 224 225 union { 226 uint32_t dat; 227 228 struct { 229 /**< data size for single block, offset for multiple block case */ 230 uint32_t data_off_size : 20; 231 /**< param type : VENDOR_CONFIG_PARAM / GENERIC_CONFIG_PARAM */ 232 uint32_t large_param_id : 8; 233 /**< 1 if final block */ 234 uint32_t final_block : 1; 235 /**< 1 if init block */ 236 uint32_t init_block : 1; 237 uint32_t _reserved_2 : 2; 238 } r; 239 } extension; 240 } __attribute__((packed, aligned(4))); 241 242 struct ipc4_module_large_config_reply { 243 union { 244 uint32_t dat; 245 246 struct { 247 uint32_t status :IPC4_IXC_STATUS_BITS; 248 /**< ModuleMsg::LARGE_CONFIG_GET / LARGE_CONFIG_SET */ 249 uint32_t type : 5; 250 /**< Msg::MSG_REQUEST */ 251 uint32_t rsp : 1; 252 /**< Msg::MODULE_MSG */ 253 uint32_t msg_tgt : 1; 254 uint32_t _reserved_0 : 1; 255 } r; 256 } primary; 257 258 union { 259 uint32_t dat; 260 261 struct { 262 /**< data size/offset */ 263 uint32_t data_off_size : 20; 264 /**< param type : VENDOR_CONFIG_PARAM / GENERIC_CONFIG_PARAM */ 265 uint32_t large_param_id : 8; 266 /**< 1 if final block */ 267 uint32_t final_block : 1; 268 /**< 1 if first block */ 269 uint32_t init_block : 1; 270 uint32_t _reserved_2 : 2; 271 } r; 272 } extension; 273 } __attribute__((packed, aligned(4))); 274 275 struct ipc4_module_delete_instance { 276 union { 277 uint32_t dat; 278 279 struct { 280 uint32_t module_id : 16; 281 uint32_t instance_id : 8; 282 /**< ModuleMsg::DELETE_INSTANCE */ 283 uint32_t type : 5; 284 /**< Msg::MSG_REQUEST */ 285 uint32_t rsp : 1; 286 /**< Msg::MODULE_MSG */ 287 uint32_t msg_tgt : 1; 288 uint32_t _reserved_0 : 1; 289 } r; 290 } primary; 291 292 union { 293 uint32_t dat; 294 295 struct { 296 uint32_t rsvd : 30; 297 uint32_t _reserved_1 : 2; 298 } r; 299 } extension; 300 } __attribute__((packed, aligned(4))); 301 302 struct ipc4_module_set_d0ix { 303 union { 304 uint32_t dat; 305 306 struct { 307 /* module id (must be 0 - Base FW) */ 308 uint32_t module_id : 16; 309 /* instance id (must be 0 - core 0) */ 310 uint32_t instance_id : 8; 311 /* ModuleMsg::SET_D0IX */ 312 uint32_t type : 5; 313 /* Msg::MSG_REQUEST */ 314 uint32_t rsp : 1; 315 /* Msg::MODULE_MSG */ 316 uint32_t msg_tgt : 1; 317 uint32_t _reserved_0 : 1; 318 } r; 319 } primary; 320 321 union { 322 uint32_t dat; 323 324 struct { 325 /* legacy wake type (see WakeType) */ 326 uint32_t wake : 1; 327 /* streaming active now */ 328 uint32_t streaming : 1; 329 /* D0/D0ix transitions allowed (PG disabled) */ 330 uint32_t prevent_power_gating : 1; 331 /* Clock gating enabled */ 332 uint32_t prevent_local_clock_gating : 1; 333 334 uint32_t rsvd1 : 26; 335 uint32_t _reserved_2 : 2; 336 } r; 337 } extension; 338 } __attribute__((packed, aligned(4))); 339 340 struct ipc4_dx_state_info { 341 /* Indicates which cores are subject to change the power state */ 342 uint32_t core_mask; 343 /* Indicates core state. 344 * bit[core_id] = 0 -> put core_id to D3 345 * bit[core_id] = 1 -> put core_id to D0 346 */ 347 uint32_t dx_mask; 348 } __packed __aligned(4); 349 350 struct ipc4_module_set_dx { 351 union { 352 uint32_t dat; 353 354 struct { 355 /* module id (must be 0 - Base FW) */ 356 uint32_t module_id : 16; 357 /* instance id (must be 0 - core 0) */ 358 uint32_t instance_id : 8; 359 /* ModuleMsg::SET_DX */ 360 uint32_t type : 5; 361 /* Msg::MSG_REQUEST */ 362 uint32_t rsp : 1; 363 /* Msg::MODULE_MSG */ 364 uint32_t msg_tgt : 1; 365 uint32_t _reserved_0 : 1; 366 } r; 367 } primary; 368 369 union { 370 uint32_t dat; 371 372 struct { 373 uint32_t rsvd : 30; 374 uint32_t _reserved_2 : 2; 375 } r; 376 } extension; 377 } __attribute__((packed, aligned(4))); 378 379 struct ipc4_module_load_library { 380 union { 381 uint32_t dat; 382 383 struct { 384 /* ID of HD/A HO DMA to load the code */ 385 uint32_t dma_id : 5; 386 uint32_t rsvd0 : 11; 387 /* ID of library */ 388 uint32_t lib_id : 4; 389 uint32_t rsvd1 : 4; 390 /* Global::LOAD_LIBRARY */ 391 uint32_t type : 5; 392 /* Msg::MSG_REQUEST */ 393 uint32_t rsp : 1; 394 /* Msg::FW_GEN_MSG */ 395 uint32_t msg_tgt : 1; 396 uint32_t _reserved_0 : 1; 397 } r; 398 } header; 399 400 union { 401 uint32_t dat; 402 403 struct { 404 uint32_t load_offset : 30; 405 uint32_t _reserved_2 : 2; 406 } r; 407 } data; 408 } __packed __aligned(4); 409 410 #define IPC4_COMP_ID(x, y) ((x) << 16 | (y)) 411 #define IPC4_MOD_ID(x) ((x) >> 16) 412 #define IPC4_INST_ID(x) ((x) & 0xffff) 413 #define IPC4_SRC_QUEUE_ID(x) (((x) >> 16) & 0xffff) 414 #define IPC4_SINK_QUEUE_ID(x) ((x) & 0xffff) 415 416 #endif 417