@@ -126,6 +126,51 @@ static void dw_dma_increment_pointer(struct dw_dma_chan_data *chan, int bytes)
126126 (chan -> ptr_data .current_ptr - chan -> ptr_data .end_ptr );
127127}
128128
129+ #if !CONFIG_HW_LLI
130+ /* reload using LLI data from DMA IRQ cb */
131+ static inline void dw_dma_chan_reload_lli_cb (void * arg , enum notify_id type ,
132+ void * data )
133+ {
134+ struct dma_chan_data * channel = data ;
135+ struct dma * dma = channel -> dma ;
136+ struct dw_dma_chan_data * dw_chan = dma_chan_get_data (channel );
137+ struct dw_lli * lli = dw_chan -> lli_current ;
138+
139+ /* only need to reload if this is a block transfer */
140+ if (!lli || !lli -> llp ) {
141+ channel -> status = COMP_STATE_PREPARE ;
142+ return ;
143+ }
144+
145+ /* channel not active */
146+ if (channel -> status != COMP_STATE_ACTIVE )
147+ return ;
148+
149+ /* channel still transferring previous lli */
150+ if (dma_reg_read (dma , DW_DMA_CHAN_EN ) & DW_CHAN (channel -> index ))
151+ return ;
152+
153+ /* get current and next block pointers */
154+ lli = (struct dw_lli * )lli -> llp ;
155+ dw_chan -> lli_current = lli ;
156+
157+ /* channel needs to start from scratch, so write SAR and DAR */
158+ dma_reg_write (dma , DW_SAR (channel -> index ), lli -> sar );
159+ dma_reg_write (dma , DW_DAR (channel -> index ), lli -> dar );
160+
161+ /* program CTL_LO and CTL_HI */
162+ dma_reg_write (dma , DW_CTRL_LOW (channel -> index ), lli -> ctrl_lo );
163+ dma_reg_write (dma , DW_CTRL_HIGH (channel -> index ), lli -> ctrl_hi );
164+
165+ /* program CFG_LO and CFG_HI */
166+ dma_reg_write (dma , DW_CFG_LOW (channel -> index ), dw_chan -> cfg_lo );
167+ dma_reg_write (dma , DW_CFG_HIGH (channel -> index ), dw_chan -> cfg_hi );
168+
169+ /* enable the channel */
170+ dma_reg_write (dma , DW_DMA_CHAN_EN , DW_CHAN_UNMASK (channel -> index ));
171+ }
172+ #endif
173+
129174/* allocate next free DMA channel */
130175static struct dma_chan_data * dw_dma_channel_get (struct dma * dma ,
131176 unsigned int req_chan )
@@ -148,6 +193,10 @@ static struct dma_chan_data *dw_dma_channel_get(struct dma *dma,
148193 dma -> chan [i ].status = COMP_STATE_READY ;
149194
150195 atomic_add (& dma -> num_channels_busy , 1 );
196+ #if !CONFIG_HW_LLI
197+ notifier_register (& dma -> chan [i ], & dma -> chan [i ],
198+ NOTIFIER_ID_DMA_IRQ , dw_dma_chan_reload_lli_cb );
199+ #endif
151200
152201 /* return channel */
153202 spin_unlock_irq (dma -> lock , flags );
@@ -760,50 +809,6 @@ static int dw_dma_pm_context_store(struct dma *dma)
760809 return 0 ;
761810}
762811
763- #if !CONFIG_HW_LLI
764- /* reload using LLI data from DMA IRQ cb */
765- static inline void dw_dma_chan_reload_lli_cb (void * arg , enum notify_id type ,
766- void * data )
767- {
768- struct dma_chan_data * channel = data ;
769- struct dma * dma = channel -> dma ;
770- struct dw_dma_chan_data * dw_chan = dma_chan_get_data (channel );
771- struct dw_lli * lli = dw_chan -> lli_current ;
772-
773- /* only need to reload if this is a block transfer */
774- if (!lli || !lli -> llp ) {
775- channel -> status = COMP_STATE_PREPARE ;
776- return ;
777- }
778-
779- /* channel not active */
780- if (channel -> status != COMP_STATE_ACTIVE )
781- return ;
782-
783- /* channel still transferring previous lli */
784- if (dma_reg_read (dma , DW_DMA_CHAN_EN ) & DW_CHAN (channel -> index ))
785- return ;
786-
787- /* get current and next block pointers */
788- lli = (struct dw_lli * )lli -> llp ;
789- dw_chan -> lli_current = lli ;
790-
791- /* channel needs to start from scratch, so write SAR and DAR */
792- dma_reg_write (dma , DW_SAR (channel -> index ), lli -> sar );
793- dma_reg_write (dma , DW_DAR (channel -> index ), lli -> dar );
794-
795- /* program CTL_LO and CTL_HI */
796- dma_reg_write (dma , DW_CTRL_LOW (channel -> index ), lli -> ctrl_lo );
797- dma_reg_write (dma , DW_CTRL_HIGH (channel -> index ), lli -> ctrl_hi );
798-
799- /* program CFG_LO and CFG_HI */
800- dma_reg_write (dma , DW_CFG_LOW (channel -> index ), dw_chan -> cfg_lo );
801- dma_reg_write (dma , DW_CFG_HIGH (channel -> index ), dw_chan -> cfg_hi );
802-
803- /* enable the channel */
804- dma_reg_write (dma , DW_DMA_CHAN_EN , DW_CHAN_UNMASK (channel -> index ));
805- }
806- #endif
807812
808813static void dw_dma_verify_transfer (struct dma_chan_data * channel ,
809814 struct dma_cb_data * next )
@@ -968,10 +973,6 @@ static int dw_dma_probe(struct dma *dma)
968973 chan -> dma = dma ;
969974 chan -> index = i ;
970975 chan -> core = DMA_CORE_INVALID ;
971- #if !CONFIG_HW_LLI
972- notifier_register (chan , chan , NOTIFIER_ID_DMA_IRQ ,
973- dw_dma_chan_reload_lli_cb );
974- #endif
975976
976977 dw_chan = rzalloc (RZONE_SYS_RUNTIME | RZONE_FLAG_UNCACHED ,
977978 SOF_MEM_CAPS_RAM , sizeof (* dw_chan ));
0 commit comments