@@ -1369,6 +1369,23 @@ sof_ipc4_update_resource_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *
13691369 pipeline = pipe_widget -> private ;
13701370 pipeline -> mem_usage += total ;
13711371
1372+ /*
1373+ * If this is not a Data Processing module instance, add the
1374+ * required heap sizes to the sum of all modules instance's
1375+ * belonging to same pipeline and find the maximum stack
1376+ * requirement of all module instances belonging to the same
1377+ * pipeline.
1378+ */
1379+ if (swidget -> comp_domain != SOF_COMP_DOMAIN_DP ) {
1380+ pipe_widget -> heap_bytes += swidget -> heap_bytes ;
1381+ if (pipe_widget -> stack_bytes < swidget -> stack_bytes )
1382+ pipe_widget -> stack_bytes = swidget -> stack_bytes ;
1383+
1384+ dev_dbg (sdev -> dev , "%s mem reqs to %s heap %u stack %u" ,
1385+ swidget -> widget -> name , pipe_widget -> widget -> name ,
1386+ pipe_widget -> heap_bytes , pipe_widget -> stack_bytes );
1387+ }
1388+
13721389 /* Update base_config->cpc from the module manifest */
13731390 sof_ipc4_update_cpc_from_manifest (sdev , fw_module , base_config );
13741391
@@ -1686,6 +1703,8 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
16861703 pipe_widget = swidget -> spipe -> pipe_widget ;
16871704 pipeline = pipe_widget -> private ;
16881705 pipeline -> mem_usage = 0 ;
1706+ pipe_widget -> heap_bytes = 0 ;
1707+ pipe_widget -> stack_bytes = 0 ;
16891708
16901709 if (WIDGET_IS_AIF (swidget -> id ) || swidget -> id == snd_soc_dapm_buffer ) {
16911710 if (pipeline -> use_chain_dma ) {
@@ -3083,11 +3102,11 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr
30833102 return 0 ;
30843103}
30853104
3086- static int sof_ipc4_widget_setup_msg_payload (struct snd_sof_dev * sdev ,
3087- struct snd_sof_widget * swidget ,
3088- struct sof_ipc4_msg * msg ,
3089- void * ipc_data , u32 ipc_size ,
3090- void * * new_data )
3105+ static int sof_ipc4_widget_mod_init_msg_payload (struct snd_sof_dev * sdev ,
3106+ struct snd_sof_widget * swidget ,
3107+ struct sof_ipc4_msg * msg ,
3108+ void * ipc_data , u32 ipc_size ,
3109+ void * * new_data )
30913110{
30923111 struct sof_ipc4_mod_init_ext_dp_memory_data * dp_mem_data ;
30933112 struct sof_ipc4_module_init_ext_init * ext_init ;
@@ -3111,13 +3130,14 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
31113130
31123131 /* Add ext_init first and set objects array flag to 1 */
31133132 ext_init = (struct sof_ipc4_module_init_ext_init * )payload ;
3114- ext_init -> word0 |= SOF_IPC4_MOD_INIT_EXT_OBJ_ARRAY_MASK ;
31153133 ext_pos = DIV_ROUND_UP (sizeof (* ext_init ), sizeof (u32 ));
31163134
31173135 /* Add object array objects after ext_init */
31183136
31193137 /* Add memory_data if comp_domain indicates DP */
31203138 if (swidget -> comp_domain == SOF_COMP_DOMAIN_DP ) {
3139+ ext_init -> word0 |= SOF_IPC4_MOD_INIT_EXT_OBJ_ARRAY_MASK ;
3140+
31213141 hdr = (struct sof_ipc4_module_init_ext_object * )& payload [ext_pos ];
31223142 hdr -> header = SOF_IPC4_MOD_INIT_EXT_OBJ_LAST_MASK |
31233143 SOF_IPC4_MOD_INIT_EXT_OBJ_ID (SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA ) |
@@ -3130,7 +3150,6 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
31303150 dp_mem_data -> heap_bytes = swidget -> heap_bytes ;
31313151 ext_pos += DIV_ROUND_UP (sizeof (* dp_mem_data ), sizeof (u32 ));
31323152 }
3133-
31343153 /* If another array object is added, remember clear previous OBJ_LAST bit */
31353154
31363155 /* Calculate final size and check that it fits to max payload size */
@@ -3154,6 +3173,69 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
31543173 return new_size ;
31553174}
31563175
3176+ static void sof_ipc4_widget_pipe_ext_obj_memory_data (struct snd_sof_dev * sdev ,
3177+ struct snd_sof_widget * swidget ,
3178+ u32 * payload , u32 * ext_pos ,
3179+ struct sof_ipc4_glb_pipe_ext_object * * hdr )
3180+ {
3181+ struct sof_ipc4_glb_pipe_ext_obj_memory_data * mem_data ;
3182+
3183+ * hdr = (struct sof_ipc4_glb_pipe_ext_object * )& payload [* ext_pos ];
3184+ (* hdr )-> header =
3185+ SOF_IPC4_GLB_PIPE_EXT_OBJ_ID (SOF_IPC4_GLB_PIPE_DATA_ID_MEM_DATA ) |
3186+ SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS (DIV_ROUND_UP (sizeof (* mem_data ),
3187+ sizeof (u32 )));
3188+ * ext_pos += DIV_ROUND_UP (sizeof (* * hdr ), sizeof (u32 ));
3189+ mem_data = (struct sof_ipc4_glb_pipe_ext_obj_memory_data * )& payload [* ext_pos ];
3190+ mem_data -> domain_id = swidget -> domain_id ;
3191+ mem_data -> stack_bytes = swidget -> stack_bytes ;
3192+ mem_data -> heap_bytes = swidget -> heap_bytes ;
3193+ * ext_pos += DIV_ROUND_UP (sizeof (* mem_data ), sizeof (u32 ));
3194+
3195+ dev_dbg (sdev -> dev ,
3196+ "%s; domain_id %u stack %u heap %u bytes" ,
3197+ swidget -> widget -> name , mem_data -> domain_id , mem_data -> stack_bytes ,
3198+ mem_data -> heap_bytes );
3199+ }
3200+
3201+ static int sof_ipc4_widget_pipe_create_msg_payload (struct snd_sof_dev * sdev ,
3202+ struct snd_sof_widget * swidget ,
3203+ struct sof_ipc4_msg * msg ,
3204+ void * * new_data )
3205+ {
3206+ struct sof_ipc4_glb_pipe_payload * payload_hdr ;
3207+ struct sof_ipc4_glb_pipe_ext_object * hdr = NULL ;
3208+ u32 * payload ;
3209+ u32 ext_pos ;
3210+
3211+ payload = kzalloc (sdev -> ipc -> max_payload_size , GFP_KERNEL );
3212+ if (!payload )
3213+ return - ENOMEM ;
3214+
3215+ /* Add sof_ipc4_glb_pipe_payload and set array bit to 1 */
3216+ payload_hdr = (struct sof_ipc4_glb_pipe_payload * )payload ;
3217+ payload_hdr -> word0 |= SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY_MASK ;
3218+ ext_pos = DIV_ROUND_UP (sizeof (* payload_hdr ), sizeof (u32 ));
3219+
3220+ sof_ipc4_widget_pipe_ext_obj_memory_data (sdev , swidget , payload , & ext_pos , & hdr );
3221+ /* Add following array objects here */
3222+
3223+ /* Mark end of object array */
3224+ hdr -> header |= SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST_MASK ;
3225+
3226+ /* Put total payload size in words to the payload header */
3227+ payload_hdr -> word0 |= SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS (ext_pos );
3228+ * new_data = payload ;
3229+
3230+ /* Update msg extension bits according to the payload changes */
3231+ msg -> extension |= SOF_IPC4_GLB_PIPE_PAYLOAD_MASK ;
3232+
3233+ dev_dbg (sdev -> dev , "%s: payload word0 %#x" , swidget -> widget -> name ,
3234+ payload_hdr -> word0 );
3235+
3236+ return ext_pos * sizeof (int32_t );
3237+ }
3238+
31573239static int sof_ipc4_widget_setup (struct snd_sof_dev * sdev , struct snd_sof_widget * swidget )
31583240{
31593241 struct snd_sof_widget * pipe_widget = swidget -> spipe -> pipe_widget ;
@@ -3307,8 +3389,8 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
33073389 swidget -> widget -> name , swidget -> pipeline_id , module_id ,
33083390 swidget -> instance_id , swidget -> core );
33093391
3310- ret = sof_ipc4_widget_setup_msg_payload (sdev , swidget , msg , ipc_data , ipc_size ,
3311- & ext_data );
3392+ ret = sof_ipc4_widget_mod_init_msg_payload (sdev , swidget , msg , ipc_data , ipc_size ,
3393+ & ext_data );
33123394 if (ret < 0 )
33133395 goto fail ;
33143396
@@ -3320,6 +3402,17 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
33203402 dev_dbg (sdev -> dev , "Create pipeline %s (pipe %d) - instance %d, core %d\n" ,
33213403 swidget -> widget -> name , swidget -> pipeline_id ,
33223404 swidget -> instance_id , swidget -> core );
3405+
3406+ msg -> extension &= ~SOF_IPC4_GLB_PIPE_PAYLOAD_MASK ;
3407+ ret = sof_ipc4_widget_pipe_create_msg_payload (sdev , swidget , msg ,
3408+ & ext_data );
3409+ if (ret < 0 )
3410+ goto fail ;
3411+
3412+ if (ret > 0 ) {
3413+ ipc_size = ret ;
3414+ ipc_data = ext_data ;
3415+ }
33233416 }
33243417
33253418 msg -> data_size = ipc_size ;
@@ -3377,6 +3470,8 @@ static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget
33773470 swidget -> widget -> name );
33783471
33793472 pipeline -> mem_usage = 0 ;
3473+ swidget -> heap_bytes = 0 ;
3474+ swidget -> stack_bytes = 0 ;
33803475 pipeline -> state = SOF_IPC4_PIPE_UNINITIALIZED ;
33813476 ida_free (& pipeline_ida , swidget -> instance_id );
33823477 swidget -> instance_id = - EINVAL ;
0 commit comments