fix(esp_hw_support): disable mpll clock after L1 dcache writeback

This commit is contained in:
wuzhenghui 2024-06-19 11:43:42 +08:00
parent 0291269573
commit edf14a1de1
No known key found for this signature in database
GPG Key ID: 3EFEDECDEBA39BB9
3 changed files with 20 additions and 18 deletions

View File

@ -11,6 +11,7 @@
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_attr.h"
#include "esp_private/rtc_clk.h"
#include "esp_private/regi2c_ctrl.h"
#include "esp32p4/rom/cache.h"
#include "soc/chip_revision.h"
@ -22,6 +23,7 @@
#include "soc/pau_reg.h"
#include "soc/pmu_reg.h"
#include "soc/pmu_struct.h"
#include "hal/clk_tree_hal.h"
#include "hal/lp_aon_hal.h"
#include "soc/lp_system_reg.h"
#include "hal/pmu_hal.h"
@ -290,6 +292,8 @@ FORCE_INLINE_ATTR void sleep_writeback_l1_dcache(void) {
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)
{
lp_aon_hal_inform_wakeup_type(dslp);
@ -302,8 +306,15 @@ 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();
// !!! Need to manually check that data in PSRAM will not be accessed from now on. !!!
s_mpll_freq_mhz_before_sleep = rtc_clk_mpll_get_freq();
if (s_mpll_freq_mhz_before_sleep) {
rtc_clk_mpll_disable();
}
/* Start entry into sleep mode */
pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev);
@ -333,6 +344,11 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp)
pmu_sleep_shutdown_ldo();
}
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);
}
// Wait eFuse memory update done.
while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE);

View File

@ -28,7 +28,7 @@ static const char *TAG = "rtc_clk";
static int s_cur_cpll_freq = 0;
// MPLL frequency option, 400MHz. Zero if MPLL is not enabled.
static DRAM_ATTR uint32_t s_cur_mpll_freq = 0;
static TCM_DRAM_ATTR uint32_t s_cur_mpll_freq = 0;
void rtc_clk_32k_enable(bool enable)
{
@ -484,13 +484,13 @@ bool rtc_dig_8m_enabled(void)
}
//------------------------------------MPLL-------------------------------------//
void rtc_clk_mpll_disable(void)
TCM_IRAM_ATTR void rtc_clk_mpll_disable(void)
{
clk_ll_mpll_disable();
s_cur_mpll_freq = 0;
}
void rtc_clk_mpll_enable(void)
TCM_IRAM_ATTR void rtc_clk_mpll_enable(void)
{
clk_ll_mpll_enable();
}
@ -508,7 +508,7 @@ void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq)
s_cur_mpll_freq = mpll_freq;
}
uint32_t rtc_clk_mpll_get_freq(void)
TCM_IRAM_ATTR uint32_t rtc_clk_mpll_get_freq(void)
{
return s_cur_mpll_freq;
}

View File

@ -989,13 +989,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif
#endif
#if SOC_CLK_MPLL_SUPPORTED
uint32_t mpll_freq_mhz = rtc_clk_mpll_get_freq();
if (mpll_freq_mhz) {
rtc_clk_mpll_disable();
}
#endif
#if SOC_DCDC_SUPPORTED
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
if (!deep_sleep) {
@ -1030,13 +1023,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
#endif
#if SOC_CLK_MPLL_SUPPORTED
if (mpll_freq_mhz) {
rtc_clk_mpll_enable();
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), mpll_freq_mhz);
}
#endif
/* Unhold the SPI CS pin */
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet