Re: (re)use and (re)definition of snd_pcm_hw_params->fifo_size for 'jumpy DMA'

Péter Ujfalusi
2026-03-23T16:17:31Z

On 23/03/2026 16:54, Jaroslav Kysela wrote:
>> Or should we add a new member (carved out from the reserved section of
>> hw_params struct) specifically for this purpose, like dma_burst_size,
>> which likely going to be equal to fifo_size if both is filled by the
>> driver.
>
> I would not change the fifo_size definition at this moment. It's not
> directly related to the sample transfers. This value just describes the
> additional latency for streaming.

Aren't we have the delay reported for this reason, which is actually in
use by user space?

> The new member seems like a good way to go with more universal name like
> 'chunk_size' (in frames) defining the transfer granularity information
> for the PCM buffer I/O.

right, but (I think these are the main issues that blocked any progress
on this) this is not really about the chunk_size, it is telling user
space what is the safe distance from hw_ptr to modify samples without
the DMA jumping over the area.

I know how SOF and tlv320dac33 does this, they have one overlapping and
one-one different modes

A. nSample mode (SOF with bigger than 8ms host buffer or dac33 MODE1)
initially fill the FIFO, then when only threshold amount of data remain
in FIFO, read N number of samples then wait for the threshold to be reached.

B. keep full (SOF with less than 8ms host buffer)
initially fill the FIFO, then whenever 1ms is free, read 1ms

C. two threshold mode (dac33 MODE7)
initially fill the FIFO up to upper threshold, then if the low threshold
is reached start reading data until the high threshold is hit, then wait
again for the low threshold to burst again.

The initial burst for A and B is equal, it is the size of the FIFO, in
case of C it is somewhere above the upper threshold as while filling the
FIFO there are samples played out, so it is a moving target, sort of.

But consequent DMA activity is different:
A: it is nSample, which is smaller than the fifo size
B: it is 1ms
C: something about the diff between the two thresholds

There could be different FIFO and burst setups out there, but in all
cases the fifo_size is something which is a hard safety limit that
applications must be aware of.

Fwiw, ASoC collects the delay from CPU driver, codec driver and also
from platform (DMA) driver, while the fifo_size never been configured,
afaik.

And the fun comes when we give numbers to these! Let's say the FIFO is
100ms long and we have the low threshold at 4ms (start DMA when only 4ms
left in FIFO).
A
start: read 100ms, wait
after 96ms read 96ms, wait
after 96ms, read 96ms, wait
The hw_ptr after 20ms after the start will be at 100ms
The hw_ptr after 70ms after the start will be at 100ms
The hw_ptr after 100ms after the start will be at 196ms

B (theoretical as SOF only uses this in 'small' FIFO case)
start: read 100ms, wait
after 1m, read 1ms, wait
after 1m, read 1ms, wait
The hw_ptr after 20ms after the start will be at 120ms
The hw_ptr after 70ms after the start will be at 170ms
The hw_ptr after 100ms after the start will be at 200ms

C
More like A, with reduced fifo_size, but that is a variable size.

Application must keep 2x fifo_size distance initially, if you plan to
check back in fifo_size time, B will be at one fifo_size ahead already
for examplem, but with A if you check at fifo_size time again, you risk
to race with the coming bursts, so you should not poke too close either..

My idea is to tell user space to keep fifo_size of data as minimum, but
initially this should be 2x fifo_size. How to document and do this is
still not clear, but the only thing the driver can tell: this is my
fifo_size, I burst based on this number.

And I'm really bad at naming things ;)

--
Péter