fix(esp_hw_support): disable mpll before sleep to avoid mspi module entering an error state

pull/13557/merge
wuzhenghui 2024-04-16 18:06:35 +08:00
rodzic f3d963a93b
commit 8f33c69c30
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 3EFEDECDEBA39BB9
5 zmienionych plików z 40 dodań i 8 usunięć

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -32,7 +32,7 @@ void rtc_clk_cpu_set_to_default_config(void);
* Currently, this function is only used for tracking whether USB Serial/JTAG is using the 48MHz PHY clock
*
* Note: Calling this function only helps to not disable the BBPLL clock in `rtc_clk_cpu_freq_set_config`.
* For light and deep sleep, whether to disable the BBPLL in the interal call to `rtc_clk_cpu_freq_set_xtal`
* For light and deep sleep, whether to disable the BBPLL in the internal call to `rtc_clk_cpu_freq_set_xtal`
* varies for targets.
* On ESP32C3/S3, USB CDC device can not function properly during sleep due to the lack of APB clock. Therefore.
* `rtc_clk_cpu_freq_set_xtal` will always disable BBPLL, no matter whether BBPLL has any consumer.
@ -65,6 +65,13 @@ void rtc_clk_mpll_disable(void);
* @param[in] mpll_freq MPLL frequency
*/
void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq);
/**
* Get the MPLL frequency
* @return the value of MPLL frequency in MHz
*/
uint32_t rtc_clk_mpll_get_freq(void);
#endif //#if SOC_CLK_MPLL_SUPPORTED
/**

Wyświetl plik

@ -13,6 +13,7 @@
#include "esp32p4/rom/rtc.h"
#include "soc/rtc.h"
#include "esp_private/rtc_clk.h"
#include "esp_attr.h"
#include "esp_hw_log.h"
#include "esp_rom_sys.h"
#include "hal/clk_tree_ll.h"
@ -26,6 +27,9 @@ static const char *TAG = "rtc_clk";
// CPLL frequency option, in 360/400MHz. Zero if CPLL is not enabled.
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;
void rtc_clk_32k_enable(bool enable)
{
if (enable) {
@ -483,6 +487,7 @@ bool rtc_dig_8m_enabled(void)
void rtc_clk_mpll_disable(void)
{
clk_ll_mpll_disable();
s_cur_mpll_freq = 0;
}
void rtc_clk_mpll_enable(void)
@ -500,4 +505,10 @@ void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq)
while(!regi2c_ctrl_ll_mpll_calibration_is_done());
/* MPLL calibration stop */
regi2c_ctrl_ll_mpll_calibration_stop();
s_cur_mpll_freq = mpll_freq;
}
uint32_t rtc_clk_mpll_get_freq(void)
{
return s_cur_mpll_freq;
}

Wyświetl plik

@ -16,6 +16,7 @@
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/esp_timer_private.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/rtc_clk.h"
#include "esp_private/sleep_event.h"
#include "esp_private/system_internal.h"
#include "esp_log.h"
@ -27,6 +28,7 @@
#include "soc/soc_caps.h"
#include "driver/rtc_io.h"
#include "hal/rtc_io_hal.h"
#include "hal/clk_tree_hal.h"
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#include "esp_private/pm_impl.h"
@ -924,6 +926,13 @@ 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
uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period);
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
@ -951,6 +960,13 @@ 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

Wyświetl plik

@ -78,7 +78,6 @@ TEST_CASE_MULTIPLE_STAGES("enter deep sleep on APP CPU and wake up using timer",
#endif
#if !(CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4) // TODO: IDF-9569
static void do_deep_sleep_timer(void)
{
esp_sleep_enable_timer_wakeup(2000000);
@ -111,7 +110,6 @@ TEST_CASE("wake up from light sleep using timer", "[deepsleep]")
(tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
}
#endif
//NOTE: Explained in IDF-1445 | MR !14996
#if !(CONFIG_SPIRAM) || (CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL >= 16384)
@ -253,7 +251,6 @@ TEST_CASE("light sleep and frequency switching", "[deepsleep]")
}
}
#if !(CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4) // TODO: IDF-9569
static void do_deep_sleep(void)
{
esp_sleep_enable_timer_wakeup(100000);
@ -289,7 +286,6 @@ TEST_CASE_MULTIPLE_STAGES("enter deep sleep after abort", "[deepsleep][reset=abo
do_abort,
check_abort_reset_and_sleep,
check_sleep_reset);
#endif
#if ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB
static RTC_DATA_ATTR uint32_t s_wake_stub_var;
@ -331,7 +327,7 @@ TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub", "[deepsleep][reset=DEEPSLEE
trigger a CRC calculation (done in hardware) for the entire RTC FAST memory
before going to deep sleep and if it's invalid then the stub is not
run. Also, while the CRC is being calculated the RTC FAST memory is not
accesible by the CPU (reads all zeros).
accessible by the CPU (reads all zeros).
*/
static void increment_rtc_memory_cb(void *arg)
@ -491,7 +487,7 @@ static void trigger_deepsleep(void)
struct timeval start;
// Use NVS instead of RTC mem to store the start time of deep sleep
// Beacuse not all esp chips support RTC mem(such as esp32c2)
// Because not all esp chips support RTC mem(such as esp32c2)
// Initialize NVS
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {

Wyświetl plik

@ -24,3 +24,5 @@ entries:
spi_flash_hal_gpspi (noflash)
if SOC_PMU_SUPPORTED = y:
pmu_hal (noflash)
if SOC_CLK_MPLL_SUPPORTED = y:
clk_tree_hal: clk_hal_xtal_get_freq_mhz (noflash)