mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-04 06:11:06 +00:00 
			
		
		
		
	fix(mspi): fixed cpu and mspi freq mismatch issue when in dfs/sleep on p4
This commit is contained in:
		@@ -43,7 +43,8 @@ if(NOT non_os_build)
 | 
			
		||||
                     "dma/esp_dma_utils.c"
 | 
			
		||||
                     "dma/gdma_link.c"
 | 
			
		||||
                     "spi_share_hw_ctrl.c"
 | 
			
		||||
                     "spi_bus_lock.c")
 | 
			
		||||
                     "spi_bus_lock.c"
 | 
			
		||||
                     "clk_utils.c")
 | 
			
		||||
 | 
			
		||||
    if(CONFIG_SOC_ADC_SUPPORTED)
 | 
			
		||||
        list(APPEND srcs "adc_share_hw_ctrl.c")
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										71
									
								
								components/esp_hw_support/clk_utils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								components/esp_hw_support/clk_utils.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "esp_check.h"
 | 
			
		||||
#include "esp_log.h"
 | 
			
		||||
#include "soc/soc_caps.h"
 | 
			
		||||
#include "soc/rtc.h"
 | 
			
		||||
#include "hal/clk_tree_ll.h"
 | 
			
		||||
#include "esp_private/mspi_timing_tuning.h"
 | 
			
		||||
#include "esp_private/esp_clk_utils.h"
 | 
			
		||||
 | 
			
		||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
 | 
			
		||||
void esp_clk_utils_mspi_speed_mode_sync_before_cpu_freq_switching(uint32_t target_cpu_src_freq, uint32_t target_cpu_freq)
 | 
			
		||||
{
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
    (void) target_cpu_freq;
 | 
			
		||||
    if (target_cpu_src_freq <= clk_ll_xtal_load_freq_mhz()) {
 | 
			
		||||
        mspi_timing_change_speed_mode_cache_safe(true);
 | 
			
		||||
    }
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32P4
 | 
			
		||||
    (void) target_cpu_src_freq;
 | 
			
		||||
    /**
 | 
			
		||||
     * Workaround for ESP32P4,
 | 
			
		||||
     * f_cpu >= f_mspi
 | 
			
		||||
     */
 | 
			
		||||
    if (((target_cpu_freq) < CONFIG_ESPTOOLPY_FLASHFREQ_VAL)
 | 
			
		||||
#if CONFIG_SPIRAM
 | 
			
		||||
        || ((target_cpu_freq) < CONFIG_SPIRAM_SPEED)
 | 
			
		||||
#endif
 | 
			
		||||
    ) {
 | 
			
		||||
        mspi_timing_change_speed_mode_cache_safe(true);
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    (void) target_cpu_src_freq;
 | 
			
		||||
    (void) target_cpu_freq;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void esp_clk_utils_mspi_speed_mode_sync_after_cpu_freq_switching(uint32_t target_cpu_src_freq, uint32_t target_cpu_freq)
 | 
			
		||||
{
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
    (void) target_cpu_freq;
 | 
			
		||||
    if (target_cpu_src_freq > clk_ll_xtal_load_freq_mhz()) {
 | 
			
		||||
        mspi_timing_change_speed_mode_cache_safe(false);
 | 
			
		||||
    }
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32P4
 | 
			
		||||
    (void) target_cpu_src_freq;
 | 
			
		||||
    /**
 | 
			
		||||
     * Workaround for ESP32P4,
 | 
			
		||||
     * f_cpu >= f_mspi
 | 
			
		||||
     */
 | 
			
		||||
    if (((target_cpu_freq) >= CONFIG_ESPTOOLPY_FLASHFREQ_VAL)
 | 
			
		||||
#if CONFIG_SPIRAM
 | 
			
		||||
        && ((target_cpu_freq) >= CONFIG_SPIRAM_SPEED)
 | 
			
		||||
#endif
 | 
			
		||||
    ) {
 | 
			
		||||
        mspi_timing_change_speed_mode_cache_safe(false);
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    (void) target_cpu_src_freq;
 | 
			
		||||
    (void) target_cpu_freq;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "soc/rtc.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Sync MSPI speed mode before CPU frequency switching, only needed when frequency is decreasing.
 | 
			
		||||
 *
 | 
			
		||||
 * @param target_cpu_src_freq   Target clock source frequency for CPU frequency switching
 | 
			
		||||
 * @param target_cpu_freq       CPU frequency switching target frequency
 | 
			
		||||
 */
 | 
			
		||||
void esp_clk_utils_mspi_speed_mode_sync_before_cpu_freq_switching(uint32_t target_cpu_src_freq, uint32_t target_cpu_freq);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Sync MSPI speed mode after CPU frequency switching, only needed when frequency is upcreasing.
 | 
			
		||||
 *
 | 
			
		||||
 * @param target_cpu_src_freq Target clock source frequency for CPU frequency switching
 | 
			
		||||
 * @param target_cpu_freq     CPU frequency switching target frequency
 | 
			
		||||
 */
 | 
			
		||||
void esp_clk_utils_mspi_speed_mode_sync_after_cpu_freq_switching(uint32_t target_cpu_src_freq, uint32_t target_cpu_freq);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -13,6 +13,7 @@ entries:
 | 
			
		||||
    cpu: esp_cpu_compare_and_set (noflash)
 | 
			
		||||
    esp_memory_utils (noflash)
 | 
			
		||||
    rtc_clk (noflash)
 | 
			
		||||
    clk_utils (noflash)
 | 
			
		||||
    if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y:
 | 
			
		||||
        rtc_init:rtc_vddsdio_get_config (noflash)
 | 
			
		||||
        rtc_init:rtc_vddsdio_set_config (noflash)
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
#include "esp_memory_utils.h"
 | 
			
		||||
#include "esp_sleep.h"
 | 
			
		||||
#include "esp_private/esp_clk_tree_common.h"
 | 
			
		||||
#include "esp_private/esp_clk_utils.h"
 | 
			
		||||
#include "esp_private/esp_sleep_internal.h"
 | 
			
		||||
#include "esp_private/esp_timer_private.h"
 | 
			
		||||
#include "esp_private/rtc_clk.h"
 | 
			
		||||
@@ -81,9 +82,6 @@
 | 
			
		||||
#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"
 | 
			
		||||
@@ -96,7 +94,6 @@
 | 
			
		||||
#include "esp_private/gpio.h"
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
#include "esp32s3/rom/rtc.h"
 | 
			
		||||
#include "esp_private/mspi_timing_tuning.h"
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
#include "esp32c3/rom/rtc.h"
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32C2
 | 
			
		||||
@@ -824,9 +821,9 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t sleep_flags, esp_sleep_mode_
 | 
			
		||||
    }
 | 
			
		||||
#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);
 | 
			
		||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
 | 
			
		||||
    uint32_t xtal_freq = rtc_clk_xtal_freq_get();
 | 
			
		||||
    esp_clk_utils_mspi_speed_mode_sync_before_cpu_freq_switching(xtal_freq, xtal_freq);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
 | 
			
		||||
@@ -1128,14 +1125,9 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t sleep_flags, esp_sleep_mode_
 | 
			
		||||
        }
 | 
			
		||||
        misc_modules_wake_prepare(sleep_flags);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
    }
 | 
			
		||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
 | 
			
		||||
    esp_clk_utils_mspi_speed_mode_sync_after_cpu_freq_switching(cpu_freq_config.source_freq_mhz, cpu_freq_config.freq_mhz);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // re-enable UART output
 | 
			
		||||
    resume_uarts();
 | 
			
		||||
    return result ? ESP_ERR_SLEEP_REJECT : ESP_OK;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 * SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
@@ -49,9 +49,7 @@
 | 
			
		||||
#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_private/esp_clk_utils.h"
 | 
			
		||||
#include "esp_sleep.h"
 | 
			
		||||
#include "esp_memory_utils.h"
 | 
			
		||||
 | 
			
		||||
@@ -669,16 +667,12 @@ 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 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
 | 
			
		||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
 | 
			
		||||
        esp_clk_utils_mspi_speed_mode_sync_before_cpu_freq_switching(new_config.source_freq_mhz, new_config.freq_mhz);
 | 
			
		||||
#endif
 | 
			
		||||
        rtc_clk_cpu_freq_set_config_fast(&new_config);
 | 
			
		||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
 | 
			
		||||
        esp_clk_utils_mspi_speed_mode_sync_after_cpu_freq_switching(new_config.source_freq_mhz, new_config.freq_mhz);
 | 
			
		||||
#endif
 | 
			
		||||
        if (!switch_down) {
 | 
			
		||||
            on_freq_update(old_ticks_per_us, new_ticks_per_us);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
@@ -9,10 +9,11 @@
 | 
			
		||||
#include "esp_cpu.h"
 | 
			
		||||
#include "soc/soc.h"
 | 
			
		||||
#include "soc/soc_caps.h"
 | 
			
		||||
#include "hal/clk_tree_ll.h"
 | 
			
		||||
#include "esp_private/esp_clk_utils.h"
 | 
			
		||||
#include "esp_private/rtc_clk.h"
 | 
			
		||||
#include "esp_private/panic_internal.h"
 | 
			
		||||
#include "esp_private/system_internal.h"
 | 
			
		||||
#include "esp_private/mspi_timing_tuning.h"
 | 
			
		||||
#include "esp_heap_caps.h"
 | 
			
		||||
#include "esp_rom_uart.h"
 | 
			
		||||
#include "esp_rom_sys.h"
 | 
			
		||||
@@ -36,15 +37,9 @@ void IRAM_ATTR esp_restart_noos_dig(void)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
 | 
			
		||||
    /**
 | 
			
		||||
     * Turn down MSPI speed
 | 
			
		||||
     *
 | 
			
		||||
     * We set MSPI clock to a high speed one before, ROM doesn't have such high speed clock source option.
 | 
			
		||||
     * This function will change clock source to a ROM supported one when system restarts.
 | 
			
		||||
     */
 | 
			
		||||
    mspi_timing_change_speed_mode_cache_safe(true);
 | 
			
		||||
#endif  //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
 | 
			
		||||
 | 
			
		||||
    uint32_t xtal_freq = clk_ll_xtal_load_freq_mhz();
 | 
			
		||||
    esp_clk_utils_mspi_speed_mode_sync_before_cpu_freq_switching(xtal_freq, xtal_freq);
 | 
			
		||||
#endif
 | 
			
		||||
    // switch to XTAL (otherwise we will keep running from the PLL)
 | 
			
		||||
    rtc_clk_cpu_set_to_default_config();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -222,6 +222,8 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_get_freq_mhz(v
 | 
			
		||||
    return PCR.sysclk_conf.clk_xtal_freq;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define clk_ll_xtal_load_freq_mhz() clk_ll_xtal_get_freq_mhz()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get SPLL_CLK frequency
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -215,6 +215,8 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_get_freq_mhz(v
 | 
			
		||||
    return PCR.sysclk_conf.clk_xtal_freq;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define clk_ll_xtal_load_freq_mhz() clk_ll_xtal_get_freq_mhz()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get SPLL_CLK frequency
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -10,3 +10,10 @@ choice ESPTOOLPY_FLASHFREQ
 | 
			
		||||
    config ESPTOOLPY_FLASHFREQ_20M
 | 
			
		||||
        bool "20 MHz"
 | 
			
		||||
endchoice
 | 
			
		||||
 | 
			
		||||
config ESPTOOLPY_FLASHFREQ_VAL
 | 
			
		||||
    int
 | 
			
		||||
    default 20 if ESPTOOLPY_FLASHFREQ_20M
 | 
			
		||||
    default 40 if ESPTOOLPY_FLASHFREQ_40M
 | 
			
		||||
    default 80 if ESPTOOLPY_FLASHFREQ_80M
 | 
			
		||||
    default 120 if ESPTOOLPY_FLASHFREQ_120M
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user