mirror of https://github.com/thesofproject/sof.git
host: add a completion work to notify host side
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@linux.intel.com>
This commit is contained in:
parent
1e524a17f0
commit
9e58cf39a5
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) |\
|
||||
|
|
Loading…
Reference in New Issue