From 41e854d7dff5ca6e1ad6b2dae03bfd2bf9f8e9ad Mon Sep 17 00:00:00 2001 From: armando Date: Fri, 9 Jan 2026 10:37:49 +0800 Subject: [PATCH] fix(mspi): fixed mspi dma burst timing issue --- components/esp_mm/esp_cache_msync.c | 2 +- components/esp_mm/include/esp_cache.h | 2 +- .../include/esp_private/esp_cache_private.h | 2 +- components/esp_psram/CMakeLists.txt | 4 +- .../include/esp_private/esp_psram_mspi.h | 17 +++++++- components/esp_psram/system_layer/esp_psram.c | 12 ++++-- .../esp_psram/system_layer/esp_psram_mspi.c | 43 +++++++++++++++++-- .../esp_psram/test_apps/psram/pytest_psram.py | 2 +- 8 files changed, 71 insertions(+), 13 deletions(-) diff --git a/components/esp_mm/esp_cache_msync.c b/components/esp_mm/esp_cache_msync.c index 411fc4eb25..5ef4f9a532 100644 --- a/components/esp_mm/esp_cache_msync.c +++ b/components/esp_mm/esp_cache_msync.c @@ -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 */ diff --git a/components/esp_mm/include/esp_cache.h b/components/esp_mm/include/esp_cache.h index 71080518af..b76636a9ef 100644 --- a/components/esp_mm/include/esp_cache.h +++ b/components/esp_mm/include/esp_cache.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_mm/include/esp_private/esp_cache_private.h b/components/esp_mm/include/esp_private/esp_cache_private.h index 4c37b4027c..3d7d51ef64 100644 --- a/components/esp_mm/include/esp_private/esp_cache_private.h +++ b/components/esp_mm/include/esp_private/esp_cache_private.h @@ -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 */ diff --git a/components/esp_psram/CMakeLists.txt b/components/esp_psram/CMakeLists.txt index 2b2ce2baec..198a37a565 100644 --- a/components/esp_psram/CMakeLists.txt +++ b/components/esp_psram/CMakeLists.txt @@ -15,10 +15,10 @@ if(${target} STREQUAL "esp32") list(APPEND priv_requires bootloader_support esp_driver_spi esp_driver_gpio) endif() -set(srcs) +set(srcs "system_layer/esp_psram_mspi.c") if(CONFIG_SPIRAM) - list(APPEND srcs "system_layer/esp_psram.c" "system_layer/esp_psram_mspi.c") + list(APPEND srcs "system_layer/esp_psram.c") if(${target} STREQUAL "esp32") list(APPEND srcs "esp32/esp_psram_extram_cache.c" diff --git a/components/esp_psram/include/esp_private/esp_psram_mspi.h b/components/esp_psram/include/esp_private/esp_psram_mspi.h index 849a0cdc38..3ef0aa0592 100644 --- a/components/esp_psram/include/esp_private/esp_psram_mspi.h +++ b/components/esp_psram/include/esp_private/esp_psram_mspi.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,12 +8,15 @@ #include #include +#include "sdkconfig.h" #include "esp_err.h" #ifdef __cplusplus extern "C" { #endif +#define ESP_PSRAM_MSPI_MB_WORKAROUND (CONFIG_IDF_TARGET_ESP32C5 && CONFIG_ESP32C5_REV_MIN_FULL < 102) || (CONFIG_IDF_TARGET_ESP32C61 && CONFIG_ESP32C61_REV_MIN_FULL < 101) + /** * @brief Register MSPI PSRAM interrupt * @@ -34,6 +37,18 @@ esp_err_t esp_psram_mspi_register_isr(void); */ esp_err_t esp_psram_mspi_unregister_isr(void); +/** + * @brief Initialize PSRAM MSPI memory barrier + * + * @return ESP_OK on success, otherwise an error code + */ +esp_err_t esp_psram_mspi_mb_init(void); + +/** + * @brief PSRAM MSPI memory barrier + */ +void esp_psram_mspi_mb(void); + #ifdef __cplusplus } #endif diff --git a/components/esp_psram/system_layer/esp_psram.c b/components/esp_psram/system_layer/esp_psram.c index 77a6855df8..fb7f70db74 100644 --- a/components/esp_psram/system_layer/esp_psram.c +++ b/components/esp_psram/system_layer/esp_psram.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -129,7 +129,7 @@ ESP_SYSTEM_INIT_FN(psram_core_stage_init, CORE, BIT(0), 103) ret = esp_psram_extram_add_to_heap_allocator(); if (ret != ESP_OK) { ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!"); - abort(); + return ret; } #if CONFIG_SPIRAM_USE_MALLOC heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL); @@ -140,7 +140,13 @@ ESP_SYSTEM_INIT_FN(psram_core_stage_init, CORE, BIT(0), 103) ret = esp_psram_mspi_register_isr(); if (ret != ESP_OK) { ESP_EARLY_LOGE(TAG, "Failed to register PSRAM ISR!"); - abort(); + return ret; + } + + ret = esp_psram_mspi_mb_init(); + if (ret != ESP_OK) { + ESP_EARLY_LOGE(TAG, "Failed to initialize PSRAM MSPI memory barrier!"); + return ret; } return ret; diff --git a/components/esp_psram/system_layer/esp_psram_mspi.c b/components/esp_psram/system_layer/esp_psram_mspi.c index 63b3481db7..3c423f7186 100644 --- a/components/esp_psram/system_layer/esp_psram_mspi.c +++ b/components/esp_psram/system_layer/esp_psram_mspi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,13 +13,21 @@ #include "esp_log.h" #include "esp_check.h" #include "esp_intr_alloc.h" +#include "esp_cache.h" +#include "esp_heap_caps.h" #include "hal/mspi_ll.h" #include "hal/mspi_periph.h" #include "esp_private/mspi_intr.h" +#include "esp_private/esp_psram_mspi.h" +#if CONFIG_SPIRAM #if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32S2 #include "hal/psram_ctrlr_ll.h" #endif +#endif +__attribute__((unused)) ESP_LOG_ATTR_TAG_DRAM(TAG, "psram_mspi"); + +#if CONFIG_SPIRAM #if PSRAM_CTRLR_LL_INTR_EVENT_SUPPORTED #if CONFIG_ESP_PANIC_HANDLER_IRAM @@ -30,8 +38,6 @@ #define PSRAM_ISR_FLAGS 0 #endif -ESP_LOG_ATTR_TAG_DRAM(TAG, "psram_mspi"); - static void PSRAM_ISR_ATTR mspi_psram_isr_handler(void *arg, uint32_t intr_events) { #if PSRAM_CTRLR_LL_PMS_INT_SUPPORTED @@ -124,3 +130,34 @@ esp_err_t esp_psram_mspi_unregister_isr(void) return ESP_OK; } #endif //#if PSRAM_CTRLR_LL_INTR_EVENT_SUPPORTED +#endif //#if CONFIG_SPIRAM + +#if ESP_PSRAM_MSPI_MB_WORKAROUND +static void *s_psram_mb_dummy_cacheline; //dummy cacheline for cache memory barrier +#endif + +esp_err_t esp_psram_mspi_mb_init(void) +{ +#if ESP_PSRAM_MSPI_MB_WORKAROUND + s_psram_mb_dummy_cacheline = heap_caps_calloc(1, CONFIG_CACHE_L1_CACHE_LINE_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_CACHE_ALIGNED); + if (!s_psram_mb_dummy_cacheline) { + ESP_EARLY_LOGE(TAG, "Failed to allocate dummy cacheline for PSRAM memory barrier!"); + } +#endif + + return ESP_OK; +} + +void IRAM_ATTR esp_psram_mspi_mb(void) +{ +#if ESP_PSRAM_MSPI_MB_WORKAROUND + if (!s_psram_mb_dummy_cacheline) { + uint32_t *p = (uint32_t *)s_psram_mb_dummy_cacheline; + *p = (*p + 1) % UINT32_MAX; + __attribute__((unused)) esp_err_t ret = ESP_FAIL; + ret = esp_cache_msync(s_psram_mb_dummy_cacheline, sizeof(uint32_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); //malloc is aligned, no need to writeback all + assert(ret == ESP_OK); + asm volatile("fence"); + } +#endif +} diff --git a/components/esp_psram/test_apps/psram/pytest_psram.py b/components/esp_psram/test_apps/psram/pytest_psram.py index 2cf712373d..124446d4ba 100644 --- a/components/esp_psram/test_apps/psram/pytest_psram.py +++ b/components/esp_psram/test_apps/psram/pytest_psram.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut