diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index 49f16336d5e..e179fe9fc6c 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -132,6 +132,8 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) #include "esp32c5/rom/opi_flash.h" #elif CONFIG_IDF_TARGET_ESP32C61 #include "esp32c61/rom/opi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S31 +#include "esp32s31/rom/opi_flash.h" #endif #include "esp_flash_chips/spi_flash_defs.h" @@ -699,7 +701,7 @@ void bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t fla break; } cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); - esp_rom_opiflash_cache_mode_config(flash_mode, &cache_rd); + esp_rom_spiflash_cache_mode_config(flash_mode, &cache_rd); cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } #endif diff --git a/components/esp_hal_mspi/esp32c5/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32c5/include/hal/spimem_flash_ll.h index da62b885987..d67fd92ca63 100644 --- a/components/esp_hal_mspi/esp32c5/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32c5/include/hal/spimem_flash_ll.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 */ @@ -226,6 +226,23 @@ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dl dev->sus_status.flash_pes_dly_128 = 1; } +/** + * @brief Get trs unit values in SPI_CLK cycles + * + * @param dev Beginning address of the peripheral registers. + * @return uint32_t trs unit values + */ +static inline uint32_t spimem_flash_ll_get_trs_unit_in_cycles(spi_mem_dev_t *dev) +{ + uint32_t trs_unit = 0; + if (dev->sus_status.flash_per_dly_128 == 1) { + trs_unit = 128; + } else { + trs_unit = 4; + } + return trs_unit; +} + /** * Configure the delay after Resume * @@ -235,7 +252,6 @@ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dl static inline void spimem_flash_ll_set_rs_delay(spi_mem_dev_t *dev, uint32_t dly_val) { dev->ctrl1.cs_hold_dly_per = dly_val; - dev->sus_status.flash_per_dly_128 = 1; } /** diff --git a/components/esp_hal_mspi/esp32c61/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32c61/include/hal/spimem_flash_ll.h index 464c5f6af1e..72ccb9085f1 100644 --- a/components/esp_hal_mspi/esp32c61/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32c61/include/hal/spimem_flash_ll.h @@ -226,6 +226,23 @@ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dl dev->sus_status.flash_pes_dly_128 = 1; } +/** + * @brief Get trs unit values in SPI_CLK cycles + * + * @param dev Beginning address of the peripheral registers. + * @return uint32_t trs unit values + */ +static inline uint32_t spimem_flash_ll_get_trs_unit_in_cycles(spi_mem_dev_t *dev) +{ + uint32_t trs_unit = 0; + if (dev->sus_status.flash_per_dly_128 == 1) { + trs_unit = 128; + } else { + trs_unit = 4; + } + return trs_unit; +} + /** * Configure the delay after Resume * @@ -235,7 +252,6 @@ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dl static inline void spimem_flash_ll_set_rs_delay(spi_mem_dev_t *dev, uint32_t dly_val) { dev->ctrl1.cs_hold_dly_per = dly_val; - dev->sus_status.flash_per_dly_128 = 1; } /** diff --git a/components/esp_hal_mspi/esp32h21/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32h21/include/hal/spimem_flash_ll.h index 77af0c544b5..45f380a0477 100644 --- a/components/esp_hal_mspi/esp32h21/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32h21/include/hal/spimem_flash_ll.h @@ -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 */ @@ -225,6 +225,34 @@ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dl dev->sus_status.flash_pes_dly_128 = 1; } +/** + * @brief Get trs unit values in SPI_CLK cycles + * + * @param dev Beginning address of the peripheral registers. + * @return uint32_t trs unit values + */ +static inline uint32_t spimem_flash_ll_get_trs_unit_in_cycles(spi_mem_dev_t *dev) +{ + uint32_t trs_unit = 0; + if (dev->sus_status.flash_per_dly_128 == 1) { + trs_unit = 128; + } else { + trs_unit = 4; + } + return trs_unit; +} + +/** + * Configure the delay after Resume + * + * @param dev Beginning address of the peripheral registers. + * @param dly_val delay time + */ +static inline void spimem_flash_ll_set_rs_delay(spi_mem_dev_t *dev, uint32_t dly_val) +{ + dev->ctrl1.cs_hold_dly_per = dly_val; +} + /** * Configure the cs hold delay time(used to set the minimum CS high time tSHSL) * diff --git a/components/esp_hal_mspi/esp32h4/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32h4/include/hal/spimem_flash_ll.h index f60f1855ec2..423409b0010 100644 --- a/components/esp_hal_mspi/esp32h4/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32h4/include/hal/spimem_flash_ll.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 */ @@ -225,6 +225,34 @@ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dl dev->sus_status.flash_pes_dly_128 = 1; } +/** + * @brief Get trs unit values in SPI_CLK cycles + * + * @param dev Beginning address of the peripheral registers. + * @return uint32_t trs unit values + */ +static inline uint32_t spimem_flash_ll_get_trs_unit_in_cycles(spi_mem_dev_t *dev) +{ + uint32_t trs_unit = 0; + if (dev->sus_status.flash_per_dly_128 == 1) { + trs_unit = 128; + } else { + trs_unit = 4; + } + return trs_unit; +} + +/** + * Configure the delay after Resume + * + * @param dev Beginning address of the peripheral registers. + * @param dly_val delay time + */ +static inline void spimem_flash_ll_set_rs_delay(spi_mem_dev_t *dev, uint32_t dly_val) +{ + dev->ctrl1.cs_hold_dly_per = dly_val; +} + /** * Configure the cs hold delay time(used to set the minimum CS high time tSHSL) * diff --git a/components/esp_hal_mspi/esp32p4/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/spimem_flash_ll.h index 3e8267c4248..10273f5cd5b 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/spimem_flash_ll.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 */ @@ -230,6 +230,23 @@ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dl dev->sus_status.flash_per_dly_128 = 1; } +/** + * @brief Get trs unit values in SPI_CLK cycles + * + * @param dev Beginning address of the peripheral registers. + * @return uint32_t trs unit values + */ +static inline uint32_t spimem_flash_ll_get_trs_unit_in_cycles(spi_mem_dev_t *dev) +{ + uint32_t trs_unit = 0; + if (dev->sus_status.flash_per_dly_128 == 1) { + trs_unit = 128; + } else { + trs_unit = 4; + } + return trs_unit; +} + #if (HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300) /** * Configure the delay after Resume @@ -240,7 +257,6 @@ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dl static inline void spimem_flash_ll_set_rs_delay(spi_mem_dev_t *dev, uint32_t dly_val) { dev->ctrl1.cs_hold_dly_per = dly_val; - dev->sus_status.flash_per_dly_128 = 1; } #endif diff --git a/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h index e35291b5740..2d1f6586689 100644 --- a/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h @@ -315,6 +315,34 @@ static inline uint32_t spimem_flash_ll_get_tsus_unit_in_cycles(spi_mem_dev_t *de return tsus_unit; } +/** + * @brief Get trs unit values in SPI_CLK cycles + * + * @param dev Beginning address of the peripheral registers. + * @return uint32_t trs unit values + */ +static inline uint32_t spimem_flash_ll_get_trs_unit_in_cycles(spi_mem_dev_t *dev) +{ + uint32_t trs_unit = 0; + if (dev->sus_status.flash_per_dly_128 == 1) { + trs_unit = 128; + } else { + trs_unit = 4; + } + return trs_unit; +} + +/** + * Configure the delay after Resume + * + * @param dev Beginning address of the peripheral registers. + * @param dly_val delay time + */ +static inline void spimem_flash_ll_set_rs_delay(spi_mem_dev_t *dev, uint32_t dly_val) +{ + dev->ctrl1.cs_hold_dly_per = dly_val; +} + /** * Enable/disable write protection for the flash chip. * diff --git a/components/esp_hal_mspi/spi_flash_hal_iram.c b/components/esp_hal_mspi/spi_flash_hal_iram.c index 4dcb77e0f8c..d24999f2657 100644 --- a/components/esp_hal_mspi/spi_flash_hal_iram.c +++ b/components/esp_hal_mspi/spi_flash_hal_iram.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 */ @@ -171,9 +171,9 @@ void spi_flash_hal_setup_auto_suspend_mode(spi_flash_host_inst_t *host) uint32_t tsus = (ctx->tsus_val * ctx->freq_mhz / spimem_flash_ll_get_tsus_unit_in_cycles(dev)) + ((ctx->tsus_val * ctx->freq_mhz) % spimem_flash_ll_get_tsus_unit_in_cycles(dev) != 0); spimem_flash_ll_set_sus_delay(dev, tsus); #if SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR -#if (HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300) && SOC_IS(ESP32P4) - // trs = ceil(ctx->trs_val * ctx->freq_mhz / spimem_flash_ll_get_tsus_unit_in_cycles); - uint32_t trs = (ctx->trs_val * ctx->freq_mhz / spimem_flash_ll_get_tsus_unit_in_cycles(dev)) + ((ctx->trs_val * ctx->freq_mhz) % spimem_flash_ll_get_tsus_unit_in_cycles(dev) != 0); +#if !((HAL_CONFIG(CHIP_SUPPORT_MIN_REV) < 300) && SOC_IS(ESP32P4)) + // trs = ceil(ctx->trs_val * ctx->freq_mhz / spimem_flash_ll_get_trs_unit_in_cycles); + uint32_t trs = (ctx->trs_val * ctx->freq_mhz / spimem_flash_ll_get_trs_unit_in_cycles(dev)) + ((ctx->trs_val * ctx->freq_mhz) % spimem_flash_ll_get_trs_unit_in_cycles(dev) != 0); spimem_flash_ll_set_rs_delay(dev, trs); #endif #endif // SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR diff --git a/components/esp_rom/esp32c5/include/esp32c5/rom/opi_flash.h b/components/esp_rom/esp32c5/include/esp32c5/rom/opi_flash.h index f1165d805f7..ee23773d336 100644 --- a/components/esp_rom/esp32c5/include/esp32c5/rom/opi_flash.h +++ b/components/esp_rom/esp32c5/include/esp32c5/rom/opi_flash.h @@ -312,7 +312,7 @@ esp_rom_spiflash_result_t esp_rom_opiflash_wren(void* arg); * @note command format would be defined in initialization * */ -void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); +void esp_rom_spiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); esp_rom_spiflash_result_t esp_rom_opiflash_read_raw(uint32_t flash_addr, uint8_t* buf, int len); diff --git a/components/esp_rom/esp32c61/include/esp32c61/rom/opi_flash.h b/components/esp_rom/esp32c61/include/esp32c61/rom/opi_flash.h index 8a5236801c8..cf17ad0b274 100644 --- a/components/esp_rom/esp32c61/include/esp32c61/rom/opi_flash.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/opi_flash.h @@ -311,7 +311,7 @@ esp_rom_spiflash_result_t esp_rom_opiflash_wren(void* arg); * @note command format would be defined in initialization * */ -void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); +void esp_rom_spiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); esp_rom_spiflash_result_t esp_rom_opiflash_read_raw(uint32_t flash_addr, uint8_t* buf, int len); diff --git a/components/esp_rom/esp32p4/include/esp32p4/rom/opi_flash.h b/components/esp_rom/esp32p4/include/esp32p4/rom/opi_flash.h index 3184c98e3a3..09a980f5d14 100644 --- a/components/esp_rom/esp32p4/include/esp32p4/rom/opi_flash.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/opi_flash.h @@ -313,7 +313,7 @@ esp_rom_spiflash_result_t esp_rom_opiflash_wren(void* arg); * @note command format would be defined in initialization * */ -void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); +void esp_rom_spiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); esp_rom_spiflash_result_t esp_rom_opiflash_read_raw(uint32_t flash_addr, uint8_t* buf, int len); diff --git a/components/esp_rom/esp32s2/ld/esp32s2.rom.ld b/components/esp_rom/esp32s2/ld/esp32s2.rom.ld index 4edc70f0fde..dc9795f0746 100644 --- a/components/esp_rom/esp32s2/ld/esp32s2.rom.ld +++ b/components/esp_rom/esp32s2/ld/esp32s2.rom.ld @@ -196,7 +196,7 @@ PROVIDE ( dummy_len_plus = 0x3ffffd54 ); PROVIDE ( Enable_QMode = 0x40016690 ); PROVIDE ( esp_crc8 = 0x40011a78 ); PROVIDE ( esp_rom_config_pad_power_select = 0x40016e58 ); -PROVIDE ( esp_rom_opiflash_cache_mode_config = 0x40016754 ); +PROVIDE ( esp_rom_spiflash_cache_mode_config = 0x40016754 ); PROVIDE ( esp_rom_opiflash_exec_cmd = 0x40017e30 ); PROVIDE ( esp_rom_opiflash_exit_continuous_read_mode = 0x40017ee8 ); PROVIDE ( esp_rom_opiflash_mode_reset = 0x40017f90 ); diff --git a/components/esp_rom/esp32s3/include/esp32s3/rom/opi_flash.h b/components/esp_rom/esp32s3/include/esp32s3/rom/opi_flash.h index 3f5d8405498..fee9727e4f9 100644 --- a/components/esp_rom/esp32s3/include/esp32s3/rom/opi_flash.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/opi_flash.h @@ -311,7 +311,7 @@ esp_rom_spiflash_result_t esp_rom_opiflash_wren(void* arg); * @note command format would be defined in initialization * */ -void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); +void esp_rom_spiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); esp_rom_spiflash_result_t esp_rom_opiflash_read_raw(uint32_t flash_addr, uint8_t* buf, int len); diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index c3a2f2e715a..bea929edd98 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -170,7 +170,7 @@ PROVIDE( esp_rom_spiflash_config_readmode = 0x40000aa4 ); PROVIDE( esp_rom_spiflash_read_status = 0x40000ab0 ); PROVIDE( esp_rom_spiflash_read_statushigh = 0x40000abc ); PROVIDE( esp_rom_spiflash_write_status = 0x40000ac8 ); -PROVIDE( esp_rom_opiflash_cache_mode_config = 0x40000ad4 ); +PROVIDE( esp_rom_spiflash_cache_mode_config = 0x40000ad4 ); PROVIDE( esp_rom_spiflash_auto_wait_idle = 0x40000ae0 ); PROVIDE( spi_flash_attach = 0x40000aec ); PROVIDE( spi_flash_get_chip_size = 0x40000af8 ); diff --git a/components/esp_rom/esp32s31/include/esp32s31/rom/opi_flash.h b/components/esp_rom/esp32s31/include/esp32s31/rom/opi_flash.h index 5ae5c4ae589..87f425e236b 100644 --- a/components/esp_rom/esp32s31/include/esp32s31/rom/opi_flash.h +++ b/components/esp_rom/esp32s31/include/esp32s31/rom/opi_flash.h @@ -313,7 +313,7 @@ * @note command format would be defined in initialization * */ - void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); + void esp_rom_spiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); esp_rom_spiflash_result_t esp_rom_opiflash_read_raw(uint32_t flash_addr, uint8_t* buf, int len); diff --git a/components/esp_rom/patches/esp_rom_spiflash.c b/components/esp_rom/patches/esp_rom_spiflash.c index ed06a12e29d..997e870f192 100644 --- a/components/esp_rom/patches/esp_rom_spiflash.c +++ b/components/esp_rom/patches/esp_rom_spiflash.c @@ -723,7 +723,7 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_disable(void) #elif CONFIG_IDF_TARGET_ESP32S3 extern void esp_rom_spi_set_address_bit_len(int spi, int addr_bits); -void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache) +void esp_rom_spiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache) { esp_rom_spi_set_op_mode(0, mode); REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI); @@ -748,7 +748,7 @@ void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const #elif CONFIG_IDF_TARGET_ESP32P4 extern void esp_rom_spi_set_address_bit_len(int spi, int addr_bits); -void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache) +void esp_rom_spiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache) { esp_rom_spi_set_op_mode(0, mode); @@ -776,7 +776,7 @@ void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const } #elif CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 extern void esp_rom_spi_set_address_bit_len(int spi, int addr_bits); -void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache) +void esp_rom_spiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache) { esp_rom_spi_set_op_mode(0, mode); diff --git a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in index 98eb2c90138..17f25e4fd10 100644 --- a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in @@ -747,6 +747,10 @@ config SOC_SPI_MEM_SUPPORT_WRAP bool default y +config SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR + bool + default y + config SOC_MEMSPI_IS_INDEPENDENT bool default y diff --git a/components/soc/esp32h21/include/soc/soc_caps.h b/components/soc/esp32h21/include/soc/soc_caps.h index 6352ae108d7..f4749010f38 100644 --- a/components/soc/esp32h21/include/soc/soc_caps.h +++ b/components/soc/esp32h21/include/soc/soc_caps.h @@ -348,6 +348,7 @@ #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_WRAP (1) +#define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1) #define SOC_MEMSPI_IS_INDEPENDENT 1 #define SOC_MEMSPI_ENCRYPTION_ALIGNMENT 16 /*!< 16-byte alignment restriction to mem addr and size if encryption is enabled */ diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index 6fdeb2a0c17..9209a8f21f0 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -867,6 +867,10 @@ config SOC_SPI_MEM_SUPPORT_WRAP bool default y +config SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR + bool + default y + config SOC_MEMSPI_IS_INDEPENDENT bool default y diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index 00c1eb08936..2c35173c9a8 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -375,6 +375,7 @@ #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_WRAP (1) +#define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1) #define SOC_MEMSPI_IS_INDEPENDENT 1 #define SOC_MEMSPI_ENCRYPTION_ALIGNMENT 16 /*!< 16-byte alignment restriction to mem addr and size if encryption is enabled */ diff --git a/components/soc/esp32s31/register/soc/spi1_mem_c_struct.h b/components/soc/esp32s31/register/soc/spi1_mem_c_struct.h index 115f9233c03..331ba905d1a 100644 --- a/components/soc/esp32s31/register/soc/spi1_mem_c_struct.h +++ b/components/soc/esp32s31/register/soc/spi1_mem_c_struct.h @@ -367,14 +367,8 @@ typedef union { * After PER command is sent, SPI1 waits (SPI1_MEM_C_CS_HOLD_DLY_PER[8:0] * 128) * SPI_CLK cycles. */ - uint32_t cs_hold_dly_per:9; - uint32_t reserved_21:2; - /** cs_hold_dly_per_en : R/W; bitpos: [23]; default: 0; - * 1: use SPI1_MEM_C_CS_HOLD_DLY_PER for per, use SPI1_MEM_C_CS_HOLD_DELAY_RES for - * pes/dp/hpm . 0: use SPI1_MEM_C_CS_HOLD_DELAY_RES for pes/dp/hpm/per . - */ - uint32_t cs_hold_dly_per_en:1; - uint32_t reserved_24:8; + uint32_t cs_hold_dly_per:10; + uint32_t reserved_22:10; }; uint32_t val; } spi1_mem_c_ctrl1_reg_t; @@ -462,7 +456,17 @@ typedef union { * This field is only for internal debugging purposes. Do not use it in applications. */ uint32_t wb_mode:8; - uint32_t reserved_24:8; + /** wb_mode_bitlen : R/W; bitpos: [26:24]; default: 0; + * Mode bits length for flash fast read mode. + * This field is only for internal debugging purposes. Do not use it in applications. + */ + uint32_t wb_mode_bitlen:3; + /** wb_mode_en : R/W; bitpos: [27]; default: 0; + * Mode bits is valid while this bit is enable. 1: enable 0: disable. + * This field is only for internal debugging purposes. Do not use it in applications. + */ + uint32_t wb_mode_en:1; + uint32_t reserved_28:4; }; uint32_t val; } spi1_mem_c_rd_status_reg_t; @@ -743,6 +747,24 @@ typedef union { uint32_t val; } spi1_mem_c_sus_status_reg_t; +/** Type of flash_waiti_ctrl1 register + * SPI1 wait idle control register + */ +typedef union { + struct { + /** waiti_idle_delay_time : R/W; bitpos: [9:0]; default: 0; + * SPI1 wait idle gap time configuration. SPI1 slv fsm will count during SPI1 IDLE. + */ + uint32_t waiti_idle_delay_time:10; + /** waiti_idle_delay_time_en : R/W; bitpos: [10]; default: 0; + * Enable SPI1 wait idle gap time count function. 1: Enable. 0: Disable. + */ + uint32_t waiti_idle_delay_time_en:1; + uint32_t reserved_11:21; + }; + uint32_t val; +} spi1_mem_c_flash_waiti_ctrl1_reg_t; + /** Type of ddr register * SPI1 DDR control register */ diff --git a/components/soc/esp32s31/register/soc/spi1_mem_s_struct.h b/components/soc/esp32s31/register/soc/spi1_mem_s_struct.h index 5dc83b69bbf..b2820508fc8 100644 --- a/components/soc/esp32s31/register/soc/spi1_mem_s_struct.h +++ b/components/soc/esp32s31/register/soc/spi1_mem_s_struct.h @@ -365,14 +365,8 @@ typedef union { * After PER command is sent, SPI1 waits (SPI1_MEM_S_CS_HOLD_DLY_PER[8:0] * 128) * SPI_CLK cycles. */ - uint32_t cs_hold_dly_per:9; - uint32_t reserved_21:2; - /** cs_hold_dly_per_en : R/W; bitpos: [23]; default: 0; - * 1: use SPI1_MEM_S_CS_HOLD_DLY_PER for per, use SPI1_MEM_S_CS_HOLD_DELAY_RES for - * pes/dp/hpm . 0: use SPI1_MEM_S_CS_HOLD_DELAY_RES for pes/dp/hpm/per . - */ - uint32_t cs_hold_dly_per_en:1; - uint32_t reserved_24:8; + uint32_t cs_hold_dly_per:10; + uint32_t reserved_22:10; }; uint32_t val; } spi1_mem_s_ctrl1_reg_t; @@ -460,7 +454,17 @@ typedef union { * This field is only for internal debugging purposes. Do not use it in applications. */ uint32_t wb_mode:8; - uint32_t reserved_24:8; + /** wb_mode_bitlen : R/W; bitpos: [26:24]; default: 0; + * Mode bits length for flash fast read mode. + * This field is only for internal debugging purposes. Do not use it in applications. + */ + uint32_t wb_mode_bitlen:3; + /** wb_mode_en : R/W; bitpos: [27]; default: 0; + * Mode bits is valid while this bit is enable. 1: enable 0: disable. + * This field is only for internal debugging purposes. Do not use it in applications. + */ + uint32_t wb_mode_en:1; + uint32_t reserved_28:4; }; uint32_t val; } spi1_mem_s_rd_status_reg_t; @@ -741,6 +745,24 @@ typedef union { uint32_t val; } spi1_mem_s_sus_status_reg_t; +/** Type of flash_waiti_ctrl1 register + * SPI1 wait idle control register + */ +typedef union { + struct { + /** waiti_idle_delay_time : R/W; bitpos: [9:0]; default: 0; + * SPI1 wait idle gap time configuration. SPI1 slv fsm will count during SPI1 IDLE. + */ + uint32_t waiti_idle_delay_time:10; + /** waiti_idle_delay_time_en : R/W; bitpos: [10]; default: 0; + * Enable SPI1 wait idle gap time count function. 1: Enable. 0: Disable. + */ + uint32_t waiti_idle_delay_time_en:1; + uint32_t reserved_11:21; + }; + uint32_t val; +} spi1_mem_s_flash_waiti_ctrl1_reg_t; + /** Type of ddr register * SPI1 DDR control register */ diff --git a/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c b/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c index ba78e0ed122..acdfbfe03c9 100644 --- a/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c +++ b/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c @@ -203,14 +203,14 @@ static void s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode) #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR s_set_pin_drive_capability(3); s_set_flash_dtr_str_opi_mode(1, 0x1); - esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd); + esp_rom_spiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd); esp_rom_spi_set_dtr_swap_mode(0, false, false); esp_rom_spi_set_dtr_swap_mode(1, false, false); #else //CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR s_set_pin_drive_capability(3); bool need_swap = s_mxic_dtr_need_swap(); s_set_flash_dtr_str_opi_mode(1, 0x2); - esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd); + esp_rom_spiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd); esp_rom_spi_set_dtr_swap_mode(0, need_swap, need_swap); esp_rom_spi_set_dtr_swap_mode(1, need_swap, need_swap); #endif diff --git a/components/spi_flash/test_apps/.build-test-rules.yml b/components/spi_flash/test_apps/.build-test-rules.yml index b95b5bd3277..565c4d465c8 100644 --- a/components/spi_flash/test_apps/.build-test-rules.yml +++ b/components/spi_flash/test_apps/.build-test-rules.yml @@ -81,9 +81,9 @@ components/spi_flash/test_apps/flash_suspend: disable: - if: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND != 1 disable_test: - - if: IDF_TARGET != "esp32c3" + - if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2", "esp32p4", "esp32s3", "esp32h4"] temporary: true - reason: lack of runners + reason: lack of runners, or we don't trust generic runner must support suspend depends_components: - *common_components - spi_flash diff --git a/components/spi_flash/test_apps/flash_suspend/main/test_flash_suspend.c b/components/spi_flash/test_apps/flash_suspend/main/test_flash_suspend.c index 6d52d167d16..cb40dffa4a5 100644 --- a/components/spi_flash/test_apps/flash_suspend/main/test_flash_suspend.c +++ b/components/spi_flash/test_apps/flash_suspend/main/test_flash_suspend.c @@ -213,7 +213,7 @@ TEST_CASE("flash suspend test", "[spi_flash][suspend]") // 15 stands for threshold. We allow the interval time minus duration time is little bit larger than TSUS value #if CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM // Don't check the performance because it should be slow. - TEST_ASSERT_LESS_THAN(CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US + 15, isr_interval_time - isr_duration_time); + TEST_ASSERT_LESS_THAN(CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US + 35, isr_interval_time - isr_duration_time); #endif ESP_LOGI(TAG, "Reasonable value!"); diff --git a/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py b/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py index 624898ccae6..14f10d5a0a3 100644 --- a/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py +++ b/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded import Dut @@ -17,3 +17,18 @@ from pytest_embedded_idf.utils import idf_parametrize @idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_flash_auto_suspend(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=30) + + +# Generic test for all targets that support flash auto suspend +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + 'text_in_flash_when_suspend', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5', 'esp32c61', 'esp32s31'], indirect=['target']) +def test_flash_auto_suspend_generic(dut: Dut) -> None: + dut.run_all_single_board_cases(timeout=30)