feat(esp_hw_support): support esp32p4 psram retention

This commit is contained in:
wuzhenghui
2024-09-04 16:41:35 +08:00
parent 4fff077599
commit 2c68d03182
12 changed files with 177 additions and 56 deletions
@@ -26,7 +26,8 @@ void mspi_timing_config_set_psram_clock(uint32_t psram_freq_mhz, mspi_timing_spe
ESP_EARLY_LOGD(TAG, "psram_freq_mhz: %" PRIu32 " mhz, bus clock div: %" PRIu32, psram_freq_mhz, freqdiv);
PERIPH_RCC_ATOMIC() {
//MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here.
psram_ctrlr_ll_set_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, MSPI_TIMING_CORE_CLOCK_DIV);
psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true);
psram_ctrlr_ll_set_core_clock_div(PSRAM_CTRLR_LL_MSPI_ID_2, MSPI_TIMING_CORE_CLOCK_DIV);
psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, freqdiv);
psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, freqdiv);
}
@@ -27,6 +27,7 @@
#include "hal/lp_aon_hal.h"
#include "soc/lp_system_reg.h"
#include "hal/pmu_hal.h"
#include "hal/psram_ctrlr_ll.h"
#include "hal/lp_sys_ll.h"
#include "esp_private/esp_pmu.h"
#include "pmu_param.h"
@@ -135,6 +136,8 @@ static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default(
return param;
}
TCM_DRAM_ATTR static uint32_t s_saved_pd_flags = 0;
const pmu_sleep_config_t* pmu_sleep_config_default(
pmu_sleep_config_t *config,
uint32_t pd_flags,
@@ -144,6 +147,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
bool dslp
)
{
s_saved_pd_flags = pd_flags;
pmu_sleep_power_config_t power_default = PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags);
uint32_t iram_pd_flags = 0;
@@ -290,11 +294,6 @@ void pmu_sleep_shutdown_ldo(void) {
CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD);
}
FORCE_INLINE_ATTR void sleep_writeback_l1_dcache(void) {
Cache_WriteBack_All(CACHE_MAP_L1_DCACHE);
while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE));
}
static TCM_DRAM_ATTR uint32_t s_mpll_freq_mhz_before_sleep = 0;
TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
@@ -309,12 +308,28 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt,
pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev);
pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev);
// !!! Need to manually check that data in L2 memory will not be modified from now on. !!!
sleep_writeback_l1_dcache();
if (s_saved_pd_flags & PMU_SLEEP_PD_TOP) {
// L1 Cache will be powered down during PD_TOP sleep, write it back to L2 Cache here.
// !!! Need to manually check that data in L2 memory will not be modified from now on. !!!
Cache_WriteBack_All(CACHE_MAP_L1_DCACHE);
}
// !!! Need to manually check that data in PSRAM will not be accessed from now on. !!!
#if CONFIG_SPIRAM
psram_ctrlr_ll_wait_all_transaction_done();
#endif
s_mpll_freq_mhz_before_sleep = rtc_clk_mpll_get_freq();
if (s_mpll_freq_mhz_before_sleep) {
#if CONFIG_SPIRAM
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_XTAL);
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_XTAL);
if (!s_pmu_sleep_regdma_backup_enabled) {
// MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here.
// If it's a PD_TOP sleep, psram MSPI core clock will be disabled by REGDMA
// !!! Need to manually check that data in PSRAM will not be accessed from now on. !!!
_psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, false);
_psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, false);
}
#endif
rtc_clk_mpll_disable();
}
@@ -350,6 +365,16 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp)
if (s_mpll_freq_mhz_before_sleep) {
rtc_clk_mpll_enable();
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), s_mpll_freq_mhz_before_sleep);
#if CONFIG_SPIRAM
if (!s_pmu_sleep_regdma_backup_enabled) {
// MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here.
// If it's a PD_TOP sleep, psram MSPI core clock will be enabled by REGDMA
_psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true);
_psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true);
}
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_MPLL);
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_MPLL);
#endif
}
// Wait eFuse memory update done.
@@ -73,14 +73,24 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_iomux_retention_init(v
return ESP_OK;
}
static __attribute__((unused)) esp_err_t sleep_sys_periph_spimem_retention_init(void *arg)
static __attribute__((unused)) esp_err_t sleep_sys_periph_flash_spimem_retention_init(void *arg)
{
esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SPI mem");
ESP_LOGD(TAG, "SPI Mem sleep retention initialization");
esp_err_t err = sleep_retention_entries_create(flash_spimem_regs_retention, ARRAY_SIZE(flash_spimem_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Flash SPI mem");
ESP_LOGD(TAG, "Flash SPI Mem sleep retention initialization");
return ESP_OK;
}
#if CONFIG_SPIRAM
static __attribute__((unused)) esp_err_t sleep_sys_periph_psram_spimem_retention_init(void *arg)
{
esp_err_t err = sleep_retention_entries_create(psram_spimem_regs_retention, ARRAY_SIZE(psram_spimem_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "PSRAM SPI mem");
ESP_LOGD(TAG, "PSRAM SPI Mem sleep retention initialization");
return ESP_OK;
}
#endif
static __attribute__((unused)) esp_err_t sleep_sys_periph_systimer_retention_init(void *arg)
{
esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH);
@@ -130,8 +140,12 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a
#endif
err = sleep_sys_periph_iomux_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_spimem_retention_init(arg);
err = sleep_sys_periph_flash_spimem_retention_init(arg);
if(err) goto error;
#if CONFIG_SPIRAM
err = sleep_sys_periph_psram_spimem_retention_init(arg);
if(err) goto error;
#endif
err = sleep_sys_periph_systimer_retention_init(arg);
if(err) goto error;
#if SOC_PAU_IN_TOP_DOMAIN