LCOV - code coverage report
Current view: top level - zephyr/drivers - dma.h Coverage Total Hit
Test: new.info Lines: 97.3 % 74 72
Test Date: 2025-09-25 19:22:35

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

Generated by: LCOV version 2.0-1