[Sound-open-firmware] [PATCH] dai: fix dma pointer init for passthrough pipelines.

Liam Girdwood liam.r.girdwood at linux.intel.com
Mon Dec 11 15:44:48 CET 2017


Replace the r_ptr == w_ptr check as it was racy on the completion of the
host DMA preload. Better to check using the source component type.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/audio/dai.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/audio/dai.c b/src/audio/dai.c
index 1afbc87..c50a274 100644
--- a/src/audio/dai.c
+++ b/src/audio/dai.c
@@ -492,27 +492,34 @@ static int dai_reset(struct comp_dev *dev)
 	return 0;
 }
 
-/* the configuration of the upstream pipeline is unknown
- * to the DAI so we have to check that the r_ptr != w_ptr for the
- * DAI DMA buffer. This is not required for capture as the pipeline is
- * run after the first period has been copied (i.e. r_ptr != w_ptr).
+/* The playback source pipeline must be advanced by one period so that it
+ * does not write to the period that DMA is reading. The configuration of the
+ * upstream pipeline is unknown to the DAI but we can check if the source buffer
+ * is shared with another DMA engine (which preloads the buffer by one period)
+ * and only advance the write pointer when source component is not another
+ * DMA engine.
  */
 static void dai_pointer_init(struct comp_dev *dev)
 {
 	struct comp_buffer *dma_buffer;
 	struct dai_data *dd = comp_get_drvdata(dev);
 
-	/* advance w/r pointer by one period if equal at stream start */
+	/* not reuquired for capture streams */
 	if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK) {
 		dma_buffer = list_first_item(&dev->bsource_list,
 			struct comp_buffer, sink_list);
 
-		if (dma_buffer->w_ptr != dma_buffer->r_ptr)
-			return;
-
-		/* advance source pipeline w_ptr by one period
-		 * this places pipeline w_ptr in period before DAI r_ptr */
-		comp_update_buffer_produce(dma_buffer, dd->period_bytes);
+		switch (dma_buffer->source->comp.type) {
+		case SOF_COMP_HOST:
+		case SOF_COMP_SG_HOST:
+			/* buffer is preloaded and advanced by host DMA engine */
+			break;
+		default:
+			/* advance source pipeline w_ptr by one period
+			 * this places pipeline w_ptr in period before DAI r_ptr */
+			comp_update_buffer_produce(dma_buffer, dd->period_bytes);
+			break;
+		}
 	}
 }
 
-- 
2.14.1



More information about the Sound-open-firmware mailing list