refactor(gdma): increase performance and optimize api

This commit is contained in:
Chen Jichang
2026-09-03 19:09:30 +08:00
committed by Chen Ji Chang
parent 305d434bda
commit bd2d64bffb
23 changed files with 119 additions and 142 deletions
@@ -7,6 +7,7 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include "esp_etm.h"
#include "hal/gdma_types.h"
#include "esp_err.h"
@@ -221,52 +222,44 @@ typedef struct {
esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transfer_config_t *config);
/**
* @brief Get the alignment constraints for a configured GDMA channel
* @brief Alignment constraints of a configured GDMA channel
*
* @note You should call this function after `gdma_config_transfer`, the later one can
* adjust the alignment constraints based on GDMA-specific conditions, e.g. burst size.
* @note Prefer this when allocating DMA buffers. Once a concrete buffer address is available,
* use `gdma_get_buffer_alignment_constraint` for the effective runtime constraint of that region.
* @note For allocation from external memory:
* - Use `ext_enc_mem_alignment` as the safe default (worst-case MSPI encryption/ECC).
* - Use `ext_no_enc_mem_alignment` when intentionally targeting no-encryption external memory (e.g. no-enc PSRAM).
* @note The returned alignment doesn't take the cache line size into account, if you want to do aligned memory allocation,
* you should align the buffer size to the cache line size by yourself if the DMA buffer is behind a cache.
* @note The returned alignment doesn't take the cache line size into account. If the DMA buffer is behind a cache,
* align the buffer size to the cache line size yourself when needed.
*/
typedef struct {
size_t int_mem_alignment; /*!< Alignment for internal memory */
size_t ext_enc_mem_alignment; /*!< Alignment for external memory including MSPI encryption/ECC constraints */
size_t ext_no_enc_mem_alignment; /*!< Alignment for external memory without MSPI region-specific constraints */
} gdma_channel_alignment_info_t;
/**
* @brief Get the alignment constraints for a configured GDMA channel
*
* @note Call this function after `gdma_config_transfer`.
*
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_ahb_channel/gdma_new_axi_channel`
* @param[out] int_mem_alignment Internal memory alignment
* @param[out] ext_enc_mem_alignment External memory alignment including MSPI encryption/ECC constraints
* @param[out] ext_no_enc_mem_alignment External memory alignment without MSPI region-specific constraints.
* Useful when allocating from no-encryption external memory. Set to NULL if unused.
* @param[out] info Alignment constraints of the channel
* @return
* - ESP_OK: Get alignment constraints successfully
* - ESP_ERR_INVALID_ARG: Get alignment constraints failed because of invalid argument
* - ESP_FAIL: Get alignment constraints failed because of other error
*/
esp_err_t gdma_get_channel_alignment_constraints(gdma_channel_handle_t dma_chan, size_t *int_mem_alignment,
size_t *ext_enc_mem_alignment, size_t *ext_no_enc_mem_alignment);
/**
* @brief Check whether buffer sizes must meet the configured channel alignment
*
* @note Call this function after `gdma_config_transfer`.
* @note This reports GDMA hardware constraints only. Region-specific MSPI constraints
* are enforced independently when buffers are mounted to a GDMA link list.
*
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_ahb_channel/gdma_new_axi_channel`
* @return True when buffer sizes must be aligned, otherwise false
*/
bool gdma_is_size_alignment_required(gdma_channel_handle_t dma_chan);
esp_err_t gdma_get_channel_alignment_constraints(gdma_channel_handle_t dma_chan, gdma_channel_alignment_info_t *info);
/**
* @brief Get the effective alignment constraint for a specific DMA buffer
*
* @note You should call this function after `gdma_config_transfer`.
* @note The returned alignment combines GDMA channel constraints with MSPI constraints
* of the actual buffer region. This lets external no-encryption PSRAM buffers use
* their real runtime constraint instead of a generic worst-case MSPI alignment.
* @note Call this function after `gdma_config_transfer`.
* @note Combines GDMA channel constraints with MSPI constraints of the actual buffer region.
* External no-encryption PSRAM buffers can therefore use their real runtime constraint
* instead of a generic worst-case MSPI alignment.
* @note The returned alignment doesn't take the cache line size into account.
* @note On invalid arguments, returns an impossible alignment (BIT(31)).
* @note On invalid arguments, returns an impossible value (BIT(31)).
*
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_ahb_channel/gdma_new_axi_channel`
* @param[in] buffer DMA buffer address
@@ -82,12 +82,10 @@ typedef struct {
gdma_final_node_link_type_t mark_final: 2; /*!< Specify the next item of the final item of this mount.
For the other items that not the final one, it will be linked to the next item automatically and this field takes no effect.
Note, the final item here does not mean the last item in the link list. It is `start_item_index + num_items - 1` */
uint32_t bypass_buffer_align_check: 1; /*!< Whether to bypass the buffer alignment check.
uint32_t bypass_buffer_addr_align_check: 1; /*!< Whether to bypass the buffer address alignment check.
Only enable it when you know what you are doing. */
uint32_t bypass_buffer_size_align_check: 1; /*!< Whether to bypass the buffer size alignment check.
Only enable it when you know what you are doing. */
uint32_t check_size_align: 1; /*!< Whether to check that `length` is aligned to the alignment.
RX callers can query `gdma_is_size_alignment_required` to determine whether
the configured channel requires this check. Under MSPI Flash Encryption /
PSRAM ECC, length alignment is always enforced regardless of this flag. */
} flags; //!< Flags for buffer mount configurations
} gdma_buffer_mount_config_t;