• Russell King - ARM Linux's avatar
    Update imx-sdma cyclic handling to report residue · d1a792f3
    Russell King - ARM Linux authored
    I received a report this morning from one of the Novena developers that
    the behaviour of the iMX6 ASoC codec driver (using imx-pcm-dma.c) was
    sub-optimal under high system load.
    
    While there are issues relating to system load remaining, upon reviewing
    the ASoC imx-pcm-dma.c driver, it was noticed that it not using the
    residue support, because SDMA doesn't support it.  This has the effect
    that SDMA has to make multiple calls into the ASoC and ALSA code, one
    for each period.
    
    Since ALSA's snd_pcm_elapsed() does not need to be called multiple times
    and it is entirely sufficient to call it once to update ALSA with the
    current buffer position via the pointer method, we can do better here.
    We can also avoid stopping the DMA entirely, just like real cyclic DMA
    implementations behave.  While this means that we replay some old samples,
    this is a nicer behaviour than having audio stop and restart.
    
    The changes to achieve this are relatively minor - imx-sdma.c can track
    where the DMA is to the nearest descriptor boundary - it does this
    already when deciding how many callbacks to issue.  In doing this,
    buf_tail always points at the descriptor which will complete next.
    
    The residue is defined by the bytes remaining to the end of the buffer,
    when the buffer is viewed as a single block of memory [start...end].
    So, when we start out, there's a full buffer worth of residue, and this
    counts down as we approach the end of the buffer, eventually becoming
    zero at the end, before returning to the full buffer worth when we
    wrap back to the start.
    
    Moving the walking of the descriptors into the interrupt handler means
    that we can update the BD_DONE flag at interrupt time, thus avoiding
    a delayed tasklet stopping the cyclic DMA.
    
    This means that the residue can be calculated from (total descriptors -
    buf_tail) * descriptor size.  This is what the change below does.  We
    update imx-pcm-dma.c to remove the NO_RESIDUE flag since we now provide
    the residue.
    Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
    Tested-by: default avatarShawn Guo <shawn.guo@linaro.org>
    Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
    d1a792f3
imx-sdma.c 41.1 KB