mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
fix(esp_system): fix mspi write stuck after cpu/digital reset on c5/c61
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdint.h>
|
||||
#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
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdint.h>
|
||||
#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
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user