mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
refactor(gdma): increase performance and optimize api
This commit is contained in:
committed by
Chen Ji Chang
parent
305d434bda
commit
bd2d64bffb
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -221,10 +221,12 @@ esp_err_t bitscrambler_loopback_run(bitscrambler_handle_t bs, void *buffer_in, s
|
|||||||
gdma_reset(bsl->tx_channel);
|
gdma_reset(bsl->tx_channel);
|
||||||
bitscrambler_reset(bs);
|
bitscrambler_reset(bs);
|
||||||
|
|
||||||
|
size_t in_alignment = gdma_get_buffer_alignment_constraint(bsl->tx_channel, buffer_in);
|
||||||
|
size_t out_alignment = gdma_get_buffer_alignment_constraint(bsl->rx_channel, buffer_out);
|
||||||
// mount in and out buffer to the DMA link list
|
// mount in and out buffer to the DMA link list
|
||||||
gdma_buffer_mount_config_t in_buf_mount_config = {
|
gdma_buffer_mount_config_t in_buf_mount_config = {
|
||||||
.buffer = buffer_in,
|
.buffer = buffer_in,
|
||||||
.buffer_alignment = 4,
|
.buffer_alignment = in_alignment,
|
||||||
.length = length_bytes_in,
|
.length = length_bytes_in,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
@@ -234,12 +236,11 @@ esp_err_t bitscrambler_loopback_run(bitscrambler_handle_t bs, void *buffer_in, s
|
|||||||
gdma_link_mount_buffers(bsl->tx_link_list, 0, &in_buf_mount_config, 1, NULL);
|
gdma_link_mount_buffers(bsl->tx_link_list, 0, &in_buf_mount_config, 1, NULL);
|
||||||
gdma_buffer_mount_config_t out_buf_mount_config = {
|
gdma_buffer_mount_config_t out_buf_mount_config = {
|
||||||
.buffer = buffer_out,
|
.buffer = buffer_out,
|
||||||
.buffer_alignment = 4,
|
.buffer_alignment = out_alignment,
|
||||||
.length = length_bytes_out,
|
.length = length_bytes_out,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = false,
|
.mark_eof = false,
|
||||||
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
||||||
.check_size_align = gdma_is_size_alignment_required(bsl->rx_channel),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
gdma_link_mount_buffers(bsl->rx_link_list, 0, &out_buf_mount_config, 1, NULL);
|
gdma_link_mount_buffers(bsl->rx_link_list, 0, &out_buf_mount_config, 1, NULL);
|
||||||
|
|||||||
@@ -106,7 +106,10 @@ esp_err_t esp_cam_ctlr_dvp_dma_init(esp_cam_ctlr_dvp_dma_t *dma, uint32_t burst_
|
|||||||
};
|
};
|
||||||
ESP_GOTO_ON_ERROR(gdma_config_transfer(dma->dma_chan, &transfer_config), fail1, TAG, "set trans ability failed");
|
ESP_GOTO_ON_ERROR(gdma_config_transfer(dma->dma_chan, &transfer_config), fail1, TAG, "set trans ability failed");
|
||||||
|
|
||||||
gdma_get_channel_alignment_constraints(dma->dma_chan, &dma->int_mem_align, &dma->ext_mem_align, NULL);
|
gdma_channel_alignment_info_t align_info;
|
||||||
|
gdma_get_channel_alignment_constraints(dma->dma_chan, &align_info);
|
||||||
|
dma->int_mem_align = align_info.int_mem_alignment;
|
||||||
|
dma->ext_mem_align = align_info.ext_enc_mem_alignment;
|
||||||
|
|
||||||
size_t buffer_alignment = dma->ext_mem_align;
|
size_t buffer_alignment = dma->ext_mem_align;
|
||||||
size_t desc_max_size = ESP_CAM_CTLR_DVP_DMA_DESC_BUFFER_MAX_SIZE;
|
size_t desc_max_size = ESP_CAM_CTLR_DVP_DMA_DESC_BUFFER_MAX_SIZE;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include "esp_etm.h"
|
#include "esp_etm.h"
|
||||||
#include "hal/gdma_types.h"
|
#include "hal/gdma_types.h"
|
||||||
#include "esp_err.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);
|
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,
|
* @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.
|
* use `gdma_get_buffer_alignment_constraint` for the effective runtime constraint of that region.
|
||||||
* @note For allocation from external memory:
|
* @note For allocation from external memory:
|
||||||
* - Use `ext_enc_mem_alignment` as the safe default (worst-case MSPI encryption/ECC).
|
* - 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).
|
* - 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,
|
* @note The returned alignment doesn't take the cache line size into account. If the DMA buffer is behind a cache,
|
||||||
* you should align the buffer size to the cache line size by yourself 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[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] info Alignment constraints of the channel
|
||||||
* @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.
|
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK: Get alignment constraints successfully
|
* - ESP_OK: Get alignment constraints successfully
|
||||||
* - ESP_ERR_INVALID_ARG: Get alignment constraints failed because of invalid argument
|
* - 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,
|
esp_err_t gdma_get_channel_alignment_constraints(gdma_channel_handle_t dma_chan, gdma_channel_alignment_info_t *info);
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the effective alignment constraint for a specific DMA buffer
|
* @brief Get the effective alignment constraint for a specific DMA buffer
|
||||||
*
|
*
|
||||||
* @note You should call this function after `gdma_config_transfer`.
|
* @note Call this function after `gdma_config_transfer`.
|
||||||
* @note The returned alignment combines GDMA channel constraints with MSPI constraints
|
* @note Combines GDMA channel constraints with MSPI constraints of the actual buffer region.
|
||||||
* of the actual buffer region. This lets external no-encryption PSRAM buffers use
|
* External no-encryption PSRAM buffers can therefore use their real runtime constraint
|
||||||
* their real runtime constraint instead of a generic worst-case MSPI alignment.
|
* instead of a generic worst-case MSPI alignment.
|
||||||
* @note The returned alignment doesn't take the cache line size into account.
|
* @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] dma_chan GDMA channel handle, allocated by `gdma_new_ahb_channel/gdma_new_axi_channel`
|
||||||
* @param[in] buffer DMA buffer address
|
* @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.
|
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.
|
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` */
|
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. */
|
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
|
} flags; //!< Flags for buffer mount configurations
|
||||||
} gdma_buffer_mount_config_t;
|
} gdma_buffer_mount_config_t;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ entries:
|
|||||||
gdma: gdma_append (noflash)
|
gdma: gdma_append (noflash)
|
||||||
gdma: gdma_reset (noflash)
|
gdma: gdma_reset (noflash)
|
||||||
gdma: gdma_get_buffer_alignment_constraint (noflash)
|
gdma: gdma_get_buffer_alignment_constraint (noflash)
|
||||||
gdma: gdma_is_size_alignment_required (noflash)
|
|
||||||
|
|
||||||
[mapping:gdma_hal]
|
[mapping:gdma_hal]
|
||||||
archive: libesp_hal_dma.a
|
archive: libesp_hal_dma.a
|
||||||
|
|||||||
@@ -163,8 +163,9 @@ esp_err_t esp_async_crc_install_gdma_template(const async_crc_config_t *config,
|
|||||||
ESP_GOTO_ON_ERROR(gdma_config_transfer(crc_gdma->rx_channel, &transfer_cfg), err, TAG, "config RX DMA transfer failed");
|
ESP_GOTO_ON_ERROR(gdma_config_transfer(crc_gdma->rx_channel, &transfer_cfg), err, TAG, "config RX DMA transfer failed");
|
||||||
|
|
||||||
// Get buffer alignment required by GDMA channel
|
// Get buffer alignment required by GDMA channel
|
||||||
size_t rx_int_mem_alignment = 0;
|
gdma_channel_alignment_info_t rx_align_info;
|
||||||
gdma_get_channel_alignment_constraints(crc_gdma->rx_channel, &rx_int_mem_alignment, NULL, NULL);
|
gdma_get_channel_alignment_constraints(crc_gdma->rx_channel, &rx_align_info);
|
||||||
|
size_t rx_int_mem_alignment = rx_align_info.int_mem_alignment;
|
||||||
size_t rx_buffer_size = (rx_int_mem_alignment > CRC_DMA_RX_SINK_BUFFER_SIZE) ?
|
size_t rx_buffer_size = (rx_int_mem_alignment > CRC_DMA_RX_SINK_BUFFER_SIZE) ?
|
||||||
rx_int_mem_alignment : CRC_DMA_RX_SINK_BUFFER_SIZE;
|
rx_int_mem_alignment : CRC_DMA_RX_SINK_BUFFER_SIZE;
|
||||||
crc_gdma->rx_sink_buffer = heap_caps_aligned_calloc(rx_int_mem_alignment, 1, rx_buffer_size,
|
crc_gdma->rx_sink_buffer = heap_caps_aligned_calloc(rx_int_mem_alignment, 1, rx_buffer_size,
|
||||||
@@ -189,7 +190,6 @@ esp_err_t esp_async_crc_install_gdma_template(const async_crc_config_t *config,
|
|||||||
.length = rx_buffer_size,
|
.length = rx_buffer_size,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_final = GDMA_FINAL_LINK_TO_HEAD,
|
.mark_final = GDMA_FINAL_LINK_TO_HEAD,
|
||||||
.check_size_align = gdma_is_size_alignment_required(crc_gdma->rx_channel),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ESP_GOTO_ON_ERROR(gdma_link_mount_buffers(crc_gdma->rx_link_list, 0, &rx_buf_mount_config, 1, NULL),
|
ESP_GOTO_ON_ERROR(gdma_link_mount_buffers(crc_gdma->rx_link_list, 0, &rx_buf_mount_config, 1, NULL),
|
||||||
|
|||||||
@@ -324,12 +324,11 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
|
|||||||
trans->stash_buffer = NULL;
|
trans->stash_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t buffer_alignment = 0;
|
|
||||||
size_t num_dma_nodes = 0;
|
size_t num_dma_nodes = 0;
|
||||||
|
|
||||||
// allocate gdma TX link
|
// allocate gdma TX link
|
||||||
buffer_alignment = gdma_get_buffer_alignment_constraint(mcp_gdma->tx_channel, src);
|
size_t tx_buffer_alignment = gdma_get_buffer_alignment_constraint(mcp_gdma->tx_channel, src);
|
||||||
num_dma_nodes = esp_dma_calculate_node_count(n, buffer_alignment, MCP_DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
num_dma_nodes = esp_dma_calculate_node_count(n, tx_buffer_alignment, MCP_DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
||||||
gdma_link_list_config_t tx_link_cfg = {
|
gdma_link_list_config_t tx_link_cfg = {
|
||||||
.item_alignment = dma_link_item_alignment,
|
.item_alignment = dma_link_item_alignment,
|
||||||
.num_items = num_dma_nodes,
|
.num_items = num_dma_nodes,
|
||||||
@@ -343,7 +342,7 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
|
|||||||
gdma_buffer_mount_config_t tx_buf_mount_config[1] = {
|
gdma_buffer_mount_config_t tx_buf_mount_config[1] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.buffer = src,
|
.buffer = src,
|
||||||
.buffer_alignment = buffer_alignment,
|
.buffer_alignment = tx_buffer_alignment,
|
||||||
.length = n,
|
.length = n,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true, // mark the last item as EOF, so the RX channel can also received an EOF list item
|
.mark_eof = true, // mark the last item as EOF, so the RX channel can also received an EOF list item
|
||||||
@@ -361,8 +360,8 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocate gdma RX link
|
// allocate gdma RX link
|
||||||
buffer_alignment = gdma_get_buffer_alignment_constraint(mcp_gdma->rx_channel, dst);
|
size_t rx_buffer_alignment = gdma_get_buffer_alignment_constraint(mcp_gdma->rx_channel, dst);
|
||||||
num_dma_nodes = esp_dma_calculate_node_count(n, buffer_alignment, MCP_DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
num_dma_nodes = esp_dma_calculate_node_count(n, rx_buffer_alignment, MCP_DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
||||||
gdma_link_list_config_t rx_link_cfg = {
|
gdma_link_list_config_t rx_link_cfg = {
|
||||||
.item_alignment = dma_link_item_alignment,
|
.item_alignment = dma_link_item_alignment,
|
||||||
.num_items = num_dma_nodes + 3, // add 3 extra items for the cache aligned buffers
|
.num_items = num_dma_nodes + 3, // add 3 extra items for the cache aligned buffers
|
||||||
@@ -379,9 +378,8 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
|
|||||||
gdma_buffer_mount_config_t rx_buf_mount_config[3] = {0};
|
gdma_buffer_mount_config_t rx_buf_mount_config[3] = {0};
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
rx_buf_mount_config[i].buffer = trans->rx_buf_array.aligned_buffer[i].aligned_buffer;
|
rx_buf_mount_config[i].buffer = trans->rx_buf_array.aligned_buffer[i].aligned_buffer;
|
||||||
rx_buf_mount_config[i].buffer_alignment = buffer_alignment;
|
rx_buf_mount_config[i].buffer_alignment = rx_buffer_alignment;
|
||||||
rx_buf_mount_config[i].length = trans->rx_buf_array.aligned_buffer[i].length;
|
rx_buf_mount_config[i].length = trans->rx_buf_array.aligned_buffer[i].length;
|
||||||
rx_buf_mount_config[i].flags.check_size_align = gdma_is_size_alignment_required(mcp_gdma->rx_channel);
|
|
||||||
}
|
}
|
||||||
gdma_link_mount_buffers(trans->rx_link_list, 0, rx_buf_mount_config, 3, NULL);
|
gdma_link_mount_buffers(trans->rx_link_list, 0, rx_buf_mount_config, 3, NULL);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -45,7 +45,7 @@ esp_err_t esp_dma_split_rx_buffer_to_cache_aligned(void *rx_buffer, size_t buffe
|
|||||||
split_line_size = int_mem_cache_line_size;
|
split_line_size = int_mem_cache_line_size;
|
||||||
}
|
}
|
||||||
bool align_required = split_line_size > 0;
|
bool align_required = split_line_size > 0;
|
||||||
ESP_EARLY_LOGV(TAG, "split_line_size:%d", split_line_size);
|
ESP_EARLY_LOGV(TAG, "split_line_size:%" PRIu32, (uint32_t)split_line_size);
|
||||||
|
|
||||||
if (*ret_stash_buffer == NULL) {
|
if (*ret_stash_buffer == NULL) {
|
||||||
// If the stash buffer is not offered by the caller, allocate the stash buffer from internal RAM
|
// If the stash buffer is not offered by the caller, allocate the stash buffer from internal RAM
|
||||||
@@ -69,10 +69,10 @@ esp_err_t esp_dma_split_rx_buffer_to_cache_aligned(void *rx_buffer, size_t buffe
|
|||||||
// calculate head_overflow_len
|
// calculate head_overflow_len
|
||||||
size_t head_overflow_len = (uintptr_t)rx_buffer % split_line_size;
|
size_t head_overflow_len = (uintptr_t)rx_buffer % split_line_size;
|
||||||
head_overflow_len = head_overflow_len ? split_line_size - head_overflow_len : 0;
|
head_overflow_len = head_overflow_len ? split_line_size - head_overflow_len : 0;
|
||||||
ESP_EARLY_LOGV(TAG, "head_addr:%p head_overflow_len:%zu", rx_buffer, head_overflow_len);
|
ESP_EARLY_LOGV(TAG, "head_addr:%p head_overflow_len:%" PRIu32, rx_buffer, (uint32_t)head_overflow_len);
|
||||||
// calculate tail_overflow_len
|
// calculate tail_overflow_len
|
||||||
size_t tail_overflow_len = ((uintptr_t)rx_buffer + buffer_len) % split_line_size;
|
size_t tail_overflow_len = ((uintptr_t)rx_buffer + buffer_len) % split_line_size;
|
||||||
ESP_EARLY_LOGV(TAG, "tail_addr:%p tail_overflow_len:%zu", rx_buffer + buffer_len - tail_overflow_len, tail_overflow_len);
|
ESP_EARLY_LOGV(TAG, "tail_addr:%p tail_overflow_len:%" PRIu32, rx_buffer + buffer_len - tail_overflow_len, (uint32_t)tail_overflow_len);
|
||||||
|
|
||||||
// special handling when input_buffer length is no more than buffer alignment
|
// special handling when input_buffer length is no more than buffer alignment
|
||||||
bool is_small_buf = head_overflow_len >= buffer_len || tail_overflow_len >= buffer_len;
|
bool is_small_buf = head_overflow_len >= buffer_len || tail_overflow_len >= buffer_len;
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf
|
|||||||
|
|
||||||
if (config->access_ext_mem) {
|
if (config->access_ext_mem) {
|
||||||
#if (SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH) && SOC_AHB_GDMA_VERSION != 1
|
#if (SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH) && SOC_AHB_GDMA_VERSION != 1
|
||||||
// Under Flash Encryption/PSRAM ECC, external DMA must use MSPI-aligned bursts.
|
// Under Flash Encryption/PSRAM ECC, DMA must use MSPI-aligned bursts.
|
||||||
size_t mspi_alignment = esp_mspi_get_alignment(NULL);
|
size_t mspi_alignment = esp_mspi_get_alignment(NULL);
|
||||||
if (mspi_alignment > 1) {
|
if (mspi_alignment > 1) {
|
||||||
if (max_data_burst_size < mspi_alignment) {
|
if (max_data_burst_size < mspi_alignment) {
|
||||||
@@ -449,7 +449,6 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool en_data_burst = max_data_burst_size > 0;
|
bool en_data_burst = max_data_burst_size > 0;
|
||||||
dma_chan->flags.size_alignment_required = false;
|
|
||||||
if (en_data_burst) {
|
if (en_data_burst) {
|
||||||
#if CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION
|
#if CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION
|
||||||
// due to hardware limitation, if weighted arbitration is enabled, the data must be aligned to burst size
|
// due to hardware limitation, if weighted arbitration is enabled, the data must be aligned to burst size
|
||||||
@@ -464,7 +463,6 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf
|
|||||||
int_mem_alignment = MAX(int_mem_alignment, 4);
|
int_mem_alignment = MAX(int_mem_alignment, 4);
|
||||||
ext_enc_mem_alignment = MAX(ext_enc_mem_alignment, max_data_burst_size);
|
ext_enc_mem_alignment = MAX(ext_enc_mem_alignment, max_data_burst_size);
|
||||||
ext_no_enc_mem_alignment = MAX(ext_no_enc_mem_alignment, max_data_burst_size);
|
ext_no_enc_mem_alignment = MAX(ext_no_enc_mem_alignment, max_data_burst_size);
|
||||||
dma_chan->flags.size_alignment_required = true;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -513,42 +511,30 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t gdma_get_channel_alignment_constraints(gdma_channel_handle_t dma_chan, size_t *int_mem_alignment,
|
esp_err_t gdma_get_channel_alignment_constraints(gdma_channel_handle_t dma_chan, gdma_channel_alignment_info_t *info)
|
||||||
size_t *ext_enc_mem_alignment, size_t *ext_no_enc_mem_alignment)
|
|
||||||
{
|
{
|
||||||
if (!dma_chan) {
|
if (!dma_chan || !info) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
if (int_mem_alignment) {
|
info->int_mem_alignment = dma_chan->int_mem_alignment;
|
||||||
*int_mem_alignment = dma_chan->int_mem_alignment;
|
info->ext_enc_mem_alignment = dma_chan->ext_enc_mem_alignment;
|
||||||
}
|
info->ext_no_enc_mem_alignment = dma_chan->ext_no_enc_mem_alignment;
|
||||||
if (ext_enc_mem_alignment) {
|
|
||||||
*ext_enc_mem_alignment = dma_chan->ext_enc_mem_alignment;
|
|
||||||
}
|
|
||||||
if (ext_no_enc_mem_alignment) {
|
|
||||||
*ext_no_enc_mem_alignment = dma_chan->ext_no_enc_mem_alignment;
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gdma_is_size_alignment_required(gdma_channel_handle_t dma_chan)
|
|
||||||
{
|
|
||||||
return dma_chan && dma_chan->flags.size_alignment_required;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t gdma_get_buffer_alignment_constraint(gdma_channel_handle_t dma_chan, const void *buffer)
|
size_t gdma_get_buffer_alignment_constraint(gdma_channel_handle_t dma_chan, const void *buffer)
|
||||||
{
|
{
|
||||||
if (!dma_chan || !buffer) {
|
if (!dma_chan || !buffer) {
|
||||||
return BIT(31);
|
return BIT(31);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t base_alignment = dma_chan->int_mem_alignment;
|
// Internal SRAM only needs the DMA-side constraint; MSPI rules apply to PSRAM/Flash.
|
||||||
if (esp_ptr_external_ram(buffer) || esp_ptr_in_drom(buffer)) {
|
if (!(esp_ptr_external_ram(buffer) || esp_ptr_in_drom(buffer))) {
|
||||||
base_alignment = dma_chan->ext_no_enc_mem_alignment;
|
return dma_chan->int_mem_alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t mspi_alignment = esp_mspi_get_alignment(buffer);
|
size_t mspi_alignment = esp_mspi_get_alignment(buffer);
|
||||||
return MAX(base_alignment, mspi_alignment);
|
return MAX(dma_chan->ext_no_enc_mem_alignment, mspi_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t gdma_apply_strategy(gdma_channel_handle_t dma_chan, const gdma_strategy_config_t *config)
|
esp_err_t gdma_apply_strategy(gdma_channel_handle_t dma_chan, const gdma_strategy_config_t *config)
|
||||||
|
|||||||
@@ -186,17 +186,13 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, int start_item_i
|
|||||||
}
|
}
|
||||||
// alignment must be a power of 2
|
// alignment must be a power of 2
|
||||||
ESP_RETURN_ON_FALSE_ISR((buffer_alignment & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "align err idx=%"PRIu32" align=%"PRIu32, bi, buffer_alignment);
|
ESP_RETURN_ON_FALSE_ISR((buffer_alignment & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "align err idx=%"PRIu32" align=%"PRIu32, bi, buffer_alignment);
|
||||||
size_t mspi_alignment = esp_mspi_get_alignment(buf);
|
size_t max_buffer_mount_length = ALIGN_DOWN(GDMA_MAX_BUFFER_SIZE_PER_LINK_ITEM, buffer_alignment);
|
||||||
size_t effective_alignment = MAX(buffer_alignment, mspi_alignment);
|
// Address and size alignment checks are independent; both use the caller-provided buffer_alignment.
|
||||||
size_t max_buffer_mount_length = ALIGN_DOWN(GDMA_MAX_BUFFER_SIZE_PER_LINK_ITEM, effective_alignment);
|
if (!config->flags.bypass_buffer_addr_align_check) {
|
||||||
if (!config->flags.bypass_buffer_align_check) {
|
ESP_RETURN_ON_FALSE_ISR(((uintptr_t)buf & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "buf misalign idx=%"PRIu32" align=%"PRIu32, bi, buffer_alignment);
|
||||||
ESP_RETURN_ON_FALSE_ISR(((uintptr_t)buf & (effective_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "buf misalign idx=%"PRIu32" align=%"PRIu32, bi, effective_alignment);
|
}
|
||||||
// Length alignment:
|
if (!config->flags.bypass_buffer_size_align_check) {
|
||||||
// - Always required under MSPI strict mode (Flash Encryption / PSRAM ECC): size must align.
|
ESP_RETURN_ON_FALSE_ISR((len & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "buf len misalign idx=%"PRIu32" len=%"PRIu32" align=%"PRIu32"", bi, len, buffer_alignment);
|
||||||
// - Also when check_size_align is set by a caller whose configured channel requires size alignment.
|
|
||||||
if (mspi_alignment > 1 || config->flags.check_size_align) {
|
|
||||||
ESP_RETURN_ON_FALSE_ISR((len & (effective_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "buf len misalign idx=%"PRIu32" len=%"PRIu32" align=%"PRIu32"", bi, len, effective_alignment);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
size_t num_items_need = (len + max_buffer_mount_length - 1) / max_buffer_mount_length;
|
size_t num_items_need = (len + max_buffer_mount_length - 1) / max_buffer_mount_length;
|
||||||
ESP_RETURN_ON_FALSE_ISR(num_items_need <= remaining, ESP_ERR_INVALID_ARG, TAG,
|
ESP_RETURN_ON_FALSE_ISR(num_items_need <= remaining, ESP_ERR_INVALID_ARG, TAG,
|
||||||
@@ -224,9 +220,7 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, int start_item_i
|
|||||||
memset(lli_nc, 0, item_size);
|
memset(lli_nc, 0, item_size);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
size_t mspi_alignment = esp_mspi_get_alignment(buf);
|
size_t max_buffer_mount_length = ALIGN_DOWN(GDMA_MAX_BUFFER_SIZE_PER_LINK_ITEM, buffer_alignment);
|
||||||
size_t effective_alignment = MAX(buffer_alignment, mspi_alignment);
|
|
||||||
size_t max_buffer_mount_length = ALIGN_DOWN(GDMA_MAX_BUFFER_SIZE_PER_LINK_ITEM, effective_alignment);
|
|
||||||
size_t num_items_need = (len + max_buffer_mount_length - 1) / max_buffer_mount_length;
|
size_t num_items_need = (len + max_buffer_mount_length - 1) / max_buffer_mount_length;
|
||||||
// mount the buffer to the link list
|
// mount the buffer to the link list
|
||||||
for (size_t i = 0; i < num_items_need; i++) {
|
for (size_t i = 0; i < num_items_need; i++) {
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ struct gdma_channel_t {
|
|||||||
struct {
|
struct {
|
||||||
uint32_t start_stop_by_etm: 1; // whether the channel is started/stopped by ETM
|
uint32_t start_stop_by_etm: 1; // whether the channel is started/stopped by ETM
|
||||||
uint32_t isr_cache_safe: 1; // whether the interrupt of this channel need to be cache safe
|
uint32_t isr_cache_safe: 1; // whether the interrupt of this channel need to be cache safe
|
||||||
uint32_t size_alignment_required: 1; // whether buffer size must meet the channel alignment
|
|
||||||
} flags;
|
} flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -283,9 +283,10 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe
|
|||||||
gdma_link_list_handle_t rx_link_list = NULL;
|
gdma_link_list_handle_t rx_link_list = NULL;
|
||||||
test_gdma_config_link_list(tx_chan, rx_chan, &tx_link_list, &rx_link_list, 16, dma_link_in_ext_mem);
|
test_gdma_config_link_list(tx_chan, rx_chan, &tx_link_list, &rx_link_list, 16, dma_link_in_ext_mem);
|
||||||
|
|
||||||
size_t int_mem_alignment = 0;
|
gdma_channel_alignment_info_t tx_align_info;
|
||||||
size_t ext_mem_alignment = 0;
|
TEST_ESP_OK(gdma_get_channel_alignment_constraints(tx_chan, &tx_align_info));
|
||||||
TEST_ESP_OK(gdma_get_channel_alignment_constraints(tx_chan, &int_mem_alignment, &ext_mem_alignment, NULL));
|
size_t int_mem_alignment = tx_align_info.int_mem_alignment;
|
||||||
|
size_t __attribute__((unused)) ext_mem_alignment = tx_align_info.ext_enc_mem_alignment;
|
||||||
|
|
||||||
// allocate the source buffer from SRAM
|
// allocate the source buffer from SRAM
|
||||||
uint8_t *src_data = heap_caps_aligned_calloc(int_mem_alignment, 1, 128, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
uint8_t *src_data = heap_caps_aligned_calloc(int_mem_alignment, 1, 128, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||||
@@ -352,9 +353,6 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe
|
|||||||
.buffer = dst_data,
|
.buffer = dst_data,
|
||||||
.buffer_alignment = sram_alignment, // RX buffer should be aligned to the cache line size, because we will do cache invalidate later
|
.buffer_alignment = sram_alignment, // RX buffer should be aligned to the cache line size, because we will do cache invalidate later
|
||||||
.length = 256,
|
.length = 256,
|
||||||
.flags = {
|
|
||||||
.check_size_align = gdma_is_size_alignment_required(rx_chan),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, &rx_buf_mount_config, 1, NULL));
|
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, &rx_buf_mount_config, 1, NULL));
|
||||||
|
|
||||||
@@ -503,7 +501,6 @@ static void test_gdma_m2m_desc_empty_event(gdma_channel_handle_t tx_chan, gdma_c
|
|||||||
.length = 64,
|
.length = 64,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
||||||
.check_size_align = gdma_is_size_alignment_required(rx_chan),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, &rx_buf_mount_config, 1, NULL));
|
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, &rx_buf_mount_config, 1, NULL));
|
||||||
@@ -584,7 +581,9 @@ static void test_gdma_m2m_unaligned_buffer_test(uint8_t *dst_data, uint8_t *src_
|
|||||||
TEST_ESP_OK(gdma_config_transfer(rx_chan, &transfer_config));
|
TEST_ESP_OK(gdma_config_transfer(rx_chan, &transfer_config));
|
||||||
|
|
||||||
size_t rx_mem_alignment = 0;
|
size_t rx_mem_alignment = 0;
|
||||||
TEST_ESP_OK(gdma_get_channel_alignment_constraints(rx_chan, &rx_mem_alignment, NULL, NULL));
|
gdma_channel_alignment_info_t rx_align_info;
|
||||||
|
TEST_ESP_OK(gdma_get_channel_alignment_constraints(rx_chan, &rx_align_info));
|
||||||
|
rx_mem_alignment = rx_align_info.int_mem_alignment;
|
||||||
|
|
||||||
// prepare the source data
|
// prepare the source data
|
||||||
for (int i = 0; i < data_length; i++) {
|
for (int i = 0; i < data_length; i++) {
|
||||||
@@ -616,7 +615,7 @@ static void test_gdma_m2m_unaligned_buffer_test(uint8_t *dst_data, uint8_t *src_
|
|||||||
rx_aligned_buf_mount_config[i].buffer = align_array.aligned_buffer[i].aligned_buffer;
|
rx_aligned_buf_mount_config[i].buffer = align_array.aligned_buffer[i].aligned_buffer;
|
||||||
rx_aligned_buf_mount_config[i].buffer_alignment = MAX(sram_alignment, rx_mem_alignment);
|
rx_aligned_buf_mount_config[i].buffer_alignment = MAX(sram_alignment, rx_mem_alignment);
|
||||||
rx_aligned_buf_mount_config[i].length = align_array.aligned_buffer[i].length;
|
rx_aligned_buf_mount_config[i].length = align_array.aligned_buffer[i].length;
|
||||||
rx_aligned_buf_mount_config[i].flags.check_size_align = gdma_is_size_alignment_required(rx_chan);
|
rx_aligned_buf_mount_config[i].flags.bypass_buffer_size_align_check = true; // head and tail buffer size is not aligned to the cache line size
|
||||||
}
|
}
|
||||||
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, rx_aligned_buf_mount_config, 3, NULL));
|
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, rx_aligned_buf_mount_config, 3, NULL));
|
||||||
|
|
||||||
@@ -779,7 +778,6 @@ TEST_CASE("GDMA M2M Unaligned RX Buffer Test", "[GDMA][M2M]")
|
|||||||
.length = COPY_SIZE,
|
.length = COPY_SIZE,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_final = GDMA_FINAL_LINK_TO_NULL, // using singly list, so terminate the link here
|
.mark_final = GDMA_FINAL_LINK_TO_NULL, // using singly list, so terminate the link here
|
||||||
.check_size_align = gdma_is_size_alignment_required(rx_chan),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, &rx_buf_mount_config, 1, NULL));
|
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, &rx_buf_mount_config, 1, NULL));
|
||||||
|
|||||||
@@ -369,9 +369,9 @@ static esp_err_t i3c_master_init_dma(i3c_master_bus_t *i3c_master_handle, const
|
|||||||
ESP_GOTO_ON_ERROR(gdma_config_transfer(i3c_master_handle->dma_tx_chan, &transfer_cfg), err2, TAG, "Config DMA tx channel transfer failed");
|
ESP_GOTO_ON_ERROR(gdma_config_transfer(i3c_master_handle->dma_tx_chan, &transfer_cfg), err2, TAG, "Config DMA tx channel transfer failed");
|
||||||
|
|
||||||
// create DMA link list
|
// create DMA link list
|
||||||
size_t int_mem_align = 0;
|
gdma_channel_alignment_info_t align_info;
|
||||||
gdma_get_channel_alignment_constraints(i3c_master_handle->dma_tx_chan, &int_mem_align, NULL, NULL);
|
gdma_get_channel_alignment_constraints(i3c_master_handle->dma_tx_chan, &align_info);
|
||||||
i3c_master_handle->dma_buffer_alignment = I3C_ALIGN_UP(int_mem_align, I3C_MASTER_DMA_INTERFACE_ALIGNMENT);
|
i3c_master_handle->dma_buffer_alignment = I3C_ALIGN_UP(align_info.int_mem_alignment, I3C_MASTER_DMA_INTERFACE_ALIGNMENT);
|
||||||
size_t num_dma_nodes = esp_dma_calculate_node_count(dma_config->max_transfer_size, i3c_master_handle->dma_buffer_alignment, DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
size_t num_dma_nodes = esp_dma_calculate_node_count(dma_config->max_transfer_size, i3c_master_handle->dma_buffer_alignment, DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
||||||
gdma_link_list_config_t dma_link_config = {
|
gdma_link_list_config_t dma_link_config = {
|
||||||
.item_alignment = 4, // 4 bytes alignment for AHB-DMA
|
.item_alignment = 4, // 4 bytes alignment for AHB-DMA
|
||||||
@@ -581,7 +581,6 @@ static esp_err_t do_dma_transaction_handler(i3c_master_bus_handle_t bus_handle,
|
|||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
||||||
.check_size_align = gdma_is_size_alignment_required(bus_handle->dma_rx_chan),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -147,16 +147,13 @@ size_t parlio_rx_mount_transaction_buffer(parlio_rx_unit_handle_t rx_unit, parli
|
|||||||
rx_unit->node_num = required_node_num;
|
rx_unit->node_num = required_node_num;
|
||||||
|
|
||||||
gdma_buffer_mount_config_t mount_config[required_node_num] = {};
|
gdma_buffer_mount_config_t mount_config[required_node_num] = {};
|
||||||
bool size_alignment_required = gdma_is_size_alignment_required(rx_unit->dma_chan);
|
|
||||||
/* Mount head buffer */
|
/* Mount head buffer */
|
||||||
if (head_node_num) {
|
if (head_node_num) {
|
||||||
mount_config[0].buffer = trans->aligned_payload.buf.head.aligned_buffer;
|
mount_config[0].buffer = trans->aligned_payload.buf.head.aligned_buffer;
|
||||||
mount_config[0].buffer_alignment = trans->alignment;
|
mount_config[0].buffer_alignment = trans->alignment;
|
||||||
mount_config[0].length = trans->aligned_payload.buf.head.length;
|
mount_config[0].length = trans->aligned_payload.buf.head.length;
|
||||||
mount_config[0].flags.bypass_buffer_align_check = false;
|
|
||||||
mount_config[0].flags.mark_eof = false;
|
mount_config[0].flags.mark_eof = false;
|
||||||
mount_config[0].flags.mark_final = GDMA_FINAL_LINK_TO_DEFAULT;
|
mount_config[0].flags.mark_final = GDMA_FINAL_LINK_TO_DEFAULT;
|
||||||
mount_config[0].flags.check_size_align = size_alignment_required;
|
|
||||||
}
|
}
|
||||||
/* Mount body buffer */
|
/* Mount body buffer */
|
||||||
size_t mount_size = 0;
|
size_t mount_size = 0;
|
||||||
@@ -173,10 +170,8 @@ size_t parlio_rx_mount_transaction_buffer(parlio_rx_unit_handle_t rx_unit, parli
|
|||||||
mount_config[i].buffer = (void *)((uint8_t *)trans->aligned_payload.buf.body.aligned_buffer + offset);
|
mount_config[i].buffer = (void *)((uint8_t *)trans->aligned_payload.buf.body.aligned_buffer + offset);
|
||||||
mount_config[i].buffer_alignment = trans->alignment;
|
mount_config[i].buffer_alignment = trans->alignment;
|
||||||
mount_config[i].length = mount_size;
|
mount_config[i].length = mount_size;
|
||||||
mount_config[i].flags.bypass_buffer_align_check = false;
|
|
||||||
mount_config[i].flags.mark_eof = false;
|
mount_config[i].flags.mark_eof = false;
|
||||||
mount_config[i].flags.mark_final = GDMA_FINAL_LINK_TO_DEFAULT;
|
mount_config[i].flags.mark_final = GDMA_FINAL_LINK_TO_DEFAULT;
|
||||||
mount_config[i].flags.check_size_align = size_alignment_required;
|
|
||||||
offset += mount_size;
|
offset += mount_size;
|
||||||
rest_size -= mount_size;
|
rest_size -= mount_size;
|
||||||
}
|
}
|
||||||
@@ -185,8 +180,6 @@ size_t parlio_rx_mount_transaction_buffer(parlio_rx_unit_handle_t rx_unit, parli
|
|||||||
mount_config[required_node_num - 1].buffer = trans->aligned_payload.buf.tail.aligned_buffer;
|
mount_config[required_node_num - 1].buffer = trans->aligned_payload.buf.tail.aligned_buffer;
|
||||||
mount_config[required_node_num - 1].buffer_alignment = trans->alignment;
|
mount_config[required_node_num - 1].buffer_alignment = trans->alignment;
|
||||||
mount_config[required_node_num - 1].length = trans->aligned_payload.buf.tail.length;
|
mount_config[required_node_num - 1].length = trans->aligned_payload.buf.tail.length;
|
||||||
mount_config[required_node_num - 1].flags.bypass_buffer_align_check = false;
|
|
||||||
mount_config[required_node_num - 1].flags.check_size_align = size_alignment_required;
|
|
||||||
}
|
}
|
||||||
/* For infinite transaction, link the node as a ring */
|
/* For infinite transaction, link the node as a ring */
|
||||||
mount_config[required_node_num - 1].flags.mark_final = !trans->flags.infinite ? GDMA_FINAL_LINK_TO_NULL : GDMA_FINAL_LINK_TO_HEAD;
|
mount_config[required_node_num - 1].flags.mark_final = !trans->flags.infinite ? GDMA_FINAL_LINK_TO_NULL : GDMA_FINAL_LINK_TO_HEAD;
|
||||||
@@ -476,7 +469,10 @@ static esp_err_t parlio_rx_unit_init_dma(parlio_rx_unit_handle_t rx_unit, size_t
|
|||||||
.access_ext_mem = true,
|
.access_ext_mem = true,
|
||||||
};
|
};
|
||||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(rx_unit->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
ESP_RETURN_ON_ERROR(gdma_config_transfer(rx_unit->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
||||||
ESP_RETURN_ON_ERROR(gdma_get_channel_alignment_constraints(rx_unit->dma_chan, &rx_unit->int_mem_align, &rx_unit->ext_mem_align, NULL), TAG, "get alignment constraints failed");
|
gdma_channel_alignment_info_t align_info;
|
||||||
|
ESP_RETURN_ON_ERROR(gdma_get_channel_alignment_constraints(rx_unit->dma_chan, &align_info), TAG, "get alignment constraints failed");
|
||||||
|
rx_unit->int_mem_align = align_info.int_mem_alignment;
|
||||||
|
rx_unit->ext_mem_align = align_info.ext_enc_mem_alignment;
|
||||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
uint32_t cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
uint32_t cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||||
rx_unit->int_mem_align = rx_unit->int_mem_align > cache_line_size ? rx_unit->int_mem_align : cache_line_size;
|
rx_unit->int_mem_align = rx_unit->int_mem_align > cache_line_size ? rx_unit->int_mem_align : cache_line_size;
|
||||||
|
|||||||
@@ -163,7 +163,10 @@ static esp_err_t parlio_tx_unit_init_dma(parlio_tx_unit_t *tx_unit, const parlio
|
|||||||
.access_ext_mem = true, // support transmit PSRAM buffer
|
.access_ext_mem = true, // support transmit PSRAM buffer
|
||||||
};
|
};
|
||||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(tx_unit->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
ESP_RETURN_ON_ERROR(gdma_config_transfer(tx_unit->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
||||||
gdma_get_channel_alignment_constraints(tx_unit->dma_chan, &tx_unit->int_mem_align, &tx_unit->ext_mem_align, NULL);
|
gdma_channel_alignment_info_t align_info;
|
||||||
|
gdma_get_channel_alignment_constraints(tx_unit->dma_chan, &align_info);
|
||||||
|
tx_unit->int_mem_align = align_info.int_mem_alignment;
|
||||||
|
tx_unit->ext_mem_align = align_info.ext_enc_mem_alignment;
|
||||||
|
|
||||||
// create DMA link list
|
// create DMA link list
|
||||||
size_t buffer_alignment = MAX(tx_unit->int_mem_align, tx_unit->ext_mem_align);
|
size_t buffer_alignment = MAX(tx_unit->int_mem_align, tx_unit->ext_mem_align);
|
||||||
@@ -463,8 +466,7 @@ esp_err_t parlio_tx_unit_register_event_callbacks(parlio_tx_unit_handle_t tx_uni
|
|||||||
|
|
||||||
static void parlio_mount_buffer(parlio_tx_unit_t *tx_unit, parlio_tx_trans_desc_t *t)
|
static void parlio_mount_buffer(parlio_tx_unit_t *tx_unit, parlio_tx_trans_desc_t *t)
|
||||||
{
|
{
|
||||||
size_t buffer_alignment = 0;
|
size_t buffer_alignment = gdma_get_buffer_alignment_constraint(tx_unit->dma_chan, t->payload);
|
||||||
buffer_alignment = gdma_get_buffer_alignment_constraint(tx_unit->dma_chan, t->payload);
|
|
||||||
// DMA transfer data based on bytes not bits, so convert the bit length to bytes, round up
|
// DMA transfer data based on bytes not bits, so convert the bit length to bytes, round up
|
||||||
size_t payload_bytes = (t->payload_bits + 7) / 8;
|
size_t payload_bytes = (t->payload_bits + 7) / 8;
|
||||||
gdma_buffer_mount_config_t mount_config = {
|
gdma_buffer_mount_config_t mount_config = {
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ static inline void rmt_rx_mount_dma_buffer(rmt_rx_channel_t *rx_chan, const void
|
|||||||
.buffer_alignment = mem_alignment,
|
.buffer_alignment = mem_alignment,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_final = GDMA_FINAL_LINK_TO_DEFAULT,
|
.mark_final = GDMA_FINAL_LINK_TO_DEFAULT,
|
||||||
.check_size_align = gdma_is_size_alignment_required(rx_chan->base.dma_chan),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -63,9 +62,9 @@ static esp_err_t rmt_rx_init_dma_link(rmt_rx_channel_t *rx_channel, const rmt_rx
|
|||||||
ESP_RETURN_ON_ERROR(gdma_register_rx_event_callbacks(rx_channel->base.dma_chan, &cbs, rx_channel), TAG, "register DMA callbacks failed");
|
ESP_RETURN_ON_ERROR(gdma_register_rx_event_callbacks(rx_channel->base.dma_chan, &cbs, rx_channel), TAG, "register DMA callbacks failed");
|
||||||
|
|
||||||
// get the alignment requirement from DMA
|
// get the alignment requirement from DMA
|
||||||
size_t dma_int_mem_alignment = 0, dma_ext_mem_alignment = 0;
|
gdma_channel_alignment_info_t align_info;
|
||||||
gdma_get_channel_alignment_constraints(rx_channel->base.dma_chan, &dma_int_mem_alignment, &dma_ext_mem_alignment, NULL);
|
gdma_get_channel_alignment_constraints(rx_channel->base.dma_chan, &align_info);
|
||||||
size_t buffer_alignment = MAX(dma_int_mem_alignment, dma_ext_mem_alignment);
|
size_t buffer_alignment = MAX(align_info.int_mem_alignment, align_info.ext_enc_mem_alignment);
|
||||||
rx_channel->num_dma_nodes = esp_dma_calculate_node_count(config->mem_block_symbols * sizeof(rmt_symbol_word_t),
|
rx_channel->num_dma_nodes = esp_dma_calculate_node_count(config->mem_block_symbols * sizeof(rmt_symbol_word_t),
|
||||||
buffer_alignment, DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
buffer_alignment, DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
||||||
rx_channel->num_dma_nodes = MAX(2, rx_channel->num_dma_nodes); // at least 2 DMA nodes for ping-pong
|
rx_channel->num_dma_nodes = MAX(2, rx_channel->num_dma_nodes); // at least 2 DMA nodes for ping-pong
|
||||||
|
|||||||
@@ -53,9 +53,10 @@ static esp_err_t rmt_tx_init_dma_link(rmt_tx_channel_t *tx_channel, const rmt_tx
|
|||||||
// register the DMA callbacks may fail if the interrupt service can not be installed successfully
|
// register the DMA callbacks may fail if the interrupt service can not be installed successfully
|
||||||
ESP_RETURN_ON_ERROR(gdma_register_tx_event_callbacks(tx_channel->base.dma_chan, &cbs, tx_channel), TAG, "register DMA callbacks failed");
|
ESP_RETURN_ON_ERROR(gdma_register_tx_event_callbacks(tx_channel->base.dma_chan, &cbs, tx_channel), TAG, "register DMA callbacks failed");
|
||||||
|
|
||||||
size_t int_alignment = 0;
|
gdma_channel_alignment_info_t align_info;
|
||||||
// get the alignment requirement from DMA
|
// get the alignment requirement from DMA
|
||||||
gdma_get_channel_alignment_constraints(tx_channel->base.dma_chan, &int_alignment, NULL, NULL);
|
gdma_get_channel_alignment_constraints(tx_channel->base.dma_chan, &align_info);
|
||||||
|
size_t int_alignment = align_info.int_mem_alignment;
|
||||||
// apply RMT hardware alignment requirement
|
// apply RMT hardware alignment requirement
|
||||||
int_alignment = MAX(int_alignment, sizeof(rmt_symbol_word_t));
|
int_alignment = MAX(int_alignment, sizeof(rmt_symbol_word_t));
|
||||||
// the memory returned by `heap_caps_aligned_calloc` also meets the cache alignment requirement (both address and size)
|
// the memory returned by `heap_caps_aligned_calloc` also meets the cache alignment requirement (both address and size)
|
||||||
|
|||||||
@@ -320,8 +320,14 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch
|
|||||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(dma_ctx->rx_dma_chan, &trans_cfg), SPI_TAG, "config gdma rx transfer failed");
|
ESP_RETURN_ON_ERROR(gdma_config_transfer(dma_ctx->rx_dma_chan, &trans_cfg), SPI_TAG, "config gdma rx transfer failed");
|
||||||
|
|
||||||
// Get DMA alignment constraints
|
// Get DMA alignment constraints
|
||||||
gdma_get_channel_alignment_constraints(dma_ctx->tx_dma_chan, &dma_ctx->dma_align_tx_int, &dma_ctx->dma_align_tx_ext, NULL);
|
gdma_channel_alignment_info_t tx_align_info;
|
||||||
gdma_get_channel_alignment_constraints(dma_ctx->rx_dma_chan, &dma_ctx->dma_align_rx_int, &dma_ctx->dma_align_rx_ext, NULL);
|
gdma_get_channel_alignment_constraints(dma_ctx->tx_dma_chan, &tx_align_info);
|
||||||
|
dma_ctx->dma_align_tx_int = tx_align_info.int_mem_alignment;
|
||||||
|
dma_ctx->dma_align_tx_ext = tx_align_info.ext_enc_mem_alignment;
|
||||||
|
gdma_channel_alignment_info_t rx_align_info;
|
||||||
|
gdma_get_channel_alignment_constraints(dma_ctx->rx_dma_chan, &rx_align_info);
|
||||||
|
dma_ctx->dma_align_rx_int = rx_align_info.int_mem_alignment;
|
||||||
|
dma_ctx->dma_align_rx_ext = rx_align_info.ext_enc_mem_alignment;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,9 +211,9 @@ static esp_err_t uhci_gdma_initialize(uhci_controller_handle_t uhci_ctrl, const
|
|||||||
gdma_apply_strategy(uhci_ctrl->tx_dir.dma_chan, &strategy_config);
|
gdma_apply_strategy(uhci_ctrl->tx_dir.dma_chan, &strategy_config);
|
||||||
|
|
||||||
// create DMA link list
|
// create DMA link list
|
||||||
size_t tx_dma_int_mem_alignment = 0, tx_dma_ext_mem_alignment = 0;
|
gdma_channel_alignment_info_t tx_align_info;
|
||||||
gdma_get_channel_alignment_constraints(uhci_ctrl->tx_dir.dma_chan, &tx_dma_int_mem_alignment, &tx_dma_ext_mem_alignment, NULL);
|
gdma_get_channel_alignment_constraints(uhci_ctrl->tx_dir.dma_chan, &tx_align_info);
|
||||||
size_t buffer_alignment = MAX(tx_dma_int_mem_alignment, tx_dma_ext_mem_alignment);
|
size_t buffer_alignment = MAX(tx_align_info.int_mem_alignment, tx_align_info.ext_enc_mem_alignment);
|
||||||
// Given that the combined size of all buffers does not exceed `max_transmit_size` and
|
// Given that the combined size of all buffers does not exceed `max_transmit_size` and
|
||||||
// the number of buffers does not exceed `max_transmit_buffer_count`, a single transfer
|
// the number of buffers does not exceed `max_transmit_buffer_count`, a single transfer
|
||||||
// requires at most `esp_dma_calculate_node_count(max_transmit_size) + max_transmit_buffer_count - 1` DMA descriptors.
|
// requires at most `esp_dma_calculate_node_count(max_transmit_size) + max_transmit_buffer_count - 1` DMA descriptors.
|
||||||
@@ -236,9 +236,9 @@ static esp_err_t uhci_gdma_initialize(uhci_controller_handle_t uhci_ctrl, const
|
|||||||
gdma_connect(uhci_ctrl->rx_dir.dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0));
|
gdma_connect(uhci_ctrl->rx_dir.dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0));
|
||||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(uhci_ctrl->rx_dir.dma_chan, &transfer_cfg), TAG, "Config DMA rx channel transfer failed");
|
ESP_RETURN_ON_ERROR(gdma_config_transfer(uhci_ctrl->rx_dir.dma_chan, &transfer_cfg), TAG, "Config DMA rx channel transfer failed");
|
||||||
|
|
||||||
size_t rx_dma_int_mem_alignment = 0, rx_dma_ext_mem_alignment = 0;
|
gdma_channel_alignment_info_t rx_align_info;
|
||||||
gdma_get_channel_alignment_constraints(uhci_ctrl->rx_dir.dma_chan, &rx_dma_int_mem_alignment, &rx_dma_ext_mem_alignment, NULL);
|
gdma_get_channel_alignment_constraints(uhci_ctrl->rx_dir.dma_chan, &rx_align_info);
|
||||||
buffer_alignment = MAX(rx_dma_int_mem_alignment, rx_dma_ext_mem_alignment);
|
buffer_alignment = MAX(rx_align_info.int_mem_alignment, rx_align_info.ext_enc_mem_alignment);
|
||||||
uhci_ctrl->rx_dir.rx_num_dma_nodes = esp_dma_calculate_node_count(config->max_receive_internal_mem, buffer_alignment, DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
uhci_ctrl->rx_dir.rx_num_dma_nodes = esp_dma_calculate_node_count(config->max_receive_internal_mem, buffer_alignment, DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
||||||
dma_link_config.num_items = uhci_ctrl->rx_dir.rx_num_dma_nodes;
|
dma_link_config.num_items = uhci_ctrl->rx_dir.rx_num_dma_nodes;
|
||||||
ESP_RETURN_ON_ERROR(gdma_new_link_list(&dma_link_config, &uhci_ctrl->rx_dir.dma_link), TAG, "DMA rx link list alloc failed");
|
ESP_RETURN_ON_ERROR(gdma_new_link_list(&dma_link_config, &uhci_ctrl->rx_dir.dma_link), TAG, "DMA rx link list alloc failed");
|
||||||
@@ -284,11 +284,10 @@ static void uhci_do_transmit(uhci_controller_handle_t uhci_ctrl, uhci_transactio
|
|||||||
uhci_ctrl->tx_dir.cur_trans = trans;
|
uhci_ctrl->tx_dir.cur_trans = trans;
|
||||||
size_t buf_count = trans->buf_info_count;
|
size_t buf_count = trans->buf_info_count;
|
||||||
gdma_buffer_mount_config_t *mount_configs = uhci_ctrl->tx_dir.mount_configs;
|
gdma_buffer_mount_config_t *mount_configs = uhci_ctrl->tx_dir.mount_configs;
|
||||||
size_t buffer_alignment = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < buf_count; i++) {
|
for (size_t i = 0; i < buf_count; i++) {
|
||||||
bool is_last = (i == buf_count - 1);
|
bool is_last = (i == buf_count - 1);
|
||||||
buffer_alignment = gdma_get_buffer_alignment_constraint(uhci_ctrl->tx_dir.dma_chan, trans->buf_info[i].write_buffer);
|
size_t buffer_alignment = gdma_get_buffer_alignment_constraint(uhci_ctrl->tx_dir.dma_chan, trans->buf_info[i].write_buffer);
|
||||||
mount_configs[i] = (gdma_buffer_mount_config_t) {
|
mount_configs[i] = (gdma_buffer_mount_config_t) {
|
||||||
.buffer = (void *)trans->buf_info[i].write_buffer,
|
.buffer = (void *)trans->buf_info[i].write_buffer,
|
||||||
.buffer_alignment = buffer_alignment,
|
.buffer_alignment = buffer_alignment,
|
||||||
@@ -367,7 +366,6 @@ static esp_err_t uhci_receive_internal(uhci_controller_handle_t uhci_ctrl, uint8
|
|||||||
ESP_GOTO_ON_FALSE_ISR(uhci_ctrl->rx_dir.buffer_size_per_desc_node[i] != 0 && uhci_ctrl->rx_dir.buffer_size_per_desc_node[i] <= DMA_DESCRIPTOR_BUFFER_MAX_SIZE,
|
ESP_GOTO_ON_FALSE_ISR(uhci_ctrl->rx_dir.buffer_size_per_desc_node[i] != 0 && uhci_ctrl->rx_dir.buffer_size_per_desc_node[i] <= DMA_DESCRIPTOR_BUFFER_MAX_SIZE,
|
||||||
ESP_ERR_INVALID_ARG, err, TAG, "buffer_size is too small or too large");
|
ESP_ERR_INVALID_ARG, err, TAG, "buffer_size is too small or too large");
|
||||||
|
|
||||||
size_t buffer_alignment = 0;
|
|
||||||
buffer_alignment = gdma_get_buffer_alignment_constraint(uhci_ctrl->rx_dir.dma_chan, read_buffer);
|
buffer_alignment = gdma_get_buffer_alignment_constraint(uhci_ctrl->rx_dir.dma_chan, read_buffer);
|
||||||
mount_configs[i] = (gdma_buffer_mount_config_t) {
|
mount_configs[i] = (gdma_buffer_mount_config_t) {
|
||||||
.buffer = read_buffer,
|
.buffer = read_buffer,
|
||||||
@@ -375,7 +373,6 @@ static esp_err_t uhci_receive_internal(uhci_controller_handle_t uhci_ctrl, uint8
|
|||||||
.length = uhci_ctrl->rx_dir.buffer_size_per_desc_node[i],
|
.length = uhci_ctrl->rx_dir.buffer_size_per_desc_node[i],
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_final = GDMA_FINAL_LINK_TO_DEFAULT,
|
.mark_final = GDMA_FINAL_LINK_TO_DEFAULT,
|
||||||
.check_size_align = gdma_is_size_alignment_required(uhci_ctrl->rx_dir.dma_chan),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ESP_DRAM_LOGD(TAG, "The DMA node %d has %d byte", i, uhci_ctrl->rx_dir.buffer_size_per_desc_node[i]);
|
ESP_DRAM_LOGD(TAG, "The DMA node %d has %d byte", i, uhci_ctrl->rx_dir.buffer_size_per_desc_node[i]);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ size_t esp_mspi_get_alignment(const void *ptr)
|
|||||||
is_psram_enc = is_psram && !esp_psram_ptr_is_no_enc(ptr);
|
is_psram_enc = is_psram && !esp_psram_ptr_is_no_enc(ptr);
|
||||||
#endif /* CONFIG_SPIRAM */
|
#endif /* CONFIG_SPIRAM */
|
||||||
|
|
||||||
if (esp_efuse_is_flash_encryption_enabled() && (generic_query || is_drom || is_psram_enc)) {
|
if ((generic_query || is_drom || is_psram_enc) && esp_efuse_is_flash_encryption_enabled()) {
|
||||||
alignment = MAX(alignment, MSPI_FLASH_ENC_ALIGNMENT);
|
alignment = MAX(alignment, MSPI_FLASH_ENC_ALIGNMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -678,7 +678,10 @@ static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus, const esp_l
|
|||||||
.access_ext_mem = true, // the LCD can carry pixel buffer from the external memory
|
.access_ext_mem = true, // the LCD can carry pixel buffer from the external memory
|
||||||
};
|
};
|
||||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(bus->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
ESP_RETURN_ON_ERROR(gdma_config_transfer(bus->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
||||||
gdma_get_channel_alignment_constraints(bus->dma_chan, &bus->int_mem_align, &bus->ext_mem_align, NULL);
|
gdma_channel_alignment_info_t align_info;
|
||||||
|
gdma_get_channel_alignment_constraints(bus->dma_chan, &align_info);
|
||||||
|
bus->int_mem_align = align_info.int_mem_alignment;
|
||||||
|
bus->ext_mem_align = align_info.ext_enc_mem_alignment;
|
||||||
|
|
||||||
size_t buffer_alignment = MAX(bus->int_mem_align, bus->ext_mem_align);
|
size_t buffer_alignment = MAX(bus->int_mem_align, bus->ext_mem_align);
|
||||||
size_t num_dma_nodes = esp_dma_calculate_node_count(bus->max_transfer_bytes, buffer_alignment, LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
size_t num_dma_nodes = esp_dma_calculate_node_count(bus->max_transfer_bytes, buffer_alignment, LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
||||||
|
|||||||
@@ -1244,7 +1244,10 @@ static esp_err_t lcd_rgb_create_dma_channel(esp_rgb_panel_t *rgb_panel)
|
|||||||
};
|
};
|
||||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(rgb_panel->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
ESP_RETURN_ON_ERROR(gdma_config_transfer(rgb_panel->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
||||||
// get the memory alignment required by the DMA
|
// get the memory alignment required by the DMA
|
||||||
gdma_get_channel_alignment_constraints(rgb_panel->dma_chan, &rgb_panel->int_mem_align, &rgb_panel->ext_mem_align, NULL);
|
gdma_channel_alignment_info_t align_info;
|
||||||
|
gdma_get_channel_alignment_constraints(rgb_panel->dma_chan, &align_info);
|
||||||
|
rgb_panel->int_mem_align = align_info.int_mem_alignment;
|
||||||
|
rgb_panel->ext_mem_align = align_info.ext_enc_mem_alignment;
|
||||||
|
|
||||||
// register DMA event callbacks
|
// register DMA event callbacks
|
||||||
gdma_tx_event_callbacks_t cbs = {
|
gdma_tx_event_callbacks_t cbs = {
|
||||||
@@ -1358,7 +1361,9 @@ static esp_err_t lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *rgb_panel)
|
|||||||
.buffer = rgb_panel->fbs[0] + restart_skip_bytes,
|
.buffer = rgb_panel->fbs[0] + restart_skip_bytes,
|
||||||
.buffer_alignment = buffer_alignment,
|
.buffer_alignment = buffer_alignment,
|
||||||
.length = MIN(LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE, rgb_panel->fb_size) - restart_skip_bytes,
|
.length = MIN(LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE, rgb_panel->fb_size) - restart_skip_bytes,
|
||||||
.flags.bypass_buffer_align_check = true, // the restart buffer may doesn't match the buffer alignment but it doesn't really matter in this case
|
// the restart buffer may doesn't match the buffer alignment but it doesn't really matter in this case
|
||||||
|
.flags.bypass_buffer_addr_align_check = true,
|
||||||
|
.flags.bypass_buffer_size_align_check = true,
|
||||||
};
|
};
|
||||||
ESP_RETURN_ON_ERROR(gdma_link_mount_buffers(rgb_panel->dma_restart_link, 0, &restart_buffer_mount_cfg, 1, NULL),
|
ESP_RETURN_ON_ERROR(gdma_link_mount_buffers(rgb_panel->dma_restart_link, 0, &restart_buffer_mount_cfg, 1, NULL),
|
||||||
TAG, "mount DMA restart buffer failed");
|
TAG, "mount DMA restart buffer failed");
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
#define IDF_PERFORMANCE_MIN_AES_GCM_UPDATE_THROUGHPUT_MBSEC 2.1
|
#define IDF_PERFORMANCE_MIN_AES_GCM_UPDATE_THROUGHPUT_MBSEC 2.1
|
||||||
|
|
||||||
// SHA256 hardware throughput at 240MHz, threshold set lower than worst case
|
// SHA256 hardware throughput at 240MHz, threshold set lower than worst case
|
||||||
#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 90.0
|
#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 88.0
|
||||||
// esp_sha() time to process 32KB of input data from RAM
|
// esp_sha() time to process 32KB of input data from RAM
|
||||||
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 900
|
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 900
|
||||||
#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900
|
#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900
|
||||||
|
|||||||
Reference in New Issue
Block a user