88#include <sof/audio/buffer.h>
99#include <sof/audio/component.h>
1010#include <sof/audio/component_ext.h>
11+ #include <sof/audio/module_adapter/module/generic.h>
1112#include <sof/audio/pipeline.h>
1213#include <sof/common.h>
1314#include <rtos/interrupt.h>
@@ -424,15 +425,20 @@ static int ll_wait_finished_on_core(struct comp_dev *dev)
424425
425426int ipc_comp_connect (struct ipc * ipc , ipc_pipe_comp_connect * _connect )
426427{
428+ struct ipc4_base_module_cfg_ext * src_basecfg_ext , * sink_basecfg_ext ;
427429 struct ipc4_module_bind_unbind * bu ;
428430 struct comp_buffer * buffer ;
429431 struct comp_dev * source ;
430432 struct comp_dev * sink ;
431433 struct ipc4_base_module_cfg source_src_cfg ;
432434 struct ipc4_base_module_cfg sink_src_cfg ;
433435 uint32_t flags ;
436+ uint32_t ibs = 0 ;
437+ uint32_t obs = 0 ;
438+ uint32_t buf_size ;
434439 int src_id , sink_id ;
435440 int ret ;
441+ size_t size ;
436442
437443 bu = (struct ipc4_module_bind_unbind * )_connect ;
438444 src_id = IPC4_COMP_ID (bu -> primary .r .module_id , bu -> primary .r .instance_id );
@@ -453,32 +459,88 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
453459 if (!cpu_is_me (source -> ipc_config .core ) && !cross_core_bind )
454460 return ipc4_process_on_core (source -> ipc_config .core , false);
455461
456- /* these might call comp_ipc4_get_attribute_remote() if necessary */
457- ret = comp_get_attribute (source , COMP_ATTR_BASE_CONFIG , & source_src_cfg );
458- if (ret < 0 ) {
459- tr_err (& ipc_tr , "failed to get base config for module %#x" , dev_comp_id (source ));
460- return IPC4_FAILURE ;
462+ size = MODULE_MAX_SINKS * sizeof (struct ipc4_output_pin_format ) +
463+ MODULE_MAX_SOURCES * sizeof (struct ipc4_input_pin_format );
464+
465+ /* get obs from the base config extension if the src queue ID is non-zero */
466+ if (bu -> extension .r .src_queue ) {
467+ struct ipc4_output_pin_format * out_fmt ;
468+ size_t output_fmt_offset ;
469+
470+ src_basecfg_ext = rzalloc (SOF_MEM_ZONE_RUNTIME , 0 , SOF_MEM_CAPS_RAM ,
471+ sizeof (* src_basecfg_ext ) + size );
472+ if (!src_basecfg_ext )
473+ return IPC4_OUT_OF_MEMORY ;
474+
475+ ret = comp_get_attribute (source , COMP_ATTR_BASE_CONFIG_EXT , src_basecfg_ext );
476+ if (!ret ) {
477+ size_t in_fmt_size = sizeof (struct ipc4_input_pin_format );
478+ size_t out_fmt_size = sizeof (struct ipc4_output_pin_format );
479+
480+ /*
481+ * offset of the format for the output pin with ID 'src_queue' within the
482+ * base config extension.
483+ */
484+ output_fmt_offset =
485+ src_basecfg_ext -> nb_input_pins * in_fmt_size +
486+ bu -> extension .r .src_queue * out_fmt_size ;
487+ out_fmt = (struct ipc4_output_pin_format * )& sink_basecfg_ext -> pin_formats [output_fmt_offset ];
488+ obs = out_fmt -> obs ;
489+ }
490+ rfree (src_basecfg_ext );
461491 }
462492
463- ret = comp_get_attribute (sink , COMP_ATTR_BASE_CONFIG , & sink_src_cfg );
464- if (ret < 0 ) {
465- tr_err (& ipc_tr , "failed to get base config for module %#x" , dev_comp_id (sink ));
466- return IPC4_FAILURE ;
493+ /* get obs from base config if src queue ID is 0 or if base config extn is missing */
494+ if (!obs ) {
495+ /* these might call comp_ipc4_get_attribute_remote() if necessary */
496+ ret = comp_get_attribute (source , COMP_ATTR_BASE_CONFIG , & source_src_cfg );
497+
498+ if (ret < 0 ) {
499+ tr_err (& ipc_tr , "failed to get base config for src module %#x" ,
500+ dev_comp_id (source ));
501+ return IPC4_FAILURE ;
502+ }
503+ obs = source_src_cfg .obs ;
467504 }
468505
469- /* create a buffer
470- * in case of LL -> LL or LL->DP
471- * size = 2*obs of source module (obs is single buffer size)
472- * in case of DP -> LL
473- * size = 2*ibs of destination (LL) module. DP queue will handle obs of DP module
474- */
475- uint32_t buf_size ;
506+ /* get ibs from the base config extension if the sink queue ID is non-zero */
507+ if (bu -> extension .r .dst_queue ) {
508+ struct ipc4_input_pin_format * in_fmt ;
509+ size_t input_fmt_offset ;
510+
511+ sink_basecfg_ext = rzalloc (SOF_MEM_ZONE_RUNTIME , 0 , SOF_MEM_CAPS_RAM ,
512+ sizeof (* sink_basecfg_ext ) + size );
513+ if (!sink_basecfg_ext )
514+ return IPC4_OUT_OF_MEMORY ;
515+
516+ ret = comp_get_attribute (sink , COMP_ATTR_BASE_CONFIG_EXT , sink_basecfg_ext );
517+ if (!ret ) {
518+ /*
519+ * offset of the format for the input pin with ID 'dst_queue' within the
520+ * base config extension.
521+ */
522+ input_fmt_offset =
523+ bu -> extension .r .dst_queue * sizeof (struct ipc4_input_pin_format );
524+ in_fmt = (struct ipc4_input_pin_format * )& sink_basecfg_ext -> pin_formats [input_fmt_offset ];
525+ ibs = in_fmt -> ibs ;
526+ }
527+ rfree (sink_basecfg_ext );
528+ }
476529
477- if (source -> ipc_config .proc_domain == COMP_PROCESSING_DOMAIN_LL )
478- buf_size = source_src_cfg .obs * 2 ;
479- else
480- buf_size = sink_src_cfg .ibs * 2 ;
530+ /* get ibs from base config if sink queue ID is 0 or if base config extn is missing */
531+ if (!ibs ) {
532+ ret = comp_get_attribute (sink , COMP_ATTR_BASE_CONFIG , & sink_src_cfg );
533+ if (ret < 0 ) {
534+ tr_err (& ipc_tr , "failed to get base config for sink module %#x" ,
535+ dev_comp_id (sink ));
536+ return IPC4_FAILURE ;
537+ }
538+
539+ ibs = sink_src_cfg .ibs ;
540+ }
481541
542+ /* allocate buffer with size large enough to fit ibs of the sink or obs of the source */
543+ buf_size = MAX (ibs * 2 , obs * 2 );
482544 buffer = ipc4_create_buffer (source , cross_core_bind , buf_size , bu -> extension .r .src_queue ,
483545 bu -> extension .r .dst_queue );
484546 if (!buffer ) {
@@ -496,8 +558,8 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
496558 * sink_module needs to set its IBS (input buffer size)
497559 * as min_available in buffer's source ifc
498560 */
499- sink_set_min_free_space (audio_stream_get_sink (& buffer -> stream ), source_src_cfg . obs );
500- source_set_min_available (audio_stream_get_source (& buffer -> stream ), sink_src_cfg . ibs );
561+ sink_set_min_free_space (audio_stream_get_sink (& buffer -> stream ), obs );
562+ source_set_min_available (audio_stream_get_source (& buffer -> stream ), ibs );
501563
502564 /*
503565 * Connect and bind the buffer to both source and sink components with LL processing been
0 commit comments