On 6/6/2019 11:30 AM, Peter Ujfalusi wrote:
Hi Sameer,
On 06/06/2019 6.49, Sameer Pujar wrote:
Sorry for late reply.
[Resending the reply since delivery failed for few recipients]
I discussed this internally with HW folks and below is the reason why
DMA needs
to know FIFO size.
- FIFOs reside in peripheral device(ADMAIF), which is the ADMA interface
to the audio sub-system.
- ADMAIF has multiple channels and share FIFO buffer for individual
operations. There is a provision
to allocate specific fifo size for each individual ADMAIF channel from
the shared buffer.
- Tegra Audio DMA(ADMA) architecture is different from the usual DMA
engines, which you described earlier.
It is not really different than what other DMAs are doing.
- The flow control logic is placed inside ADMA. Slave peripheral
device(ADMAIF) signals ADMA whenever a
read or write happens on the FIFO(per WORD basis). Please note that
the signaling is per channel. There is
no other signaling present from ADMAIF to ADMA.
- ADMA keeps a counter related to above signaling. Whenever a sufficient
space is available, it initiates a transfer.
But the question is, how does it know when to transfer. This is the
reason, why ADMA has to be aware of FIFO
depth of ADMAIF channel. Depending on the counters and FIFO depth, it
knows exactly when a free space is available
in the context of a specific channel. On ADMA, FIFO_SIZE is just a
value which should match to actual FIFO_DEPTH/SIZE
of ADMAIF channel.
- Now consider two cases based on above logic,
* Case 1: when DMA_FIFO_SIZE > SLAVE_FIFO_SIZE
In this case, ADMA thinks that there is enough space available for
transfer, when actually the FIFO data
on slave is not consumed yet. It would result in OVERRUN.
* Case 2: when DMA_FIFO_SIZE < SLAVE_FIFO_SIZE
This is case where ADMA won’t transfer, even though sufficient space
is available, resulting in UNDERRUN.
- The guideline is to program, DMA_FIFO_SIZE(on ADMA side) =
SLAVE_FIFO_SIZE(on ADMAIF side) and hence we need a
way to communicate fifo size info to ADMA.
The src_maxburst / dst_maxburst is exactly for this reason. To
communicate how much data should be transferred per DMA request to/from
peripheral.
In TI land we have now 3 DMA engines servicing McASP. McASP has FIFO
which is dynamically configured (you can see the AFIFO of McASP as a
small DMA: on McASP side it services the peripheral, on the other side
it interacts with the given system DMA used by the SoC - EDMA, sDMA or
UDMAP). All DMAs needs a bit different configuration, but the AFIFO
depth on the McASP side is coming in via the src/dst_maxburst and the
drivers just need to interpret it correctly.
It does sounds like that FIFO_SIZE == src/dst_maxburst in your case as well.
Not exactly equal.
ADMA burst_size can range from 1(WORD) to 16(WORDS)
FIFO_SIZE can be adjusted from 16(WORDS) to 1024(WORDS) [can vary in
multiples of 16]
So without this RFC patch, I need to do following.
- pass FIFO_SIZE via src/dst_maxburst (from peripheral ADMAIF driver)
- DMA driver can have following code,
* Program DMA_FIFO_SIZE value from src/dst_maxburst
* Add below logic
if (src/dst_maxburst > 16)
program ADMA burst_size = 16
else
program ADMA burst_size = 8 (1/2 of minimum FIFO depth of
ADMAIF channel)
With above, the flexibility to program ADMA burst_size to any of the
required values in the specified range is not there.
Hence ideally would have liked to have independent control over
burst_size and fifo_size on ADMA side.
If there is no merit in this, I will update ADMA/ADMAIF driver as
mentioned above.
Thanks,
Sameer.
- Péter
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki