aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0583-amd-i2s-dma-pointer-uses-Link-position-counter.This-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0583-amd-i2s-dma-pointer-uses-Link-position-counter.This-.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0583-amd-i2s-dma-pointer-uses-Link-position-counter.This-.patch117
1 files changed, 117 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0583-amd-i2s-dma-pointer-uses-Link-position-counter.This-.patch b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0583-amd-i2s-dma-pointer-uses-Link-position-counter.This-.patch
new file mode 100644
index 00000000..fa4c92c2
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0583-amd-i2s-dma-pointer-uses-Link-position-counter.This-.patch
@@ -0,0 +1,117 @@
+From e4063812b5c6f06ce7a5ed815c520b5e91078891 Mon Sep 17 00:00:00 2001
+From: Sudheesh Mavila <sudheesh.mavila@amd.com>
+Date: Thu, 24 Jan 2019 11:06:42 +0530
+Subject: [PATCH 0583/2940] amd-i2s dma pointer uses Link position counter.This
+ has been changed to Linear position counter and this rectifies underruns
+
+Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
+---
+ sound/soc/amd/raven/acp3x-pcm-dma.c | 64 ++++++++++++++++++++++++-----
+ 1 file changed, 53 insertions(+), 11 deletions(-)
+
+diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
+index 23b0fe631a5b..427b2a089a6d 100755
+--- a/sound/soc/amd/raven/acp3x-pcm-dma.c
++++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
+@@ -36,12 +36,24 @@ struct i2s_dev_data {
+ struct snd_pcm_substream *capture_stream;
+ };
+
++union acp3x_dma_count {
++ struct {
++ u32 low;
++ u32 high;
++ } bcount;
++ u64 bytescount;
++};
++
++
+ struct i2s_stream_instance {
+ u16 num_pages;
+ u16 channels;
+ u32 xfer_resolution;
+ u32 val;
+ dma_addr_t dma_addr;
++ u32 byte_cnt_high_reg_offset;
++ u32 byte_cnt_low_reg_offset;
++ u64 bytescount;
+ void __iomem *acp3x_base;
+ };
+
+@@ -331,6 +343,25 @@ static int acp3x_dma_open(struct snd_pcm_substream *substream)
+ return 0;
+ }
+
++static u64 acp_get_byte_count(struct i2s_stream_instance *rtd, int direction)
++{
++ union acp3x_dma_count byte_count;
++
++ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
++ byte_count.bcount.high = rv_readl(rtd->acp3x_base +
++ mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
++ byte_count.bcount.low = rv_readl(rtd->acp3x_base +
++ mmACP_BT_TX_LINEARPOSITIONCNTR_LOW);
++ } else {
++ byte_count.bcount.high = rv_readl(rtd->acp3x_base +
++ mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
++ byte_count.bcount.low = rv_readl(rtd->acp3x_base +
++ mmACP_BT_RX_LINEARPOSITIONCNTR_LOW);
++ }
++ return byte_count.bytescount;
++}
++
++
+ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+ {
+@@ -362,18 +393,28 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
+
+ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream)
+ {
++ u64 bytescount = 0;
+ u32 pos = 0;
+- struct i2s_stream_instance *rtd = substream->runtime->private_data;
+-
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+- pos = rv_readl(rtd->acp3x_base +
+- mmACP_BT_TX_LINKPOSITIONCNTR);
+- else
+- pos = rv_readl(rtd->acp3x_base +
+- mmACP_BT_RX_LINKPOSITIONCNTR);
+-
+- if (pos >= MAX_BUFFER)
+- pos = 0;
++ u32 buffersize = 0;
++ struct i2s_stream_instance *rtd =
++ substream->runtime->private_data;
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ buffersize = frames_to_bytes(substream->runtime,
++ substream->runtime->buffer_size);
++ bytescount = acp_get_byte_count(rtd, substream->stream);
++ if (bytescount > rtd->bytescount)
++ bytescount -= rtd->bytescount;
++ pos = do_div(bytescount, buffersize);
++ } else {
++ buffersize = frames_to_bytes(substream->runtime,
++ substream->runtime->buffer_size);
++ bytescount = acp_get_byte_count(rtd, substream->stream);
++ if (bytescount > rtd->bytescount)
++ bytescount -= rtd->bytescount;
++ pos = do_div(bytescount, buffersize);
++ }
++ if (pos >= MAX_BUFFER)
++ pos %= buffersize;
+
+ return bytes_to_frames(substream->runtime, pos);
+ }
+@@ -540,6 +581,7 @@ static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream,
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ rtd->bytescount = acp_get_byte_count(rtd, substream->stream);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
+ val = val | BIT(0);
+--
+2.17.1
+