[Sound-open-firmware] [PATCH v3 12/27] host: add a completion work to notify host side

Keyon Jie yang.jie at linux.intel.com
Sat Feb 11 03:17:52 CET 2017


We need to wait until the last bytes/period is finished in dai,
before we can notify host side about that, otherwise, host side
will trigger stop too early, and we will miss rendering them.

Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
---
 src/audio/host.c                                  | 38 +++++++++++++++++++++++
 src/audio/pipeline.c                              |  1 +
 src/include/reef/audio/pipeline.h                 |  2 ++
 src/platform/baytrail/include/platform/platform.h |  6 ++++
 4 files changed, 47 insertions(+)

diff --git a/src/audio/host.c b/src/audio/host.c
index e8265df..6a4c669 100644
--- a/src/audio/host.c
+++ b/src/audio/host.c
@@ -64,6 +64,7 @@ struct host_data {
 	completion_t complete;
 	struct period_desc *period;
 	struct comp_buffer *dma_buffer;
+	struct work work;
 
 	/* local and host DMA buffer info */
 	struct hc_buf host;
@@ -220,6 +221,10 @@ static void host_dma_cb_playback(struct comp_dev *dev,
 			/* end of stream, stop */
 			next->size = 0;
 			need_copy = 0;
+
+			/* will notify host side once dai tell us */
+			wait_init(&dev->pipeline->complete);
+			work_schedule_default(&hd->work, PLATFORM_HOST_FINISH_DELAY);
 			goto next_copy;
 		}
 
@@ -354,6 +359,38 @@ static void host_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
 		host_dma_cb_capture(dev, next);
 }
 
+/* We need to wait until the last bytes/period is finished in dai, before we
+ * can notify host side about that, otherwise, host side will trigger stop too
+ * early, and we will miss rendering them.
+ * This work should be scheduled once the copy for host component is finished,
+ * and wait a timeout inside the work for pipeline->complete, which should be
+ * set in the endpoint(dai) rendering finishing callback.
+ */
+static uint32_t host_finish_work(void *data, uint32_t udelay)
+{
+	struct comp_dev *dev = (struct comp_dev *)data;
+	struct host_data *hd = comp_get_drvdata(dev);
+	int ret;
+
+	dev->pipeline->complete.timeout = PLATFORM_HOST_FINISH_TIMEOUT;
+	ret = wait_for_completion_timeout(&dev->pipeline->complete);
+	if (ret < 0)
+		trace_comp_error("eHf");
+	else {
+		trace_comp("hFw");
+		/* update for host side */
+		if (hd->host_pos) {
+			*hd->host_pos = hd->host_pos_read;
+			/* send the last notification to host */
+			ipc_stream_send_notification(dev, &hd->cp);
+		}
+	}
+
+	return 0;
+}
+
+
+
 static struct comp_dev *host_new(uint32_t type, uint32_t index,
 	uint32_t direction)
 {
@@ -389,6 +426,7 @@ static struct comp_dev *host_new(uint32_t type, uint32_t index,
 	hd->source = NULL;
 	hd->sink = NULL;
 	hd->split_remaining = 0;
+	work_init(&hd->work, host_finish_work, dev, WORK_ASYNC);
 
 	/* init buffer elems */
 	list_init(&hd->config.elem_list);
diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c
index 9d74e37..41693ae 100644
--- a/src/audio/pipeline.c
+++ b/src/audio/pipeline.c
@@ -141,6 +141,7 @@ struct pipeline *pipeline_new(uint32_t id)
 	list_init(&p->host_ep_list);
 	list_init(&p->dai_ep_list);
 	list_init(&p->buffer_list);
+	wait_init(&p->complete);
 
 	spinlock_init(&p->lock);
 	list_item_prepend(&p->list, &pipe_data->pipeline_list);
diff --git a/src/include/reef/audio/pipeline.h b/src/include/reef/audio/pipeline.h
index 26c1dd6..e7de501 100644
--- a/src/include/reef/audio/pipeline.h
+++ b/src/include/reef/audio/pipeline.h
@@ -39,6 +39,7 @@
 #include <reef/dma.h>
 #include <reef/audio/component.h>
 #include <reef/trace.h>
+#include <reef/wait.h>
 
 #define trace_pipe(__e)	trace_event(TRACE_CLASS_PIPE, __e)
 #define trace_pipe_error(__e)	trace_error(TRACE_CLASS_PIPE, __e)
@@ -50,6 +51,7 @@
 struct pipeline {
 	uint32_t id;		/* id */
 	spinlock_t lock;
+	completion_t complete;	/* indicate if the pipeline data is finished*/
 
 	/* lists */
 	struct list_item host_ep_list;		/* list of host endpoints */
diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h
index f86019d..7df65b8 100644
--- a/src/platform/baytrail/include/platform/platform.h
+++ b/src/platform/baytrail/include/platform/platform.h
@@ -86,6 +86,12 @@
 /* WorkQ window size in microseconds */
 #define PLATFORM_WORKQ_WINDOW	2000
 
+/* Host finish work schedule delay in microseconds */
+#define PLATFORM_HOST_FINISH_DELAY	100
+
+/* Host finish work(drain from host to dai) timeout in microseconds */
+#define PLATFORM_HOST_FINISH_TIMEOUT	50000
+
 /* Platform defined panic code */
 #define platform_panic(__x) \
 		shim_write(SHIM_IPCXL, ((shim_read(SHIM_IPCXL) & 0xc0000000) |\
-- 
2.7.4



More information about the Sound-open-firmware mailing list