@@ -688,15 +688,22 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
688688 goto free_available_fmt ;
689689
690690 sps = & spcm -> stream [dir ];
691- if (dir == SNDRV_PCM_STREAM_PLAYBACK ) {
691+ sof_update_ipc_object (scomp , & sps -> dsp_max_burst_size_in_ms ,
692+ SOF_COPIER_DEEP_BUFFER_TOKENS ,
693+ swidget -> tuples ,
694+ swidget -> num_tuples , sizeof (u32 ), 1 );
695+
696+ /* Set default DMA buffer size if it is not specified in topology */
697+ if (!sps -> dsp_max_burst_size_in_ms ) {
692698 struct snd_sof_widget * pipe_widget = swidget -> spipe -> pipe_widget ;
693699 struct sof_ipc4_pipeline * pipeline = pipe_widget -> private ;
694700
695- sps -> dsp_max_burst_size_in_ms = pipeline -> use_chain_dma ?
696- SOF_IPC4_CHAIN_DMA_BUFFER_SIZE : SOF_IPC4_MIN_DMA_BUFFER_SIZE ;
697- } else {
698- /* Capture data is copied from DSP to host in 1ms bursts */
699- sps -> dsp_max_burst_size_in_ms = 1 ;
701+ if (dir == SNDRV_PCM_STREAM_PLAYBACK )
702+ sps -> dsp_max_burst_size_in_ms = pipeline -> use_chain_dma ?
703+ SOF_IPC4_CHAIN_DMA_BUFFER_SIZE : SOF_IPC4_MIN_DMA_BUFFER_SIZE ;
704+ else
705+ /* Capture data is copied from DSP to host in 1ms bursts */
706+ sps -> dsp_max_burst_size_in_ms = 1 ;
700707 }
701708
702709skip_gtw_cfg :
@@ -2037,79 +2044,6 @@ static void sof_ipc4_host_config(struct snd_sof_dev *sdev, struct snd_sof_widget
20372044 copier_data -> gtw_cfg .node_id |= SOF_IPC4_NODE_INDEX (host_dma_id );
20382045}
20392046
2040- static void
2041- sof_ipc4_set_host_copier_dma_buffer_size (struct snd_sof_widget * swidget ,
2042- unsigned int fe_period_bytes )
2043- {
2044- unsigned int min_size , no_headroom_mark , fw_period_bytes ;
2045- struct snd_soc_component * scomp = swidget -> scomp ;
2046- struct sof_ipc4_copier_data * copier_data ;
2047- struct sof_ipc4_copier * ipc4_copier ;
2048- unsigned int deep_buffer_dma_ms = 0 ;
2049- u32 buffer_bytes ;
2050- int ret ;
2051-
2052- ipc4_copier = (struct sof_ipc4_copier * )swidget -> private ;
2053- copier_data = & ipc4_copier -> data ;
2054-
2055- if (swidget -> id == snd_soc_dapm_aif_in )
2056- fw_period_bytes = copier_data -> base_config .ibs ;
2057- else
2058- fw_period_bytes = copier_data -> base_config .obs ;
2059-
2060- /*
2061- * Calculate the minimum size of the host copier DMA host buffer and the
2062- * cut-out watermark when no headroom is needed to be added between the
2063- * host copier buffer size and the ALSA period size
2064- */
2065- min_size = SOF_IPC4_MIN_DMA_BUFFER_SIZE * fw_period_bytes ;
2066- no_headroom_mark = SOF_IPC4_NO_DMA_BUFFER_HEADROOM_MS * fw_period_bytes ;
2067-
2068- /* parse the deep buffer dma size */
2069- ret = sof_update_ipc_object (scomp , & deep_buffer_dma_ms ,
2070- SOF_COPIER_DEEP_BUFFER_TOKENS , swidget -> tuples ,
2071- swidget -> num_tuples , sizeof (u32 ), 1 );
2072- if (ret ) {
2073- dev_dbg (scomp -> dev ,
2074- "Failed to parse deep buffer dma size for %s\n" ,
2075- swidget -> widget -> name );
2076- buffer_bytes = min_size ;
2077- goto out ;
2078- }
2079-
2080- /*
2081- * Non Deepbuffer and small ALSA periods must use the minimal host DMA
2082- * buffer size in firmware.
2083- * Note: smaller than 2x the minimum host DMA buffer size for ALSA
2084- * period is not allowed and should be protected by platform code with
2085- * constraint.
2086- *
2087- * Add headroom the between host copier DMA buffer size and the ALSA
2088- * period size if the ALSA period is less than
2089- * SOF_IPC4_NO_DMA_BUFFER_HEADROOM_MS, otherwise equal the host copier
2090- * DMA buffer size to ALSA period size, capped at the maximum DeepBuffer
2091- * depth specified in topology
2092- */
2093- if (deep_buffer_dma_ms <= SOF_IPC4_MIN_DMA_BUFFER_SIZE ||
2094- fe_period_bytes < (min_size * 2 ))
2095- buffer_bytes = min_size ;
2096- else if (fe_period_bytes < no_headroom_mark )
2097- buffer_bytes = fe_period_bytes - min_size ;
2098- else
2099- buffer_bytes = min (deep_buffer_dma_ms * fw_period_bytes ,
2100- fe_period_bytes );
2101-
2102- out :
2103- dev_dbg (scomp -> dev ,
2104- "%s, dma buffer%s: %u ms (max: %u) / %u bytes, ALSA period: %u / %u\n" ,
2105- swidget -> widget -> name , deep_buffer_dma_ms ? " (using Deep Buffer)" : "" ,
2106- buffer_bytes / fw_period_bytes ,
2107- deep_buffer_dma_ms ? deep_buffer_dma_ms : SOF_IPC4_MIN_DMA_BUFFER_SIZE ,
2108- buffer_bytes , fe_period_bytes / fw_period_bytes , fe_period_bytes );
2109-
2110- copier_data -> gtw_cfg .dma_buffer_size = buffer_bytes ;
2111- }
2112-
21132047static int
21142048sof_ipc4_prepare_copier_module (struct snd_sof_widget * swidget ,
21152049 struct snd_pcm_hw_params * fe_params ,
@@ -2131,6 +2065,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21312065 u32 * * data ;
21322066 int ipc_size , ret , out_ref_valid_bits ;
21332067 u32 out_ref_rate , out_ref_channels , out_ref_type ;
2068+ u32 deep_buffer_dma_ms = 0 ;
21342069 bool single_output_bitdepth ;
21352070 int i ;
21362071
@@ -2148,6 +2083,16 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21482083 str_yes_no (pipeline -> use_chain_dma ),
21492084 platform_params -> stream_tag );
21502085
2086+ /* parse the deep buffer dma size */
2087+ ret = sof_update_ipc_object (scomp , & deep_buffer_dma_ms ,
2088+ SOF_COPIER_DEEP_BUFFER_TOKENS , swidget -> tuples ,
2089+ swidget -> num_tuples , sizeof (u32 ), 1 );
2090+ if (ret ) {
2091+ dev_err (scomp -> dev , "Failed to parse deep buffer dma size for %s\n" ,
2092+ swidget -> widget -> name );
2093+ return ret ;
2094+ }
2095+
21512096 ipc4_copier = (struct sof_ipc4_copier * )swidget -> private ;
21522097 gtw_attr = ipc4_copier -> gtw_attr ;
21532098 copier_data = & ipc4_copier -> data ;
@@ -2482,19 +2427,34 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
24822427 * in topology.
24832428 */
24842429 switch (swidget -> id ) {
2485- case snd_soc_dapm_aif_in :
2486- case snd_soc_dapm_aif_out :
2487- sof_ipc4_set_host_copier_dma_buffer_size (swidget ,
2488- params_period_bytes (fe_params ));
2489- break ;
24902430 case snd_soc_dapm_dai_in :
24912431 copier_data -> gtw_cfg .dma_buffer_size =
24922432 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data -> base_config .ibs ;
24932433 break ;
2434+ case snd_soc_dapm_aif_in :
2435+ copier_data -> gtw_cfg .dma_buffer_size =
2436+ max ((u32 )SOF_IPC4_MIN_DMA_BUFFER_SIZE , deep_buffer_dma_ms ) *
2437+ copier_data -> base_config .ibs ;
2438+ dev_dbg (sdev -> dev , "copier %s, dma buffer%s: %u ms (%u bytes)" ,
2439+ swidget -> widget -> name ,
2440+ deep_buffer_dma_ms ? " (using Deep Buffer)" : "" ,
2441+ max ((u32 )SOF_IPC4_MIN_DMA_BUFFER_SIZE , deep_buffer_dma_ms ),
2442+ copier_data -> gtw_cfg .dma_buffer_size );
2443+ break ;
24942444 case snd_soc_dapm_dai_out :
24952445 copier_data -> gtw_cfg .dma_buffer_size =
24962446 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data -> base_config .obs ;
24972447 break ;
2448+ case snd_soc_dapm_aif_out :
2449+ copier_data -> gtw_cfg .dma_buffer_size =
2450+ max ((u32 )SOF_IPC4_MIN_DMA_BUFFER_SIZE , deep_buffer_dma_ms ) *
2451+ copier_data -> base_config .obs ;
2452+ dev_dbg (sdev -> dev , "copier %s, dma buffer%s: %u ms (%u bytes)" ,
2453+ swidget -> widget -> name ,
2454+ deep_buffer_dma_ms ? " (using Deep Buffer)" : "" ,
2455+ max ((u32 )SOF_IPC4_MIN_DMA_BUFFER_SIZE , deep_buffer_dma_ms ),
2456+ copier_data -> gtw_cfg .dma_buffer_size );
2457+ break ;
24982458 default :
24992459 break ;
25002460 }
0 commit comments