Zephyr API Documentation  3.6.0
A Scalable Open Source RTOS
3.6.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
dma.h
Go to the documentation of this file.
1
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
20extern "C" {
21#endif
22
23
47
52
58
63};
64
77};
78
83 DMA_CHANNEL_NORMAL, /* normal DMA channel */
84 DMA_CHANNEL_PERIODIC, /* can be triggered by periodic sources */
85};
86
95};
96
105#ifdef CONFIG_DMA_64BIT
110#else
115#endif
161
162 uint16_t _reserved : 3;
163};
164
166#define DMA_STATUS_COMPLETE 0
168#define DMA_STATUS_BLOCK 1
169
188typedef void (*dma_callback_t)(const struct device *dev, void *user_data,
189 uint32_t channel, int status);
190
250
251 uint32_t _reserved : 3;
268};
269
275 bool busy;
288};
289
302};
303
305#define DMA_MAGIC 0x47494749
306
313typedef int (*dma_api_config)(const struct device *dev, uint32_t channel,
314 struct dma_config *config);
315
316#ifdef CONFIG_DMA_64BIT
317typedef int (*dma_api_reload)(const struct device *dev, uint32_t channel,
318 uint64_t src, uint64_t dst, size_t size);
319#else
320typedef int (*dma_api_reload)(const struct device *dev, uint32_t channel,
321 uint32_t src, uint32_t dst, size_t size);
322#endif
323
324typedef int (*dma_api_start)(const struct device *dev, uint32_t channel);
325
326typedef int (*dma_api_stop)(const struct device *dev, uint32_t channel);
327
328typedef int (*dma_api_suspend)(const struct device *dev, uint32_t channel);
329
330typedef int (*dma_api_resume)(const struct device *dev, uint32_t channel);
331
332typedef int (*dma_api_get_status)(const struct device *dev, uint32_t channel,
333 struct dma_status *status);
334
335typedef int (*dma_api_get_attribute)(const struct device *dev, uint32_t type, uint32_t *value);
336
350typedef bool (*dma_api_chan_filter)(const struct device *dev,
351 int channel, void *filter_param);
352
353__subsystem struct dma_driver_api {
354 dma_api_config config;
355 dma_api_reload reload;
356 dma_api_start start;
357 dma_api_stop stop;
358 dma_api_suspend suspend;
359 dma_api_resume resume;
360 dma_api_get_status get_status;
361 dma_api_get_attribute get_attribute;
362 dma_api_chan_filter chan_filter;
363};
379static inline int dma_config(const struct device *dev, uint32_t channel,
380 struct dma_config *config)
381{
382 const struct dma_driver_api *api =
383 (const struct dma_driver_api *)dev->api;
384
385 return api->config(dev, channel, config);
386}
387
401#ifdef CONFIG_DMA_64BIT
402static inline int dma_reload(const struct device *dev, uint32_t channel,
403 uint64_t src, uint64_t dst, size_t size)
404#else
405static inline int dma_reload(const struct device *dev, uint32_t channel,
406 uint32_t src, uint32_t dst, size_t size)
407#endif
408{
409 const struct dma_driver_api *api =
410 (const struct dma_driver_api *)dev->api;
411
412 if (api->reload) {
413 return api->reload(dev, channel, src, dst, size);
414 }
415
416 return -ENOSYS;
417}
418
438__syscall int dma_start(const struct device *dev, uint32_t channel);
439
440static inline int z_impl_dma_start(const struct device *dev, uint32_t channel)
441{
442 const struct dma_driver_api *api =
443 (const struct dma_driver_api *)dev->api;
444
445 return api->start(dev, channel);
446}
447
466__syscall int dma_stop(const struct device *dev, uint32_t channel);
467
468static inline int z_impl_dma_stop(const struct device *dev, uint32_t channel)
469{
470 const struct dma_driver_api *api =
471 (const struct dma_driver_api *)dev->api;
472
473 return api->stop(dev, channel);
474}
475
476
493__syscall int dma_suspend(const struct device *dev, uint32_t channel);
494
495static inline int z_impl_dma_suspend(const struct device *dev, uint32_t channel)
496{
497 const struct dma_driver_api *api = (const struct dma_driver_api *)dev->api;
498
499 if (api->suspend == NULL) {
500 return -ENOSYS;
501 }
502 return api->suspend(dev, channel);
503}
504
521__syscall int dma_resume(const struct device *dev, uint32_t channel);
522
523static inline int z_impl_dma_resume(const struct device *dev, uint32_t channel)
524{
525 const struct dma_driver_api *api = (const struct dma_driver_api *)dev->api;
526
527 if (api->resume == NULL) {
528 return -ENOSYS;
529 }
530 return api->resume(dev, channel);
531}
532
547__syscall int dma_request_channel(const struct device *dev,
548 void *filter_param);
549
550static inline int z_impl_dma_request_channel(const struct device *dev,
551 void *filter_param)
552{
553 int i = 0;
554 int channel = -EINVAL;
555 const struct dma_driver_api *api =
556 (const struct dma_driver_api *)dev->api;
557 /* dma_context shall be the first one in dev data */
558 struct dma_context *dma_ctx = (struct dma_context *)dev->data;
559
560 if (dma_ctx->magic != DMA_MAGIC) {
561 return channel;
562 }
563
564 for (i = 0; i < dma_ctx->dma_channels; i++) {
565 if (!atomic_test_and_set_bit(dma_ctx->atomic, i)) {
566 if (api->chan_filter &&
567 !api->chan_filter(dev, i, filter_param)) {
568 atomic_clear_bit(dma_ctx->atomic, i);
569 continue;
570 }
571 channel = i;
572 break;
573 }
574 }
575
576 return channel;
577}
578
590__syscall void dma_release_channel(const struct device *dev,
591 uint32_t channel);
592
593static inline void z_impl_dma_release_channel(const struct device *dev,
594 uint32_t channel)
595{
596 struct dma_context *dma_ctx = (struct dma_context *)dev->data;
597
598 if (dma_ctx->magic != DMA_MAGIC) {
599 return;
600 }
601
602 if ((int)channel < dma_ctx->dma_channels) {
603 atomic_clear_bit(dma_ctx->atomic, channel);
604 }
605
606}
607
620__syscall int dma_chan_filter(const struct device *dev,
621 int channel, void *filter_param);
622
623static inline int z_impl_dma_chan_filter(const struct device *dev,
624 int channel, void *filter_param)
625{
626 const struct dma_driver_api *api =
627 (const struct dma_driver_api *)dev->api;
628
629 if (api->chan_filter) {
630 return api->chan_filter(dev, channel, filter_param);
631 }
632
633 return -ENOSYS;
634}
635
652static inline int dma_get_status(const struct device *dev, uint32_t channel,
653 struct dma_status *stat)
654{
655 const struct dma_driver_api *api =
656 (const struct dma_driver_api *)dev->api;
657
658 if (api->get_status) {
659 return api->get_status(dev, channel, stat);
660 }
661
662 return -ENOSYS;
663}
664
682static inline int dma_get_attribute(const struct device *dev, uint32_t type, uint32_t *value)
683{
684 const struct dma_driver_api *api = (const struct dma_driver_api *)dev->api;
685
686 if (api->get_attribute) {
687 return api->get_attribute(dev, type, value);
688 }
689
690 return -ENOSYS;
691}
692
707{
708 /* Check boundaries (max supported width is 32 Bytes) */
709 if (size < 1 || size > 32) {
710 return 0; /* Zero is the default (8 Bytes) */
711 }
712
713 /* Ensure size is a power of 2 */
714 if (!is_power_of_two(size)) {
715 return 0; /* Zero is the default (8 Bytes) */
716 }
717
718 /* Convert to bit pattern for writing to a register */
719 return find_msb_set(size);
720}
721
736{
737 /* Check boundaries (max supported burst length is 256) */
738 if (burst < 1 || burst > 256) {
739 return 0; /* Zero is the default (1 burst length) */
740 }
741
742 /* Ensure burst is a power of 2 */
743 if (!(burst & (burst - 1))) {
744 return 0; /* Zero is the default (1 burst length) */
745 }
746
747 /* Convert to bit pattern for writing to a register */
748 return find_msb_set(burst);
749}
750
760#define DMA_BUF_ADDR_ALIGNMENT(node) DT_PROP(node, dma_buf_addr_alignment)
761
771#define DMA_BUF_SIZE_ALIGNMENT(node) DT_PROP(node, dma_buf_size_alignment)
772
779#define DMA_COPY_ALIGNMENT(node) DT_PROP(node, dma_copy_alignment)
780
785#ifdef __cplusplus
786}
787#endif
788
789#include <syscalls/dma.h>
790
791#endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_H_ */
long atomic_t
Definition: atomic_types.h:15
static ALWAYS_INLINE unsigned int find_msb_set(uint32_t op)
find most significant bit set in a 32-bit word
Definition: ffs.h:31
static void atomic_clear_bit(atomic_t *target, int bit)
Atomically clear a bit.
Definition: atomic.h:191
static bool atomic_test_and_set_bit(atomic_t *target, int bit)
Atomically set a bit.
Definition: atomic.h:170
dma_attribute_type
DMA attributes.
Definition: dma.h:90
static int dma_get_status(const struct device *dev, uint32_t channel, struct dma_status *stat)
get current runtime status of DMA transfer
Definition: dma.h:652
int dma_stop(const struct device *dev, uint32_t channel)
Stops the DMA transfer and disables the channel.
static int dma_reload(const struct device *dev, uint32_t channel, uint32_t src, uint32_t dst, size_t size)
Reload buffer(s) for a DMA channel.
Definition: dma.h:405
static int dma_get_attribute(const struct device *dev, uint32_t type, uint32_t *value)
get attribute of a dma controller
Definition: dma.h:682
int dma_suspend(const struct device *dev, uint32_t channel)
Suspend a DMA channel transfer.
int dma_chan_filter(const struct device *dev, int channel, void *filter_param)
DMA channel filter.
int dma_resume(const struct device *dev, uint32_t channel)
Resume a DMA channel transfer.
int dma_request_channel(const struct device *dev, void *filter_param)
request DMA channel.
static uint32_t dma_burst_index(uint32_t burst)
Look-up generic burst index to be used in registers.
Definition: dma.h:735
void dma_release_channel(const struct device *dev, uint32_t channel)
release DMA channel.
int dma_start(const struct device *dev, uint32_t channel)
Enables DMA channel and starts the transfer, the channel must be configured beforehand.
void(* dma_callback_t)(const struct device *dev, void *user_data, uint32_t channel, int status)
Callback function for DMA transfer completion.
Definition: dma.h:188
static uint32_t dma_width_index(uint32_t size)
Look-up generic width index to be used in registers.
Definition: dma.h:706
dma_channel_filter
DMA channel attributes.
Definition: dma.h:82
#define DMA_MAGIC
Magic code to identify context content.
Definition: dma.h:305
dma_channel_direction
DMA channel direction.
Definition: dma.h:34
dma_addr_adj
DMA address adjustment.
Definition: dma.h:70
@ DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT
Definition: dma.h:91
@ DMA_ATTR_COPY_ALIGNMENT
Definition: dma.h:93
@ DMA_ATTR_BUFFER_SIZE_ALIGNMENT
Definition: dma.h:92
@ DMA_ATTR_MAX_BLOCK_COUNT
Definition: dma.h:94
@ DMA_CHANNEL_NORMAL
Definition: dma.h:83
@ DMA_CHANNEL_PERIODIC
Definition: dma.h:84
@ DMA_CHANNEL_DIRECTION_PRIV_START
This and higher values are dma controller or soc specific.
Definition: dma.h:57
@ MEMORY_TO_PERIPHERAL
Memory to peripheral.
Definition: dma.h:38
@ MEMORY_TO_MEMORY
Memory to memory.
Definition: dma.h:36
@ PERIPHERAL_TO_MEMORY
Peripheral to memory.
Definition: dma.h:40
@ MEMORY_TO_HOST
Memory to host.
Definition: dma.h:46
@ HOST_TO_MEMORY
Host to memory.
Definition: dma.h:44
@ DMA_CHANNEL_DIRECTION_MAX
Maximum allowed value (3 bit field!)
Definition: dma.h:62
@ PERIPHERAL_TO_PERIPHERAL
Peripheral to peripheral.
Definition: dma.h:42
@ DMA_CHANNEL_DIRECTION_COMMON_COUNT
Number of all common channel directions.
Definition: dma.h:51
@ DMA_ADDR_ADJ_DECREMENT
Decrement the address.
Definition: dma.h:74
@ DMA_ADDR_ADJ_INCREMENT
Increment the address.
Definition: dma.h:72
@ DMA_ADDR_ADJ_NO_CHANGE
No change the address.
Definition: dma.h:76
static bool is_power_of_two(unsigned int x)
Is x a power of two?
Definition: util.h:411
#define EINVAL
Invalid argument.
Definition: errno.h:61
#define ENOSYS
Function not implemented.
Definition: errno.h:83
Public kernel APIs.
#define bool
Definition: stdbool.h:13
__UINT32_TYPE__ uint32_t
Definition: stdint.h:90
__INT32_TYPE__ int32_t
Definition: stdint.h:74
__UINT64_TYPE__ uint64_t
Definition: stdint.h:91
__UINT16_TYPE__ uint16_t
Definition: stdint.h:89
Runtime device structure (in ROM) per driver instance.
Definition: device.h:387
void * data
Address of the device instance private data.
Definition: device.h:397
const void * api
Address of the API structure exposed by the device instance.
Definition: device.h:393
DMA block configuration structure.
Definition: dma.h:104
uint32_t dest_scatter_interval
Address adjustment at scatter boundary.
Definition: dma.h:119
uint32_t source_gather_interval
Address adjustment at gather boundary.
Definition: dma.h:117
uint32_t block_size
Number of bytes to be transferred for this block.
Definition: dma.h:125
uint16_t source_reload_en
Reload source address at the end of block transfer.
Definition: dma.h:149
uint16_t dest_scatter_en
Enable destination scattering when set to 1.
Definition: dma.h:131
uint16_t dest_reload_en
Reload destination address at the end of block transfer.
Definition: dma.h:151
uint16_t fifo_mode_control
FIFO fill before starting transfer, HW specific meaning.
Definition: dma.h:153
uint16_t source_gather_count
Continuous transfer count between gather boundaries.
Definition: dma.h:123
uint16_t source_addr_adj
Source address adjustment option.
Definition: dma.h:139
struct dma_block_config * next_block
Pointer to next block in a transfer list.
Definition: dma.h:127
uint32_t dest_address
block starting address at destination
Definition: dma.h:114
uint32_t source_address
block starting address at source
Definition: dma.h:112
uint16_t source_gather_en
Enable source gathering when set to 1.
Definition: dma.h:129
uint16_t dest_addr_adj
Destination address adjustment.
Definition: dma.h:147
uint16_t dest_scatter_count
Continuous transfer count between scatter boundaries.
Definition: dma.h:121
uint16_t flow_control_mode
Transfer flow control mode.
Definition: dma.h:160
DMA configuration structure.
Definition: dma.h:195
uint32_t channel_priority
Channel priority for arbitration, HW specific.
Definition: dma.h:241
uint32_t source_handshake
Source handshake, HW specific.
Definition: dma.h:230
uint32_t complete_callback_en
Completion callback enable.
Definition: dma.h:216
void * user_data
Optional attached user data for callbacks.
Definition: dma.h:265
uint32_t error_callback_en
Error callback enable.
Definition: dma.h:223
dma_callback_t dma_callback
Optional callback for completion and error events.
Definition: dma.h:267
uint32_t source_chaining_en
Source chaining enable, HW specific.
Definition: dma.h:243
uint32_t dest_chaining_en
Destination chaining enable, HW specific.
Definition: dma.h:245
uint32_t dma_slot
Which peripheral and direction, HW specific.
Definition: dma.h:197
uint32_t channel_direction
Direction the transfers are occurring.
Definition: dma.h:209
uint32_t source_data_size
Width of source data (in bytes)
Definition: dma.h:253
uint32_t dest_burst_length
Destination burst length in bytes.
Definition: dma.h:259
struct dma_block_config * head_block
Pointer to the first block in the transfer list.
Definition: dma.h:263
uint32_t linked_channel
Linked channel, HW specific.
Definition: dma.h:247
uint32_t source_burst_length
Source burst length in bytes.
Definition: dma.h:257
uint32_t block_count
Number of blocks in transfer list.
Definition: dma.h:261
uint32_t dest_data_size
Width of destination data (in bytes)
Definition: dma.h:255
uint32_t dest_handshake
Destination handshake, HW specific.
Definition: dma.h:237
uint32_t cyclic
Cyclic transfer list, HW specific.
Definition: dma.h:249
DMA context structure Note: the dma_context shall be the first member of DMA client driver Data,...
Definition: dma.h:295
int32_t magic
magic code to identify the context
Definition: dma.h:297
atomic_t * atomic
atomic holding bit flags for each channel to mark as used/unused
Definition: dma.h:301
int dma_channels
number of dma channels
Definition: dma.h:299
DMA runtime status structure.
Definition: dma.h:273
uint32_t free
Available buffers space, HW specific.
Definition: dma.h:281
uint32_t pending_length
Pending length to be transferred in bytes, HW specific.
Definition: dma.h:279
bool busy
Is the current DMA transfer busy or idle.
Definition: dma.h:275
uint64_t total_copied
Total copied, HW specific.
Definition: dma.h:287
uint32_t write_position
Write position in circular DMA buffer, HW specific.
Definition: dma.h:283
enum dma_channel_direction dir
Direction fo the transfer.
Definition: dma.h:277
uint32_t read_position
Read position in circular DMA buffer, HW specific.
Definition: dma.h:285
Definition: stat.h:92