From d1475b5d72c14d4be905b1f82bec416862498f15 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Thu, 12 Dec 2024 11:02:52 +0800 Subject: [PATCH 1/2] fix(esp_hw_support): fix mspi clock freq changed after lightsleep --- components/esp_hw_support/sleep_modes.c | 13 ++++++-- components/esp_pm/pm_impl.c | 31 +++++++++++-------- .../include/hal/mspi_timing_tuning_ll.h | 2 ++ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 122a21d6f3..07c373d510 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -56,12 +56,17 @@ #include "hal/cache_hal.h" #include "hal/cache_ll.h" +#include "hal/clk_tree_ll.h" #include "hal/wdt_hal.h" #include "hal/uart_hal.h" #if SOC_TOUCH_SENSOR_SUPPORTED #include "hal/touch_sensor_hal.h" #endif +#if __has_include("hal/mspi_timing_tuning_ll.h") +#include "hal/mspi_timing_tuning_ll.h" +#endif + #include "sdkconfig.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" @@ -72,7 +77,9 @@ #include "esp_private/esp_clk.h" #include "esp_private/esp_task_wdt.h" #include "esp_private/sar_periph_ctrl.h" +#if MSPI_TIMING_LL_FLASH_CPU_CLK_SRC_BINDED #include "esp_private/mspi_timing_tuning.h" +#endif #ifdef CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/cache.h" @@ -788,8 +795,10 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m } #endif +#if MSPI_TIMING_LL_FLASH_CPU_CLK_SRC_BINDED // Will switch to XTAL turn down MSPI speed mspi_timing_change_speed_mode_cache_safe(true); +#endif #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA if (!deep_sleep && (pd_flags & PMU_SLEEP_PD_TOP)) { @@ -1071,8 +1080,8 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m misc_modules_wake_prepare(pd_flags); } -#if SOC_SPI_MEM_SUPPORT_TIMING_TUNING - if (cpu_freq_config.source == SOC_CPU_CLK_SRC_PLL) { +#if MSPI_TIMING_LL_FLASH_CPU_CLK_SRC_BINDED + if (cpu_freq_config.source_freq_mhz > clk_ll_xtal_load_freq_mhz()) { // Turn up MSPI speed if switch to PLL mspi_timing_change_speed_mode_cache_safe(false); } diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 4f96565581..4f1190fe31 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -22,8 +22,14 @@ #include "esp_private/periph_ctrl.h" #include "soc/rtc.h" +#include "hal/clk_tree_ll.h" #include "hal/uart_ll.h" #include "hal/uart_types.h" + +#if __has_include("hal/mspi_timing_tuning_ll.h") +#include "hal/mspi_timing_tuning_ll.h" +#endif + #include "driver/gpio.h" #include "freertos/FreeRTOS.h" @@ -33,10 +39,6 @@ #include "xtensa/core-macros.h" #endif -#if SOC_SPI_MEM_SUPPORT_TIMING_TUNING -#include "esp_private/mspi_timing_tuning.h" -#endif - #include "esp_private/pm_impl.h" #include "esp_private/pm_trace.h" #include "esp_private/esp_timer_private.h" @@ -45,6 +47,9 @@ #include "esp_private/sleep_gpio.h" #include "esp_private/sleep_modem.h" #include "esp_private/uart_share_hw_ctrl.h" +#if MSPI_TIMING_LL_FLASH_CPU_CLK_SRC_BINDED +#include "esp_private/mspi_timing_tuning.h" +#endif #include "esp_sleep.h" #include "esp_memory_utils.h" @@ -663,16 +668,16 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode) if (switch_down) { on_freq_update(old_ticks_per_us, new_ticks_per_us); } -#if SOC_SPI_MEM_SUPPORT_TIMING_TUNING - if (new_config.source == SOC_CPU_CLK_SRC_PLL) { - rtc_clk_cpu_freq_set_config_fast(&new_config); - mspi_timing_change_speed_mode_cache_safe(false); - } else { - mspi_timing_change_speed_mode_cache_safe(true); - rtc_clk_cpu_freq_set_config_fast(&new_config); - } +#if MSPI_TIMING_LL_FLASH_CPU_CLK_SRC_BINDED + if (new_config.source_freq_mhz > clk_ll_xtal_load_freq_mhz()) { + rtc_clk_cpu_freq_set_config_fast(&new_config); + mspi_timing_change_speed_mode_cache_safe(false); + } else { + mspi_timing_change_speed_mode_cache_safe(true); + rtc_clk_cpu_freq_set_config_fast(&new_config); + } #else - rtc_clk_cpu_freq_set_config_fast(&new_config); + rtc_clk_cpu_freq_set_config_fast(&new_config); #endif if (!switch_down) { on_freq_update(old_ticks_per_us, new_ticks_per_us); diff --git a/components/hal/esp32s3/include/hal/mspi_timing_tuning_ll.h b/components/hal/esp32s3/include/hal/mspi_timing_tuning_ll.h index 09232af277..9ba2778472 100644 --- a/components/hal/esp32s3/include/hal/mspi_timing_tuning_ll.h +++ b/components/hal/esp32s3/include/hal/mspi_timing_tuning_ll.h @@ -37,6 +37,8 @@ extern "C" { #define MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT 80 +#define MSPI_TIMING_LL_FLASH_CPU_CLK_SRC_BINDED 1 + typedef enum { MSPI_TIMING_LL_FLASH_OPI_MODE = BIT(0), MSPI_TIMING_LL_FLASH_QIO_MODE = BIT(1), From b0a1735b55ad6bad02ea34c6b9711fcfec28c100 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 17 Oct 2024 12:23:49 +0800 Subject: [PATCH 2/2] fix(clk): rtc_clk_cpu_freq_set_xtal will always disable CPU's PLL Align C6/H2/C5/C61 rtc_clk_cpu_freq_set_xtal behavior to other chips For PMU supported chips, powering down CPU PLL in sleep will be done by PMU, not sleep code --- components/esp_hw_support/include/esp_private/rtc_clk.h | 5 +++-- components/esp_hw_support/sleep_modes.c | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/rtc_clk.h b/components/esp_hw_support/include/esp_private/rtc_clk.h index 0933f00706..4480780217 100644 --- a/components/esp_hw_support/include/esp_private/rtc_clk.h +++ b/components/esp_hw_support/include/esp_private/rtc_clk.h @@ -21,8 +21,9 @@ extern "C" { * `rtc_clk_cpu_freq_set_xtal` instead. It will always disable the corresponding PLL after switching the CPU clock * source to XTAL (except for S2). * - * Currently, this function should only be called in `esp_restart_noos` and `esp_restart_noos_dig` to switch the CPU - * clock source back to XTAL (by default) before reset. + * Currently, this function is only called in `esp_restart_noos` and `esp_restart_noos_dig` to switch the CPU + * clock source back to XTAL (by default) before reset, and in `esp_sleep_start` to switch CPU clock source to XTAL + * before entering sleep for PMU supported chips. */ void rtc_clk_cpu_set_to_default_config(void); diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 07c373d510..6eba6ab8a3 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -809,7 +809,16 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m // Save current frequency and switch to XTAL rtc_cpu_freq_config_t cpu_freq_config; rtc_clk_cpu_freq_get_config(&cpu_freq_config); +#if SOC_PMU_SUPPORTED + // For PMU supported chips, CPU's PLL power can be turned off by PMU, so no need to disable the PLL at here. + // Leaving PLL on at this stage also helps USJ keep connection and retention operation (if they rely on this PLL). + rtc_clk_cpu_set_to_default_config(); +#else + // For earlier chips, there is no PMU module that can turn off the CPU's PLL, so it has to be disabled at here to save the power consumption. + // Though ESP32C3/S3 has USB CDC device, it can not function properly during sleep due to the lack of APB clock (before C6, USJ relies on APB clock to work). + // Therefore, we will always disable CPU's PLL (i.e. BBPLL). rtc_clk_cpu_freq_set_xtal(); +#endif #if SOC_PM_SUPPORT_EXT0_WAKEUP // Configure pins for external wakeup