dmaengine: xilinx_dma: Fix control reg update in vdma_channel_set_config
authorRadhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Thu, 26 Sep 2019 10:50:58 +0000 (16:20 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Nov 2019 18:20:53 +0000 (19:20 +0100)
[ Upstream commit 6c6de1ddb1be3840f2ed5cc9d009a622720940c9 ]

In vdma_channel_set_config clear the delay, frame count and master mask
before updating their new values. It avoids programming incorrect state
when input parameters are different from default.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Acked-by: Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Link: https://lore.kernel.org/r/1569495060-18117-3-git-send-email-radhey.shyam.pandey@xilinx.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/dma/xilinx/xilinx_dma.c

index c124423..8aec137 100644 (file)
@@ -72,6 +72,9 @@
 #define XILINX_DMA_DMACR_CIRC_EN               BIT(1)
 #define XILINX_DMA_DMACR_RUNSTOP               BIT(0)
 #define XILINX_DMA_DMACR_FSYNCSRC_MASK         GENMASK(6, 5)
+#define XILINX_DMA_DMACR_DELAY_MASK            GENMASK(31, 24)
+#define XILINX_DMA_DMACR_FRAME_COUNT_MASK      GENMASK(23, 16)
+#define XILINX_DMA_DMACR_MASTER_MASK           GENMASK(11, 8)
 
 #define XILINX_DMA_REG_DMASR                   0x0004
 #define XILINX_DMA_DMASR_EOL_LATE_ERR          BIT(15)
@@ -2112,8 +2115,10 @@ int xilinx_vdma_channel_set_config(struct dma_chan *dchan,
        chan->config.gen_lock = cfg->gen_lock;
        chan->config.master = cfg->master;
 
+       dmacr &= ~XILINX_DMA_DMACR_GENLOCK_EN;
        if (cfg->gen_lock && chan->genlock) {
                dmacr |= XILINX_DMA_DMACR_GENLOCK_EN;
+               dmacr &= ~XILINX_DMA_DMACR_MASTER_MASK;
                dmacr |= cfg->master << XILINX_DMA_DMACR_MASTER_SHIFT;
        }
 
@@ -2129,11 +2134,13 @@ int xilinx_vdma_channel_set_config(struct dma_chan *dchan,
        chan->config.delay = cfg->delay;
 
        if (cfg->coalesc <= XILINX_DMA_DMACR_FRAME_COUNT_MAX) {
+               dmacr &= ~XILINX_DMA_DMACR_FRAME_COUNT_MASK;
                dmacr |= cfg->coalesc << XILINX_DMA_DMACR_FRAME_COUNT_SHIFT;
                chan->config.coalesc = cfg->coalesc;
        }
 
        if (cfg->delay <= XILINX_DMA_DMACR_DELAY_MAX) {
+               dmacr &= ~XILINX_DMA_DMACR_DELAY_MASK;
                dmacr |= cfg->delay << XILINX_DMA_DMACR_DELAY_SHIFT;
                chan->config.delay = cfg->delay;
        }