From a94685a22256c675a2d66a143e25ea6b164879f5 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 7 Jul 2020 14:35:52 +1000 Subject: [PATCH] esp32: Use package identifier to look up SPI flash/PSRAM WP Pin, unless overridden Allows booting in QIO/QOUT mode or with PSRAM on ESP32-PICO-V3 and ESP32-PICO-V3-O2 without any config changes. Custom WP pins (needed for fully custom circuit boards) should still be compatible. --- components/bootloader/Kconfig.projbuild | 32 +++++++++++----- .../include/bootloader_flash_config.h | 17 +++++++++ .../src/bootloader_flash_config_esp32.c | 32 +++++++++++++++- .../bootloader_support/src/flash_qio_mode.c | 35 ++--------------- components/esp32/Kconfig | 38 +++++++++++++------ components/esp32/spiram_psram.c | 10 +---- 6 files changed, 103 insertions(+), 61 deletions(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index b0dc4881bb..477ee662c4 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -53,20 +53,34 @@ 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. + + 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 "SPI Flash WP Pin when customising pins via eFuse (read help)" + int "Custom SPI Flash WP Pin" range 0 33 default 7 - depends on ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT + 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 - This value is ignored unless flash mode is set to QIO or QOUT *and* the SPI flash pins have been - overriden by setting the eFuses SPI_PAD_CONFIG_xxx. + 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. That pin number is compiled into the - bootloader instead. - - The default value (GPIO 7) is correct for WP pin on ESP32-D2WD integrated flash. + 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. choice BOOTLOADER_VDDSDIO_BOOST bool "VDDSDIO LDO voltage" diff --git a/components/bootloader_support/include/bootloader_flash_config.h b/components/bootloader_support/include/bootloader_flash_config.h index 98c169f48a..453677307f 100644 --- a/components/bootloader_support/include/bootloader_flash_config.h +++ b/components/bootloader_support/include/bootloader_flash_config.h @@ -14,6 +14,7 @@ #pragma once +#include "sdkconfig.h" #include "esp_image_format.h" #ifdef __cplusplus @@ -66,6 +67,22 @@ void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr); */ void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr); +#ifdef CONFIG_IDF_TARGET_ESP32 +/** + * @brief Return the pin number used for custom SPI flash and/or SPIRAM WP pin + * + * Can be determined by eFuse values in most cases, or overriden in configuration + * + * This value is only meaningful if the other SPI flash pins are overriden via eFuse. + * + * This value is only meaningful if flash is set to QIO or QOUT mode, or if + * SPIRAM is enabled. + * + * @return Pin number to use, or -1 if the default should be kept + */ +int bootloader_flash_get_wp_pin(void); +#endif + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/src/bootloader_flash_config_esp32.c b/components/bootloader_support/src/bootloader_flash_config_esp32.c index dcc8faadbf..6e8baa014b 100644 --- a/components/bootloader_support/src/bootloader_flash_config_esp32.c +++ b/components/bootloader_support/src/bootloader_flash_config_esp32.c @@ -25,6 +25,7 @@ #include "soc/spi_reg.h" #include "soc/spi_caps.h" #include "flash_qio_mode.h" +#include "bootloader_common.h" #include "bootloader_flash_config.h" void bootloader_flash_update_id(void) @@ -156,4 +157,33 @@ void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t* pfhdr) SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + g_rom_spiflash_dummy_len_plus[0], SPI_USR_DUMMY_CYCLELEN_S); -} \ No newline at end of file +} + +#define ESP32_D2WD_WP_GPIO 7 /* ESP32-D2WD & ESP32-PICO-D4 has this GPIO wired to WP pin of flash */ +#define ESP32_PICO_V3_GPIO 18 /* ESP32-PICO-V3* use this GPIO for WP pin of flash */ + +int bootloader_flash_get_wp_pin(void) +{ +#if CONFIG_BOOTLOADER_SPI_CUSTOM_WP_PIN + return CONFIG_BOOTLOADER_SPI_WP_PIN; // can be set for bootloader when QIO or QOUT config in use +#elif CONFIG_SPIRAM_CUSTOM_SPIWP_SD3_PIN + return CONFIG_SPIRAM_SPIWP_SD3_PIN; // can be set for app when DIO or DOUT config used for PSRAM only +#else + // no custom value, find it based on the package eFuse value + uint8_t chip_ver; + uint32_t pkg_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); + switch(pkg_ver) { + case EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5: + return ESP32_D2WD_WP_GPIO; + case EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2: + case EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4: + /* Same package IDs are used for ESP32-PICO-V3 and ESP32-PICO-D4, silicon version differentiates */ + chip_ver = bootloader_common_get_chip_revision(); + return (chip_ver < 3) ? ESP32_D2WD_WP_GPIO : ESP32_PICO_V3_GPIO; + case EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302: + return ESP32_PICO_V3_GPIO; + default: + return SPI_WP_GPIO_NUM; + } +#endif +} diff --git a/components/bootloader_support/src/flash_qio_mode.c b/components/bootloader_support/src/flash_qio_mode.c index 4c5bda6e65..a360e26f8d 100644 --- a/components/bootloader_support/src/flash_qio_mode.c +++ b/components/bootloader_support/src/flash_qio_mode.c @@ -13,6 +13,7 @@ // limitations under the License. #include #include +#include "bootloader_flash_config.h" #include "flash_qio_mode.h" #include "esp_log.h" #include "esp_err.h" @@ -84,12 +85,6 @@ static unsigned read_status_8b_xmc25qu64a(void); /* Write 8 bit status of XM25QU64A */ static void write_status_8b_xmc25qu64a(unsigned new_status); -#define ESP32_D2WD_WP_GPIO 7 /* ESP32-D2WD has this GPIO wired to WP pin of flash */ - -#ifndef CONFIG_BOOTLOADER_SPI_WP_PIN // Set in menuconfig if SPI flasher config is set to a quad mode -#define CONFIG_BOOTLOADER_SPI_WP_PIN ESP32_D2WD_WP_GPIO -#endif - /* Array of known flash chips and data to enable Quad I/O mode Manufacturer & flash ID can be tested by running "esptool.py @@ -224,25 +219,6 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn, uint32_t status; const uint32_t spiconfig = ets_efuse_get_spiconfig(); -#if CONFIG_IDF_TARGET_ESP32 - if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) { - // spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP, - // which is compiled into the bootloader instead. - // - // Most commonly an overriden pin mapping means ESP32-D2WD or ESP32-PICO series. - //Warn if chip is ESP32-D2WD/ESP32-PICO series but someone has changed the WP pin - //assignment from that chip's WP pin. - uint32_t pkg_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); - if (CONFIG_BOOTLOADER_SPI_WP_PIN != ESP32_D2WD_WP_GPIO && - (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 || - pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 || - pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4 || - pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302)) { - ESP_LOGW(TAG, "Chip is ESP32-D2WD/ESP32-PICO series, but flash WP pin is different value to internal flash"); - } - } -#endif - esp_rom_spiflash_wait_idle(&g_rom_flashchip); status = read_status_fn(); @@ -277,13 +253,10 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn, esp_rom_spiflash_config_readmode(mode); #if CONFIG_IDF_TARGET_ESP32 - esp_rom_spiflash_select_qio_pins(CONFIG_BOOTLOADER_SPI_WP_PIN, spiconfig); + int wp_pin = bootloader_flash_get_wp_pin(); + esp_rom_spiflash_select_qio_pins(wp_pin, spiconfig); #elif CONFIG_IDF_TARGET_ESP32S2 - if (ets_efuse_get_wp_pad() <= MAX_PAD_GPIO_NUM) { - esp_rom_spiflash_select_qio_pins(ets_efuse_get_wp_pad(), spiconfig); - } else { - esp_rom_spiflash_select_qio_pins(CONFIG_BOOTLOADER_SPI_WP_PIN, spiconfig); - } + esp_rom_spiflash_select_qio_pins(ets_efuse_get_wp_pad(), spiconfig); #endif return ESP_OK; } diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 995fee1efe..a76a693352 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -283,23 +283,37 @@ menu "ESP32-specific" endmenu + config SPIRAM_CUSTOM_SPIWP_SD3_PIN + bool "Use custom SPI PSRAM WP(SD3) Pin when flash pins set in eFuse (read help)" + depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_DIO || ESPTOOLPY_FLASHMODE_DOUT) + default y if SPIRAM_SPIWP_SD3_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 DIO or DOUT. + + 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 psram only has QPI + mode, so a WP pin setting is necessary. + + 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 pin. + + When flash mode is set to QIO or QOUT, the PSRAM WP pin will be set the same as the SPI Flash WP pin + configured in the bootloader. + config SPIRAM_SPIWP_SD3_PIN - int "SPI PSRAM WP(SD3) Pin when customising pins via eFuse (read help)" - depends on ESPTOOLPY_FLASHMODE_DIO || ESPTOOLPY_FLASHMODE_DOUT + int "Custom SPI PSRAM WP(SD3) Pin" + depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_DIO || ESPTOOLPY_FLASHMODE_DOUT) + #depends on SPIRAM_CUSTOM_SPIWP_SD3_PIN # backwards compatibility, can uncomment in IDF 5 range 0 33 default 7 help - This value is ignored unless flash mode is set to DIO or DOUT and the SPI flash pins have been - overriden by setting the eFuses SPI_PAD_CONFIG_xxx. + The option "Use custom SPI PSRAM WP(SD3) 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. And the psram only has QPI - mode, the WP pin is necessary, so we need to configure this value here. - - When flash mode is set to QIO or QOUT, the PSRAM WP pin will be set as the value configured in - bootloader. - - For ESP32-PICO chip, the default value of this config should be 7. + If burning a customized set of SPI flash pins in eFuse and using DIO or DOUT mode for flash, set this + value to the GPIO number of the SPIRAM WP pin. config SPIRAM_2T_MODE bool "Enable SPI PSRAM 2T mode" diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index ae19d75eaa..b63fbcd631 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -36,6 +36,7 @@ #include "driver/spi_common_internal.h" #include "driver/periph_ctrl.h" #include "bootloader_common.h" +#include "bootloader_flash_config.h" #if CONFIG_SPIRAM #include "soc/rtc.h" @@ -864,14 +865,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad psram_io.psram_spiq_sd0_io = EFUSE_SPICONFIG_RET_SPIQ(spiconfig); psram_io.psram_spid_sd1_io = EFUSE_SPICONFIG_RET_SPID(spiconfig); psram_io.psram_spihd_sd2_io = EFUSE_SPICONFIG_RET_SPIHD(spiconfig); - - // If flash mode is set to QIO or QOUT, the WP pin is equal the value configured in bootloader. - // If flash mode is set to DIO or DOUT, the WP pin should config it via menuconfig. - #if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_FLASHMODE_QOUT - psram_io.psram_spiwp_sd3_io = CONFIG_BOOTLOADER_SPI_WP_PIN; - #else - psram_io.psram_spiwp_sd3_io = CONFIG_SPIRAM_SPIWP_SD3_PIN; - #endif + psram_io.psram_spiwp_sd3_io = bootloader_flash_get_wp_pin(); } assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now.");