diff --git a/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c b/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c index 725f9e2eef..ff5d6880fe 100644 --- a/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c +++ b/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c @@ -43,6 +43,7 @@ #include "hal/lpwdt_ll.h" #include "hal/regi2c_ctrl_ll.h" #include "hal/brownout_ll.h" +#include "hal/axi_icm_ll.h" ESP_LOG_ATTR_TAG(TAG, "boot.esp32c5"); @@ -85,6 +86,9 @@ static void bootloader_super_wdt_auto_feed(void) static inline void bootloader_hardware_init(void) { + // Clear bit reset_event_bypass to ensure that the system bus is also reset during a core reset (WDT), + // preventing bus freezing caused by an incorrect MSPI core reset in ROM. + axi_icm_ll_reset_with_core_reset(true); _regi2c_ctrl_ll_master_enable_clock(true); // keep ana i2c mst clock always enabled in bootloader regi2c_ctrl_ll_master_configure_clock(); } diff --git a/components/bootloader_support/src/esp32c61/bootloader_esp32c61.c b/components/bootloader_support/src/esp32c61/bootloader_esp32c61.c index 38326ffc5d..32f26e8064 100644 --- a/components/bootloader_support/src/esp32c61/bootloader_esp32c61.c +++ b/components/bootloader_support/src/esp32c61/bootloader_esp32c61.c @@ -44,6 +44,7 @@ #include "hal/lpwdt_ll.h" #include "hal/regi2c_ctrl_ll.h" #include "hal/brownout_ll.h" +#include "hal/axi_icm_ll.h" ESP_LOG_ATTR_TAG(TAG, "boot.esp32c61"); @@ -86,6 +87,9 @@ static void bootloader_super_wdt_auto_feed(void) static inline void bootloader_hardware_init(void) { + // Clear bit reset_event_bypass to ensure that the system bus is also reset during a core reset (WDT), + // preventing bus freezing caused by an incorrect MSPI core reset in ROM. + axi_icm_ll_reset_with_core_reset(true); _regi2c_ctrl_ll_master_enable_clock(true); // keep ana i2c mst clock always enabled in bootloader regi2c_ctrl_ll_master_configure_clock(); } diff --git a/components/esp_system/port/soc/esp32c5/system_internal.c b/components/esp_system/port/soc/esp32c5/system_internal.c index 95365b19b4..f36c17653a 100644 --- a/components/esp_system/port/soc/esp32c5/system_internal.c +++ b/components/esp_system/port/soc/esp32c5/system_internal.c @@ -48,6 +48,7 @@ void esp_system_reset_modules_on_exit(void) modem_lpcon_ll_reset_all(&MODEM_LPCON); #endif // Set Peripheral clk rst + SET_PERI_REG_MASK(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); // Must reset mspi AXI before reset mspi core. SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); @@ -62,6 +63,7 @@ void esp_system_reset_modules_on_exit(void) // Clear Peripheral clk rst CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + CLEAR_PERI_REG_MASK(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); // Must release mspi core reset before mspi AXI. CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); diff --git a/components/esp_system/port/soc/esp32c61/system_internal.c b/components/esp_system/port/soc/esp32c61/system_internal.c index 8fb2088d5e..2c3def9b72 100644 --- a/components/esp_system/port/soc/esp32c61/system_internal.c +++ b/components/esp_system/port/soc/esp32c61/system_internal.c @@ -49,6 +49,7 @@ void esp_system_reset_modules_on_exit(void) #endif // Set Peripheral clk rst + SET_PERI_REG_MASK(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); // Must reset mspi AXI before reset mspi core. SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); @@ -61,6 +62,7 @@ void esp_system_reset_modules_on_exit(void) SET_PERI_REG_MASK(PCR_ETM_CONF_REG, PCR_ETM_RST_EN); // Clear Peripheral clk rst + CLEAR_PERI_REG_MASK(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); // Must release mspi core reset before mspi AXI. CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); diff --git a/components/esp_system/port/soc/esp32h4/system_internal.c b/components/esp_system/port/soc/esp32h4/system_internal.c index ff9e47ed03..0a1eac492f 100644 --- a/components/esp_system/port/soc/esp32h4/system_internal.c +++ b/components/esp_system/port/soc/esp32h4/system_internal.c @@ -37,6 +37,7 @@ void esp_system_reset_modules_on_exit(void) } // Set Peripheral clk rst + SET_PERI_REG_MASK(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); // Must reset mspi AXI before reset mspi core. SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); @@ -50,6 +51,7 @@ void esp_system_reset_modules_on_exit(void) // Clear Peripheral clk rst CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + CLEAR_PERI_REG_MASK(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); // Must release mspi core reset before mspi AXI. CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); diff --git a/components/hal/esp32c5/include/hal/axi_icm_ll.h b/components/hal/esp32c5/include/hal/axi_icm_ll.h index 903a49490d..810d518a4f 100644 --- a/components/hal/esp32c5/include/hal/axi_icm_ll.h +++ b/components/hal/esp32c5/include/hal/axi_icm_ll.h @@ -9,6 +9,7 @@ #include #include "hal/assert.h" #include "soc/hp_system_struct.h" +#include "soc/pcr_struct.h" #ifdef __cplusplus extern "C" { @@ -36,6 +37,15 @@ static inline void axi_icm_ll_set_cache_arbiter_prio(uint8_t priority) HP_SYSTEM.axi_mst_pri.cache_priority = priority; } +/** + * @brief Reset system bus with soc core reset. + * @param reset_with_core_reset True to reset system bus with soc core reset. + */ +static inline void axi_icm_ll_reset_with_core_reset(bool reset_with_core_reset) +{ + PCR.reset_event_bypass.reset_event_bypass = !reset_with_core_reset; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c61/include/hal/axi_icm_ll.h b/components/hal/esp32c61/include/hal/axi_icm_ll.h index 1742a9933c..a906506a19 100644 --- a/components/hal/esp32c61/include/hal/axi_icm_ll.h +++ b/components/hal/esp32c61/include/hal/axi_icm_ll.h @@ -9,6 +9,7 @@ #include #include "hal/assert.h" #include "soc/hp_system_struct.h" +#include "soc/pcr_struct.h" #ifdef __cplusplus extern "C" { @@ -36,6 +37,15 @@ static inline void axi_icm_ll_set_cache_arbiter_prio(uint8_t priority) HP_SYSTEM.system_axi_mst_pri.system_cache_priority = priority; } +/** + * @brief Reset system bus with soc core reset. + * @param reset_with_core_reset True to reset system bus with soc core reset. + */ +static inline void axi_icm_ll_reset_with_core_reset(bool reset_with_core_reset) +{ + PCR.reset_event_bypass.reset_event_bypass = !reset_with_core_reset; +} + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c61/register/soc/pcr_struct.h b/components/soc/esp32c61/register/soc/pcr_struct.h index 9e36f9e790..97b48ecdb5 100644 --- a/components/soc/esp32c61/register/soc/pcr_struct.h +++ b/components/soc/esp32c61/register/soc/pcr_struct.h @@ -1774,6 +1774,30 @@ typedef union { uint32_t val; } pcr_timergroup_xtal_conf_reg_t; +/** Type of reset_event_bypass register + * reset event bypass backdoor configuration register + */ +typedef union { + struct { + /** reset_event_bypass_apm : R/W; bitpos: [0]; default: 0; + * This field is used to control reset event relationship for + * tee_reg/apm_reg/hp_system_reg. 1: tee_reg/apm_reg/hp_system_reg will only be reset + * by power-reset. some reset event will be bypass. 0: tee_reg/apm_reg/hp_system_reg + * will not only be reset by power-reset, but also some reset event. + */ + uint32_t reset_event_bypass_apm:1; + /** reset_event_bypass : R/W; bitpos: [1]; default: 1; + * This field is used to control reset event relationship for system-bus. 1: system + * bus (including arbiter/router) will only be reset by power-reset. some reset event + * will be bypass. 0: system bus (including arbiter/router) will not only be reset by + * power-reset, but also some reset event. + */ + uint32_t reset_event_bypass:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} pcr_reset_event_bypass_reg_t; + /** Type of regdma_conf register * REGDMA configuration register */ @@ -1966,7 +1990,7 @@ typedef struct { uint32_t reserved_128; volatile pcr_timergroup_wdt_conf_reg_t timergroup_wdt_conf; volatile pcr_timergroup_xtal_conf_reg_t timergroup_xtal_conf; - uint32_t reserved_134; + volatile pcr_reset_event_bypass_reg_t reset_event_bypass; volatile pcr_regdma_conf_reg_t regdma_conf; volatile pcr_etm_conf_reg_t etm_conf; uint32_t reserved_140[6];