hda-dma: change preload from blocking to repeating

Changes preload flow for host component using HDA-DMA.
Instead of waiting for DMA status for a limited amount
of time, it's better to just reschedule the pipeline
and check again. At least this time if the status
won't be set, we will know it's rather HW issue than
too small delay.

Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
This commit is contained in:
Tomasz Lauda 2019-06-11 15:03:13 +02:00 committed by Liam Girdwood
parent 6f65414176
commit 347ee08cb0
3 changed files with 25 additions and 5 deletions

View File

@ -763,10 +763,17 @@ static int host_copy(struct comp_dev *dev)
/* here only do preload, further copies happen
* in host_buffer_cb()
*/
if (pipeline_is_preload(dev->pipeline)) {
if (pipeline_is_preload(dev->pipeline) && !dev->position) {
ret = dma_copy(hd->dma, hd->chan, hd->dma_buffer->size,
DMA_COPY_PRELOAD | DMA_COPY_BLOCKING);
DMA_COPY_PRELOAD);
if (ret < 0) {
if (ret == -ENODATA) {
/* preload not finished, so stop processing */
trace_host("host_copy(), preload not yet "
"finished");
return PPL_STATUS_PATH_STOP;
}
trace_host_error("host_copy() error: dma_copy() "
"failed, ret = %u", ret);
return ret;

View File

@ -780,7 +780,9 @@ static int pipeline_copy(struct pipeline *p)
"->comp.id = %u, dir = %u", ret,
start->comp.id, dir);
p->preload = false;
/* stop preload only after full walkthrough */
if (ret != PPL_STATUS_PATH_STOP)
p->preload = false;
return ret;
}
@ -974,5 +976,8 @@ static uint64_t pipeline_task(void *arg)
}
tracev_pipe("pipeline_task() sched");
return pipeline_is_timer_driven(p) ? p->ipc_pipe.period : 0;
/* automatically reschedule for timer or not finished preload */
return (pipeline_is_timer_driven(p) || p->preload) ?
p->ipc_pipe.period : 0;
}

View File

@ -422,11 +422,19 @@ static int hda_dma_host_copy(struct dma *dma, unsigned int channel, int bytes,
hda_dma_get_dbg_vals(chan, HDA_DBG_PRE, HDA_DBG_HOST);
if (!(flags & DMA_COPY_PRELOAD))
if (flags & DMA_COPY_PRELOAD) {
/* report lack of data if preload is not yet finished */
ret = chan->direction == DMA_DIR_HMEM_TO_LMEM ?
hda_dma_is_buffer_full(dma, chan) :
hda_dma_is_buffer_empty(dma, chan);
if (!ret)
return -ENODATA;
} else {
/* set BFPI to let host gateway know we have read size,
* which will trigger next copy start.
*/
hda_dma_inc_fp(dma, chan->index, bytes);
}
/* blocking mode copy */
if (flags & DMA_COPY_BLOCKING) {