diff --git a/.codespellrc b/.codespellrc index 389e346d2a..25a3e29489 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,4 +1,4 @@ [codespell] skip = build,*.yuv,components/fatfs/src/*,alice.txt,*.rgb,components/wpa_supplicant/*,components/esp_wifi/* -ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart,wheight +ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart,wheight,wel write-changes = true diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index ba6f69f01b..ca817d0c6a 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -100,9 +100,15 @@ menu "Bootloader config" help This is a helper config for 32bits address flash. Invisible for users. + config BOOTLOADER_FLASH_NEEDS_32BIT_ADDR_QUAD_FLASH + bool + default y if BOOTLOADER_FLASH_NEEDS_32BIT_FEAT && SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP + help + This is a helper config for 32bits address quad flash. Invisible for users. + config BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH bool "Enable cache access to 32-bit-address (over 16MB) range of SPI Flash (READ DOCS FIRST)" - depends on BOOTLOADER_FLASH_NEEDS_32BIT_FEAT && IDF_TARGET_ESP32S3 && IDF_EXPERIMENTAL_FEATURES + depends on BOOTLOADER_FLASH_NEEDS_32BIT_ADDR_QUAD_FLASH && IDF_EXPERIMENTAL_FEATURES default n help Enabling this option allows the CPU to access 32-bit-address flash beyond 16M range. diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index 22bcf0fb69..49a3655f7a 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -136,6 +136,8 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) #if CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/opi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32P4 +#include "esp32p4/rom/opi_flash.h" #endif static const char *TAG = "bootloader_flash"; diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c index 8766a908a5..7b1c01d080 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c @@ -99,6 +99,15 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) case ESP_IMAGE_FLASH_SIZE_16MB: size = 16; break; + case ESP_IMAGE_FLASH_SIZE_32MB: + size = 32; + break; + case ESP_IMAGE_FLASH_SIZE_64MB: + size = 64; + break; + case ESP_IMAGE_FLASH_SIZE_128MB: + size = 128; + break; default: size = 2; } @@ -175,6 +184,15 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr) case ESP_IMAGE_FLASH_SIZE_16MB: str = "16MB"; break; + case ESP_IMAGE_FLASH_SIZE_32MB: + str = "32MB"; + break; + case ESP_IMAGE_FLASH_SIZE_64MB: + str = "64MB"; + break; + case ESP_IMAGE_FLASH_SIZE_128MB: + str = "128MB"; + break; default: str = "2MB"; break; @@ -203,6 +221,9 @@ esp_err_t bootloader_init_spi_flash(void) #if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT bootloader_enable_qio_mode(); #endif +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH + bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); +#endif print_flash_info(&bootloader_image_hdr); @@ -271,6 +292,10 @@ void bootloader_flash_hardware_init(void) bootloader_spi_flash_resume(); bootloader_flash_unlock(); +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH + bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); +#endif + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&hdr); cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); diff --git a/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c b/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c index f04a921698..1020dc663a 100644 --- a/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c +++ b/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c @@ -41,11 +41,13 @@ #include "hal/cache_hal.h" #include "hal/clk_tree_ll.h" #include "hal/lpwdt_ll.h" +#include "hal/spimem_flash_ll.h" #include "soc/lp_wdt_reg.h" #include "hal/efuse_hal.h" #include "soc/regi2c_syspll.h" #include "soc/regi2c_cpll.h" #include "soc/regi2c_bias.h" +#include "esp_private/periph_ctrl.h" static const char *TAG = "boot.esp32p4"; @@ -90,6 +92,7 @@ static void bootloader_super_wdt_auto_feed(void) static inline void bootloader_hardware_init(void) { + int __DECLARE_RCC_ATOMIC_ENV __attribute__ ((unused)); // regi2c is enabled by default on ESP32P4, do nothing unsigned chip_version = efuse_hal_chip_revision(); if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) { @@ -101,6 +104,12 @@ static inline void bootloader_hardware_init(void) } REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1, 10); REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 10); + + // IDF-10019 TODO: This is temporarily for ESP32P4-ECO0, please remove it when eco0 is not widly used. + if (likely(ESP_CHIP_REV_ABOVE(chip_version, 1))) { + spimem_flash_ll_select_clk_source(0, FLASH_CLK_SRC_SPLL); + spimem_ctrlr_ll_set_core_clock(0, 6); + } } static inline void bootloader_ana_reset_config(void) diff --git a/components/esp_rom/patches/esp_rom_spiflash.c b/components/esp_rom/patches/esp_rom_spiflash.c index 4608b61343..92006d3129 100644 --- a/components/esp_rom/patches/esp_rom_spiflash.c +++ b/components/esp_rom/patches/esp_rom_spiflash.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,9 @@ #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/spi_flash.h" #include "esp32s3/rom/opi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32P4 +#include "esp32p4/rom/spi_flash.h" +#include "esp32p4/rom/opi_flash.h" #endif #define SPI_IDX 1 @@ -725,6 +728,36 @@ 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) +{ + esp_rom_spi_set_op_mode(0, mode); + + if (cache) { + esp_rom_spi_set_address_bit_len(0, cache->addr_bit_len); + // Patch for ROM function `esp_rom_opiflash_cache_mode_config`, because when dummy is 0, + // `SPI_MEM_USR_DUMMY` should be 0. `esp_rom_opiflash_cache_mode_config` doesn't handle this + // properly. + if (cache->dummy_bit_len == 0) { + REG_CLR_BIT(SPI_MEM_C_USER_REG, SPI_MEM_C_USR_DUMMY); + } else { + REG_SET_BIT(SPI_MEM_C_USER_REG, SPI_MEM_C_USR_DUMMY); + REG_SET_FIELD(SPI_MEM_C_USER1_REG, SPI_MEM_C_USR_DUMMY_CYCLELEN, cache->dummy_bit_len - 1 + rom_spiflash_legacy_data->dummy_len_plus[0]); + } + REG_SET_FIELD(SPI_MEM_C_USER2_REG, SPI_MEM_C_USR_COMMAND_VALUE, cache->cmd); + REG_SET_FIELD(SPI_MEM_C_USER2_REG, SPI_MEM_C_USR_COMMAND_BITLEN, cache->cmd_bit_len - 1); + REG_SET_FIELD(SPI_MEM_C_DDR_REG, SPI_MEM_C_FMEM__VAR_DUMMY, cache->var_dummy_en); + + // Make sure CACHE-FLASH control dummy always be high level + REG_SET_BIT(SPI_MEM_C_CTRL_REG, SPI_MEM_C_FDUMMY_RIN); + REG_SET_BIT(SPI_MEM_C_CTRL_REG, SPI_MEM_C_WP_REG); + REG_SET_BIT(SPI_MEM_C_CTRL_REG, SPI_MEM_C_D_POL); + REG_SET_BIT(SPI_MEM_C_CTRL_REG, SPI_MEM_C_Q_POL); + } +} + + #endif // IDF_TARGET #endif // CONFIG_SPI_FLASH_ROM_DRIVER_PATCH diff --git a/components/hal/esp32p4/include/hal/spi_flash_ll.h b/components/hal/esp32p4/include/hal/spi_flash_ll.h index 444099fead..4f7329e5a9 100644 --- a/components/hal/esp32p4/include/hal/spi_flash_ll.h +++ b/components/hal/esp32p4/include/hal/spi_flash_ll.h @@ -64,7 +64,8 @@ typedef union { #define spi_flash_ll_set_dummy(dev, dummy) gpspi_flash_ll_set_dummy((spi_dev_t*)dev, dummy) #define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n) #define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time) -#define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-C6*/ } +#define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-P4*/ } +#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev) #else #define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev) #define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev) @@ -93,6 +94,7 @@ typedef union { #define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time) #define spi_flash_ll_set_extra_address(dev, extra_addr) spimem_flash_ll_set_extra_address((spi_mem_dev_t*)dev, extra_addr) #define spi_flash_ll_get_ctrl_val(dev) spimem_flash_ll_get_ctrl_val((spi_mem_dev_t*)dev) +#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev) #endif diff --git a/components/hal/esp32p4/include/hal/spimem_flash_ll.h b/components/hal/esp32p4/include/hal/spimem_flash_ll.h index d91af4839e..23de80140b 100644 --- a/components/hal/esp32p4/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32p4/include/hal/spimem_flash_ll.h @@ -22,10 +22,13 @@ #include "soc/spi_periph.h" #include "soc/spi1_mem_c_struct.h" #include "soc/spi1_mem_c_reg.h" +#include "soc/hp_sys_clkrst_struct.h" #include "hal/assert.h" #include "hal/spi_types.h" #include "hal/spi_flash_types.h" #include "hal/misc.h" +#include "hal/efuse_hal.h" +#include "soc/chip_revision.h" #ifdef __cplusplus extern "C" { @@ -221,10 +224,9 @@ static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint3 */ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dly_val) { - // dev->ctrl1.cs_hold_dly_res = dly_val; - // dev->sus_status.pes_dly_128 = 1; - // dev->sus_status.per_dly_128 = 1; - abort(); + dev->ctrl1.cs_hold_dly_res = dly_val; + dev->sus_status.flash_pes_dly_128 = 1; + dev->sus_status.flash_per_dly_128 = 1; } /** @@ -235,8 +237,7 @@ static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dl */ static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t cs_hold_delay) { - // SPIMEM0.ctrl2.cs_hold_delay = cs_hold_delay; - abort(); + SPIMEM0.ctrl2.cs_hold_delay = cs_hold_delay; } /** @@ -290,9 +291,8 @@ static inline bool spimem_flash_ll_sus_status(spi_mem_dev_t *dev) */ static inline void spimem_flash_ll_sus_set_spi0_lock_trans(spi_mem_dev_t *dev, uint32_t lock_time) { - // dev->sus_status.spi0_lock_en = 1; - // SPIMEM0.fsm.cspi_lock_delay_time = lock_time; - abort(); + dev->sus_status.spi0_lock_en = 1; + SPIMEM0.fsm.lock_delay_time = lock_time; } /** @@ -303,14 +303,13 @@ static inline void spimem_flash_ll_sus_set_spi0_lock_trans(spi_mem_dev_t *dev, u */ static inline uint32_t spimem_flash_ll_get_tsus_unit_in_cycles(spi_mem_dev_t *dev) { - // uint32_t tsus_unit = 0; - // if (dev->sus_status.pes_dly_128 == 1) { - // tsus_unit = 128; - // } else { - // tsus_unit = 4; - // } - // return tsus_unit; - abort(); + uint32_t tsus_unit = 0; + if (dev->sus_status.flash_pes_dly_128 == 1) { + tsus_unit = 128; + } else { + tsus_unit = 4; + } + return tsus_unit; } /** @@ -554,6 +553,10 @@ static inline int spimem_flash_ll_get_addr_bitlen(spi_mem_dev_t *dev) */ static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t bitlen) { + unsigned chip_version = efuse_hal_chip_revision(); + if (ESP_CHIP_REV_ABOVE(chip_version, 1)) { + dev->cache_fctrl.cache_usr_addr_4byte = (bitlen == 32) ? 1 : 0; + } dev->user1.usr_addr_bitlen = (bitlen - 1); dev->user.usr_addr = bitlen ? 1 : 0; } @@ -684,6 +687,73 @@ static inline uint32_t spimem_flash_ll_get_ctrl_val(spi_mem_dev_t *dev) return dev->ctrl.val; } +/** + * Set D/Q output level during dummy phase + * + * @param dev Beginning address of the peripheral registers. + * @param out_en whether to enable IO output for dummy phase + * @param out_level dummy output level + */ +static inline void spimem_flash_ll_set_dummy_out(spi_mem_dev_t *dev, uint32_t out_en, uint32_t out_lev) +{ + dev->ctrl.fdummy_rin = out_en; + dev->ctrl.q_pol = out_lev; + dev->ctrl.d_pol = out_lev; + dev->ctrl.wp_reg = out_lev; +} + +/* + * @brief Select FLASH clock source + * + * @param mspi_id mspi_id + * @param clk_src clock source, see valid sources in type `soc_periph_flash_clk_src_t` + */ +__attribute__((always_inline)) +static inline void spimem_flash_ll_select_clk_source(uint32_t mspi_id, soc_periph_flash_clk_src_t clk_src) +{ + (void)mspi_id; + uint32_t clk_val = 0; + switch (clk_src) { + case FLASH_CLK_SRC_XTAL: + clk_val = 0; + break; + case FLASH_CLK_SRC_SPLL: + clk_val = 1; + break; + case FLASH_CLK_SRC_CPLL: + clk_val = 2; + break; + default: + HAL_ASSERT(false); + break; + } + + HP_SYS_CLKRST.peri_clk_ctrl00.reg_flash_pll_clk_en = 1; + HP_SYS_CLKRST.peri_clk_ctrl00.reg_flash_clk_src_sel = clk_val; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define spimem_flash_ll_select_clk_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; spimem_flash_ll_select_clk_source(__VA_ARGS__) + +/** + * @brief Set FLASH core clock + * + * @param mspi_id mspi_id + * @param freqdiv Divider value + */ +__attribute__((always_inline)) +static inline void spimem_ctrlr_ll_set_core_clock(uint8_t mspi_id, uint32_t freqdiv) +{ + (void)mspi_id; + HP_SYS_CLKRST.peri_clk_ctrl00.reg_flash_core_clk_en = 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl00, reg_flash_core_clk_div_num, freqdiv - 1); +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define spimem_ctrlr_ll_set_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; spimem_ctrlr_ll_set_core_clock(__VA_ARGS__) + #ifdef __cplusplus } #endif diff --git a/components/hal/spi_flash_hal_common.inc b/components/hal/spi_flash_hal_common.inc index 942edf96f6..e83fd0a290 100644 --- a/components/hal/spi_flash_hal_common.inc +++ b/components/hal/spi_flash_hal_common.inc @@ -17,6 +17,8 @@ #include "hal/spi_flash_hal.h" #include "hal/assert.h" #include "soc/soc_caps.h" +#include "soc/chip_revision.h" +#include "hal/efuse_hal.h" #include "sdkconfig.h" #define ADDRESS_MASK_24BIT 0xFFFFFF @@ -130,6 +132,19 @@ esp_err_t spi_flash_hal_configure_host_io_mode( } #endif +#if CONFIG_IDF_TARGET_ESP32P4 + // TODO: This is temporarily for ESP32P4-ECO0, please remove it when eco0 is not widly used. IDF-10019 + unsigned chip_version = efuse_hal_chip_revision(); + if (unlikely(!ESP_CHIP_REV_ABOVE(chip_version, 1))) { + if (conf_required) { + int line_width = (io_mode == SPI_FLASH_DIO? 2: 4); + dummy_cyclelen_base -= SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS / line_width; + addr_bitlen += SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS; + spi_flash_ll_set_extra_address(dev, 0); + } + } +#endif + if (command >= 0x100) { spi_flash_ll_set_command(dev, command, 16); } else { diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 05f95c7ad8..eae5885c8b 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1211,6 +1211,10 @@ config SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE bool default y +config SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND + bool + default y + config SOC_SPI_MEM_SUPPORT_AUTO_RESUME bool default y @@ -1235,6 +1239,14 @@ config SOC_MEMSPI_TIMING_TUNING_BY_DQS bool default y +config SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP + bool + default y + +config SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT + bool + default y + config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 771f4ca299..49ee3e7c58 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -492,7 +492,7 @@ /*-------------------------- SPI MEM CAPS ---------------------------------------*/ #define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1) -//#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1) //TODO: IDF-7518 +#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_AUTO_RESUME (1) #define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) @@ -500,6 +500,9 @@ // #define SOC_SPI_MEM_SUPPORT_WRAP (1) // IDFCI-2073 The feature cannot be treated as supported on P4 #define SOC_SPI_MEM_SUPPORT_TIMING_TUNING (1) #define SOC_MEMSPI_TIMING_TUNING_BY_DQS (1) +#define SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP (1) + +#define SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT (1) #define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index cacd5d6b7f..cd6407a393 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -1319,6 +1319,10 @@ config SOC_MEMSPI_CORE_CLK_SHARED_WITH_PSRAM bool default y +config SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP + bool + default y + config SOC_COEX_HW_PTI bool default y diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index bd62a94337..23df7b61b0 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -514,6 +514,7 @@ #define SOC_SPI_MEM_SUPPORT_WRAP (1) #define SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY (1) #define SOC_MEMSPI_CORE_CLK_SHARED_WITH_PSRAM (1) +#define SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP (1) /*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/ #define SOC_COEX_HW_PTI (1) diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 46f43874b8..0ab6c98da1 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -25,6 +25,7 @@ #include "esp_spi_flash_counters.h" #include "esp_rom_spiflash.h" #include "bootloader_flash.h" +#include "esp_check.h" __attribute__((unused)) static const char TAG[] = "spi_flash"; @@ -395,6 +396,11 @@ esp_err_t esp_flash_init_default_chip(void) if (default_chip.size > legacy_chip->chip_size) { ESP_EARLY_LOGW(TAG, "Detected size(%dk) larger than the size in the binary image header(%dk). Using the size in the binary image header.", default_chip.size/1024, legacy_chip->chip_size/1024); } +#if !CONFIG_IDF_TARGET_ESP32P4 || !CONFIG_APP_BUILD_TYPE_RAM // IDF-10019 + if (legacy_chip->chip_size > 16 * 1024 * 1024) { + ESP_RETURN_ON_ERROR_ISR(esp_mspi_32bit_address_flash_feature_check(), TAG, "32bit address feature check failed"); + } +#endif // !CONFIG_IDF_TARGET_ESP32P4 || !CONFIG_APP_BUILD_TYPE_RAM // Set chip->size equal to ROM flash size(also equal to the size in binary image header), which means the available size that can be used default_chip.size = legacy_chip->chip_size; diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index d88259ec7d..7a41bdf5a7 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -54,6 +54,8 @@ #include "bootloader_flash_config.h" #include "esp_compiler.h" #include "esp_rom_efuse.h" +#include "soc/chip_revision.h" +#include "hal/efuse_hal.h" #if CONFIG_SPIRAM #include "esp_private/esp_psram_io.h" #endif @@ -288,3 +290,22 @@ uint8_t esp_mspi_get_io(esp_mspi_io_t io) return s_mspi_io_num_default[io]; #endif // SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE } + +#if !CONFIG_IDF_TARGET_ESP32P4 || !CONFIG_APP_BUILD_TYPE_RAM // IDF-10019 +esp_err_t IRAM_ATTR esp_mspi_32bit_address_flash_feature_check(void) +{ +#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 + ESP_EARLY_LOGE(TAG, "32bit address (flash over 16MB) has high risk on this chip"); + return ESP_ERR_NOT_SUPPORTED; +#elif CONFIG_IDF_TARGET_ESP32P4 + // IDF-10019 + unsigned chip_version = efuse_hal_chip_revision(); + if (unlikely(!ESP_CHIP_REV_ABOVE(chip_version, 1))) { + ESP_EARLY_LOGE(TAG, "32bit address (flash over 16MB) has high risk on ESP32P4 ECO0"); + return ESP_ERR_NOT_SUPPORTED; + } +#endif + + return ESP_OK; +} +#endif // !CONFIG_IDF_TARGET_ESP32P4 || !CONFIG_APP_BUILD_TYPE_RAM diff --git a/components/spi_flash/include/esp_private/spi_flash_os.h b/components/spi_flash/include/esp_private/spi_flash_os.h index e68b0c8fb3..40ec114a1d 100644 --- a/components/spi_flash/include/esp_private/spi_flash_os.h +++ b/components/spi_flash/include/esp_private/spi_flash_os.h @@ -119,6 +119,13 @@ void spi_flash_set_erasing_flag(bool status); */ bool spi_flash_brownout_need_reset(void); +/** + * @brief Check whether esp-chip supports 32bit address properly + * + * @return ESP_OK for supported, ESP_ERR_NOT_SUPPORTED for not supported +*/ +esp_err_t esp_mspi_32bit_address_flash_feature_check(void); + #if CONFIG_SPI_FLASH_HPM_ON /** * @brief Enable SPI flash high performance mode. diff --git a/components/spi_flash/test_apps/flash_suspend/README.md b/components/spi_flash/test_apps/flash_suspend/README.md index f39c17bef3..6e64f130b1 100644 --- a/components/spi_flash/test_apps/flash_suspend/README.md +++ b/components/spi_flash/test_apps/flash_suspend/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | 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 2a9e4be993..3750550885 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 @@ -75,7 +75,11 @@ static bool IRAM_ATTR gptimer_alarm_suspend_cb(gptimer_handle_t timer, const gpt #if CONFIG_IDF_TARGET_ESP32S3 Cache_Invalidate_DCache_All(); #endif +#if CONFIG_IDF_TARGET_ESP32P4 + Cache_Invalidate_All(CACHE_MAP_L2_CACHE); +#else Cache_Invalidate_ICache_All(); +#endif s_flash_func_t1 = esp_cpu_get_cycle_count(); func_in_flash(); diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst index 3f1c7d52ce..a77d8fce95 100644 --- a/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst @@ -157,15 +157,15 @@ List of Flash chips that support this feature: Restrictions ^^^^^^^^^^^^ -.. only:: not esp32s3 +.. only:: not SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP .. important:: Over 16 MBytes space on flash mentioned above can be only used for ``data saving``, like file system. - Mapping data/instructions to 32-bit physical address space (so as to be accessed by the CPU) needs the support of MMU. However {IDF_TARGET_NAME} doesn't support this feature. Only ESP32-S3 supports this up to now. + Mapping data/instructions to 32-bit physical address space (so as to be accessed by the CPU) needs the support of MMU. However {IDF_TARGET_NAME} doesn't support this feature. Only ESP32-S3 and ESP32-P4 supports this up to now. -.. only:: esp32s3 +.. only:: SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP By default, space over 16 MBytes on flash mentioned above can be used for ``data saving``, like file system. @@ -178,7 +178,7 @@ Restrictions OPI Flash Support ----------------- -This feature is only supporetd on ESP32-S3 for now. +This feature is only supported on ESP32-S3 for now. OPI flash means that the flash chip supports octal peripheral interface, which has octal I/O pins. Different octal flash has different configurations and different commands. Hence, it is necessary to carefully check the support list.