@@ -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+
31833273static 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