Skip to content

Commit dbed0a3

Browse files
Jyri Sarhaujfalusi
authored andcommitted
ASoC: sof ipc4: Add sof_ipc4_widget_setup_msg_payload() and call it
Add of_ipc4_widget_setup_msg_payload() for adding struct sof_ipc4_module_init_ext_init payload with associated objects. The function allocates memory for the additional payload, sets up the payload according to data collected from topology, and copies pre-encoded module specific payload after the ext_init payload. The function is called in sof_ipc4_widget_setup(). Signed-off-by: Jyri Sarha <[email protected]>
1 parent bd48f37 commit dbed0a3

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

sound/soc/sof/ipc4-topology.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2952,13 +2952,85 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr
29522952
return 0;
29532953
}
29542954

2955+
static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
2956+
struct snd_sof_widget *swidget,
2957+
struct sof_ipc4_msg *msg,
2958+
void *ipc_data, u32 ipc_size,
2959+
void **new_data)
2960+
{
2961+
struct sof_ipc4_mod_init_ext_dp_memory_data *dp_mem_data;
2962+
struct sof_ipc4_module_init_ext_init *ext_init;
2963+
struct sof_ipc4_module_init_ext_object *hdr;
2964+
int new_size;
2965+
u32 *payload;
2966+
u32 ext_pos;
2967+
2968+
/* For the moment the only reason for adding init_ext_init payload is DP
2969+
* memory data. If both stack and heap size are 0 (= use default), then
2970+
* there is no need for init_ext_init payload.
2971+
*/
2972+
if (swidget->comp_domain != SOF_COMP_DOMAIN_DP) {
2973+
msg->extension &= ~SOF_IPC4_MOD_EXT_EXTENDED_INIT_MASK;
2974+
return 0;
2975+
}
2976+
2977+
payload = kzalloc(sdev->ipc->max_payload_size, GFP_KERNEL);
2978+
if (!payload)
2979+
return -ENOMEM;
2980+
2981+
/* Add ext_init first and set objects array flag to 1 */
2982+
ext_init = (struct sof_ipc4_module_init_ext_init *)payload;
2983+
ext_init->word0 |= SOF_IPC4_MOD_INIT_EXT_OBJ_ARRAY_MASK;
2984+
ext_pos = DIV_ROUND_UP(sizeof(*ext_init), sizeof(u32));
2985+
2986+
/* Add object array objects after ext_init */
2987+
2988+
/* Add dp_memory_data if comp_domain indicates DP */
2989+
if (swidget->comp_domain == SOF_COMP_DOMAIN_DP) {
2990+
hdr = (struct sof_ipc4_module_init_ext_object *)&payload[ext_pos];
2991+
hdr->header = SOF_IPC4_MOD_INIT_EXT_OBJ_LAST_MASK |
2992+
SOF_IPC4_MOD_INIT_EXT_OBJ_ID(SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA) |
2993+
SOF_IPC4_MOD_INIT_EXT_OBJ_WORDS(DIV_ROUND_UP(sizeof(*dp_mem_data),
2994+
sizeof(u32)));
2995+
ext_pos += DIV_ROUND_UP(sizeof(*hdr), sizeof(u32));
2996+
dp_mem_data = (struct sof_ipc4_mod_init_ext_dp_memory_data *)&payload[ext_pos];
2997+
dp_mem_data->domain_id = swidget->dp_domain_id;
2998+
dp_mem_data->stack_bytes = swidget->dp_stack_bytes;
2999+
dp_mem_data->heap_bytes = swidget->dp_heap_bytes;
3000+
ext_pos += DIV_ROUND_UP(sizeof(*dp_mem_data), sizeof(u32));
3001+
}
3002+
3003+
/* If another array object is added, remember clear previous OBJ_LAST bit */
3004+
3005+
/* Calculate final size and check that it fits to max payload size */
3006+
new_size = ext_pos * sizeof(u32) + ipc_size;
3007+
if (new_size > sdev->ipc->max_payload_size) {
3008+
dev_err(sdev->dev, "Max ipc payload size %lu exceeded: %u",
3009+
sdev->ipc->max_payload_size, new_size);
3010+
kfree(payload);
3011+
return -EINVAL;
3012+
}
3013+
*new_data = payload;
3014+
3015+
/* Copy module specific ipc_payload to end */
3016+
memcpy(&payload[ext_pos], ipc_data, ipc_size);
3017+
3018+
/* Update msg extension bits according to the payload changes */
3019+
msg->extension |= SOF_IPC4_MOD_EXT_EXTENDED_INIT_MASK;
3020+
msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK;
3021+
msg->extension |= SOF_IPC4_MOD_EXT_PARAM_SIZE(DIV_ROUND_UP(new_size, sizeof(u32)));
3022+
3023+
return new_size;
3024+
}
3025+
29553026
static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
29563027
{
29573028
struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
29583029
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
29593030
struct sof_ipc4_pipeline *pipeline;
29603031
struct sof_ipc4_msg *msg;
29613032
void *ipc_data = NULL;
3033+
void *ext_data = NULL;
29623034
u32 ipc_size = 0;
29633035
int ret;
29643036

@@ -3103,6 +3175,16 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
31033175
dev_dbg(sdev->dev, "Create widget %s (pipe %d) - ID %d, instance %d, core %d\n",
31043176
swidget->widget->name, swidget->pipeline_id, module_id,
31053177
swidget->instance_id, swidget->core);
3178+
3179+
ret = sof_ipc4_widget_setup_msg_payload(sdev, swidget, msg, ipc_data, ipc_size,
3180+
&ext_data);
3181+
if (ret < 0)
3182+
goto fail;
3183+
3184+
if (ret > 0) {
3185+
ipc_size = ret;
3186+
ipc_data = ext_data;
3187+
}
31063188
} else {
31073189
dev_dbg(sdev->dev, "Create pipeline %s (pipe %d) - instance %d, core %d\n",
31083190
swidget->widget->name, swidget->pipeline_id,
@@ -3113,6 +3195,8 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
31133195
msg->data_ptr = ipc_data;
31143196

31153197
ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size);
3198+
3199+
fail:
31163200
if (ret < 0) {
31173201
dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name);
31183202

@@ -3125,6 +3209,7 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
31253209
}
31263210
}
31273211

3212+
kfree(ext_data);
31283213
return ret;
31293214
}
31303215

0 commit comments

Comments
 (0)