From 95fe25306512b93a48f05bc874f8ce742eabef97 Mon Sep 17 00:00:00 2001 From: morris Date: Tue, 25 Feb 2025 15:40:12 +0800 Subject: [PATCH] feat(gdma): allow bypass the alignment check in the link driver Closes https://github.com/espressif/esp-idf/issues/15228 --- components/esp_hw_support/dma/gdma_link.c | 4 +++- components/esp_hw_support/dma/include/esp_private/gdma_link.h | 2 ++ components/esp_lcd/rgb/esp_lcd_panel_rgb.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/components/esp_hw_support/dma/gdma_link.c b/components/esp_hw_support/dma/gdma_link.c index 6b141e9cda..29288decf1 100644 --- a/components/esp_hw_support/dma/gdma_link.c +++ b/components/esp_hw_support/dma/gdma_link.c @@ -166,7 +166,9 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, int start_item_i uint8_t *buf = (uint8_t *)config->buffer; size_t len = config->length; // check the buffer alignment - ESP_RETURN_ON_FALSE(((uintptr_t)buf & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "buffer not aligned to %zu", buffer_alignment); + if (!config->flags.bypass_buffer_align_check) { + ESP_RETURN_ON_FALSE(((uintptr_t)buf & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "buffer not aligned to %zu", buffer_alignment); + } uint32_t num_items_need = (len + max_buffer_mount_length - 1) / max_buffer_mount_length; // check if there are enough link list items ESP_RETURN_ON_FALSE((begin_item_idx + num_items_need) <= (start_item_index + num_items_avail), ESP_ERR_INVALID_ARG, TAG, "no more space for buffer mounting"); diff --git a/components/esp_hw_support/dma/include/esp_private/gdma_link.h b/components/esp_hw_support/dma/include/esp_private/gdma_link.h index 6972d16d16..7ab326edcc 100644 --- a/components/esp_hw_support/dma/include/esp_private/gdma_link.h +++ b/components/esp_hw_support/dma/include/esp_private/gdma_link.h @@ -72,6 +72,8 @@ typedef struct { Note, DMA engine will stop at this item and trigger an interrupt. If `mark_final` is not set, this list item will point to the next item, and wrap around to the head item if it's the last one in the list. */ + uint32_t bypass_buffer_align_check: 1; /*!< Whether to bypass the buffer alignment check. + Only enable it when you know what you are doing. */ } flags; //!< Flags for buffer mount configurations } gdma_buffer_mount_config_t; diff --git a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c index 2a1b691bbd..4df1d816d6 100644 --- a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c @@ -1000,6 +1000,7 @@ static esp_err_t lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *rgb_panel) gdma_buffer_mount_config_t restart_buffer_mount_cfg = { .buffer = rgb_panel->fbs[0] + 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 }; 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");