From bc60eb65e29bf8b6fb0a6fecc386a6ff4bb41315 Mon Sep 17 00:00:00 2001 From: chenjianqiang Date: Fri, 25 Jun 2021 17:02:20 +0800 Subject: [PATCH] psram: support for esp32-pico-v3-02 1. Support for 16Mbit PSRAM 2. Support for esp32-pico-v3-02 3. Use package identifier to look up SPI flash/PSRAM WP Pin, unless overridden Closes https://github.com/espressif/esp-idf/issues/7189 --- components/bootloader/Kconfig.projbuild | 30 ++++++++---- .../include/bootloader_flash_config.h | 15 ++++++ .../src/bootloader_flash_config.c | 47 ++++++++++++++----- .../bootloader_support/src/flash_qio_mode.c | 26 ++-------- components/esp32/Kconfig | 42 ++++++++++++----- components/esp32/cpu_start.c | 2 +- components/esp32/spiram.c | 8 ++-- components/esp32/spiram_psram.c | 23 +++++---- components/esp32/system_api.c | 3 +- components/soc/esp32/include/soc/efuse_reg.h | 1 + 10 files changed, 129 insertions(+), 68 deletions(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index a8b52e792d..58362a4228 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -28,20 +28,34 @@ menu "Bootloader config" default 4 if LOG_BOOTLOADER_LEVEL_DEBUG default 5 if LOG_BOOTLOADER_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 FLASHMODE_QIO || 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 FLASHMODE_QIO || 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 2f716cce2a..48e50de9a9 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,20 @@ void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr); */ void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr); +/** + * @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); + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/src/bootloader_flash_config.c b/components/bootloader_support/src/bootloader_flash_config.c index b3a3ed9d7e..842e3e97b1 100644 --- a/components/bootloader_support/src/bootloader_flash_config.c +++ b/components/bootloader_support/src/bootloader_flash_config.c @@ -25,6 +25,7 @@ #include "soc/spi_reg.h" #include "soc/spi_pins.h" #include "flash_qio_mode.h" +#include "bootloader_common.h" #include "bootloader_flash_config.h" void bootloader_flash_update_id() @@ -75,18 +76,11 @@ void IRAM_ATTR bootloader_flash_gpio_config(const esp_image_header_t* pfhdr) uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); uint32_t pkg_ver = chip_ver & 0x7; - if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) { - // For ESP32D2WD the SPI pins are already configured - // flash clock signal should come from IO MUX. - PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); - SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S); - } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) { - // For ESP32PICOD2 the SPI pins are already configured - // flash clock signal should come from IO MUX. - PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); - SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S); - } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) { - // For ESP32PICOD4 the SPI pins are already configured + if (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) { + // For ESP32D2WD or ESP32-PICO series,the SPI pins are already configured // flash clock signal should come from IO MUX. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S); @@ -163,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); +} + +#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_IOMUX_PIN_NUM_WP; + } +#endif } \ No newline at end of file diff --git a/components/bootloader_support/src/flash_qio_mode.c b/components/bootloader_support/src/flash_qio_mode.c index f7a0b414d7..09f6777a91 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" @@ -71,12 +72,6 @@ static unsigned read_status_8b_xmc25qu64a(); /* 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 @@ -169,22 +164,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 (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-PICOD4. - //Warn if chip is ESP32-D2WD/ESP32-PICOD4 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)) { - ESP_LOGW(TAG, "Chip is ESP32-D2WD/ESP32-PICOD4 but flash WP pin is different value to internal flash"); - } - } - esp_rom_spiflash_wait_idle(&g_rom_flashchip); status = read_status_fn(); @@ -218,7 +197,8 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn, esp_rom_spiflash_config_readmode(mode); - 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); return ESP_OK; } diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index cbc5059ecb..fb36fbe37a 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -112,6 +112,9 @@ menu "ESP32-specific" config SPIRAM_TYPE_AUTO bool "Auto-detect" + config SPIRAM_TYPE_ESPPSRAM16 + bool "ESP-PSRAM16 or APS1604" + config SPIRAM_TYPE_ESPPSRAM32 bool "ESP-PSRAM32 or IS25WP032" @@ -123,6 +126,7 @@ menu "ESP32-specific" config SPIRAM_SIZE int default -1 if SPIRAM_TYPE_AUTO + default 2097152 if SPIRAM_TYPE_ESPPSRAM16 default 4194304 if SPIRAM_TYPE_ESPPSRAM32 default 8388608 if SPIRAM_TYPE_ESPPSRAM64 default 0 @@ -340,23 +344,37 @@ menu "ESP32-specific" endmenu - config SPIRAM_SPIWP_SD3_PIN - int "SPI PSRAM WP(SD3) Pin when customising pins via eFuse (read help)" + config SPIRAM_CUSTOM_SPIWP_SD3_PIN + bool "Use custom SPI PSRAM WP(SD3) Pin when flash pins set in eFuse (read help)" depends on FLASHMODE_DIO || 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 "Custom SPI PSRAM WP(SD3) Pin" + depends on FLASHMODE_DIO || 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/cpu_start.c b/components/esp32/cpu_start.c index bc56b84d7d..0f8b7c795e 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -159,7 +159,6 @@ void IRAM_ATTR call_start_cpu0() } #if CONFIG_SPIRAM_BOOT_INIT - esp_spiram_init_cache(); if (esp_spiram_init() != ESP_OK) { #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY ESP_EARLY_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment"); @@ -174,6 +173,7 @@ void IRAM_ATTR call_start_cpu0() abort(); #endif } + esp_spiram_init_cache(); #endif #ifdef CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ diff --git a/components/esp32/spiram.c b/components/esp32/spiram.c index 7dacfa0503..ec6839437c 100644 --- a/components/esp32/spiram.c +++ b/components/esp32/spiram.c @@ -114,12 +114,14 @@ bool esp_spiram_test() void IRAM_ATTR esp_spiram_init_cache() { + int size = esp_spiram_get_size(); + if (size > 4 * 1024 * 1024) size = 4 * 1024 * 1024; // we can map at most 4MByte //Enable external RAM in MMU - cache_sram_mmu_set( 0, 0, SOC_EXTRAM_DATA_LOW, 0, 32, 128 ); + cache_sram_mmu_set(0, 0, SOC_EXTRAM_DATA_LOW, 0, 32, (size / 1024 / 32)); //Flush and enable icache for APP CPU #if !CONFIG_FREERTOS_UNICORE DPORT_CLEAR_PERI_REG_MASK(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DRAM1); - cache_sram_mmu_set( 1, 0, SOC_EXTRAM_DATA_LOW, 0, 32, 128 ); + cache_sram_mmu_set(1, 0, SOC_EXTRAM_DATA_LOW, 0, 32, (size / 1024 / 32)); #endif } @@ -127,7 +129,7 @@ esp_spiram_size_t esp_spiram_get_chip_size() { if (!spiram_inited) { ESP_EARLY_LOGE(TAG, "SPI RAM not initialized"); - return ESP_SPIRAM_SIZE_INVALID; + abort(); } psram_size_t psram_size = psram_get_size(); switch (psram_size) { diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index bb0ccd64d1..3c603d042a 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -37,6 +37,7 @@ #include "driver/spi_common.h" #include "driver/periph_ctrl.h" #include "bootloader_common.h" +#include "bootloader_flash_config.h" #if CONFIG_SPIRAM_SUPPORT #include "soc/rtc.h" @@ -121,6 +122,9 @@ typedef enum { #define PICO_PSRAM_CLK_IO 6 #define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO // Default value is 10 +#define PICO_V3_02_PSRAM_CLK_IO 10 +#define PICO_V3_02_PSRAM_CS_IO 9 + typedef struct { uint8_t flash_clk_io; uint8_t flash_cs_io; @@ -822,6 +826,16 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad s_clk_mode = PSRAM_CLK_MODE_NORM; psram_io.psram_clk_io = PICO_PSRAM_CLK_IO; psram_io.psram_cs_io = PICO_PSRAM_CS_IO; + } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302) { + ESP_EARLY_LOGI(TAG, "This chip is ESP32-PICO-V3-02"); + rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); + if (cfg.tieh != RTC_VDDSDIO_TIEH_3_3V) { + ESP_EARLY_LOGE(TAG, "VDDSDIO is not 3.3V"); + return ESP_FAIL; + } + s_clk_mode = PSRAM_CLK_MODE_NORM; + psram_io.psram_clk_io = PICO_V3_02_PSRAM_CLK_IO; + psram_io.psram_cs_io = PICO_V3_02_PSRAM_CS_IO; } else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ5)){ ESP_EARLY_LOGI(TAG, "This chip is ESP32-D0WD"); psram_io.psram_clk_io = D0WD_PSRAM_CLK_IO; @@ -852,14 +866,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_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."); diff --git a/components/esp32/system_api.c b/components/esp32/system_api.c index ec941dcac0..b36e451335 100644 --- a/components/esp32/system_api.c +++ b/components/esp32/system_api.c @@ -380,7 +380,8 @@ void esp_chip_info(esp_chip_info_t* out_info) int package = (efuse_rd3 & EFUSE_RD_CHIP_VER_PKG_M) >> EFUSE_RD_CHIP_VER_PKG_S; if (package == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 || package == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 || - package == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) { + package == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4 || + package == EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302) { out_info->features |= CHIP_FEATURE_EMB_FLASH; } } diff --git a/components/soc/esp32/include/soc/efuse_reg.h b/components/soc/esp32/include/soc/efuse_reg.h index bbe9677137..8aa78999b3 100644 --- a/components/soc/esp32/include/soc/efuse_reg.h +++ b/components/soc/esp32/include/soc/efuse_reg.h @@ -114,6 +114,7 @@ #define EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 2 #define EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 4 #define EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4 5 +#define EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302 6 /* EFUSE_RD_SPI_PAD_CONFIG_HD : RO ;bitpos:[8:4] ;default: 5'b0 ; */ /*description: read for SPI_pad_config_hd*/ #define EFUSE_RD_SPI_PAD_CONFIG_HD 0x0000001F