Skip to content

Commit aefada9

Browse files
committed
ASoC: SOF: ipc4/Intel: Fix the host buffer
Merge series from Peter Ujfalusi <peter.ujfalusi@linux.intel.com>: The size of the DSP host buffer was incorrectly defined as 2ms while it is 4ms and the ChainDMA PCMs are using 5ms as host facing buffer. The constraint will be set against the period time rather than the buffer time to make sure that application will not face with xruns when the DMA bursts to refill the host buffer. The minimal period size will be also used by Pipewire in case of SOF cards to set the headroom to a length which will avoid the cases when the hw_ptr jumps over the appl_ptr because of a burst. Iow, it will make Pipewire to keep a safe distance from the hw_ptr. thesofproject#5284 https://gitlab.freedesktop.org/pipewire/wireplumber/-/merge_requests/740 https://gitlab.freedesktop.org/pipewire/pipewire/-/merge_requests/2548
2 parents bace10b + 45ad27d commit aefada9

3 files changed

Lines changed: 33 additions & 12 deletions

File tree

sound/soc/sof/intel/hda-pcm.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#define SDnFMT_BITS(x) ((x) << 4)
3030
#define SDnFMT_CHAN(x) ((x) << 0)
3131

32+
#define HDA_MAX_PERIOD_TIME_HEADROOM 10
33+
3234
static bool hda_always_enable_dmi_l1;
3335
module_param_named(always_enable_dmi_l1, hda_always_enable_dmi_l1, bool, 0444);
3436
MODULE_PARM_DESC(always_enable_dmi_l1, "SOF HDA always enable DMI l1");
@@ -291,19 +293,30 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
291293
* On playback start the DMA will transfer dsp_max_burst_size_in_ms
292294
* amount of data in one initial burst to fill up the host DMA buffer.
293295
* Consequent DMA burst sizes are shorter and their length can vary.
294-
* To make sure that userspace allocate large enough ALSA buffer we need
295-
* to place a constraint on the buffer time.
296+
* To avoid immediate xrun by the initial burst we need to place
297+
* constraint on the period size (via PERIOD_TIME) to cover the size of
298+
* the host buffer.
299+
* We need to add headroom of max 10ms as the firmware needs time to
300+
* settle to the 1ms pacing and initially it can run faster for few
301+
* internal periods.
296302
*
297303
* On capture the DMA will transfer 1ms chunks.
298-
*
299-
* Exact dsp_max_burst_size_in_ms constraint is racy, so set the
300-
* constraint to a minimum of 2x dsp_max_burst_size_in_ms.
301304
*/
302-
if (spcm->stream[direction].dsp_max_burst_size_in_ms)
305+
if (spcm->stream[direction].dsp_max_burst_size_in_ms) {
306+
unsigned int period_time = spcm->stream[direction].dsp_max_burst_size_in_ms;
307+
308+
/*
309+
* add headroom over the maximum burst size to cover the time
310+
* needed for the DMA pace to settle.
311+
* Limit the headroom time to HDA_MAX_PERIOD_TIME_HEADROOM
312+
*/
313+
period_time += min(period_time, HDA_MAX_PERIOD_TIME_HEADROOM);
314+
303315
snd_pcm_hw_constraint_minmax(substream->runtime,
304-
SNDRV_PCM_HW_PARAM_BUFFER_TIME,
305-
spcm->stream[direction].dsp_max_burst_size_in_ms * USEC_PER_MSEC * 2,
316+
SNDRV_PCM_HW_PARAM_PERIOD_TIME,
317+
period_time * USEC_PER_MSEC,
306318
UINT_MAX);
319+
}
307320

308321
/* binding pcm substream to hda stream */
309322
substream->runtime->private_data = &dsp_stream->hstream;

sound/soc/sof/ipc4-topology.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,13 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
665665
swidget->tuples,
666666
swidget->num_tuples, sizeof(u32), 1);
667667
/* Set default DMA buffer size if it is not specified in topology */
668-
if (!sps->dsp_max_burst_size_in_ms)
669-
sps->dsp_max_burst_size_in_ms = SOF_IPC4_MIN_DMA_BUFFER_SIZE;
668+
if (!sps->dsp_max_burst_size_in_ms) {
669+
struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
670+
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
671+
672+
sps->dsp_max_burst_size_in_ms = pipeline->use_chain_dma ?
673+
SOF_IPC4_CHAIN_DMA_BUFFER_SIZE : SOF_IPC4_MIN_DMA_BUFFER_SIZE;
674+
}
670675
} else {
671676
/* Capture data is copied from DSP to host in 1ms bursts */
672677
spcm->stream[dir].dsp_max_burst_size_in_ms = 1;

sound/soc/sof/ipc4-topology.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,11 @@
7070
#define SOF_IPC4_CHAIN_DMA_NODE_ID 0x7fffffff
7171
#define SOF_IPC4_INVALID_NODE_ID 0xffffffff
7272

73-
/* FW requires minimum 2ms DMA buffer size */
74-
#define SOF_IPC4_MIN_DMA_BUFFER_SIZE 2
73+
/* FW requires minimum 4ms DMA buffer size */
74+
#define SOF_IPC4_MIN_DMA_BUFFER_SIZE 4
75+
76+
/* ChainDMA in fw uses 5ms DMA buffer */
77+
#define SOF_IPC4_CHAIN_DMA_BUFFER_SIZE 5
7578

7679
/*
7780
* The base of multi-gateways. Multi-gateways addressing starts from

0 commit comments

Comments
 (0)