Skip to content

Commit 2dec631

Browse files
author
Jyri Sarha
committed
ASoC: SOF: ipc4-topology: Add payload to pipeline create messages
Start adding payloads to pipeline create messages. The payload contains information for payload specific memory configuration. All non DP module instances within the same pipeline share the same memory attributes and access the same resources. The new logic sums interim, lifetime, and shared heap memory requirements together and picks the highest stack requirement of all module instances belonging to a pipeline. These pipeline specific attributes are sent as struct sof_ipc4_glb_pipe_payload payload in pipeline's create message. The idea is to pass common memory configuration for all the Low Latency modules in the pipeline in pipeline create message payload. The Data Processing module instances will still have an individual memory configuration in struct sof_ipc4_mod_init_ext_dp_memory_data payloads as before. In their payload everything is as it was before, all attributes are copied directly from their topology attributes. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1 parent aef3116 commit 2dec631

1 file changed

Lines changed: 115 additions & 10 deletions

File tree

sound/soc/sof/ipc4-topology.c

Lines changed: 115 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,6 +1348,26 @@ sof_ipc4_update_resource_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *
13481348
pipeline = pipe_widget->private;
13491349
pipeline->mem_usage += total;
13501350

1351+
/*
1352+
* If this is not a Data Processing module instance, add the
1353+
* required heap sizes to the sum of all modules instance's
1354+
* belonging to same pipeline and find the maximum stack
1355+
* requirement of all module instances belonging to the same
1356+
* pipeline.
1357+
*/
1358+
if (swidget->comp_domain != SOF_COMP_DOMAIN_DP) {
1359+
pipe_widget->interim_bytes += swidget->interim_bytes;
1360+
pipe_widget->lifetime_bytes += swidget->lifetime_bytes;
1361+
pipe_widget->shared_bytes += swidget->shared_bytes;
1362+
if (pipe_widget->stack_bytes < swidget->stack_bytes)
1363+
pipe_widget->stack_bytes = swidget->stack_bytes;
1364+
1365+
dev_dbg(sdev->dev, "%s mem reqs to %s lifetime %u heap %u shared %u stack %u",
1366+
swidget->widget->name, pipe_widget->widget->name,
1367+
pipe_widget->lifetime_bytes, pipe_widget->interim_bytes,
1368+
pipe_widget->shared_bytes, pipe_widget->stack_bytes);
1369+
}
1370+
13511371
/* Update base_config->cpc from the module manifest */
13521372
sof_ipc4_update_cpc_from_manifest(sdev, fw_module, base_config);
13531373

@@ -1665,6 +1685,10 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
16651685
pipe_widget = swidget->spipe->pipe_widget;
16661686
pipeline = pipe_widget->private;
16671687
pipeline->mem_usage = 0;
1688+
pipe_widget->lifetime_bytes = 0;
1689+
pipe_widget->interim_bytes = 0;
1690+
pipe_widget->shared_bytes = 0;
1691+
pipe_widget->stack_bytes = 0;
16681692

16691693
if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) {
16701694
if (pipeline->use_chain_dma) {
@@ -3109,11 +3133,11 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr
31093133
return 0;
31103134
}
31113135

3112-
static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
3113-
struct snd_sof_widget *swidget,
3114-
struct sof_ipc4_msg *msg,
3115-
void *ipc_data, u32 ipc_size,
3116-
void **new_data)
3136+
static int sof_ipc4_widget_mod_init_msg_payload(struct snd_sof_dev *sdev,
3137+
struct snd_sof_widget *swidget,
3138+
struct sof_ipc4_msg *msg,
3139+
void *ipc_data, u32 ipc_size,
3140+
void **new_data)
31173141
{
31183142
struct sof_ipc4_mod_init_ext_dp_memory_data *dp_mem_data;
31193143
struct sof_ipc4_module_init_ext_init *ext_init;
@@ -3137,13 +3161,14 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
31373161

31383162
/* Add ext_init first and set objects array flag to 1 */
31393163
ext_init = (struct sof_ipc4_module_init_ext_init *)payload;
3140-
ext_init->word0 |= SOF_IPC4_MOD_INIT_EXT_OBJ_ARRAY_MASK;
31413164
ext_pos = DIV_ROUND_UP(sizeof(*ext_init), sizeof(u32));
31423165

31433166
/* Add object array objects after ext_init */
31443167

31453168
/* Add memory_data if comp_domain indicates DP */
31463169
if (swidget->comp_domain == SOF_COMP_DOMAIN_DP) {
3170+
ext_init->word0 |= SOF_IPC4_MOD_INIT_EXT_OBJ_ARRAY_MASK;
3171+
31473172
hdr = (struct sof_ipc4_module_init_ext_object *)&payload[ext_pos];
31483173
hdr->header = SOF_IPC4_MOD_INIT_EXT_OBJ_LAST_MASK |
31493174
SOF_IPC4_MOD_INIT_EXT_OBJ_ID(SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA) |
@@ -3153,10 +3178,9 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
31533178
dp_mem_data = (struct sof_ipc4_mod_init_ext_dp_memory_data *)&payload[ext_pos];
31543179
dp_mem_data->domain_id = swidget->domain_id;
31553180
dp_mem_data->stack_bytes = swidget->stack_bytes;
3156-
dp_mem_data->heap_bytes = swidget->heap_bytes;
3181+
dp_mem_data->heap_bytes = swidget->interim_bytes;
31573182
ext_pos += DIV_ROUND_UP(sizeof(*dp_mem_data), sizeof(u32));
31583183
}
3159-
31603184
/* If another array object is added, remember clear previous OBJ_LAST bit */
31613185

31623186
/* Calculate final size and check that it fits to max payload size */
@@ -3180,6 +3204,72 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
31803204
return new_size;
31813205
}
31823206

3207+
static void sof_ipc4_widget_pipe_ext_obj_memory_data(struct snd_sof_dev *sdev,
3208+
struct snd_sof_widget *swidget,
3209+
u32 *payload, u32 *ext_pos,
3210+
struct sof_ipc4_glb_pipe_ext_object **hdr)
3211+
{
3212+
struct sof_ipc4_glb_pipe_ext_obj_memory_data *mem_data;
3213+
3214+
*hdr = (struct sof_ipc4_glb_pipe_ext_object *)&payload[*ext_pos];
3215+
(*hdr)->header =
3216+
SOF_IPC4_GLB_PIPE_EXT_OBJ_ID(SOF_IPC4_GLB_PIPE_DATA_ID_MEM_DATA) |
3217+
SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS(DIV_ROUND_UP(sizeof(*mem_data),
3218+
sizeof(u32)));
3219+
*ext_pos += DIV_ROUND_UP(sizeof(**hdr), sizeof(u32));
3220+
mem_data = (struct sof_ipc4_glb_pipe_ext_obj_memory_data *)&payload[*ext_pos];
3221+
mem_data->domain_id = swidget->domain_id;
3222+
mem_data->stack_bytes = swidget->stack_bytes;
3223+
mem_data->interim_heap_bytes = swidget->interim_bytes;
3224+
mem_data->lifetime_heap_bytes = swidget->lifetime_bytes;
3225+
mem_data->shared_bytes = swidget->shared_bytes;
3226+
*ext_pos += DIV_ROUND_UP(sizeof(*mem_data), sizeof(u32));
3227+
3228+
dev_dbg(sdev->dev,
3229+
"%s; domain_id %u stack %u interim %u lifetime %u shared %u bytes",
3230+
swidget->widget->name, mem_data->domain_id, mem_data->stack_bytes,
3231+
mem_data->interim_heap_bytes, mem_data->lifetime_heap_bytes,
3232+
mem_data->shared_bytes);
3233+
}
3234+
3235+
static int sof_ipc4_widget_pipe_create_msg_payload(struct snd_sof_dev *sdev,
3236+
struct snd_sof_widget *swidget,
3237+
struct sof_ipc4_msg *msg,
3238+
void **new_data)
3239+
{
3240+
struct sof_ipc4_glb_pipe_payload *payload_hdr;
3241+
struct sof_ipc4_glb_pipe_ext_object *hdr = NULL;
3242+
u32 *payload;
3243+
u32 ext_pos;
3244+
3245+
payload = kzalloc(sdev->ipc->max_payload_size, GFP_KERNEL);
3246+
if (!payload)
3247+
return -ENOMEM;
3248+
3249+
/* Add sof_ipc4_glb_pipe_payload and set array bit to 1 */
3250+
payload_hdr = (struct sof_ipc4_glb_pipe_payload *)payload;
3251+
payload_hdr->word0 |= SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY_MASK;
3252+
ext_pos = DIV_ROUND_UP(sizeof(*payload_hdr), sizeof(u32));
3253+
3254+
sof_ipc4_widget_pipe_ext_obj_memory_data(sdev, swidget, payload, &ext_pos, &hdr);
3255+
/* Add following array objects here */
3256+
3257+
/* Mark end of object array */
3258+
hdr->header |= SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST_MASK;
3259+
3260+
/* Put total payload size in words to the payload header */
3261+
payload_hdr->word0 |= SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS(ext_pos);
3262+
*new_data = payload;
3263+
3264+
/* Update msg extension bits according to the payload changes */
3265+
msg->extension |= SOF_IPC4_GLB_PIPE_PAYLOAD_MASK;
3266+
3267+
dev_dbg(sdev->dev, "%s: payload word0 %#x", swidget->widget->name,
3268+
payload_hdr->word0);
3269+
3270+
return ext_pos * sizeof(int32_t);
3271+
}
3272+
31833273
static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
31843274
{
31853275
struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
@@ -3333,8 +3423,8 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
33333423
swidget->widget->name, swidget->pipeline_id, module_id,
33343424
swidget->instance_id, swidget->core);
33353425

3336-
ret = sof_ipc4_widget_setup_msg_payload(sdev, swidget, msg, ipc_data, ipc_size,
3337-
&ext_data);
3426+
ret = sof_ipc4_widget_mod_init_msg_payload(sdev, swidget, msg, ipc_data, ipc_size,
3427+
&ext_data);
33383428
if (ret < 0)
33393429
goto fail;
33403430

@@ -3346,6 +3436,17 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
33463436
dev_dbg(sdev->dev, "Create pipeline %s (pipe %d) - instance %d, core %d\n",
33473437
swidget->widget->name, swidget->pipeline_id,
33483438
swidget->instance_id, swidget->core);
3439+
3440+
msg->extension &= ~SOF_IPC4_GLB_PIPE_PAYLOAD_MASK;
3441+
ret = sof_ipc4_widget_pipe_create_msg_payload(sdev, swidget, msg,
3442+
&ext_data);
3443+
if (ret < 0)
3444+
goto fail;
3445+
3446+
if (ret > 0) {
3447+
ipc_size = ret;
3448+
ipc_data = ext_data;
3449+
}
33493450
}
33503451

33513452
msg->data_size = ipc_size;
@@ -3403,6 +3504,10 @@ static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget
34033504
swidget->widget->name);
34043505

34053506
pipeline->mem_usage = 0;
3507+
swidget->lifetime_bytes = 0;
3508+
swidget->interim_bytes = 0;
3509+
swidget->shared_bytes = 0;
3510+
swidget->stack_bytes = 0;
34063511
pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED;
34073512
ida_free(&pipeline_ida, swidget->instance_id);
34083513
swidget->instance_id = -EINVAL;

0 commit comments

Comments
 (0)