From fa287e637b8ea4f8bd54ce54d1a2efa47b23ec0d Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Wed, 9 Feb 2022 16:01:04 +0800 Subject: [PATCH] dw-dma: disable linear link position when releasing dma channel The linear link position is only used by windows driver for computing present position. When doing pause-resume operation only zero data is reported by linear link position register. Currently when stream is resumed after paused, dw-dma will be first stopped and then started and the value of link position register is cleared when it is disabled. This patch will disable linear link position when the dma channel is released Signed-off-by: Rander Wang --- src/drivers/dw/dma.c | 6 +++--- src/platform/intel/cavs/include/cavs/drivers/dw-dma.h | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/drivers/dw/dma.c b/src/drivers/dw/dma.c index 14246bde9..1d570256b 100644 --- a/src/drivers/dw/dma.c +++ b/src/drivers/dw/dma.c @@ -228,6 +228,9 @@ static void dw_dma_channel_put_unlocked(struct dma_chan_data *channel) dw_dma_interrupt_mask(channel); + /* disable linear link position */ + platform_dw_dma_llp_disable(channel->dma, channel); + /* free the lli allocated by set_config*/ if (dw_chan->lli) { rfree(dw_chan->lli); @@ -443,9 +446,6 @@ static int dw_dma_stop(struct dma_chan_data *channel) sizeof(struct dw_lli) * channel->desc_count); #endif - /* disable linear link position */ - platform_dw_dma_llp_disable(dma, channel); - channel->status = COMP_STATE_PREPARE; out: diff --git a/src/platform/intel/cavs/include/cavs/drivers/dw-dma.h b/src/platform/intel/cavs/include/cavs/drivers/dw-dma.h index 3c7026ad0..4a48333ac 100644 --- a/src/platform/intel/cavs/include/cavs/drivers/dw-dma.h +++ b/src/platform/intel/cavs/include/cavs/drivers/dw-dma.h @@ -80,8 +80,11 @@ static inline void platform_dw_dma_llp_config(struct dma *dma, static inline void platform_dw_dma_llp_enable(struct dma *dma, struct dma_chan_data *chan) { - shim_write(DW_CHLLPC(dma, chan), - shim_read(DW_CHLLPC(dma, chan)) | SHIM_GPDMA_CHLLPC_EN); + uint32_t val; + + val = shim_read(DW_CHLLPC(dma, chan)); + if (!(val & SHIM_GPDMA_CHLLPC_EN)) + shim_write(DW_CHLLPC(dma, chan), val | SHIM_GPDMA_CHLLPC_EN); } static inline void platform_dw_dma_llp_disable(struct dma *dma,