diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash.h index ade6ef01f6..6a359e055f 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash.h @@ -57,6 +57,13 @@ esp_err_t __attribute__((weak)) bootloader_flash_unlock(void); */ esp_err_t bootloader_flash_reset_chip(void); +/** + * @brief Check if octal flash mode is enabled in eFuse + * + * @return True if flash is in octal mode, false else + */ +bool bootloader_flash_is_octal_mode_enabled(void); + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index 321010fba7..26994f7291 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -10,6 +10,7 @@ #include #include "sdkconfig.h" #include "soc/soc_caps.h" +#include "hal/efuse_ll.h" #if CONFIG_IDF_TARGET_ESP32 # include "soc/spi_struct.h" @@ -780,3 +781,12 @@ esp_err_t IRAM_ATTR bootloader_flash_reset_chip(void) return ESP_OK; } + +bool bootloader_flash_is_octal_mode_enabled(void) +{ +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + return efuse_ll_get_flash_type(); +#else + return false; +#endif +} diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c index 33ebf6b687..9146ef5431 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c @@ -17,6 +17,7 @@ #include "flash_qio_mode.h" #include "bootloader_flash_config.h" #include "bootloader_common.h" +#include "bootloader_flash.h" #define FLASH_IO_MATRIX_DUMMY_40M 0 #define FLASH_IO_MATRIX_DUMMY_80M 0 @@ -34,17 +35,18 @@ void bootloader_flash_update_id() void IRAM_ATTR bootloader_flash_cs_timing_config() { //SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for FLASH, so we only need to set SPI0 related registers here -#if CONFIG_ESPTOOLPY_OCT_FLASH - SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); - SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, FLASH_CS_HOLD_TIME, SPI_MEM_CS_HOLD_TIME_S); - SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, FLASH_CS_SETUP_TIME, SPI_MEM_CS_SETUP_TIME_S); - //CS high time - SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_DELAY_V, FLASH_CS_HOLD_DELAY, SPI_MEM_CS_HOLD_DELAY_S); -#else - SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, 0, SPI_MEM_CS_HOLD_TIME_S); - SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S); - SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); -#endif + if (bootloader_flash_is_octal_mode_enabled()) { + + SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, FLASH_CS_HOLD_TIME, SPI_MEM_CS_HOLD_TIME_S); + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, FLASH_CS_SETUP_TIME, SPI_MEM_CS_SETUP_TIME_S); + //CS high time + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_DELAY_V, FLASH_CS_HOLD_DELAY, SPI_MEM_CS_HOLD_DELAY_S); + } else { + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, 0, SPI_MEM_CS_HOLD_TIME_S); + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S); + SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); + } } void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr) diff --git a/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c b/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c index 7e2005391a..53a426a6c0 100644 --- a/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c +++ b/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c @@ -218,7 +218,9 @@ static esp_err_t bootloader_init_spi_flash(void) bootloader_flash_unlock(); #if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - bootloader_enable_qio_mode(); + if (!bootloader_flash_is_octal_mode_enabled()) { + bootloader_enable_qio_mode(); + } #endif print_flash_info(&bootloader_image_hdr); diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index ff4d47cfdf..e432044d2d 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -22,6 +22,7 @@ #include "esp_private/gpio.h" #include "esp_private/sleep_gpio.h" #include "esp_private/spi_flash_os.h" +#include "bootloader_flash.h" static const char *TAG = "sleep"; @@ -71,13 +72,19 @@ void esp_sleep_config_gpio_isolate(void) gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_HD), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_WP), GPIO_PULLUP_ONLY); -#if CONFIG_SPIRAM_MODE_OCT || CONFIG_ESPTOOLPY_FLASHMODE_OPI - gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_DQS), GPIO_PULLUP_ONLY); - gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D4), GPIO_PULLUP_ONLY); - gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D5), GPIO_PULLUP_ONLY); - gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D6), GPIO_PULLUP_ONLY); - gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D7), GPIO_PULLUP_ONLY); -#endif // CONFIG_SPIRAM_MODE_OCT || CONFIG_ESPTOOLPY_FLASHMODE_OPI +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + bool octal_mspi_required = bootloader_flash_is_octal_mode_enabled(); +#if CONFIG_SPIRAM_MODE_OCT + octal_mspi_required |= true; +#endif // CONFIG_SPIRAM_MODE_OCT + if (octal_mspi_required) { + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_DQS), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D4), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D5), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D6), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D7), GPIO_PULLUP_ONLY); + } +#endif // SOC_SPI_MEM_SUPPORT_OPI_MODE #endif // CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU } diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index ebc7d03cd7..88d2abeade 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -364,7 +364,7 @@ void IRAM_ATTR call_start_cpu0(void) Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size); #endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 -#if CONFIG_ESPTOOLPY_OCT_FLASH +#if CONFIG_ESPTOOLPY_OCT_FLASH && !CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT bool efuse_opflash_en = efuse_ll_get_flash_type(); if (!efuse_opflash_en) { ESP_EARLY_LOGE(TAG, "Octal Flash option selected, but EFUSE not configured!"); diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 8178b0d809..7fee8e2bc9 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -14,6 +14,25 @@ menu "Serial flasher config" bool "Enable Octal Flash" default n + config ESPTOOLPY_FLASH_MODE_AUTO_DETECT + depends on IDF_TARGET_ESP32S3 + bool "Choose flash mode automatically (please read help)" + default y + help + This config option helps decide whether flash is Quad or Octal, but please note some limitations: + + 1. If the flash chip is an Octal one, even if one of "QIO", "QOUT", "DIO", "DOUT" options is + selected in `ESPTOOLPY_FLASHMODE`, our code will automatically change the + mode to "OPI" and the sample mode will be STR. + 2. If the flash chip is a Quad one, even if "OPI" is selected in `ESPTOOLPY_FLASHMODE`, our code will + automatically change the mode to "DIO". + 3. Please do not rely on this option when you are pretty sure that you are using Octal flash, + please enable `ESPTOOLPY_OCT_FLASH` option, then you can choose `DTR` sample mode + in `ESPTOOLPY_FLASH_SAMPLE_MODE`. Otherwise, only `STR` mode is available. + 4. Enabling this feature reduces available internal RAM size (around 900 bytes). + If your IRAM space is insufficient and you're aware of your flash type, + disable this option and select corresponding flash type options. + choice ESPTOOLPY_FLASHMODE prompt "Flash SPI mode" default ESPTOOLPY_FLASHMODE_DIO diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 7096cb57d0..72544d895e 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -29,7 +29,7 @@ else() "flash_brownout_hook.c" ) - if(CONFIG_ESPTOOLPY_OCT_FLASH) + if(CONFIG_SOC_SPI_MEM_SUPPORT_OPI_MODE) list(APPEND srcs "${target}/spi_flash_oct_flash_init.c") endif() diff --git a/components/spi_flash/esp32s3/spi_timing_config.c b/components/spi_flash/esp32s3/spi_timing_config.c index cd4ae3250c..cdab930410 100644 --- a/components/spi_flash/esp32s3/spi_timing_config.c +++ b/components/spi_flash/esp32s3/spi_timing_config.c @@ -14,6 +14,7 @@ #include "soc/spi_mem_reg.h" #include "spi_timing_config.h" #include "esp_private/spi_flash_os.h" +#include "bootloader_flash.h" #define OPI_PSRAM_SYNC_READ 0x0000 #define OPI_PSRAM_SYNC_WRITE 0x8080 @@ -106,9 +107,7 @@ typedef enum { PSRAM_CMD_SPI, } psram_cmd_mode_t; -#if !CONFIG_ESPTOOLPY_OCT_FLASH static uint8_t s_rom_flash_extra_dummy[2] = {NOT_INIT_INT, NOT_INIT_INT}; -#endif #if CONFIG_SPIRAM_MODE_QUAD static uint8_t s_psram_extra_dummy; @@ -137,7 +136,6 @@ void spi_timing_config_flash_set_din_mode_num(uint8_t spi_num, uint8_t din_mode, REG_WRITE(SPI_MEM_DIN_NUM_REG(spi_num), reg_val); } -#ifndef CONFIG_ESPTOOLPY_OCT_FLASH static uint32_t spi_timing_config_get_dummy(void) { uint32_t ctrl_reg = READ_PERI_REG(SPI_MEM_CTRL_REG(0)); @@ -185,21 +183,21 @@ static uint32_t spi_timing_config_get_dummy(void) } } } -#endif void spi_timing_config_flash_set_extra_dummy(uint8_t spi_num, uint8_t extra_dummy) { -#if CONFIG_ESPTOOLPY_OCT_FLASH - if (extra_dummy > 0) { - SET_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_M); - SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, extra_dummy, - SPI_MEM_EXTRA_DUMMY_CYCLELEN_S); - } else { - CLEAR_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_M); - SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, 0, - SPI_MEM_EXTRA_DUMMY_CYCLELEN_S); + if (bootloader_flash_is_octal_mode_enabled()) { + if (extra_dummy > 0) { + SET_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_M); + SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, extra_dummy, + SPI_MEM_EXTRA_DUMMY_CYCLELEN_S); + } else { + CLEAR_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_M); + SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, 0, + SPI_MEM_EXTRA_DUMMY_CYCLELEN_S); + } + return; } -#else /** * The `SPI_MEM_TIMING_CALI_REG` register is only used for OPI on 728 * Here we only need to update this global variable for extra dummy. Since we use the ROM Flash API, which will set the dummy based on this. @@ -213,7 +211,6 @@ void spi_timing_config_flash_set_extra_dummy(uint8_t spi_num, uint8_t extra_dumm // Only Quad Flash will run into this branch. uint32_t dummy = spi_timing_config_get_dummy(); SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, dummy + g_rom_spiflash_dummy_len_plus[spi_num], SPI_MEM_USR_DUMMY_CYCLELEN_S); -#endif } //-------------------------------------PSRAM timing tuning register config-------------------------------------// @@ -252,17 +249,17 @@ void spi_timing_config_psram_set_extra_dummy(uint8_t spi_num, uint8_t extra_dumm //-------------------------------------------FLASH/PSRAM Read/Write------------------------------------------// void spi_timing_config_flash_read_data(uint8_t spi_num, uint8_t *buf, uint32_t addr, uint32_t len) { -#if CONFIG_ESPTOOLPY_OCT_FLASH - // note that in spi_flash_read API, there is a wait-idle stage, since flash can only be read in idle state. - // but after we change the timing settings, we might not read correct idle status via RDSR. - // so, here we should use a read API that won't check idle status. - for (int i = 0; i < 16; i++) { - REG_WRITE(SPI_MEM_W0_REG(1) + i*4, 0); + if (bootloader_flash_is_octal_mode_enabled()) { + // note that in spi_flash_read API, there is a wait-idle stage, since flash can only be read in idle state. + // but after we change the timing settings, we might not read correct idle status via RDSR. + // so, here we should use a read API that won't check idle status. + for (int i = 0; i < 16; i++) { + REG_WRITE(SPI_MEM_W0_REG(1) + i*4, 0); + } + esp_rom_opiflash_read_raw(addr, buf, len); + } else { + esp_rom_spiflash_read(addr, (uint32_t *)buf, len); } - esp_rom_opiflash_read_raw(addr, buf, len); -#else - esp_rom_spiflash_read(addr, (uint32_t *)buf, len); -#endif } static void s_psram_write_data(uint8_t spi_num, uint8_t *buf, uint32_t addr, uint32_t len) diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 4b946737cb..c9558a1634 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -23,6 +23,7 @@ #include "esp_private/cache_utils.h" #include "esp_spi_flash_counters.h" #include "esp_rom_spiflash.h" +#include "bootloader_flash.h" __attribute__((unused)) static const char TAG[] = "spi_flash"; @@ -61,18 +62,25 @@ esp_flash_t *esp_flash_default_chip = NULL; #if defined(CONFIG_ESPTOOLPY_FLASHMODE_QIO) #define DEFAULT_FLASH_MODE SPI_FLASH_QIO +#define FLASH_MODE_STRING "qio" #elif defined(CONFIG_ESPTOOLPY_FLASHMODE_QOUT) #define DEFAULT_FLASH_MODE SPI_FLASH_QOUT +#define FLASH_MODE_STRING "qout" #elif defined(CONFIG_ESPTOOLPY_FLASHMODE_DIO) #define DEFAULT_FLASH_MODE SPI_FLASH_DIO +#define FLASH_MODE_STRING "dio" #elif defined(CONFIG_ESPTOOLPY_FLASHMODE_DOUT) #define DEFAULT_FLASH_MODE SPI_FLASH_DOUT +#define FLASH_MODE_STRING "dout" #elif defined(CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR) #define DEFAULT_FLASH_MODE SPI_FLASH_OPI_STR +#define FLASH_MODE_STRING "opi_str" #elif defined(CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR) #define DEFAULT_FLASH_MODE SPI_FLASH_OPI_DTR +#define FLASH_MODE_STRING "opi_dtr" #else #define DEFAULT_FLASH_MODE SPI_FLASH_FASTRD +#define FLASH_MODE_STRING "fast_rd" #endif //TODO: modify cs hold to meet requirements of all chips!!! @@ -326,6 +334,29 @@ static DRAM_ATTR esp_flash_t default_chip = { .os_func = &esp_flash_noos_functions, }; +#if CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT +/* This function is used to correct flash mode if config option is not consistent with efuse information */ +static void s_esp_flash_choose_correct_mode(memspi_host_config_t *cfg) +{ + static const char *mode = FLASH_MODE_STRING; + if (bootloader_flash_is_octal_mode_enabled()) { + #if !CONFIG_ESPTOOLPY_FLASHMODE_OPI + ESP_EARLY_LOGW(TAG, "Octal flash chip is using but %s mode is selected, will automatically swich to Octal mode", mode); + cfg->octal_mode_en = 1; + cfg->default_io_mode = SPI_FLASH_OPI_STR; + default_chip.read_mode = SPI_FLASH_OPI_STR; + #endif + } else { + #if CONFIG_ESPTOOLPY_FLASHMODE_OPI + ESP_EARLY_LOGW(TAG, "Quad flash chip is using but %s flash mode is selected, will automatically swich to DIO mode", mode); + cfg->octal_mode_en = 0; + cfg->default_io_mode = SPI_FLASH_DIO; + default_chip.read_mode = SPI_FLASH_DIO; + #endif + } +} +#endif // CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT + extern esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip); esp_err_t esp_flash_init_default_chip(void) { @@ -342,6 +373,12 @@ esp_err_t esp_flash_init_default_chip(void) cfg.default_io_mode = DEFAULT_FLASH_MODE; #endif + #if CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT + // Automatically detect flash mode in run time + s_esp_flash_choose_correct_mode(&cfg); + #endif + + // For chips need time tuning, get value directely from system here. #if SOC_SPI_MEM_SUPPORT_TIME_TUNING if (spi_timing_is_tuned()) { diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index e17c8b3aab..6544264908 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -155,27 +155,36 @@ void IRAM_ATTR spi_flash_rom_impl_init(void) void IRAM_ATTR esp_mspi_pin_init(void) { -#if CONFIG_ESPTOOLPY_OCT_FLASH || CONFIG_SPIRAM_MODE_OCT - esp_rom_opiflash_pin_config(); - extern void spi_timing_set_pin_drive_strength(void); - spi_timing_set_pin_drive_strength(); -#else +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + bool octal_mspi_required = bootloader_flash_is_octal_mode_enabled(); +#if CONFIG_SPIRAM_MODE_OCT + octal_mspi_required |= true; +#endif + + if (octal_mspi_required) { + esp_rom_opiflash_pin_config(); + extern void spi_timing_set_pin_drive_strength(void); + spi_timing_set_pin_drive_strength(); + } //Set F4R4 board pin drive strength. TODO: IDF-3663 #endif } esp_err_t IRAM_ATTR spi_flash_init_chip_state(void) { -#if CONFIG_ESPTOOLPY_OCT_FLASH - return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id); -#else -#if CONFIG_IDF_TARGET_ESP32S3 - // Currently, only esp32s3 allows high performance mode. - return spi_flash_enable_high_performance_mode(); -#else - return ESP_OK; -#endif // CONFIG_IDF_TARGET_ESP32S3 -#endif // CONFIG_ESPTOOLPY_OCT_FLASH +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + if (bootloader_flash_is_octal_mode_enabled()) { + return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id); + } else +#endif + { + #if CONFIG_IDF_TARGET_ESP32S3 + // Currently, only esp32s3 allows high performance mode. + return spi_flash_enable_high_performance_mode(); + #else + return ESP_OK; + #endif // CONFIG_IDF_TARGET_ESP32S3 + } } #if CONFIG_SPI_FLASH_ENABLE_COUNTERS @@ -207,14 +216,16 @@ void spi_flash_dump_counters(void) void IRAM_ATTR spi_flash_set_rom_required_regs(void) { -#if CONFIG_ESPTOOLPY_OCT_FLASH - //Disable the variable dummy mode when doing timing tuning - CLEAR_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY); - /** - * STR /DTR mode setting is done every time when `esp_rom_opiflash_exec_cmd` is called - * - * Add any registers that are not set in ROM SPI flash functions here in the future - */ +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + if (bootloader_flash_is_octal_mode_enabled()) { + //Disable the variable dummy mode when doing timing tuning + CLEAR_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY); + /** + * STR /DTR mode setting is done every time when `esp_rom_opiflash_exec_cmd` is called + * + * Add any registers that are not set in ROM SPI flash functions here in the future + */ + } #endif } @@ -222,14 +233,14 @@ void IRAM_ATTR spi_flash_set_rom_required_regs(void) // This function will only be called when Octal PSRAM enabled. void IRAM_ATTR spi_flash_set_vendor_required_regs(void) { -#if CONFIG_ESPTOOLPY_OCT_FLASH - //Flash chip requires MSPI specifically, call this function to set them - esp_opiflash_set_required_regs(); - SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), SPI_MEM_CACHE_USR_CMD_4BYTE_V, 1, SPI_MEM_CACHE_USR_CMD_4BYTE_S); -#else - // Set back MSPI registers after Octal PSRAM initialization. - SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), SPI_MEM_CACHE_USR_CMD_4BYTE_V, 0, SPI_MEM_CACHE_USR_CMD_4BYTE_S); -#endif // CONFIG_ESPTOOLPY_OCT_FLASH + if (bootloader_flash_is_octal_mode_enabled()) { + esp_opiflash_set_required_regs(); + SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), SPI_MEM_CACHE_USR_CMD_4BYTE_V, 1, SPI_MEM_CACHE_USR_CMD_4BYTE_S); + } else { + //Flash chip requires MSPI specifically, call this function to set them + // Set back MSPI registers after Octal PSRAM initialization. + SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), SPI_MEM_CACHE_USR_CMD_4BYTE_V, 0, SPI_MEM_CACHE_USR_CMD_4BYTE_S); + } } #endif diff --git a/components/spi_flash/linker.lf b/components/spi_flash/linker.lf index fa333dea61..c3687109b0 100644 --- a/components/spi_flash/linker.lf +++ b/components/spi_flash/linker.lf @@ -17,5 +17,5 @@ entries: spi_flash_chip_mxic_opi (noflash) spi_flash_hpm_enable (noflash) - if IDF_TARGET_ESP32S3 = y && ESPTOOLPY_OCT_FLASH = y: + if ESPTOOLPY_OCT_FLASH = y || ESPTOOLPY_FLASH_MODE_AUTO_DETECT = y: spi_flash_oct_flash_init (noflash)