forked from espressif/esp-idf
fix(mcp): align the descriptor to cache line size for DMA memory copy
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -68,8 +68,9 @@ typedef struct async_memcpy_transaction_t {
|
|||||||
/// @note - Number of transaction objects are determined by the backlog parameter
|
/// @note - Number of transaction objects are determined by the backlog parameter
|
||||||
typedef struct {
|
typedef struct {
|
||||||
async_memcpy_context_t parent; // Parent IO interface
|
async_memcpy_context_t parent; // Parent IO interface
|
||||||
size_t sram_trans_align; // DMA transfer alignment (both in size and address) for SRAM memory
|
size_t descriptor_align; // DMA descriptor alignment
|
||||||
size_t psram_trans_align; // DMA transfer alignment (both in size and address) for PSRAM memory
|
size_t sram_trans_align; // DMA buffer alignment (both in size and address) for SRAM memory
|
||||||
|
size_t psram_trans_align; // DMA buffer alignment (both in size and address) for PSRAM memory
|
||||||
size_t max_single_dma_buffer; // max DMA buffer size by a single descriptor
|
size_t max_single_dma_buffer; // max DMA buffer size by a single descriptor
|
||||||
int gdma_bus_id; // GDMA bus id (AHB, AXI, etc.)
|
int gdma_bus_id; // GDMA bus id (AHB, AXI, etc.)
|
||||||
gdma_channel_handle_t tx_channel; // GDMA TX channel handle
|
gdma_channel_handle_t tx_channel; // GDMA TX channel handle
|
||||||
@@ -117,9 +118,12 @@ static esp_err_t esp_async_memcpy_install_gdma_template(const async_memcpy_confi
|
|||||||
ESP_GOTO_ON_FALSE(mcp_gdma, ESP_ERR_NO_MEM, err, TAG, "no mem for driver context");
|
ESP_GOTO_ON_FALSE(mcp_gdma, ESP_ERR_NO_MEM, err, TAG, "no mem for driver context");
|
||||||
uint32_t trans_queue_len = config->backlog ? config->backlog : DEFAULT_TRANSACTION_QUEUE_LENGTH;
|
uint32_t trans_queue_len = config->backlog ? config->backlog : DEFAULT_TRANSACTION_QUEUE_LENGTH;
|
||||||
// allocate memory for transaction pool
|
// allocate memory for transaction pool
|
||||||
mcp_gdma->transaction_pool = heap_caps_aligned_calloc(MCP_DMA_DESC_ALIGN, trans_queue_len, sizeof(async_memcpy_transaction_t),
|
uint32_t data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||||
|
uint32_t alignment = MAX(data_cache_line_size, MCP_DMA_DESC_ALIGN);
|
||||||
|
mcp_gdma->transaction_pool = heap_caps_aligned_calloc(alignment, trans_queue_len, sizeof(async_memcpy_transaction_t),
|
||||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||||
ESP_GOTO_ON_FALSE(mcp_gdma->transaction_pool, ESP_ERR_NO_MEM, err, TAG, "no mem for transaction pool");
|
ESP_GOTO_ON_FALSE(mcp_gdma->transaction_pool, ESP_ERR_NO_MEM, err, TAG, "no mem for transaction pool");
|
||||||
|
mcp_gdma->descriptor_align = alignment;
|
||||||
|
|
||||||
// create TX channel and RX channel, they should reside in the same DMA pair
|
// create TX channel and RX channel, they should reside in the same DMA pair
|
||||||
gdma_channel_alloc_config_t tx_alloc_config = {
|
gdma_channel_alloc_config_t tx_alloc_config = {
|
||||||
@@ -387,13 +391,13 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
|
|||||||
size_t max_single_dma_buffer = mcp_gdma->max_single_dma_buffer;
|
size_t max_single_dma_buffer = mcp_gdma->max_single_dma_buffer;
|
||||||
uint32_t num_desc_per_path = (n + max_single_dma_buffer - 1) / max_single_dma_buffer;
|
uint32_t num_desc_per_path = (n + max_single_dma_buffer - 1) / max_single_dma_buffer;
|
||||||
// allocate DMA descriptors, descriptors need a strict alignment
|
// allocate DMA descriptors, descriptors need a strict alignment
|
||||||
trans->tx_desc_link = heap_caps_aligned_calloc(MCP_DMA_DESC_ALIGN, num_desc_per_path, sizeof(mcp_dma_descriptor_t),
|
trans->tx_desc_link = heap_caps_aligned_calloc(mcp_gdma->descriptor_align, num_desc_per_path, sizeof(mcp_dma_descriptor_t),
|
||||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||||
ESP_GOTO_ON_FALSE(trans->tx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
ESP_GOTO_ON_FALSE(trans->tx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
||||||
trans->tx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->tx_desc_link);
|
trans->tx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->tx_desc_link);
|
||||||
// don't have to allocate the EOF descriptor, we will use trans->eof_node as the RX EOF descriptor
|
// don't have to allocate the EOF descriptor, we will use trans->eof_node as the RX EOF descriptor
|
||||||
if (num_desc_per_path > 1) {
|
if (num_desc_per_path > 1) {
|
||||||
trans->rx_desc_link = heap_caps_aligned_calloc(MCP_DMA_DESC_ALIGN, num_desc_per_path - 1, sizeof(mcp_dma_descriptor_t),
|
trans->rx_desc_link = heap_caps_aligned_calloc(mcp_gdma->descriptor_align, num_desc_per_path - 1, sizeof(mcp_dma_descriptor_t),
|
||||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||||
ESP_GOTO_ON_FALSE(trans->rx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
ESP_GOTO_ON_FALSE(trans->rx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
||||||
trans->rx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->rx_desc_link);
|
trans->rx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->rx_desc_link);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -274,7 +274,7 @@ TEST_CASE("memory copy by DMA on the fly", "[async mcp]")
|
|||||||
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEST_ASYNC_MEMCPY_BENCH_COUNTS (16)
|
#define TEST_ASYNC_MEMCPY_BENCH_COUNTS (8)
|
||||||
static int s_count = 0;
|
static int s_count = 0;
|
||||||
|
|
||||||
static IRAM_ATTR bool test_async_memcpy_isr_cb(async_memcpy_handle_t mcp_hdl, async_memcpy_event_t *event, void *cb_args)
|
static IRAM_ATTR bool test_async_memcpy_isr_cb(async_memcpy_handle_t mcp_hdl, async_memcpy_event_t *event, void *cb_args)
|
||||||
|
Reference in New Issue
Block a user