lkml.org 
[lkml]   [2018]   [Mar]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.4 034/115] dmaengine: imx-sdma: add 1ms delay to ensure SDMA channel is stopped
    Date
    From: Jiada Wang <jiada_wang@mentor.com>

    [ Upstream commit 7f3ff14b7eb1ffad132117f08a1973b48e653d43 ]

    sdma_disable_channel() cannot ensure dma is stopped to access
    module's FIFOs. There is chance SDMA core is running and accessing
    BD when disable of corresponding channel, this may cause sometimes
    even after call of .sdma_disable_channel(), SDMA core still be
    running and accessing module's FIFOs.

    According to NXP R&D team a delay of one BD SDMA cost time (maximum
    is 1ms) should be added after disable of the channel bit, to ensure
    SDMA core has really been stopped after SDMA clients call
    .device_terminate_all.

    This patch introduces adds a new function sdma_disable_channel_with_delay()
    which simply adds 1ms delay after call sdma_disable_channel(),
    and set it as .device_terminate_all.

    Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
    Signed-off-by: Vinod Koul <vinod.koul@intel.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    drivers/dma/imx-sdma.c | 17 ++++++++++++++++-
    1 file changed, 16 insertions(+), 1 deletion(-)

    diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
    index 0f6fd42f55ca..f8d740a6740d 100644
    --- a/drivers/dma/imx-sdma.c
    +++ b/drivers/dma/imx-sdma.c
    @@ -911,6 +911,21 @@ static int sdma_disable_channel(struct dma_chan *chan)
    return 0;
    }

    +static int sdma_disable_channel_with_delay(struct dma_chan *chan)
    +{
    + sdma_disable_channel(chan);
    +
    + /*
    + * According to NXP R&D team a delay of one BD SDMA cost time
    + * (maximum is 1ms) should be added after disable of the channel
    + * bit, to ensure SDMA core has really been stopped after SDMA
    + * clients call .device_terminate_all.
    + */
    + mdelay(1);
    +
    + return 0;
    +}
    +
    static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
    {
    struct sdma_engine *sdma = sdmac->sdma;
    @@ -1793,7 +1808,7 @@ static int sdma_probe(struct platform_device *pdev)
    sdma->dma_device.device_prep_slave_sg = sdma_prep_slave_sg;
    sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic;
    sdma->dma_device.device_config = sdma_config;
    - sdma->dma_device.device_terminate_all = sdma_disable_channel;
    + sdma->dma_device.device_terminate_all = sdma_disable_channel_with_delay;
    sdma->dma_device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
    sdma->dma_device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
    sdma->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
    --
    2.14.1
    \
     
     \ /
      Last update: 2018-03-03 23:39    [W:4.048 / U:0.532 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site