diff --git a/components/bootloader_support/include/bootloader_common.h b/components/bootloader_support/include/bootloader_common.h index 2f4e906220..1a641be10e 100644 --- a/components/bootloader_support/include/bootloader_common.h +++ b/components/bootloader_support/include/bootloader_common.h @@ -26,7 +26,7 @@ extern "C" { #endif -/// Type of hold a GPIO in low state +// Type of hold a GPIO in low state typedef enum { GPIO_LONG_HOLD = 1, /*!< The long hold GPIO */ GPIO_SHORT_HOLD = -1, /*!< The short hold GPIO */ diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index a48cf131ec..2a2b6eaa33 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -22,7 +22,7 @@ menu "Hardware Settings" config ESP_SLEEP_POWER_DOWN_FLASH bool "Power down flash in light sleep when there is no SPIRAM" depends on !SPIRAM - default y + default n help If enabled, chip will try to power down flash as part of esp_light_sleep_start(), which costs more time when chip wakes up. Can only be enabled if there is no SPIRAM configured. @@ -58,6 +58,7 @@ menu "Hardware Settings" config ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND bool "PSRAM leakage current workaround in light sleep" depends on SPIRAM + default y help When the CS pin of SPIRAM is not pulled up, the sleep current will increase during light sleep. If the CS pin of SPIRAM has an external @@ -66,11 +67,21 @@ menu "Hardware Settings" config ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND bool "Flash leakage current workaround in light sleep" + default y help When the CS pin of Flash is not pulled up, the sleep current will increase during light sleep. If the CS pin of Flash has an external pull-up, you do not need to select this option, otherwise, you should enable this option. + + config ESP_SLEEP_MSPI_NEED_ALL_IO_PU + bool "All pins of mspi need pull up" + depends on ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND || ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND + default y if IDF_TARGET_ESP32S3 + help + To reduce leakage current, some types of SPI Flash/RAM only need to pull up the CS pin + during light sleep. But there are also some kinds of SPI Flash/RAM that need to pull up + all pins. It depends on the SPI Flash/RAM chip used. endmenu menu "RTC Clock Config" diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index b9f874c3c6..ae4cede0f0 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,15 +19,7 @@ #include "driver/gpio.h" #include "esp_private/gpio.h" #include "esp_private/sleep_gpio.h" -#include "bootloader_common.h" - -#ifdef CONFIG_IDF_TARGET_ESP32 -#include "esp32/spiram.h" -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/spiram.h" -#elif CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/spiram.h" -#endif +#include "esp_private/spi_flash_os.h" static const char *TAG = "sleep"; @@ -55,24 +47,41 @@ IRAM_ATTR void gpio_sleep_mode_config_unapply(void) void esp_sleep_config_gpio_isolate(void) { - ESP_LOGI(TAG, "Configure to isolate all GPIO pins in sleep state"); + ESP_EARLY_LOGI(TAG, "Configure to isolate all GPIO pins in sleep state"); for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) { if (GPIO_IS_VALID_GPIO(gpio_num)) { gpio_sleep_set_direction(gpio_num, GPIO_MODE_DISABLE); gpio_sleep_set_pull_mode(gpio_num, GPIO_FLOATING); } } + #if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM - gpio_sleep_set_pull_mode(esp_spiram_get_cs_io(), GPIO_PULLUP_ONLY); -#endif + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_CS1), GPIO_PULLUP_ONLY); +#endif // CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM + #if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND - gpio_sleep_set_pull_mode(bootloader_flash_get_cs_io(), GPIO_PULLUP_ONLY); -#endif + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_CS0), GPIO_PULLUP_ONLY); +#endif // CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND + +#if CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_CLK), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_Q), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_HD), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_WP), GPIO_PULLUP_ONLY); +#if CONFIG_SPIRAM_MODE_OCT || CONFIG_ESPTOOLPY_FLASHMODE_OPI + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_DQS), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D4), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D5), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D6), GPIO_PULLUP_ONLY); + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D7), GPIO_PULLUP_ONLY); +#endif // CONFIG_SPIRAM_MODE_OCT || CONFIG_ESPTOOLPY_FLASHMODE_OPI +#endif // CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU } void esp_sleep_enable_gpio_switch(bool enable) { - ESP_LOGI(TAG, "%s automatic switching of GPIO sleep configuration", enable ? "Enable" : "Disable"); + ESP_EARLY_LOGI(TAG, "%s automatic switching of GPIO sleep configuration", enable ? "Enable" : "Disable"); for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) { if (GPIO_IS_VALID_GPIO(gpio_num)) { if (enable) { diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 0b975263b7..ccb2469800 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -11,12 +11,14 @@ if(target STREQUAL "linux") "${target}/esp_rom_crc.c" "${target}/esp_rom_md5.c" "${target}/esp_rom_efuse.c") + list(APPEND include_dirs "${IDF_PATH}/tools/mocks/soc/include") else() list(APPEND include_dirs "${target}") list(APPEND sources "patches/esp_rom_crc.c" "patches/esp_rom_sys.c" "patches/esp_rom_uart.c" - "patches/esp_rom_tjpgd.c") + "patches/esp_rom_tjpgd.c" + "patches/esp_rom_efuse.c") list(APPEND private_required_comp soc hal) endif() diff --git a/components/esp_rom/esp32s2/ld/esp32s2.rom.api.ld b/components/esp_rom/esp32s2/ld/esp32s2.rom.api.ld index afb0849271..37d0970f2f 100644 --- a/components/esp_rom/esp32s2/ld/esp32s2.rom.api.ld +++ b/components/esp_rom/esp32s2/ld/esp32s2.rom.api.ld @@ -16,6 +16,7 @@ PROVIDE ( esp_rom_gpio_connect_out_signal = gpio_matrix_out ); PROVIDE ( esp_rom_efuse_mac_address_crc8 = esp_crc8 ); PROVIDE ( esp_rom_efuse_get_flash_gpio_info = ets_efuse_get_spiconfig ); PROVIDE ( esp_rom_efuse_get_flash_wp_gpio = ets_efuse_get_wp_pad ); +PROVIDE ( esp_rom_efuse_get_opiconfig = ets_efuse_get_opiconfig ); PROVIDE ( esp_rom_efuse_is_secure_boot_enabled = ets_efuse_secure_boot_enabled ); PROVIDE ( esp_rom_uart_flush_tx = uart_tx_flush ); diff --git a/components/esp_rom/include/esp_rom_efuse.h b/components/esp_rom/include/esp_rom_efuse.h index 907e175eca..6280a1e5b6 100644 --- a/components/esp_rom/include/esp_rom_efuse.h +++ b/components/esp_rom/include/esp_rom_efuse.h @@ -1,16 +1,8 @@ -// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -20,6 +12,7 @@ extern "C" { #include #include +#include "soc/soc_caps.h" #define ESP_ROM_EFUSE_FLASH_DEFAULT_SPI (0) #define ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI (1) @@ -56,6 +49,18 @@ uint32_t esp_rom_efuse_get_flash_gpio_info(void); */ uint32_t esp_rom_efuse_get_flash_wp_gpio(void); +#if SOC_SPI_MEM_SUPPORT_OPI_MODE +/** + * @brief Read opi flash pads configuration from Efuse + * + * @return + * - 0 for default SPI pins. + * - Other values define a custom pin configuration mask. From the LSB, every 6 bits represent a GPIO number which stand for: + * DQS, D4, D5, D6, D7 accordingly. + */ +uint32_t esp_rom_efuse_get_opiconfig(void); +#endif // SOC_SPI_MEM_SUPPORT_OPI_MODE + /** * @brief Read eFuse to check whether secure boot has been enabled or not * diff --git a/components/esp_rom/linux/esp_rom_efuse.c b/components/esp_rom/linux/esp_rom_efuse.c index 70cb6f455f..fac1bbb2a3 100644 --- a/components/esp_rom/linux/esp_rom_efuse.c +++ b/components/esp_rom/linux/esp_rom_efuse.c @@ -1,16 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "esp_rom_efuse.h" @@ -49,6 +41,13 @@ uint32_t esp_rom_efuse_get_flash_wp_gpio(void) return 0; } +#if SOC_SPI_MEM_SUPPORT_OPI_MODE +uint32_t esp_rom_efuse_get_opiconfig(void) +{ + return 0; +} +#endif // SOC_SPI_MEM_SUPPORT_OPI_MODE + bool esp_rom_efuse_is_secure_boot_enabled(void) { return false; diff --git a/components/esp_rom/patches/esp_rom_efuse.c b/components/esp_rom/patches/esp_rom_efuse.c new file mode 100644 index 0000000000..5dcd890314 --- /dev/null +++ b/components/esp_rom/patches/esp_rom_efuse.c @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc.h" +#include "soc/efuse_reg.h" + +#if CONFIG_IDF_TARGET_ESP32S3 +/** + * Since rom of esp32s3 does not export function ets_efuse_get_opiconfig, + * patch this function here. + */ +uint32_t esp_rom_efuse_get_opiconfig(void) +{ + uint64_t spiconfig1 = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_2_REG, EFUSE_SPI_PAD_CONF_1); + uint64_t spiconfig2 = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_SPI_PAD_CONF_2); + uint64_t opiconfig = (spiconfig2 << 12) | (spiconfig1 >> 20); + if (opiconfig == 0 || opiconfig == 0x3fffffffllu) { + return 0; + } + // (MSB)EFUSE_SPI_PAD_CONF_2(18bit) + EFUSE_SPI_PAD_CONF_1(32bit) + EFUSE_SPI_PAD_CONF_0(16bit) (LSB) + // [36:41] -- DQS + // [42:47] -- D4 + // [48:53] -- D5 + // [54:59] -- D6 + // [60:65] -- D7 + return opiconfig & 0x3fffffff; +} +#endif diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 8af804bedb..e24c852f1d 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -15,6 +15,7 @@ #include #include #include +#include "soc/io_mux_reg.h" #include "sdkconfig.h" #include "esp_attr.h" #include "esp_spi_flash.h" @@ -51,7 +52,18 @@ #include "esp_flash.h" #include "esp_attr.h" #include "bootloader_flash.h" +#include "bootloader_flash_config.h" #include "esp_compiler.h" +#include "esp_rom_efuse.h" +#if CONFIG_SPIRAM +#ifdef CONFIG_IDF_TARGET_ESP32 +#include "esp32/spiram.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/spiram.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/spiram.h" +#endif +#endif esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size); @@ -928,3 +940,84 @@ void IRAM_ATTR spi_flash_set_vendor_required_regs(void) #endif // CONFIG_ESPTOOLPY_OCT_FLASH } #endif + +static const uint8_t s_mspi_io_num_default[] = { + SPI_CLK_GPIO_NUM, + SPI_Q_GPIO_NUM, + SPI_D_GPIO_NUM, + SPI_CS0_GPIO_NUM, + SPI_HD_GPIO_NUM, + SPI_WP_GPIO_NUM, +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + SPI_DQS_GPIO_NUM, + SPI_D4_GPIO_NUM, + SPI_D5_GPIO_NUM, + SPI_D6_GPIO_NUM, + SPI_D7_GPIO_NUM +#endif // SOC_SPI_MEM_SUPPORT_OPI_MODE +}; + +uint8_t esp_mspi_get_io(esp_mspi_io_t io) +{ +#if CONFIG_SPIRAM + if (io == ESP_MSPI_IO_CS1) { + return esp_spiram_get_cs_io(); + } +#endif + + assert(io >= ESP_MSPI_IO_CLK); +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + assert(io <= ESP_MSPI_IO_D7); +#else + assert(io <= ESP_MSPI_IO_WP); +#endif + + uint8_t mspi_io = 0; + uint32_t spiconfig = 0; + + if (io == ESP_MSPI_IO_WP) { + /** + * wp pad is a bit special: + * 1. since 32's efuse does not have enough bits for wp pad, so wp pad config put in flash bin header + * 2. rom code take 0x3f as invalid wp pad num, but take 0 as other invalid mspi pads num + */ +#if CONFIG_IDF_TARGET_ESP32 + return bootloader_flash_get_wp_pin(); +#else + spiconfig = esp_rom_efuse_get_flash_wp_gpio(); + return (spiconfig == 0x3f) ? s_mspi_io_num_default[io] : spiconfig & 0x3f; +#endif + } + +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + spiconfig = (io < ESP_MSPI_IO_WP) ? esp_rom_efuse_get_flash_gpio_info() : esp_rom_efuse_get_opiconfig(); +#else + spiconfig = esp_rom_efuse_get_flash_gpio_info(); +#endif // SOC_SPI_MEM_SUPPORT_OPI_MODE + + if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) { + mspi_io = s_mspi_io_num_default[io]; + } else if (io < ESP_MSPI_IO_WP) { + /** + * [0 : 5] -- CLK + * [6 :11] -- Q(D1) + * [12:17] -- D(D0) + * [18:23] -- CS + * [24:29] -- HD(D3) + */ + mspi_io = (spiconfig >> io * 6) & 0x3f; + } +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + else { + /** + * [0 : 5] -- DQS + * [6 :11] -- D4 + * [12:17] -- D5 + * [18:23] -- D6 + * [24:29] -- D7 + */ + mspi_io = (spiconfig >> (io - ESP_MSPI_IO_DQS) * 6) & 0x3f; + } +#endif // SOC_SPI_MEM_SUPPORT_OPI_MODE + return mspi_io; +} diff --git a/components/spi_flash/include/esp_private/spi_flash_os.h b/components/spi_flash/include/esp_private/spi_flash_os.h index e73511bc11..996606dbce 100644 --- a/components/spi_flash/include/esp_private/spi_flash_os.h +++ b/components/spi_flash/include/esp_private/spi_flash_os.h @@ -34,11 +34,32 @@ #endif #include "esp_flash.h" #include "hal/spi_flash_hal.h" +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { #endif +// Type of MSPI IO +typedef enum { + ESP_MSPI_IO_CLK = 0, + ESP_MSPI_IO_Q, + ESP_MSPI_IO_D, + ESP_MSPI_IO_CS0, /* cs for spi flash */ + ESP_MSPI_IO_HD, + ESP_MSPI_IO_WP, +#if SOC_SPI_MEM_SUPPORT_OPI_MODE + ESP_MSPI_IO_DQS, + ESP_MSPI_IO_D4, + ESP_MSPI_IO_D5, + ESP_MSPI_IO_D6, + ESP_MSPI_IO_D7, +#endif // SOC_SPI_MEM_SUPPORT_OPI_MODE +#if CONFIG_SPIRAM + ESP_MSPI_IO_CS1 /* cs for spi ram */ +#endif +} esp_mspi_io_t; + /** * @brief To setup Flash chip */ @@ -80,6 +101,15 @@ void spi_timing_psram_tuning(void); */ void esp_mspi_pin_init(void); +/** + * @brief Get the number of the GPIO corresponding to the given MSPI io + * + * @param[in] io MSPI io + * + * @return MSPI IO number + */ +uint8_t esp_mspi_get_io(esp_mspi_io_t io); + /** * @brief Set SPI1 registers to make ROM functions work * @note This function is used for setting SPI1 registers to the state that ROM SPI functions work diff --git a/components/spi_flash/sim/Makefile.files b/components/spi_flash/sim/Makefile.files index 336e63895e..333b2b2380 100644 --- a/components/spi_flash/sim/Makefile.files +++ b/components/spi_flash/sim/Makefile.files @@ -6,6 +6,7 @@ SOURCE_FILES := \ partition.c \ flash_ops.c \ esp32/flash_ops_esp32.c \ + ../esp_rom/linux/esp_rom_efuse.c \ ) \ INCLUDE_DIRS := \ diff --git a/components/spi_flash/sim/flash_mock_util.c b/components/spi_flash/sim/flash_mock_util.c index 2db51c58ae..cab0d324cb 100644 --- a/components/spi_flash/sim/flash_mock_util.c +++ b/components/spi_flash/sim/flash_mock_util.c @@ -48,3 +48,8 @@ void spi_flash_enable_interrupts_caches_no_os(void) { return; } + +int bootloader_flash_get_wp_pin(void) +{ + return 0; +} diff --git a/tools/mocks/soc/include/soc/soc_caps.h b/tools/mocks/soc/include/soc/soc_caps.h new file mode 100644 index 0000000000..d231a1c15c --- /dev/null +++ b/tools/mocks/soc/include/soc/soc_caps.h @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * NOTE: this is not the original header file from the soc component. It is a stripped-down copy to support mocking. + */