Commit 2a665dba authored by Akshu Agrawal's avatar Akshu Agrawal Committed by Mark Brown

ASoC: AMD: Ensure reset bit is cleared before configuring

HW register descriptions says:
"DMA Channel Reset...Software must confirm that this bit is
cleared before reprogramming any of the channel configuration registers."
There could be cases where dma stop errored out leaving dma channel
in reset state. We need to ensure that before the start of another dma,
channel is out of the reset state.
Signed-off-by: default avatarAkshu Agrawal <akshu.agrawal@amd.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 6c92d5a2
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
...@@ -184,6 +185,24 @@ static void config_dma_descriptor_in_sram(void __iomem *acp_mmio, ...@@ -184,6 +185,24 @@ static void config_dma_descriptor_in_sram(void __iomem *acp_mmio,
acp_reg_write(descr_info->xfer_val, acp_mmio, mmACP_SRBM_Targ_Idx_Data); acp_reg_write(descr_info->xfer_val, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
} }
static void pre_config_reset(void __iomem *acp_mmio, u16 ch_num)
{
u32 dma_ctrl;
int ret;
/* clear the reset bit */
dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRst_MASK;
acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
/* check the reset bit before programming configuration registers */
ret = readl_poll_timeout(acp_mmio + ((mmACP_DMA_CNTL_0 + ch_num) * 4),
dma_ctrl,
!(dma_ctrl & ACP_DMA_CNTL_0__DMAChRst_MASK),
100, ACP_DMA_RESET_TIME);
if (ret < 0)
pr_err("Failed to clear reset of channel : %d\n", ch_num);
}
/* /*
* Initialize the DMA descriptor information for transfer between * Initialize the DMA descriptor information for transfer between
* system memory <-> ACP SRAM * system memory <-> ACP SRAM
...@@ -236,6 +255,7 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio, ...@@ -236,6 +255,7 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx, config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
&dmadscr[i]); &dmadscr[i]);
} }
pre_config_reset(acp_mmio, ch);
config_acp_dma_channel(acp_mmio, ch, config_acp_dma_channel(acp_mmio, ch,
dma_dscr_idx - 1, dma_dscr_idx - 1,
NUM_DSCRS_PER_CHANNEL, NUM_DSCRS_PER_CHANNEL,
...@@ -275,6 +295,7 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size, ...@@ -275,6 +295,7 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx, config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
&dmadscr[i]); &dmadscr[i]);
} }
pre_config_reset(acp_mmio, ch);
/* Configure the DMA channel with the above descriptore */ /* Configure the DMA channel with the above descriptore */
config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1, config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1,
NUM_DSCRS_PER_CHANNEL, NUM_DSCRS_PER_CHANNEL,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment