From ddec7eae60bd9dfb2f1fbb1a5e25ffc5dc75b56f Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 9 Jan 2026 17:58:51 +0800 Subject: [PATCH] fix(bootloader): fix bootloader bad spi pin drv config and clear all wpu/wpd by default --- .../src/bootloader_flash_config_esp32p4.c | 28 +++--- .../esp32p4/include/hal/mspi_ll.h | 98 ++++++++++++++++++- .../hw_ver1/soc/iomux_mspi_pin_struct.h | 45 +++++++-- .../hw_ver3/soc/iomux_mspi_pin_struct.h | 45 +++++++-- 4 files changed, 188 insertions(+), 28 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c index b4cd6f98c0..a176d2aeb3 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,7 @@ #include "hal/cache_hal.h" #include "hal/cache_ll.h" #include "esp_private/bootloader_flash_internal.h" +#include "hal/mspi_iomux_ll.h" void IRAM_ATTR bootloader_flash_update_id(void) { @@ -77,18 +78,19 @@ ESP_LOG_ATTR_TAG(TAG, "boot.esp32p4"); void IRAM_ATTR bootloader_configure_spi_pins(int drv) { - uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK; - uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO; - uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI; - uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0; - uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD; - uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP; - esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); - esp_rom_gpio_pad_set_drv(q_gpio_num, drv); - esp_rom_gpio_pad_set_drv(d_gpio_num, drv); - esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); - esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); - esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); + // Configure all Flash pins: clear pull-up/pull-down, set drive strength + // SPI CS is external pull-uped so there no need to set internal pull-up + mspi_iomux_flash_pin_cfg_t flash_cfg = { + .hys = 0, + .ie = 0, + .wpu = 0, + .wpd = 0, + .drv = drv, + .reserved = 0 + }; + for (mspi_iomux_flash_pin_id_t pin_id = MSPI_IOMUX_FLASH_PIN_ID_CS; pin_id < MSPI_IOMUX_FLASH_PIN_ID_MAX; pin_id++) { + mspi_iomux_ll_set_flash_pin_cfg(pin_id, &flash_cfg); + } } static void update_flash_config(const esp_image_header_t *bootloader_hdr) diff --git a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h index 4c0069fd9f..9743b9fb12 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,6 +38,8 @@ #include "soc/clk_tree_defs.h" #include "soc/spi_mem_struct.h" #include "soc/spi_mem_s_struct.h" +#include "hal/config.h" +#include "soc/lp_system_struct.h" #ifdef __cplusplus extern "C" { @@ -660,6 +662,100 @@ static inline void mspi_ll_psram_enable_axi_access(uint8_t spi_num, bool enable) SPIMEM2.mem_cache_fctrl.close_axi_inf_en = !enable; } +/*--------------------------------------------------------------- + MSPI IOMUX pin configuration +---------------------------------------------------------------*/ +/** + * @brief MSPI IOMUX pin ID enumeration for Flash pins + * ID ranges: + * 0-5: Flash pins (CS, Q, WP, HOLD, CK, D) - maps to flash_pin_regs[] array index + */ +typedef enum { + MSPI_LL_PIN_ID_FLASH_CS = 0, /**< Flash CS pin */ + MSPI_LL_PIN_ID_FLASH_Q, /**< Flash Q pin */ + MSPI_LL_PIN_ID_FLASH_WP, /**< Flash WP pin */ + MSPI_LL_PIN_ID_FLASH_HOLD, /**< Flash HOLD pin */ + MSPI_LL_PIN_ID_FLASH_CK, /**< Flash CLK pin */ + MSPI_LL_PIN_ID_FLASH_D, /**< Flash D pin */ +} mspi_ll_flash_pin_id_t; + +/** + * @brief MSPI IOMUX Flash pin configuration structure + * Register layout: hys(0), ie(1), wpu(2), wpd(3), drv(5:4) + */ +typedef union { + struct { + uint32_t hys: 1; /**< Hysteresis enable */ + uint32_t ie: 1; /**< Input enable */ + uint32_t wpu: 1; /**< Weak pull-up enable */ + uint32_t wpd: 1; /**< Weak pull-down enable */ + uint32_t drv: 2; /**< Drive strength (0-3) */ + uint32_t reserved: 26; /**< Reserved bits */ + }; + uint32_t val; /**< Raw register value for atomic write */ +} mspi_ll_flash_pin_cfg_t; + +/** + * @brief Set configuration for Flash pin + * + * @param pin_id Pin ID (MSPI_LL_PIN_ID_FLASH_CS to MSPI_LL_PIN_ID_FLASH_D, i.e., 0-5) + * @param cfg Pin configuration structure + */ +__attribute__((always_inline)) +static inline void mspi_ll_set_flash_pin_cfg(mspi_ll_flash_pin_id_t pin_id, const mspi_ll_flash_pin_cfg_t *cfg) +{ + HAL_ASSERT(pin_id <= MSPI_LL_PIN_ID_FLASH_D); + MSPI_IOMUX.flash_pin_regs[pin_id].val = cfg->val; +} + +/** + * @brief Hold all Flash pins + * Sets all Flash pins (CS, Q, WP, HOLD, CK, D) to hold status + */ +__attribute__((always_inline)) +static inline void mspi_ll_hold_all_flash_pins(void) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 // Only rev3+ chips support mspi pad holding. + LP_SYS.ded_pad_rtc_hold_ctrl.ded_pad_rtc_hold_ctrl |= 0x3F; +#endif +} + +/** + * @brief Unhold all Flash pins + * Releases hold status for all Flash pins (CS, Q, WP, HOLD, CK, D) + */ +__attribute__((always_inline)) +static inline void mspi_ll_unhold_all_flash_pins(void) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 // Only rev3+ chips support mspi pad holding. + LP_SYS.ded_pad_rtc_hold_ctrl.ded_pad_rtc_hold_ctrl &= ~0x3F; +#endif +} + +/** + * @brief Hold all PSRAM pins + * Sets all PSRAM pins (pin_group0, dqs0, pin_group1, dqs1) to hold status + */ +__attribute__((always_inline)) +static inline void mspi_ll_hold_all_psram_pins(void) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 // Only rev3+ chips support mspi pad holding. + LP_SYS.ded_pad_rtc_hold_ctrl.ded_pad_rtc_hold_ctrl |= 0x3FFFFC0; +#endif +} + +/** + * @brief Unhold all PSRAM pins + * Releases hold status for all PSRAM pins (pin_group0, dqs0, pin_group1, dqs1) + */ +__attribute__((always_inline)) +static inline void mspi_ll_unhold_all_psram_pins(void) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 // Only rev3+ chips support mspi pad holding. + LP_SYS.ded_pad_rtc_hold_ctrl.ded_pad_rtc_hold_ctrl &= ~0x3FFFFC0; +#endif +} + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32p4/register/hw_ver1/soc/iomux_mspi_pin_struct.h b/components/soc/esp32p4/register/hw_ver1/soc/iomux_mspi_pin_struct.h index 6af9fdf782..1c034bf6f3 100644 --- a/components/soc/esp32p4/register/hw_ver1/soc/iomux_mspi_pin_struct.h +++ b/components/soc/esp32p4/register/hw_ver1/soc/iomux_mspi_pin_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -311,14 +311,45 @@ typedef struct { volatile iomux_mspi_pin_psram_dqs_pin_reg_t dqs1; } iomux_mspi_pin_psram_pin_grp_reg_t; +/** + * @brief Union type for Flash MSPI IOMUX pin registers + * All Flash register types share the same size (uint32_t) and have a 'val' member for atomic access + */ +typedef union { + iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs; + iomux_mspi_pin_flash_q_pin0_reg_t flash_q; + iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp; + iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold; + iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck; + iomux_mspi_pin_flash_d_pin0_reg_t flash_d; + uint32_t val; +} iomux_mspi_pin_reg_union_t; + typedef struct { volatile iomux_mspi_pin_clk_en0_reg_t clk_en0; - volatile iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs_pin0; - volatile iomux_mspi_pin_flash_q_pin0_reg_t flash_q_pin0; - volatile iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp_pin0; - volatile iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold_pin0; - volatile iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck_pin0; - volatile iomux_mspi_pin_flash_d_pin0_reg_t flash_d_pin0; + union { + struct { + volatile iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs_pin0; + volatile iomux_mspi_pin_flash_q_pin0_reg_t flash_q_pin0; + volatile iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp_pin0; + volatile iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold_pin0; + volatile iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck_pin0; + volatile iomux_mspi_pin_flash_d_pin0_reg_t flash_d_pin0; + }; + /** + * @brief Flash pin register array for direct access by pin ID + * Array layout matches Flash pins in mspi_iomux_pin_t enumeration: + * [0]: Flash CS pin + * [1]: Flash Q pin + * [2]: Flash WP pin + * [3]: Flash HOLD pin + * [4]: Flash CK pin + * [5]: Flash D pin + */ + struct { + volatile iomux_mspi_pin_reg_union_t flash_pin_regs[6]; + }; + }; volatile iomux_mspi_pin_psram_pin_grp_reg_t psram_pin_group; } iomux_mspi_pin_dev_t; diff --git a/components/soc/esp32p4/register/hw_ver3/soc/iomux_mspi_pin_struct.h b/components/soc/esp32p4/register/hw_ver3/soc/iomux_mspi_pin_struct.h index f5ab610d58..d1383d9b22 100644 --- a/components/soc/esp32p4/register/hw_ver3/soc/iomux_mspi_pin_struct.h +++ b/components/soc/esp32p4/register/hw_ver3/soc/iomux_mspi_pin_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -311,14 +311,45 @@ typedef struct { volatile iomux_mspi_pin_psram_dqs_pin_reg_t dqs1; } iomux_mspi_pin_psram_pin_grp_reg_t; +/** + * @brief Union type for Flash MSPI IOMUX pin registers + * All Flash register types share the same size (uint32_t) and have a 'val' member for atomic access + */ +typedef union { + iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs; + iomux_mspi_pin_flash_q_pin0_reg_t flash_q; + iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp; + iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold; + iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck; + iomux_mspi_pin_flash_d_pin0_reg_t flash_d; + uint32_t val; +} iomux_mspi_pin_reg_union_t; + typedef struct { volatile iomux_mspi_pin_clk_en0_reg_t clk_en0; - volatile iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs_pin0; - volatile iomux_mspi_pin_flash_q_pin0_reg_t flash_q_pin0; - volatile iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp_pin0; - volatile iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold_pin0; - volatile iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck_pin0; - volatile iomux_mspi_pin_flash_d_pin0_reg_t flash_d_pin0; + union { + struct { + volatile iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs_pin0; + volatile iomux_mspi_pin_flash_q_pin0_reg_t flash_q_pin0; + volatile iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp_pin0; + volatile iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold_pin0; + volatile iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck_pin0; + volatile iomux_mspi_pin_flash_d_pin0_reg_t flash_d_pin0; + }; + /** + * @brief Flash pin register array for direct access by pin ID + * Array layout matches Flash pins in mspi_iomux_pin_t enumeration: + * [0]: Flash CS pin + * [1]: Flash Q pin + * [2]: Flash WP pin + * [3]: Flash HOLD pin + * [4]: Flash CK pin + * [5]: Flash D pin + */ + struct { + volatile iomux_mspi_pin_reg_union_t flash_pin_regs[6]; + }; + }; volatile iomux_mspi_pin_psram_pin_grp_reg_t psram_pin_group; } iomux_mspi_pin_dev_t;