ffc6eaf...
by
Iuliana Prodan <email address hidden>
drivers: imx: sai: update start/stop operations
For SAI, we have the synchronous mode enabled: the transmitter is
configured for asynchronous operation and the receiver for
synchronous operation.
In this case, transmitter bit clock and frame sync are used by both
the transmitter and receiver. So, when enabling RX we need to enable TX
(if not already enabled).
Therefore, for a clear start, we first do a software reset for the current
direction, but checking the state of RX and TX.
This will reset the internal transmitter/receiver logic including the FIFO
pointers.
For capture we can disable the receiver data channel, but on playback,
we can disable the transmitter only if the RX has the DMA requests
disabled.
Also, for capture, there's no need to enable the transmit data channel.
It's sufficient to enable only the transmitter, which enables the bit
clock (shared with RX).
On stop, we just need to disable the DMA request, the transmit/receive data
channel, the interrupts and the receiver and/or the transmitter.
cdf87b9...
by
Iuliana Prodan <email address hidden>
dai: correct the order for DAI and DMA start/stop
To stop/suspend an active DMA channel:
1. Stop the DMA service request at the peripheral first (stop the DAI);
2. Disable the hardware service request on the appropriate DMA channel.
For start/resume:
1. Enable the DMA service request on the appropriate channel;
2. Enable the DMA service request at the peripheral (enable DAI).
When the start/stop order for DMA and DAI is different, on multiple
start/stop runs for playback or record or combined, we get an
underrun/overflow.
That's because the DAI makes a DMA request, before the DMA channel is
enabled.
Some platforms cannot just simple disable DMA channel during
the transfer, because it will hang the whole DMA controller.
Therefore, for DMA_SUSPEND_DRAIN, stop the DMA first
and let the DAI drain the FIFO in order to stop the channel
as soon as possible.
8963436...
by
Iuliana Prodan <email address hidden>
platform: imx: use DMA_DOMAIN in full synchronous mode
Use the full_sync attribute from dma_domain to schedule
tasks based on period ratio between the registrable
task and the current one.
Do not make it time dependent anymore.
abb8c80...
by
Iuliana Prodan <email address hidden>
schedule: dma_multi_chan: do not skip tasks for dma_domain scheduler
Add a full_sync attribute to ll_schedule domain.
This is set to true, for a full synchronous dma_domain
scheduler, which is not time dependent.
By default, it is false.
In full_sync case we use the ratio between the task period
and the registrable task period to do the scheduling, not
the task.start time.
We do this because for the DMA_DOMAIN there are no guarantees
for the accuracy of the period of the registrable task
which drives the entire scheduling.
An example is the mixer topology where we have 3 pipelines
for playback scenario:
- 1 pipeline for pcm1.0 (task 0);
- 1 pipeline for pcm1.1 (task 1);
- 1 pipeline for DAI (task 2).
Task 2 is the registrable task and this is always scheduled.
The other tasks (task 0 and task 1) are scheduled based on task->start.
The problem is that, at some point, the DMA transfer from DAI is
finished earlier than task->start for one of the task 0 or task 1
and this is not scheduled anymore.
And, task 2 ends up depleting one of the source buffers,
thus blocking the entire data flow.