summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/skylake/skl-sst-cldma.c
diff options
context:
space:
mode:
authorJeeja KP2015-11-13 14:52:10 +0100
committerMark Brown2015-11-18 19:46:36 +0100
commite797af53b8814dfbc3c6ac134c528b8ab480f275 (patch)
tree7398ed99adc690aeb3f4b4aa5f614854f15a44a7 /sound/soc/intel/skylake/skl-sst-cldma.c
parentASoC: Intel: Skylake: Reset the DSP when set D3 fails (diff)
downloadkernel-qcow2-linux-e797af53b8814dfbc3c6ac134c528b8ab480f275.tar.gz
kernel-qcow2-linux-e797af53b8814dfbc3c6ac134c528b8ab480f275.tar.xz
kernel-qcow2-linux-e797af53b8814dfbc3c6ac134c528b8ab480f275.zip
ASoC: Intel: Skylake: Fix CLDMA buffer wrap case
When downloading the firmware/module, if the ring buffer boundary is reached, we need to wrap to the zeroth position. On next copy we need to copy till end of buffer and the remaining buffer needs to be copied from zeroth position. In this case copy was not handled correctly when wrap condition is reached which caused invalid data to be copied resulting in invalid hash failure. This patch fixes the issue by handling copy at the boundary condition correctly. Signed-off-by: Jeeja KP <jeeja.kp@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/skylake/skl-sst-cldma.c')
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c
index 4ddabe30b62a..b03d9db0acad 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.c
+++ b/sound/soc/intel/skylake/skl-sst-cldma.c
@@ -180,6 +180,21 @@ static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
ctx->cl_dev.dma_buffer_offset, trigger);
dev_dbg(ctx->dev, "spib position: %d\n", ctx->cl_dev.curr_spib_pos);
+ /*
+ * Check if the size exceeds buffer boundary. If it exceeds
+ * max_buffer size, then copy till buffer size and then copy
+ * remaining buffer from the start of ring buffer.
+ */
+ if (ctx->cl_dev.dma_buffer_offset + size > ctx->cl_dev.bufsize) {
+ unsigned int size_b = ctx->cl_dev.bufsize -
+ ctx->cl_dev.dma_buffer_offset;
+ memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset,
+ curr_pos, size_b);
+ size -= size_b;
+ curr_pos += size_b;
+ ctx->cl_dev.dma_buffer_offset = 0;
+ }
+
memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset,
curr_pos, size);