1 /**
2  * @file
3  *
4  * @brief Public APIs for the DMA drivers.
5  */
6 
7 /*
8  * Copyright (c) 2016 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_DMA_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_DMA_H_
15 
16 #include <zephyr/kernel.h>
17 #include <zephyr/device.h>
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 
24 /**
25  * @brief DMA Interface
26  * @defgroup dma_interface DMA Interface
27  * @ingroup io_interfaces
28  * @{
29  */
30 
31 enum dma_channel_direction {
32 	MEMORY_TO_MEMORY = 0x0,
33 	MEMORY_TO_PERIPHERAL,
34 	PERIPHERAL_TO_MEMORY,
35 	PERIPHERAL_TO_PERIPHERAL,
36 	HOST_TO_MEMORY,
37 	MEMORY_TO_HOST,
38 
39 	/**
40 	 * Number of all common channel directions.
41 	 */
42 	DMA_CHANNEL_DIRECTION_COMMON_COUNT,
43 
44 	/**
45 	 * This and higher values are dma controller or soc specific.
46 	 * Refer to the specified dma driver header file.
47 	 */
48 	DMA_CHANNEL_DIRECTION_PRIV_START = DMA_CHANNEL_DIRECTION_COMMON_COUNT,
49 
50 	/**
51 	 * Maximum allowed value (3 bit field!)
52 	 */
53 	DMA_CHANNEL_DIRECTION_MAX = 0x7
54 };
55 
56 /** Valid values for @a source_addr_adj and @a dest_addr_adj */
57 enum dma_addr_adj {
58 	DMA_ADDR_ADJ_INCREMENT,
59 	DMA_ADDR_ADJ_DECREMENT,
60 	DMA_ADDR_ADJ_NO_CHANGE,
61 };
62 
63 /* channel attributes */
64 enum dma_channel_filter {
65 	DMA_CHANNEL_NORMAL, /* normal DMA channel */
66 	DMA_CHANNEL_PERIODIC, /* can be triggered by periodic sources */
67 };
68 
69 /* DMA attributes */
70 enum dma_attribute_type {
71 	DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT,
72 	DMA_ATTR_BUFFER_SIZE_ALIGNMENT,
73 	DMA_ATTR_COPY_ALIGNMENT,
74 	DMA_ATTR_MAX_BLOCK_COUNT,
75 };
76 
77 /**
78  * @struct dma_block_config
79  * @brief DMA block configuration structure.
80  *
81  * @param source_address is block starting address at source
82  * @param source_gather_interval is the address adjustment at gather boundary
83  * @param dest_address is block starting address at destination
84  * @param dest_scatter_interval is the address adjustment at scatter boundary
85  * @param dest_scatter_count is the continuous transfer count between scatter
86  *                    boundaries
87  * @param source_gather_count is the continuous transfer count between gather
88  *                     boundaries
89  *
90  * @param block_size is the number of bytes to be transferred for this block.
91  *
92  * @param config is a bit field with the following parts:
93  *
94  *     source_gather_en   [ 0 ]       - 0-disable, 1-enable.
95  *     dest_scatter_en    [ 1 ]       - 0-disable, 1-enable.
96  *     source_addr_adj    [ 2 : 3 ]   - 00-increment, 01-decrement,
97  *                                      10-no change.
98  *     dest_addr_adj      [ 4 : 5 ]   - 00-increment, 01-decrement,
99  *                                      10-no change.
100  *     source_reload_en   [ 6 ]       - reload source address at the end of
101  *                                      block transfer
102  *                                      0-disable, 1-enable.
103  *     dest_reload_en     [ 7 ]       - reload destination address at the end
104  *                                      of block transfer
105  *                                      0-disable, 1-enable.
106  *     fifo_mode_control  [ 8 : 11 ]  - How full  of the fifo before transfer
107  *                                      start. HW specific.
108  *     flow_control_mode  [ 12 ]      - 0-source request served upon data
109  *                                        availability.
110  *                                      1-source request postponed until
111  *                                        destination request happens.
112  *     reserved           [ 13 : 15 ]
113  */
114 struct dma_block_config {
115 #ifdef CONFIG_DMA_64BIT
116 	uint64_t source_address;
117 	uint64_t dest_address;
118 #else
119 	uint32_t source_address;
120 	uint32_t dest_address;
121 #endif
122 	uint32_t source_gather_interval;
123 	uint32_t dest_scatter_interval;
124 	uint16_t dest_scatter_count;
125 	uint16_t source_gather_count;
126 	uint32_t block_size;
127 	struct dma_block_config *next_block;
128 	uint16_t  source_gather_en :  1;
129 	uint16_t  dest_scatter_en :   1;
130 	uint16_t  source_addr_adj :   2;
131 	uint16_t  dest_addr_adj :     2;
132 	uint16_t  source_reload_en :  1;
133 	uint16_t  dest_reload_en :    1;
134 	uint16_t  fifo_mode_control : 4;
135 	uint16_t  flow_control_mode : 1;
136 	uint16_t  reserved :          3;
137 };
138 
139 #define DMA_STATUS_COMPLETE	0
140 #define DMA_STATUS_BLOCK	1
141 
142 /**
143  * @typedef dma_callback_t
144  * @brief Callback function for DMA transfer completion
145  *
146  *  If enabled, callback function will be invoked at transfer or block completion,
147  *  or when an error happens.
148  *  In circular mode, @p status indicates that the DMA device has reached either
149  *  the end of the buffer (DMA_STATUS_COMPLETE) or a water mark (DMA_STATUS_BLOCK).
150  *
151  * @param dev           Pointer to the DMA device calling the callback.
152  * @param user_data     A pointer to some user data or NULL
153  * @param channel       The channel number
154  * @param status        - 0-DMA_STATUS_COMPLETE buffer fully consumed
155  *                      - 1-DMA_STATUS_BLOCK buffer consumption reached a configured block
156  *                        or water mark
157  *                      - a negative errno otherwise
158  */
159 typedef void (*dma_callback_t)(const struct device *dev, void *user_data,
160 			       uint32_t channel, int status);
161 
162 /**
163  * @struct dma_config
164  * @brief DMA configuration structure.
165  *
166  * @param dma_slot             [ 0 : 7 ]   - which peripheral and direction
167  *                                        (HW specific)
168  * @param channel_direction    [ 8 : 10 ]  - 000-memory to memory,
169  *                                        001-memory to peripheral,
170  *                                        010-peripheral to memory,
171  *                                        011-peripheral to peripheral,
172  *                                        100-host to memory
173  *                                        101-memory to host
174  *                                        ...
175  * @param complete_callback_en [ 11 ]       - 0-callback invoked at completion only
176  *                                        1-callback invoked at completion of
177  *                                          each block
178  * @param error_callback_en    [ 12 ]      - 0-error callback enabled
179  *                                        1-error callback disabled
180  * @param source_handshake     [ 13 ]      - 0-HW, 1-SW
181  * @param dest_handshake       [ 14 ]      - 0-HW, 1-SW
182  * @param channel_priority     [ 15 : 18 ] - DMA channel priority
183  * @param source_chaining_en   [ 19 ]      - enable/disable source block chaining
184  *                                        0-disable, 1-enable
185  * @param dest_chaining_en     [ 20 ]      - enable/disable destination block
186  *                                        chaining.
187  *                                        0-disable, 1-enable
188  * @param linked_channel       [ 21 : 27 ] - after channel count exhaust will
189  *                                        initiate a channel service request
190  *                                        at this channel
191  * @param cyclic               [ 28 ]      - enable/disable cyclic buffer
192  *                                        0-disable, 1-enable
193  * @param reserved             [ 29 : 31 ]
194  * @param source_data_size    [ 0 : 15 ]   - width of source data (in bytes)
195  * @param dest_data_size      [ 16 : 31 ]  - width of dest data (in bytes)
196  * @param source_burst_length [ 0 : 15 ]   - number of source data units
197  * @param dest_burst_length   [ 16 : 31 ]  - number of destination data units
198  * @param block_count  is the number of blocks used for block chaining, this
199  *     depends on availability of the DMA controller.
200  * @param user_data  private data from DMA client.
201  * @param dma_callback see dma_callback_t for details
202  */
203 struct dma_config {
204 	uint32_t  dma_slot :             8;
205 	uint32_t  channel_direction :    3;
206 	uint32_t  complete_callback_en : 1;
207 	uint32_t  error_callback_en :    1;
208 	uint32_t  source_handshake :     1;
209 	uint32_t  dest_handshake :       1;
210 	uint32_t  channel_priority :     4;
211 	uint32_t  source_chaining_en :   1;
212 	uint32_t  dest_chaining_en :     1;
213 	uint32_t  linked_channel   :     7;
214 	uint32_t  cyclic :				 1;
215 	uint32_t  reserved :             3;
216 	uint32_t  source_data_size :    16;
217 	uint32_t  dest_data_size :      16;
218 	uint32_t  source_burst_length : 16;
219 	uint32_t  dest_burst_length :   16;
220 	uint32_t block_count;
221 	struct dma_block_config *head_block;
222 	void *user_data;
223 	dma_callback_t dma_callback;
224 };
225 
226 /**
227  * DMA runtime status structure
228  *
229  * busy 			- is current DMA transfer busy or idle
230  * dir				- DMA transfer direction
231  * pending_length 		- data length pending to be transferred in bytes
232  * 					or platform dependent.
233  * free                         - free buffer space
234  * write_position               - write position in a circular dma buffer
235  * read_position                - read position in a circular dma buffer
236  *
237  */
238 struct dma_status {
239 	bool busy;
240 	enum dma_channel_direction dir;
241 	uint32_t pending_length;
242 	uint32_t free;
243 	uint32_t write_position;
244 	uint32_t read_position;
245 	uint64_t total_copied;
246 };
247 
248 /**
249  * DMA context structure
250  * Note: the dma_context shall be the first member
251  *       of DMA client driver Data, got by dev->data
252  *
253  * magic			- magic code to identify the context
254  * dma_channels		- dma channels
255  * atomic			- driver atomic_t pointer
256  *
257  */
258 struct dma_context {
259 	int32_t magic;
260 	int dma_channels;
261 	atomic_t *atomic;
262 };
263 
264 /* magic code to identify context content */
265 #define DMA_MAGIC 0x47494749
266 
267 /**
268  * @cond INTERNAL_HIDDEN
269  *
270  * These are for internal use only, so skip these in
271  * public documentation.
272  */
273 typedef int (*dma_api_config)(const struct device *dev, uint32_t channel,
274 			      struct dma_config *config);
275 
276 #ifdef CONFIG_DMA_64BIT
277 typedef int (*dma_api_reload)(const struct device *dev, uint32_t channel,
278 			      uint64_t src, uint64_t dst, size_t size);
279 #else
280 typedef int (*dma_api_reload)(const struct device *dev, uint32_t channel,
281 			      uint32_t src, uint32_t dst, size_t size);
282 #endif
283 
284 typedef int (*dma_api_start)(const struct device *dev, uint32_t channel);
285 
286 typedef int (*dma_api_stop)(const struct device *dev, uint32_t channel);
287 
288 typedef int (*dma_api_suspend)(const struct device *dev, uint32_t channel);
289 
290 typedef int (*dma_api_resume)(const struct device *dev, uint32_t channel);
291 
292 typedef int (*dma_api_get_status)(const struct device *dev, uint32_t channel,
293 				  struct dma_status *status);
294 
295 typedef int (*dma_api_get_attribute)(const struct device *dev, uint32_t type, uint32_t *value);
296 
297 /**
298  * @typedef dma_chan_filter
299  * @brief channel filter function call
300  *
301  * filter function that is used to find the matched internal dma channel
302  * provide by caller
303  *
304  * @param dev Pointer to the DMA device instance
305  * @param channel the channel id to use
306  * @param filter_param filter function parameter, can be NULL
307  *
308  * @retval True on filter matched otherwise return False.
309  */
310 typedef bool (*dma_api_chan_filter)(const struct device *dev,
311 				int channel, void *filter_param);
312 
313 __subsystem struct dma_driver_api {
314 	dma_api_config config;
315 	dma_api_reload reload;
316 	dma_api_start start;
317 	dma_api_stop stop;
318 	dma_api_suspend suspend;
319 	dma_api_resume resume;
320 	dma_api_get_status get_status;
321 	dma_api_get_attribute get_attribute;
322 	dma_api_chan_filter chan_filter;
323 };
324 /**
325  * @endcond
326  */
327 
328 /**
329  * @brief Configure individual channel for DMA transfer.
330  *
331  * @param dev     Pointer to the device structure for the driver instance.
332  * @param channel Numeric identification of the channel to configure
333  * @param config  Data structure containing the intended configuration for the
334  *                selected channel
335  *
336  * @retval 0 if successful.
337  * @retval Negative errno code if failure.
338  */
dma_config(const struct device * dev,uint32_t channel,struct dma_config * config)339 static inline int dma_config(const struct device *dev, uint32_t channel,
340 			     struct dma_config *config)
341 {
342 	const struct dma_driver_api *api =
343 		(const struct dma_driver_api *)dev->api;
344 
345 	return api->config(dev, channel, config);
346 }
347 
348 /**
349  * @brief Reload buffer(s) for a DMA channel
350  *
351  * @param dev     Pointer to the device structure for the driver instance.
352  * @param channel Numeric identification of the channel to configure
353  *                selected channel
354  * @param src     source address for the DMA transfer
355  * @param dst     destination address for the DMA transfer
356  * @param size    size of DMA transfer
357  *
358  * @retval 0 if successful.
359  * @retval Negative errno code if failure.
360  */
361 #ifdef CONFIG_DMA_64BIT
dma_reload(const struct device * dev,uint32_t channel,uint64_t src,uint64_t dst,size_t size)362 static inline int dma_reload(const struct device *dev, uint32_t channel,
363 			     uint64_t src, uint64_t dst, size_t size)
364 #else
365 static inline int dma_reload(const struct device *dev, uint32_t channel,
366 		uint32_t src, uint32_t dst, size_t size)
367 #endif
368 {
369 	const struct dma_driver_api *api =
370 		(const struct dma_driver_api *)dev->api;
371 
372 	if (api->reload) {
373 		return api->reload(dev, channel, src, dst, size);
374 	}
375 
376 	return -ENOSYS;
377 }
378 
379 /**
380  * @brief Enables DMA channel and starts the transfer, the channel must be
381  *        configured beforehand.
382  *
383  * Implementations must check the validity of the channel ID passed in and
384  * return -EINVAL if it is invalid.
385  *
386  * Start is allowed on channels that have already been started and must report
387  * success.
388  *
389  * @param dev     Pointer to the device structure for the driver instance.
390  * @param channel Numeric identification of the channel where the transfer will
391  *                be processed
392  *
393  * @retval 0 if successful.
394  * @retval Negative errno code if failure.
395  */
396 __syscall int dma_start(const struct device *dev, uint32_t channel);
397 
z_impl_dma_start(const struct device * dev,uint32_t channel)398 static inline int z_impl_dma_start(const struct device *dev, uint32_t channel)
399 {
400 	const struct dma_driver_api *api =
401 		(const struct dma_driver_api *)dev->api;
402 
403 	return api->start(dev, channel);
404 }
405 
406 /**
407  * @brief Stops the DMA transfer and disables the channel.
408  *
409  * Implementations must check the validity of the channel ID passed in and
410  * return -EINVAL if it is invalid.
411  *
412  * Stop is allowed on channels that have already been stopped and must report
413  * success.
414  *
415  * @param dev     Pointer to the device structure for the driver instance.
416  * @param channel Numeric identification of the channel where the transfer was
417  *                being processed
418  *
419  * @retval 0 if successful.
420  * @retval Negative errno code if failure.
421  */
422 __syscall int dma_stop(const struct device *dev, uint32_t channel);
423 
z_impl_dma_stop(const struct device * dev,uint32_t channel)424 static inline int z_impl_dma_stop(const struct device *dev, uint32_t channel)
425 {
426 	const struct dma_driver_api *api =
427 		(const struct dma_driver_api *)dev->api;
428 
429 	return api->stop(dev, channel);
430 }
431 
432 
433 /**
434  * @brief Suspend a DMA channel transfer
435  *
436  * Implementations must check the validity of the channel state and ID passed
437  * in and return -EINVAL if either are invalid.
438  *
439  * @param dev Pointer to the device structure for the driver instance.
440  * @param channel Numeric identification of the channel to suspend
441  *
442  * @retval 0 If successful.
443  * @retval -ENOSYS If not implemented.
444  * @retval -EINVAL If invalid channel id or state.
445  * @retval -errno Other negative errno code failure.
446  */
447 __syscall int dma_suspend(const struct device *dev, uint32_t channel);
448 
z_impl_dma_suspend(const struct device * dev,uint32_t channel)449 static inline int z_impl_dma_suspend(const struct device *dev, uint32_t channel)
450 {
451 	const struct dma_driver_api *api = (const struct dma_driver_api *)dev->api;
452 
453 	if (api->suspend == NULL) {
454 		return -ENOSYS;
455 	}
456 	return api->suspend(dev, channel);
457 }
458 
459 /**
460  * @brief Resume a DMA channel transfer
461  *
462  * Implementations must check the validity of the channel state and ID passed
463  * in and return -EINVAL if either are invalid.
464  *
465  * @param dev Pointer to the device structure for the driver instance.
466  * @param channel Numeric identification of the channel to resume
467  *
468  * @retval 0 If successful.
469  * @retval -ENOSYS If not implemented
470  * @retval -EINVAL If invalid channel id or state.
471  * @retval -errno Other negative errno code failure.
472  */
473 __syscall int dma_resume(const struct device *dev, uint32_t channel);
474 
z_impl_dma_resume(const struct device * dev,uint32_t channel)475 static inline int z_impl_dma_resume(const struct device *dev, uint32_t channel)
476 {
477 	const struct dma_driver_api *api = (const struct dma_driver_api *)dev->api;
478 
479 	if (api->resume == NULL) {
480 		return -ENOSYS;
481 	}
482 	return api->resume(dev, channel);
483 }
484 
485 /**
486  * @brief request DMA channel.
487  *
488  * request DMA channel resources
489  * return -EINVAL if there is no valid channel available.
490  *
491  * @param dev Pointer to the device structure for the driver instance.
492  * @param filter_param filter function parameter
493  *
494  * @retval dma channel if successful.
495  * @retval Negative errno code if failure.
496  */
497 __syscall int dma_request_channel(const struct device *dev,
498 				  void *filter_param);
499 
z_impl_dma_request_channel(const struct device * dev,void * filter_param)500 static inline int z_impl_dma_request_channel(const struct device *dev,
501 					     void *filter_param)
502 {
503 	int i = 0;
504 	int channel = -EINVAL;
505 	const struct dma_driver_api *api =
506 		(const struct dma_driver_api *)dev->api;
507 	/* dma_context shall be the first one in dev data */
508 	struct dma_context *dma_ctx = (struct dma_context *)dev->data;
509 
510 	if (dma_ctx->magic != DMA_MAGIC) {
511 		return channel;
512 	}
513 
514 	for (i = 0; i < dma_ctx->dma_channels; i++) {
515 		if (!atomic_test_and_set_bit(dma_ctx->atomic, i)) {
516 			if (api->chan_filter &&
517 			    !api->chan_filter(dev, i, filter_param)) {
518 				atomic_clear_bit(dma_ctx->atomic, i);
519 				continue;
520 			}
521 			channel = i;
522 			break;
523 		}
524 	}
525 
526 	return channel;
527 }
528 
529 /**
530  * @brief release DMA channel.
531  *
532  * release DMA channel resources
533  *
534  * @param dev  Pointer to the device structure for the driver instance.
535  * @param channel  channel number
536  *
537  */
538 __syscall void dma_release_channel(const struct device *dev,
539 				   uint32_t channel);
540 
z_impl_dma_release_channel(const struct device * dev,uint32_t channel)541 static inline void z_impl_dma_release_channel(const struct device *dev,
542 					      uint32_t channel)
543 {
544 	struct dma_context *dma_ctx = (struct dma_context *)dev->data;
545 
546 	if (dma_ctx->magic != DMA_MAGIC) {
547 		return;
548 	}
549 
550 	if ((int)channel < dma_ctx->dma_channels) {
551 		atomic_clear_bit(dma_ctx->atomic, channel);
552 	}
553 
554 }
555 
556 /**
557  * @brief DMA channel filter.
558  *
559  * filter channel by attribute
560  *
561  * @param dev  Pointer to the device structure for the driver instance.
562  * @param channel  channel number
563  * @param filter_param filter attribute
564  *
565  * @retval Negative errno code if not support
566  *
567  */
568 __syscall int dma_chan_filter(const struct device *dev,
569 				   int channel, void *filter_param);
570 
z_impl_dma_chan_filter(const struct device * dev,int channel,void * filter_param)571 static inline int z_impl_dma_chan_filter(const struct device *dev,
572 					      int channel, void *filter_param)
573 {
574 	const struct dma_driver_api *api =
575 		(const struct dma_driver_api *)dev->api;
576 
577 	if (api->chan_filter) {
578 		return api->chan_filter(dev, channel, filter_param);
579 	}
580 
581 	return -ENOSYS;
582 }
583 
584 /**
585  * @brief get current runtime status of DMA transfer
586  *
587  * Implementations must check the validity of the channel ID passed in and
588  * return -EINVAL if it is invalid or -ENOSYS if not supported.
589  *
590  * @param dev     Pointer to the device structure for the driver instance.
591  * @param channel Numeric identification of the channel where the transfer was
592  *                being processed
593  * @param stat   a non-NULL dma_status object for storing DMA status
594  *
595  * @retval non-negative if successful.
596  * @retval Negative errno code if failure.
597  */
dma_get_status(const struct device * dev,uint32_t channel,struct dma_status * stat)598 static inline int dma_get_status(const struct device *dev, uint32_t channel,
599 				 struct dma_status *stat)
600 {
601 	const struct dma_driver_api *api =
602 		(const struct dma_driver_api *)dev->api;
603 
604 	if (api->get_status) {
605 		return api->get_status(dev, channel, stat);
606 	}
607 
608 	return -ENOSYS;
609 }
610 
611 /**
612  * @brief get attribute of a dma controller
613  *
614  * This function allows to get a device specific static or runtime attribute like required address
615  * and size alignment of a buffer.
616  * Implementations must check the validity of the type passed in and
617  * return -EINVAL if it is invalid or -ENOSYS if not supported.
618  *
619  * @param dev     Pointer to the device structure for the driver instance.
620  * @param type    Numeric identification of the attribute
621  * @param value   A non-NULL pointer to the variable where the read value is to be placed
622  *
623  * @retval non-negative if successful.
624  * @retval Negative errno code if failure.
625  */
dma_get_attribute(const struct device * dev,uint32_t type,uint32_t * value)626 static inline int dma_get_attribute(const struct device *dev, uint32_t type, uint32_t *value)
627 {
628 	const struct dma_driver_api *api = (const struct dma_driver_api *)dev->api;
629 
630 	if (api->get_attribute) {
631 		return api->get_attribute(dev, type, value);
632 	}
633 
634 	return -ENOSYS;
635 }
636 
637 /**
638  * @brief Look-up generic width index to be used in registers
639  *
640  * WARNING: This look-up works for most controllers, but *may* not work for
641  *          yours.  Ensure your controller expects the most common register
642  *          bit values before using this convenience function.  If your
643  *          controller does not support these values, you will have to write
644  *          your own look-up inside the controller driver.
645  *
646  * @param size: width of bus (in bytes)
647  *
648  * @retval common DMA index to be placed into registers.
649  */
dma_width_index(uint32_t size)650 static inline uint32_t dma_width_index(uint32_t size)
651 {
652 	/* Check boundaries (max supported width is 32 Bytes) */
653 	if (size < 1 || size > 32) {
654 		return 0; /* Zero is the default (8 Bytes) */
655 	}
656 
657 	/* Ensure size is a power of 2 */
658 	if (!is_power_of_two(size)) {
659 		return 0; /* Zero is the default (8 Bytes) */
660 	}
661 
662 	/* Convert to bit pattern for writing to a register */
663 	return find_msb_set(size);
664 }
665 
666 /**
667  * @brief Look-up generic burst index to be used in registers
668  *
669  * WARNING: This look-up works for most controllers, but *may* not work for
670  *          yours.  Ensure your controller expects the most common register
671  *          bit values before using this convenience function.  If your
672  *          controller does not support these values, you will have to write
673  *          your own look-up inside the controller driver.
674  *
675  * @param burst: number of bytes to be sent in a single burst
676  *
677  * @retval common DMA index to be placed into registers.
678  */
dma_burst_index(uint32_t burst)679 static inline uint32_t dma_burst_index(uint32_t burst)
680 {
681 	/* Check boundaries (max supported burst length is 256) */
682 	if (burst < 1 || burst > 256) {
683 		return 0; /* Zero is the default (1 burst length) */
684 	}
685 
686 	/* Ensure burst is a power of 2 */
687 	if (!(burst & (burst - 1))) {
688 		return 0; /* Zero is the default (1 burst length) */
689 	}
690 
691 	/* Convert to bit pattern for writing to a register */
692 	return find_msb_set(burst);
693 }
694 
695 /**
696  * Get the device tree property describing the buffer address alignment
697  *
698  * Useful when statically defining or allocating buffers for DMA usage where
699  * memory alignment often matters.
700  *
701  * @param node Node identifier, e.g. DT_NODELABEL(dma_0)
702  * @return alignment Memory byte alignment required for DMA buffers
703  */
704 #define DMA_BUF_ADDR_ALIGNMENT(node) DT_PROP(node, dma_buf_addr_alignment)
705 
706 /**
707  * Get the device tree property describing the buffer size alignment
708  *
709  * Useful when statically defining or allocating buffers for DMA usage where
710  * memory alignment often matters.
711  *
712  * @param node Node identifier, e.g. DT_NODELABEL(dma_0)
713  * @return alignment Memory byte alignment required for DMA buffers
714  */
715 #define DMA_BUF_SIZE_ALIGNMENT(node) DT_PROP(node, dma_buf_size_alignment)
716 
717 /**
718  * Get the device tree property describing the minimal chunk of data possible to be copied
719  *
720  * @param node Node identifier, e.g. DT_NODELABEL(dma_0)
721  * @return minimal Minimal chunk of data possible to be copied
722  */
723 #define DMA_COPY_ALIGNMENT(node) DT_PROP(node, dma_copy_alignment)
724 
725 /**
726  * @}
727  */
728 
729 #ifdef __cplusplus
730 }
731 #endif
732 
733 #include <syscalls/dma.h>
734 
735 #endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_H_ */
736