mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-28 21:55:59 +00:00
Merge branch 'fix/fix_xip_power_reset_stuck_issue_p4_rev3' into 'master'
psram: fixed p4 rev3 xip stuck after board reset issue See merge request espressif/esp-idf!42146
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "soc/spi1_mem_s_struct.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/hp_system_struct.h"
|
||||
#include "rom/opi_flash.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -355,20 +356,20 @@ static inline void _psram_ctrlr_ll_enable_module_clock(uint32_t mspi_id, bool en
|
||||
* @param mspi_id mspi_id
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_reset_module_clock(uint32_t mspi_id)
|
||||
static inline void _psram_ctrlr_ll_reset_module_clock(uint32_t mspi_id)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_dual_mspi_axi = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_dual_mspi_axi = 0;
|
||||
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_dual_mspi_apb = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_dual_mspi_apb = 0;
|
||||
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_dual_mspi_axi = 0;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define psram_ctrlr_ll_reset_module_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
psram_ctrlr_ll_reset_module_clock(__VA_ARGS__); \
|
||||
_psram_ctrlr_ll_reset_module_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
@@ -828,6 +829,48 @@ static inline void psram_ctrlr_ll_wait_all_transaction_done(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Backup PSRAM controller registers
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param reg registers
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_backup_registers(uint32_t mspi_id, spi_mem_s_dev_t *reg)
|
||||
{
|
||||
memcpy(reg, &SPIMEM2, sizeof(spi_mem_s_dev_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Restore PSRAM controller registers
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param reg registers
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_restore_registers(uint32_t mspi_id, spi_mem_s_dev_t *reg)
|
||||
{
|
||||
memcpy(&SPIMEM2, reg, sizeof(spi_mem_s_dev_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable core error response
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_disable_core_err_resp(void)
|
||||
{
|
||||
HP_SYSTEM.core_err_resp_dis.val = 0x7;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable core error response
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_core_err_resp(void)
|
||||
{
|
||||
HP_SYSTEM.core_err_resp_dis.val = 0x0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -154,6 +154,35 @@ static void IRAM_ATTR s_mapping(int v_start, int size)
|
||||
}
|
||||
#endif //CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#if CONFIG_ESP32P4_REV_MIN_FULL == 300
|
||||
#include "hal/psram_ctrlr_ll.h"
|
||||
static void IRAM_ATTR esp_psram_p4_rev3_workaround(void)
|
||||
{
|
||||
spi_mem_s_dev_t backup_reg = {};
|
||||
psram_ctrlr_ll_backup_registers(PSRAM_CTRLR_LL_MSPI_ID_2, &backup_reg);
|
||||
|
||||
__attribute__((unused)) volatile uint32_t val = 0;
|
||||
psram_ctrlr_ll_disable_core_err_resp();
|
||||
|
||||
/**
|
||||
* this workaround is to have two dummy reads, therefore
|
||||
* - map 1 page
|
||||
* - read 2 times
|
||||
* - delay 1us
|
||||
*
|
||||
* The mapping will be overwritten by the real mapping in `s_psram_mapping`
|
||||
*/
|
||||
mmu_ll_write_entry(1, 0, 0, MMU_TARGET_PSRAM0);
|
||||
val = *(uint32_t *)(0x88000000);
|
||||
val = *(uint32_t *)(0x88000080);
|
||||
esp_rom_delay_us(1);
|
||||
|
||||
_psram_ctrlr_ll_reset_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2);
|
||||
psram_ctrlr_ll_enable_core_err_resp();
|
||||
psram_ctrlr_ll_restore_registers(PSRAM_CTRLR_LL_MSPI_ID_2, &backup_reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static esp_err_t s_psram_chip_init(void)
|
||||
{
|
||||
if (s_psram_ctx.is_chip_initialised) {
|
||||
@@ -375,6 +404,10 @@ esp_err_t esp_psram_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_ESP32P4_REV_MIN_FULL == 300
|
||||
esp_psram_p4_rev3_workaround();
|
||||
#endif
|
||||
|
||||
uint32_t psram_available_size = 0;
|
||||
ret = esp_psram_impl_get_available_size(&psram_available_size);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
@@ -2123,7 +2123,7 @@ typedef union {
|
||||
} hp_hp2lp_intr_group3_st_reg_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
typedef struct hp_system_dev_t {
|
||||
volatile hp_sys_ver_date_reg_t sys_ver_date;
|
||||
volatile hp_clk_en_reg_t clk_en;
|
||||
uint32_t reserved_008[2];
|
||||
@@ -2244,12 +2244,12 @@ typedef struct {
|
||||
volatile hp_hp2lp_wakeup_group1_en_reg_t hp2lp_wakeup_group1_en;
|
||||
volatile hp_hp2lp_wakeup_group2_en_reg_t hp2lp_wakeup_group2_en;
|
||||
volatile hp_hp2lp_wakeup_group3_en_reg_t hp2lp_wakeup_group3_en;
|
||||
} hp_dev_t;
|
||||
} hp_system_dev_t;
|
||||
|
||||
extern hp_dev_t HP_SYSTEM;
|
||||
extern hp_system_dev_t HP_SYSTEM;
|
||||
|
||||
#ifndef __cplusplus
|
||||
_Static_assert(sizeof(hp_dev_t) == 0x220, "Invalid size of hp_dev_t structure");
|
||||
_Static_assert(sizeof(hp_system_dev_t) == 0x220, "Invalid size of hp_dev_t structure");
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user