summaryrefslogtreecommitdiffstats
path: root/drivers/dma/dw-edma/dw-edma-v0-core.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2024-03-13 18:22:15 +0000
committerMark Brown <broonie@kernel.org>2024-03-13 18:22:15 +0000
commite25293d9d92cce24aa4ca21b90064661fe4d3fcf (patch)
tree50f45e19a3e397db28b6681d9bf3975f3c6dee8e /drivers/dma/dw-edma/dw-edma-v0-core.c
parent23fb6bc2696119391ec3a92ccaffe50e567c515e (diff)
parente8f897f4afef0031fe618a8e94127a0934896aba (diff)
downloadlinux-stable-e25293d9d92cce24aa4ca21b90064661fe4d3fcf.tar.gz
linux-stable-e25293d9d92cce24aa4ca21b90064661fe4d3fcf.tar.bz2
linux-stable-e25293d9d92cce24aa4ca21b90064661fe4d3fcf.zip
ASoC: Merge up release
In order to apply additional fixes that depend on the fixes merged for v6.8 merge up the final release.
Diffstat (limited to 'drivers/dma/dw-edma/dw-edma-v0-core.c')
-rw-r--r--drivers/dma/dw-edma/dw-edma-v0-core.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/dma/dw-edma/dw-edma-v0-core.c b/drivers/dma/dw-edma/dw-edma-v0-core.c
index b38786f0ad79..b75fdaffad9a 100644
--- a/drivers/dma/dw-edma/dw-edma-v0-core.c
+++ b/drivers/dma/dw-edma/dw-edma-v0-core.c
@@ -346,6 +346,20 @@ static void dw_edma_v0_core_write_chunk(struct dw_edma_chunk *chunk)
dw_edma_v0_write_ll_link(chunk, i, control, chunk->ll_region.paddr);
}
+static void dw_edma_v0_sync_ll_data(struct dw_edma_chunk *chunk)
+{
+ /*
+ * In case of remote eDMA engine setup, the DW PCIe RP/EP internal
+ * configuration registers and application memory are normally accessed
+ * over different buses. Ensure LL-data reaches the memory before the
+ * doorbell register is toggled by issuing the dummy-read from the remote
+ * LL memory in a hope that the MRd TLP will return only after the
+ * last MWr TLP is completed
+ */
+ if (!(chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
+ readl(chunk->ll_region.vaddr.io);
+}
+
static void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
{
struct dw_edma_chan *chan = chunk->chan;
@@ -412,6 +426,9 @@ static void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
SET_CH_32(dw, chan->dir, chan->id, llp.msb,
upper_32_bits(chunk->ll_region.paddr));
}
+
+ dw_edma_v0_sync_ll_data(chunk);
+
/* Doorbell */
SET_RW_32(dw, chan->dir, doorbell,
FIELD_PREP(EDMA_V0_DOORBELL_CH_MASK, chan->id));