Skip to content

Commit 5ea5d5b

Browse files
authored
Merge pull request #142 from tlauda/topic/dw_dma_use_done
dw-dma: use done bit for linked list transfers
2 parents 74683c4 + 148ecfe commit 5ea5d5b

1 file changed

Lines changed: 51 additions & 10 deletions

File tree

src/drivers/dw-dma.c

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
#if defined (CONFIG_HASWELL) || defined (CONFIG_BROADWELL)
152152

153153
/* CTL_HI */
154-
#define DW_CTLH_DONE 0x00001000
154+
#define DW_CTLH_DONE(x) ((x) << 12)
155155
#define DW_CTLH_BLOCK_TS_MASK 0x00000fff
156156

157157
/* CFG_LO */
@@ -173,7 +173,7 @@
173173
#define DW_CTLL_D_SCAT_EN (1 << 18)
174174

175175
/* CTL_HI */
176-
#define DW_CTLH_DONE 0x00020000
176+
#define DW_CTLH_DONE(x) ((x) << 17)
177177
#define DW_CTLH_BLOCK_TS_MASK 0x0001ffff
178178
#define DW_CTLH_CLASS(x) ((x) << 29)
179179
#define DW_CTLH_WEIGHT(x) ((x) << 18)
@@ -204,13 +204,16 @@
204204
#define DW_CTLL_D_SCAT_EN (1 << 18)
205205

206206
/* CTL_HI */
207-
#define DW_CTLH_DONE 0x00020000
207+
#define DW_CTLH_DONE(x) ((x) << 17)
208208
#define DW_CTLH_BLOCK_TS_MASK 0x0001ffff
209-
#define DW_CTLH_CLASS(x) (x << 29)
210-
#define DW_CTLH_WEIGHT(x) (x << 18)
209+
#define DW_CTLH_CLASS(x) ((x) << 29)
210+
#define DW_CTLH_WEIGHT(x) ((x) << 18)
211211

212212
/* CFG_LO */
213-
#define DW_CFG_CH_DRAIN 0x400
213+
#define DW_CFG_CTL_HI_UPD_EN (1 << 5)
214+
#define DW_CFG_CH_DRAIN (1 << 10)
215+
#define DW_CFG_RELOAD_SRC (1 << 30)
216+
#define DW_CFG_RELOAD_DST (1 << 31)
214217

215218
/* CFG_HI */
216219
#define DW_CFGH_SRC_PER(x) (x << 0)
@@ -227,7 +230,7 @@
227230

228231
/* default initial setup register values */
229232
#define DW_CFG_LOW_DEF 0x00000003
230-
#define DW_CFG_HIGH_DEF 0x0
233+
#define DW_CFG_HIGH_DEF 0x0
231234

232235
#define DW_REG_MAX DW_DMA_GLB_CFG
233236
#endif
@@ -657,26 +660,43 @@ static int dw_dma_set_config(struct dma *dma, int channel,
657660
case DMA_DIR_LMEM_TO_HMEM:
658661
lli_desc->ctrl_lo |= DW_CTLL_FC_M2M;
659662
lli_desc->ctrl_lo |= DW_CTLL_SRC_INC | DW_CTLL_DST_INC;
663+
#if DW_USE_HW_LLI
664+
lli_desc->ctrl_lo |=
665+
DW_CTLL_LLP_S_EN | DW_CTLL_LLP_D_EN;
666+
#endif
660667
lli_desc->sar =
661668
(uint32_t)sg_elem->src | PLATFORM_HOST_DMA_MASK;
662669
lli_desc->dar = (uint32_t)sg_elem->dest;
663670
break;
664671
case DMA_DIR_HMEM_TO_LMEM:
665672
lli_desc->ctrl_lo |= DW_CTLL_FC_M2M;
666673
lli_desc->ctrl_lo |= DW_CTLL_SRC_INC | DW_CTLL_DST_INC;
674+
#if DW_USE_HW_LLI
675+
lli_desc->ctrl_lo |=
676+
DW_CTLL_LLP_S_EN | DW_CTLL_LLP_D_EN;
677+
#endif
667678
lli_desc->dar =
668679
(uint32_t)sg_elem->dest | PLATFORM_HOST_DMA_MASK;
669680
lli_desc->sar = (uint32_t)sg_elem->src;
670681
break;
671682
case DMA_DIR_MEM_TO_MEM:
672683
lli_desc->ctrl_lo |= DW_CTLL_FC_M2M;
673684
lli_desc->ctrl_lo |= DW_CTLL_SRC_INC | DW_CTLL_DST_INC;
685+
#if DW_USE_HW_LLI
686+
lli_desc->ctrl_lo |=
687+
DW_CTLL_LLP_S_EN | DW_CTLL_LLP_D_EN;
688+
#endif
674689
lli_desc->sar = (uint32_t)sg_elem->src | PLATFORM_HOST_DMA_MASK;
675690
lli_desc->dar = (uint32_t)sg_elem->dest | PLATFORM_HOST_DMA_MASK;
676691
break;
677692
case DMA_DIR_MEM_TO_DEV:
678693
lli_desc->ctrl_lo |= DW_CTLL_FC_M2P;
679694
lli_desc->ctrl_lo |= DW_CTLL_SRC_INC | DW_CTLL_DST_FIX;
695+
#if DW_USE_HW_LLI
696+
lli_desc->ctrl_lo |= DW_CTLL_LLP_S_EN;
697+
lli_desc->ctrl_hi |= DW_CTLH_DONE(1);
698+
p->chan[channel].cfg_lo |= DW_CFG_RELOAD_DST;
699+
#endif
680700
p->chan[channel].cfg_hi |=
681701
DW_CFGH_DST_PER(config->dest_dev);
682702
lli_desc->sar = (uint32_t)sg_elem->src | PLATFORM_HOST_DMA_MASK;
@@ -685,6 +705,11 @@ static int dw_dma_set_config(struct dma *dma, int channel,
685705
case DMA_DIR_DEV_TO_MEM:
686706
lli_desc->ctrl_lo |= DW_CTLL_FC_P2M;
687707
lli_desc->ctrl_lo |= DW_CTLL_SRC_FIX | DW_CTLL_DST_INC;
708+
#if DW_USE_HW_LLI
709+
lli_desc->ctrl_lo |= DW_CTLL_LLP_D_EN;
710+
lli_desc->ctrl_hi |= DW_CTLH_DONE(0);
711+
p->chan[channel].cfg_lo |= DW_CFG_RELOAD_SRC;
712+
#endif
688713
p->chan[channel].cfg_hi |=
689714
DW_CFGH_SRC_PER(config->src_dev);
690715
lli_desc->sar = (uint32_t)sg_elem->src;
@@ -693,6 +718,10 @@ static int dw_dma_set_config(struct dma *dma, int channel,
693718
case DMA_DIR_DEV_TO_DEV:
694719
lli_desc->ctrl_lo |= DW_CTLL_FC_P2P;
695720
lli_desc->ctrl_lo |= DW_CTLL_SRC_FIX | DW_CTLL_DST_FIX;
721+
#if DW_USE_HW_LLI
722+
lli_desc->ctrl_lo |=
723+
DW_CTLL_LLP_S_EN | DW_CTLL_LLP_D_EN;
724+
#endif
696725
p->chan[channel].cfg_hi |=
697726
DW_CFGH_SRC_PER(config->src_dev) |
698727
DW_CFGH_DST_PER(config->dest_dev);
@@ -724,13 +753,15 @@ static int dw_dma_set_config(struct dma *dma, int channel,
724753

725754
/* set next descriptor in list */
726755
lli_desc->llp = (uint32_t)(lli_desc + 1);
727-
#if DW_USE_HW_LLI
728-
lli_desc->ctrl_lo |= DW_CTLL_LLP_S_EN | DW_CTLL_LLP_D_EN;
729-
#endif
756+
730757
/* next descriptor */
731758
lli_desc++;
732759
}
733760

761+
#if DW_USE_HW_LLI
762+
p->chan[channel].cfg_lo |= DW_CFG_CTL_HI_UPD_EN;
763+
#endif
764+
734765
/* end of list or cyclic buffer ? */
735766
if (config->cyclic) {
736767
lli_desc_tail->llp = (uint32_t)lli_desc_head;
@@ -968,6 +999,11 @@ static void dw_dma_irq_handler(void *data)
968999
dw_write(dma, DW_DMA_CHAN_EN, CHAN_DISABLE(i));
9691000
p->chan[i].status = COMP_STATE_PREPARE;
9701001
}
1002+
1003+
p->chan[i].lli_current->ctrl_hi &= ~DW_CTLH_DONE(1);
1004+
dcache_writeback_region(p->chan[i].lli_current,
1005+
sizeof(*p->chan[i].lli_current));
1006+
9711007
p->chan[i].lli_current =
9721008
(struct dw_lli2 *)p->chan[i].lli_current->llp;
9731009
}
@@ -1121,6 +1157,11 @@ static void dw_dma_irq_handler(void *data)
11211157
dw_write(dma, DW_DMA_CHAN_EN, CHAN_DISABLE(i));
11221158
p->chan[i].status = COMP_STATE_PREPARE;
11231159
}
1160+
1161+
p->chan[i].lli_current->ctrl_hi &= ~DW_CTLH_DONE(1);
1162+
dcache_writeback_region(p->chan[i].lli_current,
1163+
sizeof(*p->chan[i].lli_current));
1164+
11241165
p->chan[i].lli_current =
11251166
(struct dw_lli2 *)p->chan[i].lli_current->llp;
11261167
}

0 commit comments

Comments
 (0)