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 */
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)
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)
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