Skip to content

Commit 1151570

Browse files
committed
dw-dma: use ll_current on dma start
On starting GPDMA we should use current link list item. That way every start will continue from the right buffer, not causing data corruption due to writing to the same period as Host DMA. Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
1 parent 1f1c9ed commit 1151570

1 file changed

Lines changed: 29 additions & 23 deletions

File tree

src/drivers/dw-dma.c

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -405,26 +405,28 @@ static int dw_dma_start(struct dma *dma, int channel)
405405

406406
#if DW_USE_HW_LLI
407407
/* TODO: Revisit: are we using LLP mode or single transfer ? */
408-
if (p->chan[channel].lli) {
408+
if (p->chan[channel].lli_current) {
409409
/* LLP mode - write LLP pointer */
410-
dw_write(dma, DW_LLP(channel), (uint32_t)p->chan[channel].lli);
410+
dw_write(dma, DW_LLP(channel),
411+
(uint32_t)p->chan[channel].lli_current);
411412
}
412413
#endif
413414
/* channel needs started from scratch, so write SARn, DARn */
414-
dw_write(dma, DW_SAR(channel), p->chan[channel].lli->sar);
415-
dw_write(dma, DW_DAR(channel), p->chan[channel].lli->dar);
415+
dw_write(dma, DW_SAR(channel), p->chan[channel].lli_current->sar);
416+
dw_write(dma, DW_DAR(channel), p->chan[channel].lli_current->dar);
416417

417418
/* program CTLn */
418-
dw_write(dma, DW_CTRL_LOW(channel), p->chan[channel].lli->ctrl_lo);
419-
dw_write(dma, DW_CTRL_HIGH(channel), p->chan[channel].lli->ctrl_hi);
419+
dw_write(dma, DW_CTRL_LOW(channel),
420+
p->chan[channel].lli_current->ctrl_lo);
421+
dw_write(dma, DW_CTRL_HIGH(channel),
422+
p->chan[channel].lli_current->ctrl_hi);
420423

421424
/* write channel config */
422425
dw_write(dma, DW_CFG_LOW(channel), p->chan[channel].cfg_lo);
423426
dw_write(dma, DW_CFG_HIGH(channel), p->chan[channel].cfg_hi);
424427

425428
/* enable the channel */
426429
p->chan[channel].status = COMP_STATE_ACTIVE;
427-
p->chan[channel].lli_current = p->chan[channel].lli;
428430
dw_write(dma, DW_DMA_CHAN_EN, CHAN_ENABLE(channel));
429431

430432
out:
@@ -745,6 +747,7 @@ static int dw_dma_set_config(struct dma *dma, int channel,
745747
sizeof(struct dw_lli2) * p->chan[channel].desc_count);
746748

747749
p->chan[channel].status = COMP_STATE_PREPARE;
750+
p->chan[channel].lli_current = p->chan[channel].lli;
748751
out:
749752
spin_unlock_irq(&dma->lock, flags);
750753
return ret;
@@ -949,24 +952,25 @@ static void dw_dma_irq_handler(void *data)
949952
return;
950953
}
951954

952-
953955
#if DW_USE_HW_LLI
954-
/* end of a LLI block */
955-
if (status_block & mask &&
956-
p->chan[i].cb_type & DMA_IRQ_TYPE_BLOCK) {
957-
next.src = DMA_RELOAD_LLI;
958-
next.dest = DMA_RELOAD_LLI;
959-
/* will reload lli by default */
960-
next.size = DMA_RELOAD_LLI;
961-
p->chan[i].cb(p->chan[i].cb_data,
962-
DMA_IRQ_TYPE_BLOCK, &next);
963-
if (next.size == DMA_RELOAD_END) {
964-
trace_dma("LSo");
965-
/* disable channel, finished */
966-
dw_write(dma, DW_DMA_CHAN_EN, CHAN_DISABLE(i));
967-
p->chan[i].status = COMP_STATE_PREPARE;
968-
}
956+
/* end of a LLI block */
957+
if (status_block & mask &&
958+
p->chan[i].cb_type & DMA_IRQ_TYPE_BLOCK) {
959+
next.src = DMA_RELOAD_LLI;
960+
next.dest = DMA_RELOAD_LLI;
961+
/* will reload lli by default */
962+
next.size = DMA_RELOAD_LLI;
963+
p->chan[i].cb(p->chan[i].cb_data,
964+
DMA_IRQ_TYPE_BLOCK, &next);
965+
if (next.size == DMA_RELOAD_END) {
966+
trace_dma("LSo");
967+
/* disable channel, finished */
968+
dw_write(dma, DW_DMA_CHAN_EN, CHAN_DISABLE(i));
969+
p->chan[i].status = COMP_STATE_PREPARE;
969970
}
971+
p->chan[i].lli_current =
972+
(struct dw_lli2 *)p->chan[i].lli_current->llp;
973+
}
970974
#endif
971975
/* end of a transfer */
972976
if ((status_tfr & mask) &&
@@ -1117,6 +1121,8 @@ static void dw_dma_irq_handler(void *data)
11171121
dw_write(dma, DW_DMA_CHAN_EN, CHAN_DISABLE(i));
11181122
p->chan[i].status = COMP_STATE_PREPARE;
11191123
}
1124+
p->chan[i].lli_current =
1125+
(struct dw_lli2 *)p->chan[i].lli_current->llp;
11201126
}
11211127
#endif
11221128
/* end of a transfer */

0 commit comments

Comments
 (0)