mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
Merge branch 'fix/psram-ecc-mspi-dma-align' into 'master'
fix(mspi): handle PSRAM ECC DMA alignment across MSPI users Closes IDF-15850, IDF-15910, and IDF-15700 See merge request espressif/esp-idf!49987
This commit is contained in:
@@ -93,9 +93,12 @@ extern void example_lvgl_demo_ui(lv_display_t *disp);
|
||||
#if CONFIG_EXAMPLE_USE_DMA2D_COPY_FRAME
|
||||
void example_rounder_flush_area_cb(lv_event_t * event)
|
||||
{
|
||||
// Under flash encryption, DMA2D access to PSRAM must satisfy MSPI encryption
|
||||
// alignment (typically 16 bytes) for both the buffer address and transfer size.
|
||||
// Round the LVGL invalidate area so the flush region width meets that requirement.
|
||||
lv_area_t * area = lv_event_get_invalidated_area(event);
|
||||
area->x1 = ESP_ALIGN_DOWN(area->x1, 16);
|
||||
area->x2 = ESP_ALIGN_UP(area->x2, 16) - 1;
|
||||
area->x2 = ESP_ALIGN_UP(area->x2 + 1, 16) - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -106,7 +109,7 @@ static void example_lvgl_flush_cb(lv_display_t *disp, const lv_area_t *area, uin
|
||||
int offsetx2 = area->x2;
|
||||
int offsety1 = area->y1;
|
||||
int offsety2 = area->y2;
|
||||
// pass the draw buffer to the driver
|
||||
// LVGL area coordinates are inclusive; panel draw_bitmap expects [start, end).
|
||||
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, px_map);
|
||||
}
|
||||
|
||||
@@ -296,23 +299,14 @@ void app_main(void)
|
||||
void *buf2 = NULL;
|
||||
ESP_LOGI(TAG, "Allocate separate LVGL draw buffers");
|
||||
|
||||
size_t alignment = 1;
|
||||
#if CONFIG_EXAMPLE_USE_DMA2D_COPY_FRAME
|
||||
if (esp_efuse_is_flash_encryption_enabled()) {
|
||||
alignment = SOC_GDMA_EXT_MEM_ENC_ALIGNMENT;
|
||||
if (EXAMPLE_MIPI_DSI_LCD_H_RES % alignment != 0) {
|
||||
ESP_LOGW(TAG, "EXAMPLE_MIPI_DSI_LCD_H_RES is not aligned to %d, may cause MSPI error", alignment);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
size_t draw_buffer_sz = EXAMPLE_MIPI_DSI_LCD_H_RES * EXAMPLE_LVGL_DRAW_BUF_LINES * sizeof(lv_color_t);
|
||||
|
||||
// Note:
|
||||
// Keep the display buffer in **internal** RAM can speed up the UI because LVGL uses it a lot and it should have a fast access time
|
||||
// This example allocate the buffer from PSRAM mainly because we want to save the internal RAM
|
||||
buf1 = heap_caps_aligned_calloc(alignment, 1, draw_buffer_sz, MALLOC_CAP_SPIRAM);
|
||||
buf1 = heap_caps_aligned_calloc(16, 1, draw_buffer_sz, MALLOC_CAP_SPIRAM);
|
||||
assert(buf1);
|
||||
buf2 = heap_caps_aligned_calloc(alignment, 1, draw_buffer_sz, MALLOC_CAP_SPIRAM);
|
||||
buf2 = heap_caps_aligned_calloc(16, 1, draw_buffer_sz, MALLOC_CAP_SPIRAM);
|
||||
assert(buf2);
|
||||
// initialize LVGL draw buffers
|
||||
lv_display_set_buffers(display, buf1, buf2, draw_buffer_sz, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
@@ -320,9 +314,13 @@ void app_main(void)
|
||||
lv_display_set_flush_cb(display, example_lvgl_flush_cb);
|
||||
|
||||
#if CONFIG_EXAMPLE_USE_DMA2D_COPY_FRAME
|
||||
// If flash encryption is enabled, DMA2D requires the flush buffer address and size to be aligned to 16 bytes.
|
||||
// We need to round the flush area to the multiple of 16.
|
||||
if (esp_efuse_is_flash_encryption_enabled()) {
|
||||
// If Flash Encryption/ PSRAM ECC is enabled, DMA2D requires the flush buffer address and size to be aligned.
|
||||
// Round the LVGL invalidate area accordingly (this is an LVGL integration hook, not a panel API).
|
||||
bool need_rounder = esp_efuse_is_flash_encryption_enabled();
|
||||
#if CONFIG_SPIRAM_ECC_ENABLE
|
||||
need_rounder = true;
|
||||
#endif
|
||||
if (need_rounder) {
|
||||
ESP_LOGI(TAG, "Register event callback for LVGL flush area rounding");
|
||||
lv_display_add_event_cb(display, example_rounder_flush_area_cb, LV_EVENT_INVALIDATE_AREA, NULL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user