diff --git a/components/bootloader_support/include/bootloader_common.h b/components/bootloader_support/include/bootloader_common.h index d18b97ceb..405c94c02 100644 --- a/components/bootloader_support/include/bootloader_common.h +++ b/components/bootloader_support/include/bootloader_common.h @@ -136,3 +136,8 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, * - ESP_FAIL: mapping is fail. */ esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc); + +/** + * @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode. + */ +void bootloader_common_vddsdio_configure(); diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index 29e591d1a..aa64db482 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/components/bootloader_support/src/bootloader_common.c @@ -27,6 +27,8 @@ #include "bootloader_flash.h" #include "bootloader_common.h" #include "soc/gpio_periph.h" +#include "soc/efuse_reg.h" +#include "soc/rtc.h" #include "esp_image_format.h" #include "bootloader_sha.h" #include "sys/param.h" @@ -257,3 +259,18 @@ esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t return ESP_OK; } + +void bootloader_common_vddsdio_configure() +{ +#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V + rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); + if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V + cfg.drefh = 3; + cfg.drefm = 3; + cfg.drefl = 3; + cfg.force = 1; + rtc_vddsdio_set_config(cfg); + ets_delay_us(10); // wait for regulator to become stable + } +#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST +} diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 5ae8a5e81..5d1835334 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -48,6 +48,7 @@ #include "bootloader_random.h" #include "bootloader_config.h" #include "bootloader_clock.h" +#include "bootloader_common.h" #include "flash_qio_mode.h" @@ -61,7 +62,6 @@ static const char* TAG = "boot"; static esp_err_t bootloader_main(); static void print_flash_info(const esp_image_header_t* pfhdr); static void update_flash_config(const esp_image_header_t* pfhdr); -static void vddsdio_configure(); static void flash_gpio_configure(const esp_image_header_t* pfhdr); static void uart_console_configure(void); static void wdt_reset_check(void); @@ -117,7 +117,7 @@ esp_err_t bootloader_init() static esp_err_t bootloader_main() { - vddsdio_configure(); + bootloader_common_vddsdio_configure(); /* Read and keep flash ID, for further use. */ g_rom_flashchip.device_id = bootloader_read_flash_id(); esp_image_header_t fhdr; @@ -285,21 +285,6 @@ static void print_flash_info(const esp_image_header_t* phdr) #endif } -static void vddsdio_configure() -{ -#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V - rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); - if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V - cfg.drefh = 3; - cfg.drefm = 3; - cfg.drefl = 3; - cfg.force = 1; - rtc_vddsdio_set_config(cfg); - ets_delay_us(10); // wait for regulator to become stable - } -#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST -} - #define FLASH_CLK_IO 6 #define FLASH_CS_IO 11 #define FLASH_SPIQ_IO 7 diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index a1fc6a2c5..3d0a96d4f 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -239,16 +239,84 @@ menu "ESP32-specific" bool "VSPI host (SPI3)" endchoice - config PICO_PSRAM_CS_IO - int "PSRAM CS IO for ESP32-PICO chip" - depends on SPIRAM_SUPPORT - range 0 33 - default 10 - help - When ESP32-PICO chip connect a external psram, the clock IO and data IO is fixed, but the CS IO can be - any unused GPIO, user can config it based on hardware design. + menu "PSRAM clock and cs IO for ESP32-DOWD" - endmenu + config D0WD_PSRAM_CLK_IO + int "PSRAM CLK IO number" + depends on SPIRAM_SUPPORT + range 0 33 + default 17 + help + The PSRAM CLOCK IO can be any unused GPIO, user can config it based on hardware design. If user use + 1.8V flash and 1.8V psram, this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17. + + config D0WD_PSRAM_CS_IO + int "PSRAM CS IO number" + depends on SPIRAM_SUPPORT + range 0 33 + default 16 + help + The PSRAM CS IO can be any unused GPIO, user can config it based on hardware design. If user use + 1.8V flash and 1.8V psram, this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17. + endmenu + + menu "PSRAM clock and cs IO for ESP32-D2WD" + + config D2WD_PSRAM_CLK_IO + int "PSRAM CLK IO number" + depends on SPIRAM_SUPPORT + range 0 33 + default 9 + help + User can config it based on hardware design. For ESP32-D2WD chip, the psram can only be 1.8V psram, + so this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17. + + config D2WD_PSRAM_CS_IO + int "PSRAM CS IO number" + depends on SPIRAM_SUPPORT + range 0 33 + default 10 + help + User can config it based on hardware design. For ESP32-D2WD chip, the psram can only be 1.8V psram, + so this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17. + endmenu + + menu "PSRAM clock and cs IO for ESP32-PICO" + + config PICO_PSRAM_CS_IO + int "PSRAM CS IO number" + depends on SPIRAM_SUPPORT + range 0 33 + default 10 + help + The PSRAM CS IO can be any unused GPIO, user can config it based on hardware design. + + For ESP32-PICO chip, the psram share clock with flash, so user do not need to configure the clock + IO. + For the reference hardware design, please refer to + https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf + + endmenu + + 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 + 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. + + 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. + + endmenu # "SPI RAM config" config MEMMAP_TRACEMEM bool diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index cbc25b09e..20773546c 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -28,6 +28,7 @@ #include "rom/spi_flash.h" #include "rom/gpio.h" #include "rom/cache.h" +#include "rom/efuse.h" #include "soc/io_mux_reg.h" #include "soc/dport_reg.h" #include "soc/gpio_sig_map.h" @@ -35,6 +36,7 @@ #include "driver/gpio.h" #include "driver/spi_common.h" #include "driver/periph_ctrl.h" +#include "bootloader_common.h" #if CONFIG_SPIRAM_SUPPORT #include "soc/rtc.h" @@ -94,43 +96,36 @@ typedef enum { // WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines // hardcode the flash pins as well, making this code incompatible with either a setup // that has the flash on non-standard pins or ESP32s with built-in flash. -#define FLASH_CLK_IO 6 +#define FLASH_CLK_IO 6 #define FLASH_CS_IO 11 -#define FLASH_SPIQ_SD0_IO 7 -#define FLASH_SPID_SD1_IO 8 -#define FLASH_SPIWP_SD3_IO 10 -#define FLASH_SPIHD_SD2_IO 9 - -#define PSRAM_CLK_IO 17 -#define PSRAM_CS_IO 16 -#define PSRAM_SPIQ_SD0_IO 7 -#define PSRAM_SPID_SD1_IO 8 +#define PSRAM_SPIQ_SD0_IO 7 +#define PSRAM_SPID_SD1_IO 8 #define PSRAM_SPIWP_SD3_IO 10 -#define PSRAM_SPIHD_SD2_IO 9 +#define PSRAM_SPIHD_SD2_IO 9 -// IO-pins of ESP32-PICO-D4 for PSRAM. PSRAM share clock with flash. -// The CS IO can be overwrite via menuconfig. -#define PICO_FLASH_CLK_IO 6 -#define PICO_FLASH_CS_IO 16 -#define PICO_FLASH_SPIQ_SD0_IO 17 -#define PICO_FLASH_SPID_SD1_IO 8 -#define PICO_FLASH_SPIWP_SD3_IO 7 -#define PICO_FLASH_SPIHD_SD2_IO 11 +#define FLASH_HSPI_CLK_IO 14 +#define FLASH_HSPI_CS_IO 15 +#define PSRAM_HSPI_SPIQ_SD0_IO 12 +#define PSRAM_HSPI_SPID_SD1_IO 13 +#define PSRAM_HSPI_SPIWP_SD3_IO 2 +#define PSRAM_HSPI_SPIHD_SD2_IO 4 -#define PICO_PSRAM_CLK_IO 6 -#define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO -#define PICO_PSRAM_SPIQ_SD0_IO 17 -#define PICO_PSRAM_SPID_SD1_IO 8 -#define PICO_PSRAM_SPIWP_SD3_IO 7 -#define PICO_PSRAM_SPIHD_SD2_IO 11 +// PSRAM clock and cs IO should be configured based on hardware design. +// For ESP32-WROVER or ESP32-WROVER-B module, the clock IO is IO17, the cs IO is IO16, +// they are the default value for these two configs. +#define D0WD_PSRAM_CLK_IO CONFIG_D0WD_PSRAM_CLK_IO // Default value is 17 +#define D0WD_PSRAM_CS_IO CONFIG_D0WD_PSRAM_CS_IO // Default value is 16 + +#define D2WD_PSRAM_CLK_IO CONFIG_D2WD_PSRAM_CLK_IO // Default value is 9 +#define D2WD_PSRAM_CS_IO CONFIG_D2WD_PSRAM_CS_IO // Default value is 10 + +// For ESP32-PICO chip, the psram share clock with flash. The flash clock pin is fixed, which is IO6. +#define PICO_PSRAM_CLK_IO 6 +#define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO // Default value is 10 typedef struct { uint8_t flash_clk_io; uint8_t flash_cs_io; - uint8_t flash_spiq_sd0_io; - uint8_t flash_spid_sd1_io; - uint8_t flash_spiwp_sd3_io; - uint8_t flash_spihd_sd2_io; uint8_t psram_clk_io; uint8_t psram_cs_io; uint8_t psram_spiq_sd0_io; @@ -491,7 +486,6 @@ void psram_set_cs_timing(psram_spi_num_t spi_num, psram_clk_mode_t clk_mode) void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_mode_t mode) { CLEAR_PERI_REG_MASK(SPI_SLAVE_REG(spi_num), SPI_TRANS_DONE << 5); - SET_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_CS_SETUP); // SPI_CPOL & SPI_CPHA CLEAR_PERI_REG_MASK(SPI_PIN_REG(spi_num), SPI_CK_IDLE_EDGE); CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_CK_OUT_EDGE); @@ -508,11 +502,8 @@ void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_mode_t mode) psram_set_cs_timing(spi_num, s_clk_mode); } -/* - * Psram mode init will overwrite original flash speed mode, so that it is possible to change psram and flash speed after OTA. - * Flash read mode(QIO/QOUT/DIO/DOUT) will not be changed in app bin. It is decided by bootloader, OTA can not change this mode. - */ -static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t mode) +//psram gpio init , different working frequency we have different solutions +static void IRAM_ATTR psram_gpio_config(psram_io_t *psram_io, psram_cache_mode_t mode) { int spi_cache_dummy = 0; uint32_t rd_mode_reg = READ_PERI_REG(SPI_CTRL_REG(0)); @@ -523,17 +514,6 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t } else { spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; } - // In bootloader, all the signals are already configured, - // We keep the following code in case the bootloader is some older version. - gpio_matrix_out(psram_io.flash_cs_io, SPICS0_OUT_IDX, 0, 0); - gpio_matrix_out(psram_io.psram_spiq_sd0_io, SPIQ_OUT_IDX, 0, 0); - gpio_matrix_in(psram_io.psram_spiq_sd0_io, SPIQ_IN_IDX, 0); - gpio_matrix_out(psram_io.psram_spid_sd1_io, SPID_OUT_IDX, 0, 0); - gpio_matrix_in(psram_io.psram_spid_sd1_io, SPID_IN_IDX, 0); - gpio_matrix_out(psram_io.psram_spiwp_sd3_io, SPIWP_OUT_IDX, 0, 0); - gpio_matrix_in(psram_io.psram_spiwp_sd3_io, SPIWP_IN_IDX, 0); - gpio_matrix_out(psram_io.psram_spihd_sd2_io, SPIHD_OUT_IDX, 0, 0); - gpio_matrix_in(psram_io.psram_spihd_sd2_io, SPIHD_IN_IDX, 0); switch (mode) { case PSRAM_CACHE_F80M_S40M: @@ -544,8 +524,8 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT); esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT); //set drive ability for clock - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV, 3, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV, 2, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV, 2, FUN_DRV_S); break; case PSRAM_CACHE_F80M_S80M: extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M; @@ -555,8 +535,8 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT); esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_FLASH_PORT); //set drive ability for clock - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV, 3, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV, 3, FUN_DRV_S); break; case PSRAM_CACHE_F40M_S40M: extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M; @@ -566,36 +546,54 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_CACHE_PORT); esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT); //set drive ability for clock - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV, 2, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV, 2, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV, 2, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV, 2, FUN_DRV_S); break; default: break; } - SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_USR_DUMMY); // dummy en + SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_USR_DUMMY); // dummy enable + // In bootloader, all the signals are already configured, + // We keep the following code in case the bootloader is some older version. + gpio_matrix_out(psram_io->flash_cs_io, SPICS0_OUT_IDX, 0, 0); + gpio_matrix_out(psram_io->psram_cs_io, SPICS1_OUT_IDX, 0, 0); + gpio_matrix_out(psram_io->psram_spiq_sd0_io, SPIQ_OUT_IDX, 0, 0); + gpio_matrix_in(psram_io->psram_spiq_sd0_io, SPIQ_IN_IDX, 0); + gpio_matrix_out(psram_io->psram_spid_sd1_io, SPID_OUT_IDX, 0, 0); + gpio_matrix_in(psram_io->psram_spid_sd1_io, SPID_IN_IDX, 0); + gpio_matrix_out(psram_io->psram_spiwp_sd3_io, SPIWP_OUT_IDX, 0, 0); + gpio_matrix_in(psram_io->psram_spiwp_sd3_io, SPIWP_IN_IDX, 0); + gpio_matrix_out(psram_io->psram_spihd_sd2_io, SPIHD_OUT_IDX, 0, 0); + gpio_matrix_in(psram_io->psram_spihd_sd2_io, SPIHD_IN_IDX, 0); + //select pin function gpio - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spiq_sd0_io], PIN_FUNC_GPIO); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spid_sd1_io], PIN_FUNC_GPIO); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spihd_sd2_io], PIN_FUNC_GPIO); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spiwp_sd3_io], PIN_FUNC_GPIO); - //flash clock signal should come from IO MUX. - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUNC_SD_CLK_SPICLK); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_cs_io], PIN_FUNC_GPIO); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.psram_cs_io], PIN_FUNC_GPIO); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], PIN_FUNC_GPIO); + if ((psram_io->flash_clk_io == FLASH_CLK_IO) && (psram_io->flash_clk_io != psram_io->psram_clk_io)) { + //flash clock signal should come from IO MUX. + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUNC_SD_CLK_SPICLK); + } else { + //flash clock signal should come from GPIO matrix. + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], PIN_FUNC_GPIO); + } + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->flash_cs_io], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_cs_io], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_spiq_sd0_io], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_spid_sd1_io], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_spihd_sd2_io], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_spiwp_sd3_io], PIN_FUNC_GPIO); uint32_t flash_id = g_rom_flashchip.device_id; if (flash_id == FLASH_ID_GD25LQ32C) { // Set drive ability for 1.8v flash in 80Mhz. - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spiq_sd0_io], FUN_DRV_V, 3, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spid_sd1_io], FUN_DRV_V, 3, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spihd_sd2_io], FUN_DRV_V, 3, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spiwp_sd3_io], FUN_DRV_V, 3, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_cs_io], FUN_DRV_V, 3, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV_V, 3, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_cs_io], FUN_DRV_V, 3, FUN_DRV_S); - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV_V, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_cs_io], FUN_DRV_V, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV_V, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_cs_io], FUN_DRV_V, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV_V, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spiq_sd0_io], FUN_DRV_V, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spid_sd1_io], FUN_DRV_V, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spihd_sd2_io], FUN_DRV_V, 3, FUN_DRV_S); + SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spiwp_sd3_io], FUN_DRV_V, 3, FUN_DRV_S); } } @@ -612,15 +610,24 @@ psram_size_t psram_get_size() } } -//psram gpio init , different working frequency we have different solutions +/* + * Psram mode init will overwrite original flash speed mode, so that it is possible to change psram and flash speed after OTA. + * Flash read mode(QIO/QOUT/DIO/DOUT) will not be changed in app bin. It is decided by bootloader, OTA can not change this mode. + */ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode) //psram init { psram_io_t psram_io; 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) { - ESP_EARLY_LOGE(TAG, "ESP32D2WD do not support psram yet"); - return ESP_FAIL; + ESP_EARLY_LOGI(TAG, "This chip is ESP32-D2WD"); + rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); + if (cfg.tieh != RTC_VDDSDIO_TIEH_1_8V) { + ESP_EARLY_LOGE(TAG, "VDDSDIO is not 1.8V"); + return ESP_FAIL; + } + psram_io.psram_clk_io = D2WD_PSRAM_CLK_IO; + psram_io.psram_cs_io = D2WD_PSRAM_CS_IO; } else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) { ESP_EARLY_LOGI(TAG, "This chip is ESP32-PICO"); rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); @@ -628,36 +635,46 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad ESP_EARLY_LOGE(TAG, "VDDSDIO is not 3.3V"); return ESP_FAIL; } - psram_io.flash_clk_io = PICO_FLASH_CLK_IO; - psram_io.flash_cs_io = PICO_FLASH_CS_IO; - psram_io.flash_spiq_sd0_io = PICO_FLASH_SPIQ_SD0_IO; - psram_io.flash_spid_sd1_io = PICO_FLASH_SPID_SD1_IO; - psram_io.flash_spiwp_sd3_io = PICO_FLASH_SPIWP_SD3_IO; - psram_io.flash_spihd_sd2_io = PICO_FLASH_SPIHD_SD2_IO; - psram_io.psram_clk_io = PICO_PSRAM_CLK_IO; - psram_io.psram_cs_io = PICO_PSRAM_CS_IO; - psram_io.psram_spiq_sd0_io = PICO_PSRAM_SPIQ_SD0_IO; - psram_io.psram_spid_sd1_io = PICO_PSRAM_SPID_SD1_IO; - psram_io.psram_spiwp_sd3_io = PICO_PSRAM_SPIWP_SD3_IO; - psram_io.psram_spihd_sd2_io = PICO_PSRAM_SPIHD_SD2_IO; - s_clk_mode = PSRAM_CLK_MODE_NORM; - } else { + 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_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; + psram_io.psram_cs_io = D0WD_PSRAM_CS_IO; + } + + const uint32_t spiconfig = ets_efuse_get_spiconfig(); + if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) { psram_io.flash_clk_io = FLASH_CLK_IO; psram_io.flash_cs_io = FLASH_CS_IO; - psram_io.flash_spiq_sd0_io = FLASH_SPIQ_SD0_IO; - psram_io.flash_spid_sd1_io = FLASH_SPID_SD1_IO; - psram_io.flash_spiwp_sd3_io = FLASH_SPIWP_SD3_IO; - psram_io.flash_spihd_sd2_io = FLASH_SPIHD_SD2_IO; - psram_io.psram_clk_io = PSRAM_CLK_IO; - psram_io.psram_cs_io = PSRAM_CS_IO; psram_io.psram_spiq_sd0_io = PSRAM_SPIQ_SD0_IO; psram_io.psram_spid_sd1_io = PSRAM_SPID_SD1_IO; psram_io.psram_spiwp_sd3_io = PSRAM_SPIWP_SD3_IO; psram_io.psram_spihd_sd2_io = PSRAM_SPIHD_SD2_IO; + } else if (spiconfig == EFUSE_SPICONFIG_HSPI_DEFAULTS) { + psram_io.flash_clk_io = FLASH_HSPI_CLK_IO; + psram_io.flash_cs_io = FLASH_HSPI_CS_IO; + psram_io.psram_spiq_sd0_io = PSRAM_HSPI_SPIQ_SD0_IO; + psram_io.psram_spid_sd1_io = PSRAM_HSPI_SPID_SD1_IO; + psram_io.psram_spiwp_sd3_io = PSRAM_HSPI_SPIWP_SD3_IO; + psram_io.psram_spihd_sd2_io = PSRAM_HSPI_SPIHD_SD2_IO; + } else { + psram_io.flash_clk_io = EFUSE_SPICONFIG_RET_SPICLK(spiconfig); + psram_io.flash_cs_io = EFUSE_SPICONFIG_RET_SPICS0(spiconfig); + 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 } - WRITE_PERI_REG(GPIO_ENABLE_W1TC_REG, BIT(psram_io.psram_clk_io) | BIT(psram_io.psram_cs_io)); //DISABLE OUPUT FOR IO16/17 assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now."); s_psram_mode = mode; @@ -666,7 +683,6 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad psram_spi_init(PSRAM_SPI_1, mode); - gpio_matrix_out(psram_io.psram_cs_io, SPICS1_OUT_IDX, 0, 0); switch (mode) { case PSRAM_CACHE_F80M_S80M: gpio_matrix_out(psram_io.psram_clk_io, SPICLK_OUT_IDX, 0, 0); @@ -691,25 +707,16 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad } break; } - #if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V - // For flash 80Mhz, we must update ldo voltage in case older version of bootloader didn't do this. - rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); - if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V - cfg.drefh = 3; - cfg.drefm = 3; - cfg.drefl = 3; - cfg.force = 1; - rtc_vddsdio_set_config(cfg); - ets_delay_us(10); // wait for regulator to become stable - } - #endif + + // Rise VDDSIO for 1.8V psram. + bootloader_common_vddsdio_configure(); // GPIO related settings - psram_gpio_config(psram_io, mode); + psram_gpio_config(&psram_io, mode); psram_read_id(&s_psram_id); if (!PSRAM_IS_VALID(s_psram_id)) { return ESP_FAIL; } - + if (PSRAM_IS_32MBIT_VER0(s_psram_id)) { s_clk_mode = PSRAM_CLK_MODE_DCLK; if (mode == PSRAM_CACHE_F80M_S80M) { @@ -776,42 +783,43 @@ static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psra CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(30)); //pre clk div break; } - SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_WCMD_M); // cache write command enable - SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_ADDR_BITLEN_V, 23, SPI_SRAM_ADDR_BITLEN_S); //write address for cache command. - SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_QIO_M); //enable qio mode for cache command - CLEAR_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_DIO_M); //disable dio mode for cache command - SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_RD_SRAM_DUMMY_M); //enable cache read dummy - SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_RCMD_M); //enable user mode for cache read command + CLEAR_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_DIO_M); //disable dio mode for cache command + SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_QIO_M); //enable qio mode for cache command + SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_RCMD_M); //enable cache read command + SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_WCMD_M); //enable cache write command + SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_ADDR_BITLEN_V, 23, SPI_SRAM_ADDR_BITLEN_S); //write address for cache command. + SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_RD_SRAM_DUMMY_M); //enable cache read dummy + + //config sram cache r/w command + SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 7, + SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S); + SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, PSRAM_FAST_READ_QUAD, + SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0xEB SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 7, SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S); SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, PSRAM_QUAD_WRITE, SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38 - SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 7, - SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S); - SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, PSRAM_FAST_READ_QUAD, - SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0x0b SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy, - SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy + SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy; 80m--+2dummy - //config sram cache r/w command switch (psram_cache_mode) { case PSRAM_CACHE_F80M_S80M: //in this mode , no delay is needed break; - case PSRAM_CACHE_F80M_S40M: //is sram is @40M, need 2 cycles of delay + case PSRAM_CACHE_F80M_S40M: //if sram is @40M, need 2 cycles of delay case PSRAM_CACHE_F40M_S40M: default: if (s_clk_mode == PSRAM_CLK_MODE_DCLK) { SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 15, SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S); //read command length, 2 bytes(1byte for delay),sending in qio mode in cache SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, ((PSRAM_FAST_READ_QUAD) << 8), - SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0x0b, read command value,(0x00 for delay,0x0b for cmd) + SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0xEB, read command value,(0x00 for delay,0xeb for cmd) SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 15, SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S); //write command length,2 bytes(1byte for delay,send in qio mode in cache) SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, ((PSRAM_QUAD_WRITE) << 8), SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38, write command value,(0x00 for delay) SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy, - SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy + SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy; 80m--+2dummy } break; }