lkml.org 
[lkml]   [2018]   [Oct]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.18 18/48] ASoC: AMD: Ensure reset bit is cleared before configuring
    Date
    From: Akshu Agrawal <akshu.agrawal@amd.com>

    [ Upstream commit 2a665dba016d5493c7d826fec82b0cb643b30d42 ]

    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: Akshu Agrawal <akshu.agrawal@amd.com>
    Signed-off-by: Mark Brown <broonie@kernel.org>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    sound/soc/amd/acp-pcm-dma.c | 21 +++++++++++++++++++++
    1 file changed, 21 insertions(+)

    diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
    index 77203841c535..90df61d263b8 100644
    --- a/sound/soc/amd/acp-pcm-dma.c
    +++ b/sound/soc/amd/acp-pcm-dma.c
    @@ -16,6 +16,7 @@
    #include <linux/module.h>
    #include <linux/delay.h>
    #include <linux/io.h>
    +#include <linux/iopoll.h>
    #include <linux/sizes.h>
    #include <linux/pm_runtime.h>

    @@ -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);
    }

    +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
    * system memory <-> ACP SRAM
    @@ -238,6 +257,7 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
    config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
    &dmadscr[i]);
    }
    + pre_config_reset(acp_mmio, ch);
    config_acp_dma_channel(acp_mmio, ch,
    dma_dscr_idx - 1,
    NUM_DSCRS_PER_CHANNEL,
    @@ -277,6 +297,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,
    &dmadscr[i]);
    }
    + pre_config_reset(acp_mmio, ch);
    /* Configure the DMA channel with the above descriptore */
    config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1,
    NUM_DSCRS_PER_CHANNEL,
    --
    2.17.1
    \
     
     \ /
      Last update: 2018-10-05 18:26    [W:4.247 / U:1.296 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site