fix(driver): fix drivers clock management

This commit is contained in:
wuzhenghui
2026-07-22 16:32:12 +08:00
parent 11ccd4c304
commit 7c75525edd
7 changed files with 82 additions and 3 deletions
+17 -1
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -27,6 +27,7 @@
#include "esp_private/etm_interface.h"
#include "esp_private/sleep_retention.h"
#include "esp_private/critical_section.h"
#include "esp_private/esp_clk_tree_common.h"
#define ETM_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
@@ -63,6 +64,9 @@ struct esp_etm_channel_t {
_Atomic etm_chan_fsm_t fsm; // record ETM channel's driver state
esp_etm_event_handle_t event; // which event is connect to the channel
esp_etm_task_handle_t task; // which task is connect to the channel
#if ETM_LL_SUPPORT(CLOCK_SRC)
etm_clock_source_t clk_src; // function clock source enabled for this channel
#endif
};
// ETM driver platform, it's always a singleton
@@ -272,6 +276,8 @@ esp_err_t esp_etm_new_channel(const esp_etm_channel_config_t *config, esp_etm_ch
if (clk_src == 0) {
clk_src = ETM_CLK_SRC_DEFAULT;
}
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), err, TAG, "clock source enable failed");
chan->clk_src = clk_src;
etm_ll_set_clock_source(group_id, clk_src);
#endif
@@ -290,6 +296,11 @@ esp_err_t esp_etm_new_channel(const esp_etm_channel_config_t *config, esp_etm_ch
err:
if (chan) {
#if ETM_LL_SUPPORT(CLOCK_SRC)
if (chan->clk_src != 0) {
esp_clk_tree_enable_src((soc_module_clk_t)chan->clk_src, false);
}
#endif
etm_chan_destroy(chan);
}
return ret;
@@ -310,6 +321,11 @@ esp_err_t esp_etm_del_channel(esp_etm_channel_handle_t chan)
etm_ll_channel_set_task(group->hal.regs, chan_id, 0);
ESP_LOGD(TAG, "del etm channel (%d,%d)", group_id, chan_id);
#if ETM_LL_SUPPORT(CLOCK_SRC)
// Back to hardware default clock selection, otherwise it might get stuck when stopping the bus during sleep process.
etm_ll_set_clock_source(group_id, ETM_CLK_SRC_XTAL);
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)chan->clk_src, false), TAG, "clock source disable failed");
#endif
// recycle memory resource
ESP_RETURN_ON_ERROR(etm_chan_destroy(chan), TAG, "destroy etm channel failed");
return ESP_OK;
@@ -6,6 +6,8 @@
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_check.h"
#include "esp_clk_tree.h"
#include "soc/soc_caps.h"
#include "modem/modem_clock_impl.h"
#include "esp_private/regi2c_ctrl.h"
@@ -212,7 +214,13 @@ static void IRAM_ATTR modem_clock_coex_configure(modem_clock_context_t *ctx, boo
#if SOC_MODEM_CLOCK_SOC_PLL_SOURCE_CG_SUPPORTED
static void IRAM_ATTR modem_clock_soc_pll_source_cg_configure(modem_clock_context_t *ctx, bool enable)
{
if (enable) {
ESP_ERROR_CHECK(esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F160M, true));
}
modem_clock_hal_enable_soc_pll_source_cg(ctx->hal, enable);
if (!enable) {
ESP_ERROR_CHECK(esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F160M, false));
}
}
#endif
@@ -144,6 +144,9 @@ uint32_t rtc_clk_cal_internal(soc_clk_freq_calculation_src_t cal_clk_sel, uint32
}
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
clk_ll_freq_calculation_set_divider(1);
// Back to always on clock source, Otherwise, if the source for this calibration is subsequently turned off,
// the next calibration will not be able to switch to the new calibration source.
clk_ll_freq_calulation_set_target(CLK_CAL_RC_SLOW);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {