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-10-20 12:20:01

            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 : static inline int dma_start(const struct device *dev, uint32_t channel)
     455              : {
     456              :         const struct dma_driver_api *api =
     457              :                 (const struct dma_driver_api *)dev->api;
     458              : 
     459              :         return api->start(dev, channel);
     460              : }
     461              : 
     462              : /**
     463              :  * @brief Stops the DMA transfer and disables the channel.
     464              :  *
     465              :  * Implementations must check the validity of the channel ID passed in and
     466              :  * return -EINVAL if it is invalid.
     467              :  *
     468              :  * Stop is allowed on channels that have already been stopped and must report
     469              :  * success.
     470              :  *
     471              :  * @funcprops \isr_ok
     472              :  *
     473              :  * @param dev     Pointer to the device structure for the driver instance.
     474              :  * @param channel Numeric identification of the channel where the transfer was
     475              :  *                being processed
     476              :  *
     477              :  * @retval 0 if successful.
     478              :  * @retval Negative errno code if failure.
     479              :  */
     480            1 : static inline int dma_stop(const struct device *dev, uint32_t channel)
     481              : {
     482              :         const struct dma_driver_api *api =
     483              :                 (const struct dma_driver_api *)dev->api;
     484              : 
     485              :         return api->stop(dev, channel);
     486              : }
     487              : 
     488              : 
     489              : /**
     490              :  * @brief Suspend a DMA channel transfer
     491              :  *
     492              :  * Implementations must check the validity of the channel state and ID passed
     493              :  * in and return -EINVAL if either are invalid.
     494              :  *
     495              :  * @funcprops \isr_ok
     496              :  *
     497              :  * @param dev Pointer to the device structure for the driver instance.
     498              :  * @param channel Numeric identification of the channel to suspend
     499              :  *
     500              :  * @retval 0 If successful.
     501              :  * @retval -ENOSYS If not implemented.
     502              :  * @retval -EINVAL If invalid channel id or state.
     503              :  * @retval -errno Other negative errno code failure.
     504              :  */
     505            1 : static inline int dma_suspend(const struct device *dev, uint32_t channel)
     506              : {
     507              :         const struct dma_driver_api *api = (const struct dma_driver_api *)dev->api;
     508              : 
     509              :         if (api->suspend == NULL) {
     510              :                 return -ENOSYS;
     511              :         }
     512              :         return api->suspend(dev, channel);
     513              : }
     514              : 
     515              : /**
     516              :  * @brief Resume a DMA channel transfer
     517              :  *
     518              :  * Implementations must check the validity of the channel state and ID passed
     519              :  * in and return -EINVAL if either are invalid.
     520              :  *
     521              :  * @funcprops \isr_ok
     522              :  *
     523              :  * @param dev Pointer to the device structure for the driver instance.
     524              :  * @param channel Numeric identification of the channel to resume
     525              :  *
     526              :  * @retval 0 If successful.
     527              :  * @retval -ENOSYS If not implemented
     528              :  * @retval -EINVAL If invalid channel id or state.
     529              :  * @retval -errno Other negative errno code failure.
     530              :  */
     531            1 : static inline int dma_resume(const struct device *dev, uint32_t channel)
     532              : {
     533              :         const struct dma_driver_api *api = (const struct dma_driver_api *)dev->api;
     534              : 
     535              :         if (api->resume == NULL) {
     536              :                 return -ENOSYS;
     537              :         }
     538              :         return api->resume(dev, channel);
     539              : }
     540              : 
     541              : /**
     542              :  * @brief request DMA channel.
     543              :  *
     544              :  * request DMA channel resources
     545              :  * return -EINVAL if there is no valid channel available.
     546              :  *
     547              :  * @note It is safe to use this function in contexts where blocking
     548              :  * is not allowed, e.g. ISR, provided the implementation of the filter
     549              :  * function does not block.
     550              :  *
     551              :  * @param dev Pointer to the device structure for the driver instance.
     552              :  * @param filter_param filter function parameter
     553              :  *
     554              :  * @retval dma channel if successful.
     555              :  * @retval Negative errno code if failure.
     556              :  */
     557            1 : static inline int dma_request_channel(const struct device *dev, void *filter_param)
     558              : {
     559              :         int i = 0;
     560              :         int channel = -EINVAL;
     561              :         const struct dma_driver_api *api =
     562              :                 (const struct dma_driver_api *)dev->api;
     563              :         /* dma_context shall be the first one in dev data */
     564              :         struct dma_context *dma_ctx = (struct dma_context *)dev->data;
     565              : 
     566              :         if (dma_ctx->magic != DMA_MAGIC) {
     567              :                 return channel;
     568              :         }
     569              : 
     570              :         for (i = 0; i < dma_ctx->dma_channels; i++) {
     571              :                 if (!atomic_test_and_set_bit(dma_ctx->atomic, i)) {
     572              :                         if (api->chan_filter &&
     573              :                             !api->chan_filter(dev, i, filter_param)) {
     574              :                                 atomic_clear_bit(dma_ctx->atomic, i);
     575              :                                 continue;
     576              :                         }
     577              :                         channel = i;
     578              :                         break;
     579              :                 }
     580              :         }
     581              : 
     582              :         return channel;
     583              : }
     584              : 
     585              : /**
     586              :  * @brief release DMA channel.
     587              :  *
     588              :  * release DMA channel resources
     589              :  *
     590              :  * @note It is safe to use this function in contexts where blocking
     591              :  * is not allowed, e.g. ISR, provided the implementation of the release
     592              :  * function does not block.
     593              :  *
     594              :  * @param dev  Pointer to the device structure for the driver instance.
     595              :  * @param channel  channel number
     596              :  *
     597              :  */
     598            1 : static inline void dma_release_channel(const struct device *dev, uint32_t channel)
     599              : {
     600              :         const struct dma_driver_api *api =
     601              :                 (const struct dma_driver_api *)dev->api;
     602              :         struct dma_context *dma_ctx = (struct dma_context *)dev->data;
     603              : 
     604              :         if (dma_ctx->magic != DMA_MAGIC) {
     605              :                 return;
     606              :         }
     607              : 
     608              :         if ((int)channel < dma_ctx->dma_channels) {
     609              :                 if (api->chan_release) {
     610              :                         api->chan_release(dev, channel);
     611              :                 }
     612              : 
     613              :                 atomic_clear_bit(dma_ctx->atomic, channel);
     614              :         }
     615              : 
     616              : }
     617              : 
     618              : /**
     619              :  * @brief DMA channel filter.
     620              :  *
     621              :  * filter channel by attribute
     622              :  *
     623              :  * @param dev  Pointer to the device structure for the driver instance.
     624              :  * @param channel  channel number
     625              :  * @param filter_param filter attribute
     626              :  *
     627              :  * @retval Negative errno code if not support
     628              :  *
     629              :  */
     630            1 : static inline int dma_chan_filter(const struct device *dev, int channel, void *filter_param)
     631              : {
     632              :         const struct dma_driver_api *api =
     633              :                 (const struct dma_driver_api *)dev->api;
     634              : 
     635              :         if (api->chan_filter) {
     636              :                 return api->chan_filter(dev, channel, filter_param);
     637              :         }
     638              : 
     639              :         return -ENOSYS;
     640              : }
     641              : 
     642              : /**
     643              :  * @brief get current runtime status of DMA transfer
     644              :  *
     645              :  * Implementations must check the validity of the channel ID passed in and
     646              :  * return -EINVAL if it is invalid or -ENOSYS if not supported.
     647              :  *
     648              :  * @funcprops \isr_ok
     649              :  *
     650              :  * @param dev     Pointer to the device structure for the driver instance.
     651              :  * @param channel Numeric identification of the channel where the transfer was
     652              :  *                being processed
     653              :  * @param stat   a non-NULL dma_status object for storing DMA status
     654              :  *
     655              :  * @retval non-negative if successful.
     656              :  * @retval Negative errno code if failure.
     657              :  */
     658            1 : static inline int dma_get_status(const struct device *dev, uint32_t channel,
     659              :                                  struct dma_status *stat)
     660              : {
     661              :         const struct dma_driver_api *api =
     662              :                 (const struct dma_driver_api *)dev->api;
     663              : 
     664              :         if (api->get_status) {
     665              :                 return api->get_status(dev, channel, stat);
     666              :         }
     667              : 
     668              :         return -ENOSYS;
     669              : }
     670              : 
     671              : /**
     672              :  * @brief get attribute of a dma controller
     673              :  *
     674              :  * This function allows to get a device specific static or runtime attribute like required address
     675              :  * and size alignment of a buffer.
     676              :  * Implementations must check the validity of the type passed in and
     677              :  * return -EINVAL if it is invalid or -ENOSYS if not supported.
     678              :  *
     679              :  * @funcprops \isr_ok
     680              :  *
     681              :  * @param dev     Pointer to the device structure for the driver instance.
     682              :  * @param type    Numeric identification of the attribute
     683              :  * @param value   A non-NULL pointer to the variable where the read value is to be placed
     684              :  *
     685              :  * @retval non-negative if successful.
     686              :  * @retval Negative errno code if failure.
     687              :  */
     688            1 : static inline int dma_get_attribute(const struct device *dev, uint32_t type, uint32_t *value)
     689              : {
     690              :         const struct dma_driver_api *api = (const struct dma_driver_api *)dev->api;
     691              : 
     692              :         if (api->get_attribute) {
     693              :                 return api->get_attribute(dev, type, value);
     694              :         }
     695              : 
     696              :         return -ENOSYS;
     697              : }
     698              : 
     699              : /**
     700              :  * @brief Look-up generic width index to be used in registers
     701              :  *
     702              :  * @warning This look-up works for most controllers, but *may* not work for
     703              :  *          yours.  Ensure your controller expects the most common register
     704              :  *          bit values before using this convenience function.  If your
     705              :  *          controller does not support these values, you will have to write
     706              :  *          your own look-up inside the controller driver.
     707              :  *
     708              :  * @param size: width of bus (in bytes)
     709              :  *
     710              :  * @retval common DMA index to be placed into registers.
     711              :  */
     712            1 : static inline uint32_t dma_width_index(uint32_t size)
     713              : {
     714              :         /* Check boundaries (max supported width is 32 Bytes) */
     715              :         if (size < 1 || size > 32) {
     716              :                 return 0; /* Zero is the default (8 Bytes) */
     717              :         }
     718              : 
     719              :         /* Ensure size is a power of 2 */
     720              :         if (!is_power_of_two(size)) {
     721              :                 return 0; /* Zero is the default (8 Bytes) */
     722              :         }
     723              : 
     724              :         /* Convert to bit pattern for writing to a register */
     725              :         return find_msb_set(size);
     726              : }
     727              : 
     728              : /**
     729              :  * @brief Look-up generic burst index to be used in registers
     730              :  *
     731              :  * @warning This look-up works for most controllers, but *may* not work for
     732              :  *          yours.  Ensure your controller expects the most common register
     733              :  *          bit values before using this convenience function.  If your
     734              :  *          controller does not support these values, you will have to write
     735              :  *          your own look-up inside the controller driver.
     736              :  *
     737              :  * @param burst: number of bytes to be sent in a single burst
     738              :  *
     739              :  * @retval common DMA index to be placed into registers.
     740              :  */
     741            1 : static inline uint32_t dma_burst_index(uint32_t burst)
     742              : {
     743              :         /* Check boundaries (max supported burst length is 256) */
     744              :         if (burst < 1 || burst > 256) {
     745              :                 return 0; /* Zero is the default (1 burst length) */
     746              :         }
     747              : 
     748              :         /* Ensure burst is a power of 2 */
     749              :         if (!(burst & (burst - 1))) {
     750              :                 return 0; /* Zero is the default (1 burst length) */
     751              :         }
     752              : 
     753              :         /* Convert to bit pattern for writing to a register */
     754              :         return find_msb_set(burst);
     755              : }
     756              : 
     757              : /**
     758              :  * @brief Get the device tree property describing the buffer address alignment
     759              :  *
     760              :  * Useful when statically defining or allocating buffers for DMA usage where
     761              :  * memory alignment often matters.
     762              :  *
     763              :  * @param node Node identifier, e.g. DT_NODELABEL(dma_0)
     764              :  * @return alignment Memory byte alignment required for DMA buffers
     765              :  */
     766            1 : #define DMA_BUF_ADDR_ALIGNMENT(node) DT_PROP(node, dma_buf_addr_alignment)
     767              : 
     768              : /**
     769              :  * @brief Get the device tree property describing the buffer size alignment
     770              :  *
     771              :  * Useful when statically defining or allocating buffers for DMA usage where
     772              :  * memory alignment often matters.
     773              :  *
     774              :  * @param node Node identifier, e.g. DT_NODELABEL(dma_0)
     775              :  * @return alignment Memory byte alignment required for DMA buffers
     776              :  */
     777            1 : #define DMA_BUF_SIZE_ALIGNMENT(node) DT_PROP(node, dma_buf_size_alignment)
     778              : 
     779              : /**
     780              :  * @brief Get the device tree property describing the minimal chunk of data possible to be copied
     781              :  *
     782              :  * @param node Node identifier, e.g. DT_NODELABEL(dma_0)
     783              :  * @return minimal Minimal chunk of data possible to be copied
     784              :  */
     785            1 : #define DMA_COPY_ALIGNMENT(node) DT_PROP(node, dma_copy_alignment)
     786              : 
     787              : /**
     788              :  * @}
     789              :  */
     790              : 
     791              : #ifdef __cplusplus
     792              : }
     793              : #endif
     794              : 
     795              : #endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_H_ */
        

Generated by: LCOV version 2.0-1