Skip to content

Commit

Permalink
Merge branch 'bugfix/hpm_dc_default_disabled_v4.4' into 'release/v4.4'
Browse files Browse the repository at this point in the history
spi_flash: fixed issue that enabling HPM-DC by default may cause app unable to restart (v4.4)

See merge request espressif/esp-idf!28159
  • Loading branch information
ginkgm committed Feb 2, 2024
2 parents 2ded73b + 2a6797d commit 5684098
Show file tree
Hide file tree
Showing 25 changed files with 370 additions and 162 deletions.
88 changes: 56 additions & 32 deletions components/bootloader/Kconfig.projbuild
Expand Up @@ -62,34 +62,66 @@ menu "Bootloader config"
default 4 if BOOTLOADER_LOG_LEVEL_DEBUG
default 5 if BOOTLOADER_LOG_LEVEL_VERBOSE

config BOOTLOADER_SPI_CUSTOM_WP_PIN
bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)"
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5
default n
help
This setting is only used if the SPI flash pins have been overridden by setting the eFuses
SPI_PAD_CONFIG_xxx, and the SPI flash mode is QIO or QOUT.
menu "Serial Flash Configurations"
config BOOTLOADER_SPI_CUSTOM_WP_PIN
bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)"
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5
default n
help
This setting is only used if the SPI flash pins have been overridden by setting the eFuses
SPI_PAD_CONFIG_xxx, and the SPI flash mode is QIO or QOUT.

When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka
ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. The same pin is also used
for external SPIRAM if it is enabled.

If this config item is set to N (default), the correct WP pin will be automatically used for any
Espressif chip or module with integrated flash. If a custom setting is needed, set this config item to
Y and specify the GPIO number connected to the WP.

config BOOTLOADER_SPI_WP_PIN
int "Custom SPI Flash WP Pin"
range 0 33
default 7
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
#depends on BOOTLOADER_SPI_CUSTOM_WP_PIN # backwards compatibility, can uncomment in IDF 5
help
The option "Use custom SPI Flash WP Pin" must be set or this value is ignored

When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka
ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. The same pin is also used
for external SPIRAM if it is enabled.
If burning a customized set of SPI flash pins in eFuse and using QIO or QOUT mode for flash, set this
value to the GPIO number of the SPI flash WP pin.

If this config item is set to N (default), the correct WP pin will be automatically used for any
Espressif chip or module with integrated flash. If a custom setting is needed, set this config item to
Y and specify the GPIO number connected to the WP.
config BOOTLOADER_FLASH_DC_AWARE
bool "Allow app adjust Dummy Cycle bits in SPI Flash for higher frequency (READ HELP FIRST)"
help
This will force 2nd bootloader to be loaded by DOUT mode, and will restore Dummy Cycle setting by
resetting the Flash

config BOOTLOADER_SPI_WP_PIN
int "Custom SPI Flash WP Pin"
range 0 33
default 7
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
#depends on BOOTLOADER_SPI_CUSTOM_WP_PIN # backwards compatibility, can uncomment in IDF 5
help
The option "Use custom SPI Flash WP Pin" must be set or this value is ignored
config BOOTLOADER_FLASH_XMC_SUPPORT
bool "Enable the support for flash chips of XMC (READ DOCS FIRST)"
default y
help
Perform the startup flow recommended by XMC. Please consult XMC for the details of this flow.
XMC chips will be forbidden to be used, when this option is disabled.

DON'T DISABLE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.

If burning a customized set of SPI flash pins in eFuse and using QIO or QOUT mode for flash, set this
value to the GPIO number of the SPI flash WP pin.
comment "Features below require specific hardware (READ DOCS FIRST!)"

config BOOTLOADER_FLASH_32BIT_ADDR
bool
default y if ESPTOOLPY_FLASHSIZE_32MB || ESPTOOLPY_FLASHSIZE_64MB || ESPTOOLPY_FLASHSIZE_128MB
default n
help
This is a helper config for 32bits address flash. Invisible for users.

config BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
bool
default y if ESPTOOLPY_OCT_FLASH && BOOTLOADER_FLASH_32BIT_ADDR
default n

endmenu

choice BOOTLOADER_VDDSDIO_BOOST
bool "VDDSDIO LDO voltage"
Expand Down Expand Up @@ -393,14 +425,6 @@ menu "Bootloader config"
in this area of memory, you can increase it. It must be a multiple of 4 bytes.
This area (rtc_retain_mem_t) is reserved and has access from the bootloader and an application.

config BOOTLOADER_FLASH_XMC_SUPPORT
bool "Enable the support for flash chips of XMC (READ HELP FIRST)"
default y
help
Perform the startup flow recommended by XMC. Please consult XMC for the details of this flow.
XMC chips will be forbidden to be used, when this option is disabled.

DON'T DISABLE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.

endmenu # Bootloader

Expand Down
2 changes: 2 additions & 0 deletions components/bootloader/sdkconfig.rename
Expand Up @@ -23,3 +23,5 @@ CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE CONFIG_SECURE_FLASH_

# Secure Boot Scheme
CONFIG_SECURE_BOOT_ENABLED CONFIG_SECURE_BOOT_V1_ENABLED

CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
Expand Up @@ -96,7 +96,7 @@ extern const bootloader_qio_info_t __attribute__((weak)) bootloader_flash_qe_sup
*/
esp_err_t IRAM_ATTR __attribute__((weak)) bootloader_flash_unlock(void);

#if CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
/**
* @brief Enable 32bits address flash(larger than 16MB) can map to cache.
*
Expand Down
2 changes: 1 addition & 1 deletion components/bootloader_support/src/bootloader_flash.c
Expand Up @@ -487,7 +487,7 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
return spi_to_esp_err(rc);
}

#if CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
void bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode)
{
esp_rom_opiflash_spi0rd_t cache_rd = {};
Expand Down
Expand Up @@ -218,7 +218,7 @@ static esp_err_t bootloader_init_spi_flash(void)
}
#endif

#if CONFIG_SPI_FLASH_HPM_ENABLE
#if CONFIG_BOOTLOADER_FLASH_DC_AWARE
// Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot.
bootloader_spi_flash_reset();
#endif
Expand All @@ -228,7 +228,7 @@ static esp_err_t bootloader_init_spi_flash(void)
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT
bootloader_enable_qio_mode();
#endif
#if CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode());
#endif
print_flash_info(&bootloader_image_hdr);
Expand Down
2 changes: 1 addition & 1 deletion components/esp32s3/Kconfig
Expand Up @@ -307,7 +307,7 @@ menu "ESP32S3-Specific"

config SPIRAM_SPEED_120M
depends on SPIRAM_MODE_QUAD
bool "120MHz clock speed"
bool "120MHz clock speed (READ DOCS FIRST)"
config SPIRAM_SPEED_80M
bool "80MHz clock speed"
config SPIRAM_SPEED_40M
Expand Down
2 changes: 2 additions & 0 deletions components/esp_lcd/Kconfig
@@ -1,4 +1,6 @@
menu "LCD and Touch Panel"
comment "LCD Touch Drivers are maintained in the IDF Component Registry"

menu "LCD Peripheral Configuration"
config LCD_PANEL_IO_FORMAT_BUF_SIZE
int "LCD panel io format buffer size"
Expand Down
12 changes: 9 additions & 3 deletions components/esptool_py/Kconfig.projbuild
Expand Up @@ -118,6 +118,10 @@ menu "Serial flasher config"
# information get from efuse, so don't care this dout choice.
default "dout" if ESPTOOLPY_FLASHMODE_OPI

config ESPTOOLPY_S3_STR
bool
default y if IDF_TARGET_ESP32S3 && ESPTOOLPY_FLASH_SAMPLE_MODE_STR

choice ESPTOOLPY_FLASHFREQ
prompt "Flash SPI speed"
default ESPTOOLPY_FLASHFREQ_40M if IDF_TARGET_ESP32 || IDF_TARGET_ESP32H2
Expand All @@ -126,9 +130,11 @@ menu "Serial flasher config"
The SPI flash frequency to be used.

config ESPTOOLPY_FLASHFREQ_120M
depends on IDF_TARGET_ESP32S3 && ESPTOOLPY_FLASH_SAMPLE_MODE_STR
bool "120 MHz"
select SPI_FLASH_HPM_ENABLE
bool "120 MHz (READ DOCS FIRST)"
depends on ESPTOOLPY_S3_STR && (SPI_FLASH_HPM_ON || ESPTOOLPY_OCT_FLASH)
help
- Optional feature for QSPI Flash. Read docs and enable `CONFIG_SPI_FLASH_HPM_ENA` first!

config ESPTOOLPY_FLASHFREQ_80M
bool "80 MHz"
config ESPTOOLPY_FLASHFREQ_40M
Expand Down
2 changes: 1 addition & 1 deletion components/esptool_py/project_include.cmake
Expand Up @@ -15,7 +15,7 @@ set(ESPSECUREPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espsecure.py")
set(ESPEFUSEPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espefuse.py")
set(ESPMONITOR ${python} "${idf_path}/tools/idf_monitor.py")

if(CONFIG_SPI_FLASH_HPM_ENABLE)
if(CONFIG_BOOTLOADER_FLASH_DC_AWARE)
# When set flash frequency to 120M, must keep 1st bootloader work under ``DOUT`` mode
# because on some flash chips, 120M will modify the status register,
# which will make ROM won't work.
Expand Down
5 changes: 5 additions & 0 deletions components/spi_flash/CMakeLists.txt
Expand Up @@ -23,6 +23,11 @@ else()
list(APPEND srcs
"esp32s3/spi_timing_config.c"
"spi_flash_timing_tuning.c"
)
endif()

if(CONFIG_SPI_FLASH_HPM_ON)
list(APPEND srcs
"spi_flash_hpm_enable.c")
endif()

Expand Down
115 changes: 83 additions & 32 deletions components/spi_flash/Kconfig
@@ -1,3 +1,86 @@
menu "Main Flash configuration"
depends on !APP_BUILD_TYPE_PURE_RAM_APP

menu "Optional and Experimental Features (READ DOCS FIRST)"

comment "Features here require specific hardware (READ DOCS FIRST!)"

config SPI_FLASH_UNDER_HIGH_FREQ
bool
default y if ESPTOOLPY_FLASHFREQ_120M
help
This is a helper config for HPM. Invisible for users.

choice SPI_FLASH_HPM
prompt "High Performance Mode (READ DOCS FIRST, > 80MHz)"
# Currently, only esp32s3 allows high performance mode.
depends on IDF_TARGET_ESP32S3 && !ESPTOOLPY_OCT_FLASH
default SPI_FLASH_HPM_AUTO
help
Whether the High Performance Mode of Flash is enabled. As an optional feature, user needs to manually
enable this option as a confirmation. To be back-compatible with earlier IDF versionn, this option is
automatically enabled with warning when Flash running > 80Mhz.

config SPI_FLASH_HPM_ENA
# Not using name of SPI_FLASH_HPM_ENABLE because it was used as an invisible option and we don't want
# to inherit the value of that one
bool "Enable"
config SPI_FLASH_HPM_AUTO
bool "Auto (Not recommended)"
config SPI_FLASH_HPM_DIS
bool "Disabled"
endchoice

config SPI_FLASH_HPM_ON
bool
# For ESP32-S3, it's enabled by default. For later chips it should be disabled by default
default y if SPI_FLASH_HPM_ENA || (IDF_TARGET_ESP32S3 && SPI_FLASH_HPM_AUTO)
help
This option is invisible, and will be selected automatically
when ``ESPTOOLPY_FLASHFREQ_120M`` is selected.

choice SPI_FLASH_HPM_DC
prompt "Support HPM using DC (READ DOCS FIRST)"
depends on SPI_FLASH_HPM_ON
default SPI_FLASH_HPM_DC_AUTO
help
This feature needs your bootloader to be compiled DC-aware (BOOTLOADER_FLASH_DC_AWARE=y). Otherwise the
chip will not be able to boot after a reset.

config SPI_FLASH_HPM_DC_AUTO
bool "Auto (Enable when bootloader support enabled (BOOTLOADER_FLASH_DC_AWARE))"
config SPI_FLASH_HPM_DC_DISABLE
bool "Disable (READ DOCS FIRST)"
endchoice

config SPI_FLASH_HPM_DC_ON
bool
default y if SPI_FLASH_HPM_DC_AUTO && BOOTLOADER_FLASH_DC_AWARE
help
This is a helper config for HPM. Whether HPM-DC is enabled is also determined by bootloader.
Invisible for users.

config SPI_FLASH_AUTO_SUSPEND
bool "Auto suspend long erase/write operations (READ DOCS FIRST)"
default n
depends on IDF_TARGET_ESP32C3 && !SPI_FLASH_USE_LEGACY_IMPL && !SPI_FLASH_ROM_IMPL
help
This option is disabled by default because it is supported only
for specific flash chips and for specific Espressif chips.
To evaluate if you can use this feature refer to
`Optional Features for Flash` > `Auto Suspend & Resume` of the `ESP-IDF Programming Guide`.

CAUTION: If you want to OTA to an app with this feature turned on, please make
sure the bootloader has the support for it. (later than IDF v4.3)

If you are using an official Espressif module, please contact Espressif Business support
to check if the module has the flash that support this feature installed.
Also refer to `Concurrency Constraints for Flash on SPI1` > `Flash Auto Suspend Feature`
before enabling this option.

endmenu
endmenu

menu "SPI Flash driver"

config SPI_FLASH_VERIFY_WRITE
Expand Down Expand Up @@ -147,20 +230,6 @@ menu "SPI Flash driver"
help
Defines how many ticks will be before returning to continue a erasing.

config SPI_FLASH_AUTO_SUSPEND
bool "Auto suspend long erase/write operations (READ DOCS FIRST)"
default n
depends on IDF_TARGET_ESP32C3 && !SPI_FLASH_USE_LEGACY_IMPL && !SPI_FLASH_ROM_IMPL
help
This option is default n before ESP32-C3, because it needs bootloader support.

CAUTION: If you want to OTA to an app with this feature turned on, please make
sure the bootloader has the support for it. (later than IDF v4.3)

Auto-suspend feature only supported by XMC chip.
If you are using an official module, please contact Espressif Business support.
Also reading auto suspend part in `SPI Flash API` document before you enable this function.

config SPI_FLASH_WRITE_CHUNK_SIZE
int "Flash write chunk size"
default 8192
Expand Down Expand Up @@ -279,22 +348,4 @@ menu "SPI Flash driver"
application is not using flash encryption feature and is in need of some additional
memory from IRAM region (~1KB) then this config can be disabled.

config SPI_FLASH_HPM_ENABLE
bool
default n
help
This option is invisible, and will be selected automatically
when ``ESPTOOLPY_FLASHFREQ_120M`` is selected.

config SPI_FLASH_32BIT_ADDRESS
bool
default y if ESPTOOLPY_FLASHSIZE_32MB || ESPTOOLPY_FLASHSIZE_64MB || ESPTOOLPY_FLASHSIZE_128MB
default n
help
This is a helper config for 32bits address flash. Invisible for users.

config SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE
bool
default y if ESPTOOLPY_OCT_FLASH && SPI_FLASH_32BIT_ADDRESS
default n
endmenu
6 changes: 3 additions & 3 deletions components/spi_flash/esp32s3/spi_timing_config.c
Expand Up @@ -146,8 +146,8 @@ static uint32_t spi_timing_config_get_dummy(void)
abort();
}

#if CONFIG_SPI_FLASH_HPM_ENABLE
if (spi_flash_hpm_dummy_adjust()) { // HPM is enabled
#if CONFIG_SPI_FLASH_HPM_DC_ON
if (spi_flash_hpm_dummy_adjust()) { // HPM-DC is enabled
const spi_flash_hpm_dummy_conf_t *hpm_dummy = spi_flash_hpm_get_dummy();
switch (ctrl_reg & MULTI_LINE_MASK_QUAD_FLASH) {
case SPI_FLASH_QIO_MODE:
Expand All @@ -167,7 +167,7 @@ static uint32_t spi_timing_config_get_dummy(void)
}
} else
#endif
{ // HPM is not enabled
{ // HPM-DC is not enabled
switch (ctrl_reg & MULTI_LINE_MASK_QUAD_FLASH) {
case SPI_FLASH_QIO_MODE:
return SPI1_R_QIO_DUMMY_CYCLELEN;
Expand Down
2 changes: 1 addition & 1 deletion components/spi_flash/esp_flash_spi_init.c
Expand Up @@ -333,7 +333,7 @@ esp_err_t esp_flash_init_default_chip(void)
}
#endif

#if CONFIG_SPI_FLASH_HPM_ENABLE
#if CONFIG_SPI_FLASH_HPM_DC_ON
if (spi_flash_hpm_dummy_adjust()) {
default_chip.hpm_dummy_ena = 1;
}
Expand Down
6 changes: 2 additions & 4 deletions components/spi_flash/flash_ops.c
Expand Up @@ -187,12 +187,10 @@ 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.
#if CONFIG_SPI_FLASH_HPM_ON
return spi_flash_enable_high_performance_mode();
#else
#endif // CONFIG_SPI_FLASH_HPM_ON
return ESP_OK;
#endif // CONFIG_IDF_TARGET_ESP32S3
#endif // CONFIG_ESPTOOLPY_OCT_FLASH
}

Expand Down
2 changes: 2 additions & 0 deletions components/spi_flash/include/esp_flash.h
Expand Up @@ -172,6 +172,8 @@ esp_err_t esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size);
esp_err_t esp_flash_get_physical_size(esp_flash_t *chip, uint32_t *flash_size);

/** @brief Read flash unique ID via the common "RDUID" SPI flash command.
*
* @note This is an optional feature, which is not supported on all flash chips. READ PROGRAMMING GUIDE FIRST!
*
* @param chip Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init().
* @param[out] out_id Pointer to receive unique ID value.
Expand Down

0 comments on commit 5684098

Please sign in to comment.