@@ -131,6 +131,176 @@ static uint32_t host_dma_get_split(struct host_data *hd, uint32_t bytes)
131131 return MAX (split_src , split_dst );
132132}
133133
134+ #if CONFIG_FORCE_DMA_COPY_WHOLE_BLOCK
135+
136+ static int host_dma_set_config_and_copy (struct comp_dev * dev , uint32_t bytes )
137+ {
138+ struct host_data * hd = comp_get_drvdata (dev );
139+ struct dma_sg_elem * local_elem = hd -> config .elem_array .elems ;
140+ int ret = 0 ;
141+
142+ local_elem -> size = bytes ;
143+
144+ /* reconfigure transfer */
145+ ret = dma_set_config (hd -> chan , & hd -> config );
146+ if (ret < 0 ) {
147+ comp_err (dev , "host_dma_set_config_and_copy(): dma_set_config() failed, ret = %d" ,
148+ ret );
149+ return ret ;
150+ }
151+
152+ ret = dma_copy (hd -> chan , bytes , DMA_COPY_ONE_SHOT | DMA_COPY_BLOCKING );
153+ if (ret < 0 ) {
154+ comp_err (dev , "host_dma_set_config_and_copy(): dma_copy() failed, ret = %d" ,
155+ ret );
156+ return ret ;
157+ }
158+
159+ return ret ;
160+ }
161+
162+ /**
163+ * Calculates bytes to be copied in one shot mode.
164+ * @param dev Host component device.
165+ * @return Bytes to be copied.
166+ */
167+ static uint32_t host_get_copy_bytes_one_shot (struct comp_dev * dev )
168+ {
169+ struct host_data * hd = comp_get_drvdata (dev );
170+ struct comp_buffer * buffer = hd -> local_buffer ;
171+ uint32_t copy_bytes = 0 ;
172+
173+ buffer = buffer_acquire_irq (buffer );
174+
175+ /* calculate minimum size to copy */
176+ if (dev -> direction == SOF_IPC_STREAM_PLAYBACK )
177+ copy_bytes = audio_stream_get_free_bytes (& buffer -> stream );
178+ else
179+ copy_bytes = audio_stream_get_avail_bytes (& buffer -> stream );
180+
181+ buffer_release_irq (buffer );
182+
183+ /* copy_bytes should be aligned to minimum possible chunk of
184+ * data to be copied by dma.
185+ */
186+ copy_bytes = ALIGN_DOWN (copy_bytes , hd -> dma_copy_align );
187+
188+ return copy_bytes ;
189+ }
190+
191+ /**
192+ * Performs copy operation for host component working in one shot mode.
193+ * It means DMA needs to be reconfigured after every transfer.
194+ * @param dev Host component device.
195+ * @return 0 if succeeded, error code otherwise.
196+ */
197+ static int host_copy_one_shot (struct comp_dev * dev )
198+ {
199+ struct host_data * hd = comp_get_drvdata (dev );
200+ uint32_t copy_bytes = 0 ;
201+ uint32_t split_value = 0 ;
202+ int ret = 0 ;
203+
204+ comp_dbg (dev , "host_copy_one_shot()" );
205+
206+ copy_bytes = host_get_copy_bytes_one_shot (dev );
207+ if (!copy_bytes ) {
208+ comp_info (dev , "host_copy_one_shot(): no bytes to copy" );
209+ return ret ;
210+ }
211+
212+ while (copy_bytes ) {
213+ /* get split value */
214+ split_value = host_dma_get_split (hd , copy_bytes );
215+ copy_bytes -= split_value ;
216+
217+ ret = host_dma_set_config_and_copy (dev , copy_bytes );
218+ if (ret < 0 )
219+ return ret ;
220+
221+ /* update copy bytes */
222+ copy_bytes = split_value ;
223+ }
224+
225+ return ret ;
226+ }
227+
228+ #else /* CONFIG_FORCE_DMA_COPY_WHOLE_BLOCK */
229+
230+ /**
231+ * Calculates bytes to be copied in one shot mode.
232+ * @param dev Host component device.
233+ * @return Bytes to be copied.
234+ */
235+ static uint32_t host_get_copy_bytes_one_shot (struct comp_dev * dev )
236+ {
237+ struct host_data * hd = comp_get_drvdata (dev );
238+ struct dma_sg_elem * local_elem = hd -> config .elem_array .elems ;
239+ struct comp_buffer * buffer = hd -> local_buffer ;
240+ uint32_t copy_bytes = 0 ;
241+ uint32_t split_value ;
242+
243+ buffer = buffer_acquire_irq (buffer );
244+
245+ /* calculate minimum size to copy */
246+ if (dev -> direction == SOF_IPC_STREAM_PLAYBACK )
247+ copy_bytes = audio_stream_get_free_bytes (& buffer -> stream );
248+ else
249+ copy_bytes = audio_stream_get_avail_bytes (& buffer -> stream );
250+
251+ buffer_release_irq (buffer );
252+
253+ /* copy_bytes should be aligned to minimum possible chunk of
254+ * data to be copied by dma.
255+ */
256+ copy_bytes = ALIGN_DOWN (copy_bytes , hd -> dma_copy_align );
257+
258+ split_value = host_dma_get_split (hd , copy_bytes );
259+ if (split_value )
260+ copy_bytes -= split_value ;
261+
262+ local_elem -> size = copy_bytes ;
263+
264+ return copy_bytes ;
265+ }
266+
267+ /**
268+ * Performs copy operation for host component working in one shot mode.
269+ * It means DMA needs to be reconfigured after every transfer.
270+ * @param dev Host component device.
271+ * @return 0 if succeeded, error code otherwise.
272+ */
273+ static int host_copy_one_shot (struct comp_dev * dev )
274+ {
275+ struct host_data * hd = comp_get_drvdata (dev );
276+ uint32_t copy_bytes = 0 ;
277+ int ret = 0 ;
278+
279+ comp_dbg (dev , "host_copy_one_shot()" );
280+
281+ copy_bytes = host_get_copy_bytes_one_shot (dev );
282+ if (!copy_bytes ) {
283+ comp_info (dev , "host_copy_one_shot(): no bytes to copy" );
284+ return ret ;
285+ }
286+
287+ /* reconfigure transfer */
288+ ret = dma_set_config (hd -> chan , & hd -> config );
289+ if (ret < 0 ) {
290+ comp_err (dev , "host_copy_one_shot(): dma_set_config() failed, ret = %u" , ret );
291+ return ret ;
292+ }
293+
294+ ret = dma_copy (hd -> chan , copy_bytes , DMA_COPY_ONE_SHOT );
295+ if (ret < 0 ) {
296+ comp_err (dev , "host_copy_one_shot(): dma_copy() failed, ret = %u" , ret );
297+ return ret ;
298+ }
299+
300+ return ret ;
301+ }
302+ #endif
303+
134304static void host_update_position (struct comp_dev * dev , uint32_t bytes )
135305{
136306 struct host_data * hd = comp_get_drvdata (dev );
@@ -256,79 +426,6 @@ static void host_dma_cb(void *arg, enum notify_id type, void *data)
256426 host_one_shot_cb (dev , bytes );
257427}
258428
259- /**
260- * Calculates bytes to be copied in one shot mode.
261- * @param dev Host component device.
262- * @return Bytes to be copied.
263- */
264- static uint32_t host_get_copy_bytes_one_shot (struct comp_dev * dev )
265- {
266- struct host_data * hd = comp_get_drvdata (dev );
267- struct dma_sg_elem * local_elem = hd -> config .elem_array .elems ;
268- struct comp_buffer * buffer = hd -> local_buffer ;
269- uint32_t copy_bytes = 0 ;
270- uint32_t split_value ;
271-
272- buffer = buffer_acquire_irq (buffer );
273-
274- /* calculate minimum size to copy */
275- if (dev -> direction == SOF_IPC_STREAM_PLAYBACK )
276- copy_bytes = audio_stream_get_free_bytes (& buffer -> stream );
277- else
278- copy_bytes = audio_stream_get_avail_bytes (& buffer -> stream );
279-
280- buffer_release_irq (buffer );
281-
282- /* copy_bytes should be aligned to minimum possible chunk of
283- * data to be copied by dma.
284- */
285- copy_bytes = ALIGN_DOWN (copy_bytes , hd -> dma_copy_align );
286-
287- split_value = host_dma_get_split (hd , copy_bytes );
288- if (split_value )
289- copy_bytes -= split_value ;
290-
291- local_elem -> size = copy_bytes ;
292-
293- return copy_bytes ;
294- }
295-
296- /**
297- * Performs copy operation for host component working in one shot mode.
298- * It means DMA needs to be reconfigured after every transfer.
299- * @param dev Host component device.
300- * @return 0 if succeeded, error code otherwise.
301- */
302- static int host_copy_one_shot (struct comp_dev * dev )
303- {
304- struct host_data * hd = comp_get_drvdata (dev );
305- uint32_t copy_bytes = 0 ;
306- int ret = 0 ;
307-
308- comp_dbg (dev , "host_copy_one_shot()" );
309-
310- copy_bytes = host_get_copy_bytes_one_shot (dev );
311- if (!copy_bytes ) {
312- comp_info (dev , "host_copy_one_shot(): no bytes to copy" );
313- return ret ;
314- }
315-
316- /* reconfigure transfer */
317- ret = dma_set_config (hd -> chan , & hd -> config );
318- if (ret < 0 ) {
319- comp_err (dev , "host_copy_one_shot(): dma_set_config() failed, ret = %u" , ret );
320- return ret ;
321- }
322-
323- ret = dma_copy (hd -> chan , copy_bytes , DMA_COPY_ONE_SHOT );
324- if (ret < 0 ) {
325- comp_err (dev , "host_copy_one_shot(): dma_copy() failed, ret = %u" , ret );
326- return ret ;
327- }
328-
329- return ret ;
330- }
331-
332429/**
333430 * Calculates bytes to be copied in normal mode.
334431 * @param dev Host component device.
0 commit comments