From bb7544e65aba750aad7dfd641a2b166b9e0a2ffe Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Thu, 12 Oct 2023 11:57:04 +0800 Subject: [PATCH] fix(ota): Fixed OTA fail on octal flash with 32MB memory, Closes https://github.com/espressif/esp-idf/issues/11903 --- .../include/bootloader_flash_override.h | 13 +++++++- .../include/bootloader_flash_priv.h | 2 ++ .../bootloader_flash/src/bootloader_flash.c | 29 +++++++++++++++++- .../src/bootloader_flash_config_esp32s3.c | 4 ++- components/esp_rom/patches/esp_rom_spiflash.c | 30 ++++++++++++++++++- components/spi_flash/Kconfig | 12 ++++++++ 6 files changed, 86 insertions(+), 4 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h index 8d161bd28c..6808fb9d1e 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -109,6 +109,17 @@ extern const bootloader_qio_info_t __attribute__((weak)) bootloader_flash_qe_sup */ esp_err_t __attribute__((weak)) bootloader_flash_unlock(void); +#if CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE +/** + * @brief Enable 32bits address flash(larger than 16MB) can map to cache. + * + * @param flash_mode SPI flash working mode. + * + * @note This can be overridden because it's attribute weak. + */ +void __attribute__((weak)) bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode); +#endif + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h index f46b87f63b..89edb7416e 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h @@ -52,6 +52,8 @@ extern "C" { #define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */ #define CMD_RESETEN 0x66 #define CMD_RESET 0x99 +#define CMD_FASTRD_4B 0x0C +#define CMD_SLOWRD_4B 0x13 /* Provide a Flash API for bootloader_support code, diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index c65076b705..4c547482c6 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -410,6 +410,33 @@ 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 +void bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode) +{ + esp_rom_opiflash_spi0rd_t cache_rd = {}; + switch (flash_mode) { + case ESP_ROM_SPIFLASH_FASTRD_MODE: + cache_rd.addr_bit_len = 32; + cache_rd.dummy_bit_len = 8; + cache_rd.cmd = CMD_FASTRD_4B; + cache_rd.cmd_bit_len = 8; + break; + case ESP_ROM_SPIFLASH_SLOWRD_MODE: + cache_rd.addr_bit_len = 32; + cache_rd.dummy_bit_len = 0; + cache_rd.cmd = CMD_SLOWRD_4B; + cache_rd.cmd_bit_len = 8; + break; + default: + assert(false); + break; + } + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + esp_rom_opiflash_cache_mode_config(flash_mode, &cache_rd); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); +} +#endif + #endif // BOOTLOADER_BUILD 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 151e469f3b..79b4b33ed4 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 @@ -272,7 +272,9 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_qio_mode(); } #endif - +#if CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE + bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); +#endif print_flash_info(&bootloader_image_hdr); update_flash_config(&bootloader_image_hdr); //ensure the flash is write-protected diff --git a/components/esp_rom/patches/esp_rom_spiflash.c b/components/esp_rom/patches/esp_rom_spiflash.c index 4c87e73bc2..fb525244db 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-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,9 @@ #include "esp32/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#include "esp32s3/rom/opi_flash.h" #endif #define SPI_IDX 1 @@ -697,6 +700,31 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_disable(void) return ESP_ROM_SPIFLASH_RESULT_OK; } +#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) +{ + esp_rom_spi_set_op_mode(0, mode); + REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI); + REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR); + + 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_USER_REG(0), SPI_MEM_USR_DUMMY); + } else { + REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY); + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, cache->dummy_bit_len - 1 + rom_spiflash_legacy_data->dummy_len_plus[0]); + } + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, cache->cmd); + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_BITLEN, cache->cmd_bit_len - 1); + REG_SET_FIELD(SPI_MEM_DDR_REG(0), SPI_MEM_SPI_FMEM_VAR_DUMMY, cache->var_dummy_en); + } +} + #endif // IDF_TARGET #endif // CONFIG_SPI_FLASH_ROM_DRIVER_PATCH diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 86112d67e1..8b36c6598e 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -311,4 +311,16 @@ menu "SPI Flash driver" 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