mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
Merge branch 'feat/support_c5_esp_perip_clk_init' into 'master'
feat: optimize esp32c5 active power consumption Closes IDF-8844 See merge request espressif/esp-idf!36414
This commit is contained in:
@ -480,7 +480,7 @@ esp_err_t adc_digi_start(void)
|
||||
|
||||
adc_hal_digi_init(&s_adc_digi_ctx->hal);
|
||||
#if !CONFIG_IDF_TARGET_ESP32
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)(s_adc_digi_ctx->hal_digi_ctrlr_cfg.clk_src), true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(s_adc_digi_ctx->hal_digi_ctrlr_cfg.clk_src), true));
|
||||
#endif
|
||||
adc_hal_digi_controller_config(&s_adc_digi_ctx->hal, &s_adc_digi_ctx->hal_digi_ctrlr_cfg);
|
||||
|
||||
@ -524,6 +524,7 @@ esp_err_t adc_digi_stop(void)
|
||||
if (s_adc_digi_ctx->use_adc1) {
|
||||
adc_lock_release(ADC_UNIT_1);
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(s_adc_digi_ctx->hal_digi_ctrlr_cfg.clk_src), false));
|
||||
sar_periph_ctrl_adc_continuous_power_release();
|
||||
|
||||
return ESP_OK;
|
||||
|
@ -756,7 +756,7 @@ int adc1_get_raw(adc1_channel_t channel)
|
||||
|
||||
adc_apb_periph_claim();
|
||||
sar_periph_ctrl_adc_oneshot_power_acquire();
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true));
|
||||
adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);
|
||||
|
||||
adc_atten_t atten = s_atten1_single[channel];
|
||||
@ -775,6 +775,7 @@ int adc1_get_raw(adc1_channel_t channel)
|
||||
adc_hal_convert(ADC_UNIT_1, channel, clk_src_freq_hz, &raw_out);
|
||||
ADC_REG_LOCK_EXIT();
|
||||
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, false));
|
||||
sar_periph_ctrl_adc_oneshot_power_release();
|
||||
adc_apb_periph_free();
|
||||
adc_lock_release(ADC_UNIT_1);
|
||||
@ -820,7 +821,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
||||
|
||||
adc_apb_periph_claim();
|
||||
sar_periph_ctrl_adc_oneshot_power_acquire();
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true));
|
||||
adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);
|
||||
|
||||
#if SOC_ADC_ARBITER_SUPPORTED
|
||||
@ -838,6 +839,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
||||
ret = adc_hal_convert(ADC_UNIT_2, channel, clk_src_freq_hz, raw_out);
|
||||
ADC_REG_LOCK_EXIT();
|
||||
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, false));
|
||||
sar_periph_ctrl_adc_oneshot_power_release();
|
||||
adc_apb_periph_free();
|
||||
adc_lock_release(ADC_UNIT_2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -470,7 +470,7 @@ esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpw
|
||||
uint32_t group_pre_scale = clk_src_hz / group_resolution;
|
||||
uint32_t timer_pre_scale = group_resolution / timer_resolution;
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true));
|
||||
MCPWM_CLOCK_SRC_ATOMIC() {
|
||||
mcpwm_ll_group_set_clock_source(mcpwm_num, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT);
|
||||
mcpwm_ll_group_set_clock_prescale(mcpwm_num, group_pre_scale);
|
||||
@ -868,7 +868,7 @@ esp_err_t mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_cha
|
||||
uint32_t group_resolution = mcpwm_group_get_resolution(mcpwm_num);
|
||||
uint32_t group_pre_scale = clk_src_hz / group_resolution;
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true));
|
||||
MCPWM_CLOCK_SRC_ATOMIC() {
|
||||
mcpwm_ll_group_set_clock_source(mcpwm_num, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT);
|
||||
mcpwm_ll_group_set_clock_prescale(mcpwm_num, group_pre_scale);
|
||||
@ -910,6 +910,7 @@ esp_err_t mcpwm_capture_disable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_ch
|
||||
mcpwm_ll_capture_enable_channel(hal->dev, cap_channel, false);
|
||||
mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_channel), false);
|
||||
mcpwm_critical_exit(mcpwm_num);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, false));
|
||||
|
||||
mcpwm_mutex_lock(mcpwm_num);
|
||||
context[mcpwm_num].cap_isr_func[cap_channel].fn = NULL;
|
||||
|
@ -440,7 +440,7 @@ esp_err_t rmt_set_source_clk(rmt_channel_t channel, rmt_source_clk_t base_clk)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)base_clk, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)base_clk, true));
|
||||
// `rmt_clock_source_t` and `rmt_source_clk_t` are binary compatible, as the underlying enum entries come from the same `soc_module_clk_t`
|
||||
RMT_CLOCK_SRC_ATOMIC() {
|
||||
rmt_ll_set_group_clock_src(rmt_contex.hal.regs, channel, (rmt_clock_source_t)base_clk, 1, 0, 0);
|
||||
@ -606,7 +606,7 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
|
||||
#endif
|
||||
}
|
||||
esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &rmt_source_clk_hz);
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true));
|
||||
RMT_CLOCK_SRC_ATOMIC() {
|
||||
rmt_ll_set_group_clock_src(dev, channel, clk_src, 1, 0, 0);
|
||||
rmt_ll_enable_group_clock(dev, true);
|
||||
|
@ -328,7 +328,7 @@ esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer
|
||||
if (config->clk_src) {
|
||||
clk_src = config->clk_src;
|
||||
}
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true));
|
||||
GPTIMER_CLOCK_SRC_ATOMIC() {
|
||||
// although `clk_src` is of `timer_src_clk_t` type, but it's binary compatible with `gptimer_clock_source_t`,
|
||||
// as the underlying enum entries come from the same `soc_module_clk_t`
|
||||
@ -364,6 +364,7 @@ esp_err_t timer_deinit(timer_group_t group_num, timer_idx_t timer_num)
|
||||
GPTIMER_CLOCK_SRC_ATOMIC() {
|
||||
timer_ll_enable_clock(group_num, hal->timer_id, false);
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)p_timer_obj[group_num][timer_num]->clk_src, false));
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(timer_num), false);
|
||||
timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_num));
|
||||
|
@ -321,10 +321,10 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle)
|
||||
adc_hal_set_controller(ADC_UNIT_2, ADC_HAL_CONTINUOUS_READ_MODE);
|
||||
}
|
||||
|
||||
adc_hal_digi_init(&handle->hal);
|
||||
#if !CONFIG_IDF_TARGET_ESP32
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal_digi_ctrlr_cfg.clk_src), true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal_digi_ctrlr_cfg.clk_src), true));
|
||||
#endif
|
||||
adc_hal_digi_init(&handle->hal);
|
||||
adc_hal_digi_controller_config(&handle->hal, &handle->hal_digi_ctrlr_cfg);
|
||||
adc_hal_digi_enable(false);
|
||||
|
||||
@ -362,7 +362,9 @@ esp_err_t adc_continuous_stop(adc_continuous_handle_t handle)
|
||||
#endif
|
||||
|
||||
adc_hal_digi_deinit();
|
||||
|
||||
#if !CONFIG_IDF_TARGET_ESP32
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal_digi_ctrlr_cfg.clk_src), false));
|
||||
#endif
|
||||
if (handle->use_adc2) {
|
||||
adc_lock_release(ADC_UNIT_2);
|
||||
}
|
||||
@ -377,7 +379,6 @@ esp_err_t adc_continuous_stop(adc_continuous_handle_t handle)
|
||||
ESP_RETURN_ON_ERROR(esp_pm_lock_release(handle->pm_lock), ADC_TAG, "release pm_lock failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
ANALOG_CLOCK_DISABLE();
|
||||
|
||||
return ESP_OK;
|
||||
|
@ -156,6 +156,9 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
|
||||
if (init_config->ulp_mode == ADC_ULP_MODE_DISABLE) {
|
||||
sar_periph_ctrl_adc_oneshot_power_acquire();
|
||||
} else {
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(unit->hal.clk_src), true), err, TAG, "clock source enable failed");
|
||||
#endif
|
||||
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
|
||||
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, true);
|
||||
#endif
|
||||
@ -189,9 +192,6 @@ esp_err_t adc_oneshot_config_channel(adc_oneshot_unit_handle_t handle, adc_chann
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
adc_oneshot_hal_channel_config(hal, &cfg, channel);
|
||||
if (handle->ulp_mode) {
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)(hal->clk_src), true);
|
||||
#endif
|
||||
adc_oneshot_hal_setup(hal, channel);
|
||||
}
|
||||
portEXIT_CRITICAL(&rtc_spinlock);
|
||||
@ -210,7 +210,7 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan,
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true));
|
||||
#endif
|
||||
ANALOG_CLOCK_ENABLE();
|
||||
adc_oneshot_hal_setup(&(handle->hal), chan);
|
||||
@ -222,6 +222,9 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan,
|
||||
bool valid = false;
|
||||
valid = adc_oneshot_hal_convert(&(handle->hal), out_raw);
|
||||
ANALOG_CLOCK_DISABLE();
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), false));
|
||||
#endif
|
||||
|
||||
portEXIT_CRITICAL(&rtc_spinlock);
|
||||
adc_lock_release(handle->unit_id);
|
||||
@ -238,7 +241,7 @@ esp_err_t adc_oneshot_read_isr(adc_oneshot_unit_handle_t handle, adc_channel_t c
|
||||
portENTER_CRITICAL_SAFE(&rtc_spinlock);
|
||||
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true));
|
||||
#endif
|
||||
ANALOG_CLOCK_ENABLE();
|
||||
adc_oneshot_hal_setup(&(handle->hal), chan);
|
||||
@ -249,6 +252,9 @@ esp_err_t adc_oneshot_read_isr(adc_oneshot_unit_handle_t handle, adc_channel_t c
|
||||
#endif
|
||||
adc_oneshot_hal_convert(&(handle->hal), out_raw);
|
||||
ANALOG_CLOCK_DISABLE();
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), false));
|
||||
#endif
|
||||
|
||||
portEXIT_CRITICAL_SAFE(&rtc_spinlock);
|
||||
|
||||
@ -271,7 +277,6 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle)
|
||||
_lock_release(&s_ctx.mutex);
|
||||
|
||||
ESP_LOGD(TAG, "adc unit%"PRId32" is deleted", handle->unit_id);
|
||||
free(handle);
|
||||
|
||||
if (ulp_mode == ADC_ULP_MODE_DISABLE) {
|
||||
sar_periph_ctrl_adc_oneshot_power_release();
|
||||
@ -279,7 +284,9 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle)
|
||||
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
|
||||
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, false);
|
||||
#endif
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), false));
|
||||
}
|
||||
free(handle);
|
||||
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
//To free the APB_SARADC periph if needed
|
||||
|
@ -119,7 +119,7 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_
|
||||
#endif
|
||||
|
||||
mipi_csi_phy_clock_source_t clk_src = !config->clk_src ? MIPI_CSI_PHY_CLK_SRC_DEFAULT : config->clk_src;
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), err, TAG, "clock source enable failed");
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
// phy clock source setting
|
||||
mipi_csi_ll_set_phy_clock_source(ctlr->csi_id, clk_src);
|
||||
|
@ -332,7 +332,7 @@ esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const e
|
||||
}
|
||||
}
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true));
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
cam_ll_enable_clk(ctlr_id, true);
|
||||
cam_ll_select_clk_src(ctlr_id, clk_src);
|
||||
|
@ -108,6 +108,9 @@ static void gptimer_unregister_from_group(gptimer_t *timer)
|
||||
|
||||
static esp_err_t gptimer_destroy(gptimer_t *timer)
|
||||
{
|
||||
if (timer->clk_src) {
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(timer->clk_src), false), TAG, "clock source disable failed");
|
||||
}
|
||||
#if CONFIG_PM_ENABLE
|
||||
if (timer->pm_lock) {
|
||||
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(timer->pm_lock), TAG, "delete pm_lock failed");
|
||||
@ -157,6 +160,7 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
|
||||
// initialize HAL layer
|
||||
timer_hal_init(&timer->hal, group_id, timer_id);
|
||||
// select clock source, set clock resolution
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)config->clk_src, true), err, TAG, "clock source enable failed");
|
||||
ESP_GOTO_ON_ERROR(gptimer_select_periph_clock(timer, config->clk_src, config->resolution_hz), err, TAG, "set periph clock failed");
|
||||
// initialize counter value to zero
|
||||
timer_hal_set_counter_value(&timer->hal, 0);
|
||||
|
@ -99,6 +99,7 @@ esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t s
|
||||
periph_rtc_dig_clk8m_enable();
|
||||
}
|
||||
#endif // SOC_TIMER_GROUP_SUPPORT_RC_FAST
|
||||
timer->clk_src = src_clk;
|
||||
|
||||
// get clock source frequency
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &counter_src_hz),
|
||||
@ -139,7 +140,6 @@ esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t s
|
||||
}
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)src_clk, true);
|
||||
// !!! HARDWARE SHARED RESOURCE !!!
|
||||
// on some ESP chip, different peripheral's clock source setting are mixed in the same register
|
||||
// so we need to make this done in an atomic way
|
||||
@ -147,7 +147,6 @@ esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t s
|
||||
timer_ll_set_clock_source(group_id, timer_id, src_clk);
|
||||
timer_ll_enable_clock(group_id, timer_id, true);
|
||||
}
|
||||
timer->clk_src = src_clk;
|
||||
uint32_t prescale = counter_src_hz / resolution_hz; // potential resolution loss here
|
||||
timer_ll_set_clock_prescale(timer->hal.dev, timer_id, prescale);
|
||||
timer->resolution_hz = counter_src_hz / prescale; // this is the real resolution
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "hal/timer_hal.h"
|
||||
#include "hal/timer_ll.h"
|
||||
#include "clk_ctrl_os.h"
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
|
||||
|
@ -53,6 +53,7 @@ typedef enum {
|
||||
---------------------------------------------------------------*/
|
||||
typedef struct isp_processor_t {
|
||||
int proc_id;
|
||||
isp_clk_src_t clk_src;
|
||||
isp_hal_context_t hal;
|
||||
#if SOC_ISP_SHARE_CSI_BRG
|
||||
int csi_brg_id;
|
||||
|
@ -112,14 +112,13 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_
|
||||
if (out_clk_freq_hz != proc_config->clk_hz) {
|
||||
ESP_LOGW(TAG, "precision loss, real output frequency: %"PRIu32"Hz", out_clk_freq_hz);
|
||||
}
|
||||
;
|
||||
isp_hal_init(&proc->hal, proc->proc_id);
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), err, TAG, "clock source enable failed");
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
isp_ll_select_clk_source(proc->hal.hw, clk_src);
|
||||
isp_ll_set_clock_div(proc->hal.hw, &clk_div);
|
||||
}
|
||||
|
||||
proc->clk_src = clk_src;
|
||||
proc->isp_fsm = ISP_FSM_INIT;
|
||||
proc->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
@ -197,6 +196,7 @@ esp_err_t esp_isp_del_processor(isp_proc_handle_t proc)
|
||||
#if SOC_ISP_SHARE_CSI_BRG
|
||||
ESP_RETURN_ON_ERROR(mipi_csi_brg_declaim(proc->csi_brg_id), TAG, "declaim csi bridge fail");
|
||||
#endif
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(proc->clk_src), false), TAG, "clock source disable failed");
|
||||
free(proc);
|
||||
|
||||
return ESP_OK;
|
||||
|
@ -698,7 +698,7 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
|
||||
if (p_ledc_obj[speed_mode]->glb_clk != glb_clk) {
|
||||
// TODO: release old glb_clk (if not UNINIT), and acquire new glb_clk [clk_tree]
|
||||
p_ledc_obj[speed_mode]->glb_clk = glb_clk;
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)glb_clk, true);
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)glb_clk, true), LEDC_TAG, "clock source enable failed");
|
||||
LEDC_FUNC_CLOCK_ATOMIC() {
|
||||
ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), glb_clk);
|
||||
}
|
||||
@ -863,7 +863,7 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf)
|
||||
else if (new_speed_mode_ctx_created) {
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
if (p_ledc_obj[speed_mode]->glb_clk == LEDC_SLOW_CLK_UNINIT) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)LEDC_LL_GLOBAL_CLK_DEFAULT, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)LEDC_LL_GLOBAL_CLK_DEFAULT, true));
|
||||
ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), LEDC_LL_GLOBAL_CLK_DEFAULT);
|
||||
}
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
|
@ -465,7 +465,7 @@ static void timer_frequency_test(ledc_channel_t channel, ledc_timer_bit_t timer_
|
||||
} else if (clk_src_freq == 60 * 1000 * 1000) {
|
||||
theoretical_freq = 8993;
|
||||
}
|
||||
frequency_set_get(speed_mode, timer, 9000, theoretical_freq, 50);
|
||||
frequency_set_get(speed_mode, timer, 9000, theoretical_freq, 60);
|
||||
#endif
|
||||
|
||||
// Pause and de-configure the timer so that it won't affect the following test cases
|
||||
|
@ -201,7 +201,7 @@ esp_err_t mcpwm_select_periph_clock(mcpwm_group_t *group, soc_module_clk_t clk_s
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed");
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), TAG, "clock source enable failed");
|
||||
MCPWM_CLOCK_SRC_ATOMIC() {
|
||||
mcpwm_ll_group_set_clock_source(group_id, clk_src);
|
||||
}
|
||||
|
@ -466,6 +466,7 @@ static esp_err_t parlio_select_periph_clock(parlio_rx_unit_handle_t rx_unit, con
|
||||
{
|
||||
parlio_hal_context_t *hal = &rx_unit->base.group->hal;
|
||||
parlio_clock_source_t clk_src = config->clk_src;
|
||||
rx_unit->clk_src = clk_src;
|
||||
uint32_t src_freq_hz = 0;
|
||||
uint32_t exp_freq_hz = 0;
|
||||
hal_utils_clk_div_t clk_div = {
|
||||
@ -510,14 +511,12 @@ static esp_err_t parlio_select_periph_clock(parlio_rx_unit_handle_t rx_unit, con
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
/* Set clock configuration */
|
||||
PARLIO_CLOCK_SRC_ATOMIC() {
|
||||
parlio_ll_rx_set_clock_source(hal->regs, clk_src);
|
||||
parlio_ll_rx_set_clock_div(hal->regs, &clk_div);
|
||||
}
|
||||
|
||||
rx_unit->clk_src = clk_src;
|
||||
/* warning if precision lost due to division */
|
||||
if ((clk_src != PARLIO_CLK_SRC_EXTERNAL) &&
|
||||
(config->exp_clk_freq_hz != rx_unit->cfg.exp_clk_freq_hz)) {
|
||||
@ -571,6 +570,9 @@ static esp_err_t parlio_destroy_rx_unit(parlio_rx_unit_handle_t rx_unit)
|
||||
if (rx_unit->base.group) {
|
||||
parlio_unregister_unit_from_group(&rx_unit->base);
|
||||
}
|
||||
if (rx_unit->clk_src) {
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)rx_unit->clk_src, false), TAG, "clock source disable failed");
|
||||
}
|
||||
/* Free the RX unit */
|
||||
free(rx_unit);
|
||||
return ESP_OK;
|
||||
@ -637,6 +639,7 @@ esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_un
|
||||
}
|
||||
parlio_ll_rx_start(hal->regs, false);
|
||||
/* parlio_ll_clock_source_t and parlio_clock_source_t are binary compatible if the clock source is from internal */
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(config->clk_src), true), err, TAG, "clock source enable failed");
|
||||
ESP_GOTO_ON_ERROR(parlio_select_periph_clock(unit, config), err, TAG, "set clock source failed");
|
||||
/* Set the data width */
|
||||
parlio_ll_rx_set_bus_width(hal->regs, config->data_width);
|
||||
|
@ -74,6 +74,9 @@ static esp_err_t parlio_destroy_tx_unit(parlio_tx_unit_t *tx_unit)
|
||||
ESP_RETURN_ON_ERROR(gdma_del_link_list(tx_unit->dma_link[i]), TAG, "delete dma link list failed");
|
||||
}
|
||||
}
|
||||
if (tx_unit->clk_src) {
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)tx_unit->clk_src, false), TAG, "clock source disable failed");
|
||||
}
|
||||
free(tx_unit);
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -182,6 +185,7 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par
|
||||
{
|
||||
parlio_hal_context_t *hal = &tx_unit->base.group->hal;
|
||||
parlio_clock_source_t clk_src = config->clk_src;
|
||||
tx_unit->clk_src = clk_src;
|
||||
if (config->clk_in_gpio_num >= 0 && clk_src != PARLIO_CLK_SRC_EXTERNAL) {
|
||||
ESP_LOGW(TAG, "input clock GPIO is set, use external clk src");
|
||||
clk_src = PARLIO_CLK_SRC_EXTERNAL;
|
||||
@ -223,7 +227,6 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par
|
||||
#else
|
||||
tx_unit->out_clk_freq_hz = hal_utils_calc_clk_div_integer(&clk_info, &clk_div.integer);
|
||||
#endif
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
PARLIO_CLOCK_SRC_ATOMIC() {
|
||||
// turn on the tx module clock to sync the clock divider configuration because of the CDC (Cross Domain Crossing)
|
||||
parlio_ll_tx_enable_clock(hal->regs, true);
|
||||
@ -235,8 +238,6 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par
|
||||
if (tx_unit->out_clk_freq_hz != config->output_clk_freq_hz) {
|
||||
ESP_LOGW(TAG, "precision loss, real output frequency: %"PRIu32, tx_unit->out_clk_freq_hz);
|
||||
}
|
||||
tx_unit->clk_src = clk_src;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -284,6 +285,7 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un
|
||||
parlio_group_t *group = unit->base.group;
|
||||
parlio_hal_context_t *hal = &group->hal;
|
||||
// select the clock source
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(config->clk_src), true), err, TAG, "clock source enable failed");
|
||||
ESP_GOTO_ON_ERROR(parlio_select_periph_clock(unit, config), err, TAG, "set clock source failed");
|
||||
|
||||
// install interrupt service
|
||||
|
@ -240,7 +240,7 @@ esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed");
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), TAG, "clock source enable failed");
|
||||
uint32_t real_div;
|
||||
#if SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
uint32_t periph_src_clk_hz = 0;
|
||||
|
@ -987,7 +987,7 @@ static esp_err_t sd_host_reset(sd_host_sdmmc_ctlr_t *ctlr)
|
||||
*/
|
||||
static void sd_host_set_clk_div(sd_host_sdmmc_ctlr_t *ctlr, soc_periph_sdmmc_clk_src_t src, int div)
|
||||
{
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)src, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)src, true));
|
||||
SD_HOST_SDMMC_CLK_SRC_ATOMIC() {
|
||||
sdmmc_ll_set_clock_div(ctlr->hal.dev, div);
|
||||
sdmmc_ll_select_clk_source(ctlr->hal.dev, src);
|
||||
|
@ -424,7 +424,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
||||
spi_clock_source_t clk_src = dev_config->clock_source ? dev_config->clock_source : SPI_CLK_SRC_DEFAULT;
|
||||
uint32_t clock_source_hz = 0;
|
||||
uint32_t clock_source_div = 1;
|
||||
esp_clk_tree_enable_src(clk_src, true);
|
||||
SPI_CHECK(esp_clk_tree_enable_src(clk_src, true) == ESP_OK, "clock source enable failed", ESP_ERR_INVALID_STATE);
|
||||
esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clock_source_hz);
|
||||
#if SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
|
||||
SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= MIN(clock_source_hz / 2, (80 * 1000000))), "invalid sclk speed", ESP_ERR_INVALID_ARG);
|
||||
@ -601,7 +601,7 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle)
|
||||
periph_rtc_dig_clk8m_disable();
|
||||
}
|
||||
#endif
|
||||
esp_clk_tree_enable_src(handle->hal_dev.timing_conf.clock_source, false);
|
||||
SPI_CHECK(esp_clk_tree_enable_src(handle->hal_dev.timing_conf.clock_source, false) == ESP_OK, "clock source disable failed", ESP_ERR_INVALID_STATE);
|
||||
|
||||
//return
|
||||
int spics_io_num = handle->cfg.spics_io_num;
|
||||
|
@ -376,6 +376,8 @@ static esp_err_t _node_set_bit_timing(twai_node_handle_t node, const twai_timing
|
||||
#endif
|
||||
|
||||
if (new_clock_src != twai_ctx->curr_clk_src) {
|
||||
// TODO: IDF-13144
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(new_clock_src), true));
|
||||
twai_ctx->curr_clk_src = new_clock_src;
|
||||
_twai_rcc_clock_sel(twai_ctx->ctrlr_id, new_clock_src);
|
||||
}
|
||||
|
@ -109,6 +109,7 @@ static const char *UART_TAG = "uart";
|
||||
#define UART_CONTEXT_INIT_DEF(uart_num) { \
|
||||
.port_id = uart_num, \
|
||||
.hal.dev = UART_LL_GET_HW(uart_num), \
|
||||
.sclk_sel = -1, \
|
||||
INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) \
|
||||
.hw_enabled = false, \
|
||||
.tx_io_num = -1, \
|
||||
@ -175,6 +176,7 @@ typedef struct uart_context_t {
|
||||
_lock_t mutex; /*!< Protect uart_module_enable, uart_module_disable, retention, etc. */
|
||||
uart_port_t port_id;
|
||||
uart_hal_context_t hal; /*!< UART hal context*/
|
||||
soc_module_clk_t sclk_sel; /*!< UART port clock source selection*/
|
||||
DECLARE_CRIT_SECTION_LOCK_IN_STRUCT(spinlock)
|
||||
bool hw_enabled;
|
||||
int tx_io_num;
|
||||
@ -973,6 +975,56 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
|
||||
|
||||
uart_module_enable(uart_num);
|
||||
|
||||
soc_module_clk_t uart_sclk_sel = 0; // initialize to an invalid module clock ID
|
||||
if (uart_num < SOC_UART_HP_NUM) {
|
||||
uart_sclk_sel = (soc_module_clk_t)((uart_config->source_clk) ? uart_config->source_clk : UART_SCLK_DEFAULT); // if no specifying the clock source (soc_module_clk_t starts from 1), then just use the default clock
|
||||
}
|
||||
#if (SOC_UART_LP_NUM >= 1)
|
||||
else {
|
||||
uart_sclk_sel = (soc_module_clk_t)((uart_config->lp_source_clk) ? uart_config->lp_source_clk : LP_UART_SCLK_DEFAULT);
|
||||
}
|
||||
#endif
|
||||
uint32_t sclk_freq;
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(uart_sclk_sel, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "invalid src_clk");
|
||||
|
||||
// Enable the newly selected clock source.
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(uart_sclk_sel, true), UART_TAG, "clock source enable failed");
|
||||
#if SOC_UART_SUPPORT_RTC_CLK
|
||||
if (uart_sclk_sel == (soc_module_clk_t)UART_SCLK_RTC) {
|
||||
periph_rtc_dig_clk8m_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool success = false;
|
||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
soc_module_clk_t uart_old_sclk_sel = uart_context[uart_num].sclk_sel;
|
||||
uart_context[uart_num].sclk_sel = uart_sclk_sel;
|
||||
uart_hal_init(&(uart_context[uart_num].hal), uart_num);
|
||||
if (uart_num < SOC_UART_HP_NUM) {
|
||||
HP_UART_SRC_CLK_ATOMIC() {
|
||||
uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_sclk_sel);
|
||||
success = uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq);
|
||||
}
|
||||
}
|
||||
#if (SOC_UART_LP_NUM >= 1)
|
||||
else {
|
||||
LP_UART_SRC_CLK_ATOMIC() {
|
||||
lp_uart_ll_set_source_clk(uart_context[uart_num].hal.dev, (soc_periph_lp_uart_clk_src_t)uart_sclk_sel);
|
||||
}
|
||||
success = lp_uart_ll_set_baudrate(uart_context[uart_num].hal.dev, uart_config->baud_rate, sclk_freq);
|
||||
}
|
||||
#endif
|
||||
// Disable the previously selected clock source
|
||||
uart_hal_set_parity(&(uart_context[uart_num].hal), uart_config->parity);
|
||||
uart_hal_set_data_bit_num(&(uart_context[uart_num].hal), uart_config->data_bits);
|
||||
uart_hal_set_stop_bits(&(uart_context[uart_num].hal), uart_config->stop_bits);
|
||||
uart_hal_set_tx_idle_num(&(uart_context[uart_num].hal), UART_TX_IDLE_NUM_DEFAULT);
|
||||
uart_hal_set_hw_flow_ctrl(&(uart_context[uart_num].hal), uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh);
|
||||
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
uart_hal_rxfifo_rst(&(uart_context[uart_num].hal));
|
||||
uart_hal_txfifo_rst(&(uart_context[uart_num].hal));
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(uart_old_sclk_sel, false), UART_TAG, "clock source disable failed");
|
||||
ESP_RETURN_ON_FALSE(success, ESP_FAIL, UART_TAG, "baud rate unachievable");
|
||||
#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
// Create sleep retention link if desired
|
||||
if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) {
|
||||
@ -994,52 +1046,6 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
|
||||
_lock_release(&(uart_context[uart_num].mutex));
|
||||
}
|
||||
#endif
|
||||
|
||||
soc_module_clk_t uart_sclk_sel = 0; // initialize to an invalid module clock ID
|
||||
if (uart_num < SOC_UART_HP_NUM) {
|
||||
uart_sclk_sel = (soc_module_clk_t)((uart_config->source_clk) ? uart_config->source_clk : UART_SCLK_DEFAULT); // if no specifying the clock source (soc_module_clk_t starts from 1), then just use the default clock
|
||||
}
|
||||
#if (SOC_UART_LP_NUM >= 1)
|
||||
else {
|
||||
uart_sclk_sel = (soc_module_clk_t)((uart_config->lp_source_clk) ? uart_config->lp_source_clk : LP_UART_SCLK_DEFAULT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_UART_SUPPORT_RTC_CLK
|
||||
if (uart_sclk_sel == (soc_module_clk_t)UART_SCLK_RTC) {
|
||||
periph_rtc_dig_clk8m_enable();
|
||||
}
|
||||
#endif
|
||||
uint32_t sclk_freq;
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(uart_sclk_sel, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "invalid src_clk");
|
||||
|
||||
bool success = false;
|
||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
uart_hal_init(&(uart_context[uart_num].hal), uart_num);
|
||||
if (uart_num < SOC_UART_HP_NUM) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)uart_sclk_sel, true);
|
||||
HP_UART_SRC_CLK_ATOMIC() {
|
||||
uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_sclk_sel);
|
||||
success = uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq);
|
||||
}
|
||||
}
|
||||
#if (SOC_UART_LP_NUM >= 1)
|
||||
else {
|
||||
LP_UART_SRC_CLK_ATOMIC() {
|
||||
lp_uart_ll_set_source_clk(uart_context[uart_num].hal.dev, (soc_periph_lp_uart_clk_src_t)uart_sclk_sel);
|
||||
}
|
||||
success = lp_uart_ll_set_baudrate(uart_context[uart_num].hal.dev, uart_config->baud_rate, sclk_freq);
|
||||
}
|
||||
#endif
|
||||
uart_hal_set_parity(&(uart_context[uart_num].hal), uart_config->parity);
|
||||
uart_hal_set_data_bit_num(&(uart_context[uart_num].hal), uart_config->data_bits);
|
||||
uart_hal_set_stop_bits(&(uart_context[uart_num].hal), uart_config->stop_bits);
|
||||
uart_hal_set_tx_idle_num(&(uart_context[uart_num].hal), UART_TX_IDLE_NUM_DEFAULT);
|
||||
uart_hal_set_hw_flow_ctrl(&(uart_context[uart_num].hal), uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh);
|
||||
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
uart_hal_rxfifo_rst(&(uart_context[uart_num].hal));
|
||||
uart_hal_txfifo_rst(&(uart_context[uart_num].hal));
|
||||
ESP_RETURN_ON_FALSE(success, ESP_FAIL, UART_TAG, "baud rate unachievable");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -1910,6 +1916,7 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
|
||||
uart_free_driver_obj(p_uart_obj[uart_num]);
|
||||
p_uart_obj[uart_num] = NULL;
|
||||
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(uart_context[uart_num].sclk_sel, false), UART_TAG, "clock source disable failed");
|
||||
#if SOC_UART_SUPPORT_RTC_CLK
|
||||
soc_module_clk_t sclk = 0;
|
||||
uart_hal_get_sclk(&(uart_context[uart_num].hal), &sclk);
|
||||
@ -2118,7 +2125,7 @@ esp_err_t uart_detect_bitrate_start(uart_port_t uart_num, const uart_bitrate_det
|
||||
uart_sclk_sel = (soc_module_clk_t)((config->source_clk) ? config->source_clk : UART_SCLK_DEFAULT); // if no specifying the clock source (soc_module_clk_t starts from 1), then just use the default clock
|
||||
uint32_t sclk_freq = 0;
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz(uart_sclk_sel, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), err, UART_TAG, "invalid source_clk");
|
||||
esp_clk_tree_enable_src(uart_sclk_sel, true);
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src(uart_sclk_sel, true), err, UART_TAG, "clock source enable failed");
|
||||
#if SOC_UART_SUPPORT_RTC_CLK
|
||||
if (uart_sclk_sel == (soc_module_clk_t)UART_SCLK_RTC) {
|
||||
periph_rtc_dig_clk8m_enable();
|
||||
@ -2180,6 +2187,7 @@ esp_err_t uart_detect_bitrate_stop(uart_port_t uart_num, bool deinit, uart_bitra
|
||||
|
||||
if (deinit) { // release the port
|
||||
uart_release_pin(uart_num);
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(uart_context[uart_num].sclk_sel, false), UART_TAG, "clock source disable failed");
|
||||
#if SOC_UART_SUPPORT_RTC_CLK
|
||||
if (src_clk == (soc_module_clk_t)UART_SCLK_RTC) {
|
||||
periph_rtc_dig_clk8m_disable();
|
||||
|
@ -521,7 +521,7 @@ static esp_err_t emac_config_pll_clock(emac_esp32_t *emac)
|
||||
real_freq /= div;
|
||||
}
|
||||
// Enable 50MHz MPLL derived clock
|
||||
esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F50M, true);
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F50M, true), TAG, "clock source enable failed");
|
||||
#endif
|
||||
// If the difference of real RMII CLK frequency is not within 50 ppm, i.e. 2500 Hz, the (A/M)PLL is unusable
|
||||
ESP_RETURN_ON_FALSE(abs((int)real_freq - (int)expt_freq) <= 2500,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -78,20 +78,25 @@ uint32_t esp_clk_tree_lp_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t prec
|
||||
/**
|
||||
* @brief Enable / Disable the clock gate of the clock source
|
||||
*
|
||||
* @note The clock enable status is maintained by reference counter and
|
||||
* its status is not reset after software restart.
|
||||
*
|
||||
* @param[in] clk_src Clock source available to modules, in soc_module_clk_t
|
||||
* @param[in] enable Enable / Disable the clock gate
|
||||
*
|
||||
* @note !!! WARNING !!!
|
||||
* There's no reference counter to protect the clock source status, the caller should use the interface
|
||||
* with CAUTION to disable the clock source to avoid damaging other peripherals that are dependent on
|
||||
* the clock source.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable);
|
||||
|
||||
#if SOC_CLOCK_TREE_MANAGEMENT_SUPPORTED
|
||||
/**
|
||||
* @brief Set the clock source not in use on the clock tree to the gated state.
|
||||
*/
|
||||
void esp_clk_tree_initialize(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -7,12 +7,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_regi2c.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "hal/regi2c_ctrl_ll.h"
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -25,22 +30,32 @@ extern "C" {
|
||||
|
||||
#else // !BOOTLOADER_BUILD
|
||||
|
||||
static inline __attribute__((always_inline)) void ANA_I2C_SRC_CLOCK_ENABLE(bool enable) {
|
||||
#if SOC_CLK_ANA_I2C_MST_DEPENDS_ON_MODEM_APB
|
||||
esp_clk_tree_enable_src(SOC_MOD_CLK_MODEM_APB, enable);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ANA_I2C_MST_CLK_HAS_ROOT_GATING
|
||||
// This clock needs to be enabled for regi2c write/read, pll calibaration, PHY, RNG, ADC, etc.
|
||||
// Use reference count to manage the analog i2c master clock
|
||||
#define ANALOG_CLOCK_ENABLE() \
|
||||
#define ANALOG_CLOCK_ENABLE() { \
|
||||
ANA_I2C_SRC_CLOCK_ENABLE(true); \
|
||||
PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_ANA_I2C_MASTER_MODULE, ref_count) { \
|
||||
if (ref_count == 0) { \
|
||||
regi2c_ctrl_ll_master_enable_clock(true); \
|
||||
} \
|
||||
}
|
||||
} \
|
||||
}
|
||||
|
||||
#define ANALOG_CLOCK_DISABLE() \
|
||||
#define ANALOG_CLOCK_DISABLE() { \
|
||||
PERIPH_RCC_RELEASE_ATOMIC(PERIPH_ANA_I2C_MASTER_MODULE, ref_count) { \
|
||||
if (ref_count == 0) { \
|
||||
regi2c_ctrl_ll_master_enable_clock(false); \
|
||||
} \
|
||||
}
|
||||
} \
|
||||
ANA_I2C_SRC_CLOCK_ENABLE(false); \
|
||||
}
|
||||
|
||||
#else
|
||||
#define ANALOG_CLOCK_ENABLE()
|
||||
|
@ -16,6 +16,7 @@ entries:
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
rtc_clk (noflash)
|
||||
rtc_time (noflash_text)
|
||||
esp_clk_tree: esp_clk_tree_enable_src (noflash)
|
||||
if IDF_TARGET_ESP32 = y:
|
||||
rtc_clk:rtc_clk_cpu_freq_to_pll_mhz (noflash)
|
||||
rtc_clk:rtc_clk_cpu_freq_to_xtal (noflash)
|
||||
|
@ -141,7 +141,7 @@ static void IRAM_ATTR modem_clock_data_dump_configure(modem_clock_context_t *ctx
|
||||
modem_clock_context_t * __attribute__((weak)) IRAM_ATTR MODEM_CLOCK_instance(void)
|
||||
{
|
||||
/* It should be explicitly defined in the internal RAM */
|
||||
static DRAM_ATTR modem_clock_hal_context_t modem_clock_hal = { .syscon_dev = &MODEM_SYSCON, .lpcon_dev = &MODEM_LPCON };
|
||||
static DRAM_ATTR modem_clock_hal_context_t modem_clock_hal = { .syscon_dev = NULL, .lpcon_dev = NULL };
|
||||
static DRAM_ATTR modem_clock_context_t modem_clock_context = {
|
||||
.hal = &modem_clock_hal, .lock = portMUX_INITIALIZER_UNLOCKED,
|
||||
.dev = {
|
||||
@ -167,6 +167,13 @@ modem_clock_context_t * __attribute__((weak)) IRAM_ATTR MODEM_CLOCK_instance(voi
|
||||
},
|
||||
.lpclk_src = { [0 ... PERIPH_MODEM_MODULE_NUM - 1] = MODEM_CLOCK_LPCLK_SRC_INVALID }
|
||||
};
|
||||
if (modem_clock_hal.syscon_dev == NULL || modem_clock_hal.lpcon_dev == NULL) {
|
||||
modem_clock_hal.syscon_dev = &MODEM_SYSCON;
|
||||
modem_clock_hal.lpcon_dev = &MODEM_LPCON;
|
||||
#if SOC_CLOCK_TREE_MANAGEMENT_SUPPORTED
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src(SOC_MOD_CLK_MODEM_APB, true));
|
||||
#endif
|
||||
}
|
||||
return &modem_clock_context;
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,18 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "hal/clk_tree_hal.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/clk_gate_ll.h"
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
|
||||
static const char *TAG = "esp_clk_tree";
|
||||
@ -67,8 +69,72 @@ uint32_t *freq_value)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#define ENUM2ARRAY(clk_src) (clk_src - SOC_MOD_CLK_PLL_F12M)
|
||||
static __NOINIT_ATTR int16_t s_pll_src_cg_ref_cnt[9] = { 0 };
|
||||
static bool esp_clk_tree_initialized = false;
|
||||
|
||||
void esp_clk_tree_initialize(void)
|
||||
{
|
||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
if ((rst_reason == RESET_REASON_CPU0_MWDT0) || (rst_reason == RESET_REASON_CPU0_MWDT1) \
|
||||
|| (rst_reason == RESET_REASON_CPU0_SW) || (rst_reason == RESET_REASON_CPU0_RTC_WDT) \
|
||||
|| (rst_reason == RESET_REASON_CPU0_JTAG) || (rst_reason == RESET_REASON_CPU0_LOCKUP)) {
|
||||
esp_clk_tree_initialized = true;
|
||||
return;
|
||||
} else {
|
||||
bzero(s_pll_src_cg_ref_cnt, sizeof(s_pll_src_cg_ref_cnt));
|
||||
}
|
||||
|
||||
soc_cpu_clk_src_t current_cpu_clk_src = clk_ll_cpu_get_src();
|
||||
|
||||
if (current_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) {
|
||||
s_pll_src_cg_ref_cnt[ENUM2ARRAY(SOC_MOD_CLK_PLL_F160M)] = 1;
|
||||
_clk_gate_ll_ref_240m_clk_en(false);
|
||||
} else if (current_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M) {
|
||||
s_pll_src_cg_ref_cnt[ENUM2ARRAY(SOC_MOD_CLK_PLL_F240M)] = 1;
|
||||
_clk_gate_ll_ref_160m_clk_en(false);
|
||||
}
|
||||
_clk_gate_ll_ref_120m_clk_en(false);
|
||||
_clk_gate_ll_ref_80m_clk_en(false);
|
||||
_clk_gate_ll_ref_60m_clk_en(false);
|
||||
#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
|
||||
_clk_gate_ll_ref_48m_clk_en(false);
|
||||
#endif
|
||||
_clk_gate_ll_ref_40m_clk_en(false);
|
||||
_clk_gate_ll_ref_20m_clk_en(false);
|
||||
_clk_gate_ll_ref_12m_clk_en(false);
|
||||
esp_clk_tree_initialized = true;
|
||||
}
|
||||
|
||||
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
|
||||
{
|
||||
(void)clk_src; (void)enable;
|
||||
if (!esp_clk_tree_initialized || (clk_src < SOC_MOD_CLK_PLL_F12M) || (clk_src > SOC_MOD_CLK_PLL_F240M)) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
if (enable) {
|
||||
s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)]++;
|
||||
}
|
||||
if (s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)] == 1) {
|
||||
switch (clk_src) {
|
||||
case SOC_MOD_CLK_PLL_F12M: clk_gate_ll_ref_12m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F20M: clk_gate_ll_ref_20m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F40M: clk_gate_ll_ref_40m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F48M: clk_gate_ll_ref_48m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F60M: clk_gate_ll_ref_60m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F80M: clk_gate_ll_ref_80m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F120M: clk_gate_ll_ref_120m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F160M: clk_gate_ll_ref_160m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F240M: clk_gate_ll_ref_240m_clk_en(enable); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (!enable) {
|
||||
s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)]--;
|
||||
}
|
||||
assert(s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)] >= 0);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
#undef ENUM2ARRAY
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
#include "esp_private/io_mux.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "hal/gpio_ll.h"
|
||||
@ -40,6 +41,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true));
|
||||
gpio_ll_iomux_set_clk_src(clk_src);
|
||||
|
||||
return ESP_OK;
|
||||
|
@ -286,37 +286,53 @@ __attribute__((weak)) void rtc_clk_set_cpu_switch_to_pll(int event_id)
|
||||
{
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||
static void rtc_clk_update_pll_state_on_cpu_src_switching_start(soc_cpu_clk_src_t old_src, soc_cpu_clk_src_t new_src)
|
||||
{
|
||||
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
if (((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) || (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M)) && !s_bbpll_digi_consumers_ref_count) {
|
||||
if ((new_src == SOC_CPU_CLK_SRC_PLL_F160M) || (new_src == SOC_CPU_CLK_SRC_PLL_F240M)) {
|
||||
if (s_cur_pll_freq != CLK_LL_PLL_480M_FREQ_MHZ) {
|
||||
rtc_clk_bbpll_enable();
|
||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_480M_FREQ_MHZ);
|
||||
}
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
esp_clk_tree_enable_src((new_src == SOC_CPU_CLK_SRC_PLL_F240M) ? SOC_MOD_CLK_PLL_F240M : SOC_MOD_CLK_PLL_F160M, true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void rtc_clk_update_pll_state_on_cpu_switching_end(soc_cpu_clk_src_t old_src, soc_cpu_clk_src_t new_src)
|
||||
{
|
||||
if ((old_src == SOC_CPU_CLK_SRC_PLL_F160M) || (old_src == SOC_CPU_CLK_SRC_PLL_F240M)) {
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
esp_clk_tree_enable_src((old_src == SOC_CPU_CLK_SRC_PLL_F240M) ? SOC_MOD_CLK_PLL_F240M : SOC_MOD_CLK_PLL_F160M, false);
|
||||
#endif
|
||||
if ((new_src != SOC_CPU_CLK_SRC_PLL_F160M) && (new_src != SOC_CPU_CLK_SRC_PLL_F240M) && !s_bbpll_digi_consumers_ref_count) {
|
||||
// We don't turn off the bbpll if some consumers depend on bbpll
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||
{
|
||||
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||
if (old_cpu_clk_src != config->source) {
|
||||
rtc_clk_update_pll_state_on_cpu_src_switching_start(old_cpu_clk_src, config->source);
|
||||
}
|
||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL_F240M) {
|
||||
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F240M && old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F160M) {
|
||||
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START);
|
||||
rtc_clk_bbpll_enable();
|
||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_480M_FREQ_MHZ);
|
||||
}
|
||||
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START);
|
||||
rtc_clk_cpu_freq_to_pll_240_mhz(config->freq_mhz);
|
||||
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL_F160M) {
|
||||
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F240M && old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F160M) {
|
||||
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START);
|
||||
rtc_clk_bbpll_enable();
|
||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_480M_FREQ_MHZ);
|
||||
}
|
||||
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START);
|
||||
rtc_clk_cpu_freq_to_pll_160_mhz(config->freq_mhz);
|
||||
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||
rtc_clk_cpu_freq_to_8m();
|
||||
if (((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) || (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M)) && !s_bbpll_digi_consumers_ref_count) {
|
||||
// We don't turn off the bbpll if some consumers depend on bbpll
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
}
|
||||
if (old_cpu_clk_src != config->source) {
|
||||
rtc_clk_update_pll_state_on_cpu_switching_end(old_cpu_clk_src, config->source);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
||||
rtc_dig_clk8m_enable();
|
||||
}
|
||||
}
|
||||
|
||||
clk_ll_enable_timergroup_rtc_calibration_clock(true);
|
||||
/* There may be another calibration process already running during we call this function,
|
||||
* so we should wait the last process is done.
|
||||
*/
|
||||
@ -123,6 +123,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
||||
}
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||
|
||||
clk_ll_enable_timergroup_rtc_calibration_clock(false);
|
||||
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
|
||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||
clk_ll_xtal32k_digi_disable();
|
||||
|
@ -54,5 +54,5 @@ uint32_t *freq_value)
|
||||
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
|
||||
{
|
||||
(void)clk_src; (void)enable;
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -91,6 +91,11 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr
|
||||
|
||||
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
|
||||
{
|
||||
if(!enable) {
|
||||
// TODO: remove it after reference counter supported
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
switch (clk_src) {
|
||||
case SOC_MOD_CLK_PLL_F20M:
|
||||
|
@ -44,7 +44,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true));
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
gpio_ll_iomux_set_clk_src(clk_src);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ esp_err_t esp_lcd_new_dsi_bus(const esp_lcd_dsi_bus_config_t *bus_config, esp_lc
|
||||
if (phy_clk_src == 0) {
|
||||
phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT;
|
||||
}
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)phy_clk_src, true);
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)phy_clk_src, true), err, TAG, "clock source enable failed");
|
||||
// enable the clock source for DSI PHY
|
||||
DSI_CLOCK_SRC_ATOMIC() {
|
||||
// set clock source for DSI PHY
|
||||
|
@ -262,7 +262,7 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
|
||||
&dpi_clk_src_freq_hz), err, TAG, "get clock source frequency failed");
|
||||
// divide the source clock to get the final DPI clock
|
||||
uint32_t dpi_div = mipi_dsi_hal_host_dpi_calculate_divider(hal, dpi_clk_src_freq_hz / 1000 / 1000, panel_config->dpi_clock_freq_mhz);
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)dpi_clk_src, true);
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)dpi_clk_src, true), err, TAG, "clock source enable failed");
|
||||
// set the clock source, set the divider, and enable the dpi clock
|
||||
DSI_CLOCK_SRC_ATOMIC() {
|
||||
mipi_dsi_ll_set_dpi_clock_source(bus_id, dpi_clk_src);
|
||||
|
@ -582,7 +582,7 @@ static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz),
|
||||
TAG, "get clock source frequency failed");
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), TAG, "clock source enable failed");
|
||||
LCD_CLOCK_SRC_ATOMIC() {
|
||||
lcd_ll_select_clk_src(bus->hal.dev, clk_src);
|
||||
// force to use integer division, as fractional division might lead to clock jitter
|
||||
|
@ -786,7 +786,7 @@ static esp_err_t lcd_rgb_panel_select_clock_src(esp_rgb_panel_t *rgb_panel, lcd_
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz),
|
||||
TAG, "get clock source frequency failed");
|
||||
rgb_panel->src_clk_hz = src_clk_hz;
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), TAG, "clock source enable failed");
|
||||
LCD_CLOCK_SRC_ATOMIC() {
|
||||
lcd_ll_select_clk_src(rgb_panel->hal.dev, clk_src);
|
||||
}
|
||||
|
@ -926,7 +926,7 @@ void esp_pm_impl_init(void)
|
||||
;
|
||||
}
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_source, true);
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_source, true));
|
||||
/* When DFS is enabled, override system setting and use REFTICK as UART clock source */
|
||||
HP_UART_SRC_CLK_ATOMIC() {
|
||||
uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), (soc_module_clk_t)clk_source);
|
||||
|
@ -707,6 +707,9 @@ void IRAM_ATTR call_start_cpu0(void)
|
||||
trax_start_trace(TRAX_DOWNCOUNT_WORDS);
|
||||
#endif // CONFIG_ESP32_TRAX || CONFIG_ESP32S2_TRAX || CONFIG_ESP32S3_TRAX
|
||||
|
||||
#if SOC_CLOCK_TREE_MANAGEMENT_SUPPORTED
|
||||
esp_clk_tree_initialize();
|
||||
#endif
|
||||
esp_clk_init();
|
||||
esp_perip_clk_init();
|
||||
|
||||
|
@ -27,6 +27,38 @@
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
#include "hal/modem_lpcon_ll.h"
|
||||
#endif
|
||||
#include "hal/adc_ll.h"
|
||||
#include "hal/aes_ll.h"
|
||||
#include "hal/assist_debug_ll.h"
|
||||
#include "hal/apm_ll.h"
|
||||
#include "hal/clk_gate_ll.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/ds_ll.h"
|
||||
#include "hal/ecc_ll.h"
|
||||
#include "hal/etm_ll.h"
|
||||
#include "hal/gdma_ll.h"
|
||||
#include "hal/hmac_ll.h"
|
||||
#include "hal/i2c_ll.h"
|
||||
#include "hal/i2s_ll.h"
|
||||
#include "hal/ledc_ll.h"
|
||||
#include "hal/lp_core_ll.h"
|
||||
#include "hal/lp_clkrst_ll.h"
|
||||
#include "hal/mcpwm_ll.h"
|
||||
#include "hal/mpi_ll.h"
|
||||
#include "hal/mspi_ll.h"
|
||||
#include "hal/parlio_ll.h"
|
||||
#include "hal/pau_ll.h"
|
||||
#include "hal/pcnt_ll.h"
|
||||
#include "hal/rmt_ll.h"
|
||||
#include "hal/rtc_io_ll.h"
|
||||
#include "hal/sha_ll.h"
|
||||
#include "hal/spi_ll.h"
|
||||
#include "hal/temperature_sensor_ll.h"
|
||||
#include "hal/timer_ll.h"
|
||||
#include "hal/twaifd_ll.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#include "hal/uhci_ll.h"
|
||||
#include "hal/usb_serial_jtag_ll.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_private/esp_modem_clock.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
@ -200,16 +232,14 @@ void rtc_clk_select_rtc_slow_clk(void)
|
||||
*/
|
||||
__attribute__((weak)) void esp_perip_clk_init(void)
|
||||
{
|
||||
// TODO: [ESP32C5] IDF-8844
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
// modem_clock_domain_pmu_state_icg_map_init();
|
||||
/* During system initialization, the low-power clock source of the modem
|
||||
* (WiFi, BLE or Coexist) follows the configuration of the slow clock source
|
||||
* of the system. If the WiFi, BLE or Coexist module needs a higher
|
||||
* precision sleep clock (for example, the BLE needs to use the main XTAL
|
||||
* oscillator (40 MHz) to provide the clock during the sleep process in some
|
||||
* scenarios), the module needs to switch to the required clock source by
|
||||
* itself. */ //TODO - WIFI-5233
|
||||
* itself. */
|
||||
#if CONFIG_ESP_WIFI_ENABLED
|
||||
soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
|
||||
modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)(
|
||||
(rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? MODEM_CLOCK_LPCLK_SRC_XTAL32K
|
||||
@ -225,102 +255,99 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
||||
* to IDF-11064. */
|
||||
clk_ll_soc_root_clk_auto_gating_bypass(true);
|
||||
|
||||
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
|
||||
#if 0 // TODO: [ESP32C5] IDF-8844
|
||||
uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
|
||||
uint32_t common_perip_clk1 = 0;
|
||||
|
||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
|
||||
/* For reason that only reset CPU, do not disable the clocks
|
||||
* that have been enabled before reset.
|
||||
*/
|
||||
if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
|
||||
rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
|
||||
common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
|
||||
hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
|
||||
wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
|
||||
} else {
|
||||
common_perip_clk = SYSTEM_WDG_CLK_EN |
|
||||
SYSTEM_I2S0_CLK_EN |
|
||||
if ((rst_reason != RESET_REASON_CPU0_MWDT0) && (rst_reason != RESET_REASON_CPU0_MWDT1) \
|
||||
&& (rst_reason != RESET_REASON_CPU0_SW) && (rst_reason != RESET_REASON_CPU0_RTC_WDT) \
|
||||
&& (rst_reason != RESET_REASON_CPU0_JTAG) && (rst_reason != RESET_REASON_CPU0_LOCKUP)) {
|
||||
#if CONFIG_ESP_CONSOLE_UART_NUM != 0
|
||||
SYSTEM_UART_CLK_EN |
|
||||
uart_ll_enable_bus_clock(UART_NUM_0, false);
|
||||
uart_ll_sclk_disable(&UART0);
|
||||
#elif CONFIG_ESP_CONSOLE_UART_NUM != 1
|
||||
uart_ll_sclk_disable(&UART1);
|
||||
uart_ll_enable_bus_clock(UART_NUM_1, false);
|
||||
#endif
|
||||
#if CONFIG_ESP_CONSOLE_UART_NUM != 1
|
||||
SYSTEM_UART1_CLK_EN |
|
||||
i2c_ll_enable_bus_clock(0, false);
|
||||
i2c_ll_enable_controller_clock(&I2C0, false);
|
||||
rmt_ll_enable_bus_clock(0, false);
|
||||
rmt_ll_enable_group_clock(0, false);
|
||||
ledc_ll_enable_clock(&LEDC, false);
|
||||
ledc_ll_enable_bus_clock(false);
|
||||
clk_ll_enable_timergroup_rtc_calibration_clock(false);
|
||||
timer_ll_enable_clock(0, 0, false);
|
||||
timer_ll_enable_clock(1, 0, false);
|
||||
_timer_ll_enable_bus_clock(0, false);
|
||||
_timer_ll_enable_bus_clock(1, false);
|
||||
twaifd_ll_enable_clock(0, false);
|
||||
twaifd_ll_enable_bus_clock(0, false);
|
||||
twaifd_ll_enable_clock(1, false);
|
||||
twaifd_ll_enable_bus_clock(1, false);
|
||||
i2s_ll_enable_bus_clock(0, false);
|
||||
i2s_ll_tx_disable_clock(&I2S0);
|
||||
i2s_ll_rx_disable_clock(&I2S0);
|
||||
adc_ll_enable_bus_clock(false);
|
||||
pcnt_ll_enable_bus_clock(0, false);
|
||||
etm_ll_enable_bus_clock(0, false);
|
||||
mcpwm_ll_enable_bus_clock(0, false);
|
||||
mcpwm_ll_group_enable_clock(0, false);
|
||||
parlio_ll_rx_enable_clock(&PARL_IO, false);
|
||||
parlio_ll_tx_enable_clock(&PARL_IO, false);
|
||||
parlio_ll_enable_bus_clock(0, false);
|
||||
ahb_dma_ll_force_enable_reg_clock(&AHB_DMA, false);
|
||||
_gdma_ll_enable_bus_clock(0, false);
|
||||
#if CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
mspi_timing_ll_enable_core_clock(0, false);
|
||||
#endif
|
||||
SYSTEM_SPI2_CLK_EN |
|
||||
SYSTEM_I2C_EXT0_CLK_EN |
|
||||
SYSTEM_UHCI0_CLK_EN |
|
||||
SYSTEM_RMT_CLK_EN |
|
||||
SYSTEM_LEDC_CLK_EN |
|
||||
SYSTEM_TIMERGROUP1_CLK_EN |
|
||||
SYSTEM_SPI3_CLK_EN |
|
||||
SYSTEM_SPI4_CLK_EN |
|
||||
SYSTEM_TWAI_CLK_EN |
|
||||
SYSTEM_I2S0_CLK_EN |
|
||||
SYSTEM_SPI2_DMA_CLK_EN |
|
||||
SYSTEM_SPI3_DMA_CLK_EN;
|
||||
spi_ll_enable_bus_clock(SPI2_HOST, false);
|
||||
temperature_sensor_ll_bus_clk_enable(false);
|
||||
pau_ll_enable_bus_clock(false);
|
||||
#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD
|
||||
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
||||
* if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */
|
||||
assist_debug_ll_enable_bus_clock(false);
|
||||
#endif
|
||||
mpi_ll_enable_bus_clock(false);
|
||||
aes_ll_enable_bus_clock(false);
|
||||
sha_ll_enable_bus_clock(false);
|
||||
ecc_ll_enable_bus_clock(false);
|
||||
hmac_ll_enable_bus_clock(false);
|
||||
ds_ll_enable_bus_clock(false);
|
||||
apm_tee_ll_clk_gating_enable(false);
|
||||
uhci_ll_enable_bus_clock(0, false);
|
||||
|
||||
common_perip_clk1 = 0;
|
||||
hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
|
||||
SYSTEM_CRYPTO_SHA_CLK_EN |
|
||||
SYSTEM_CRYPTO_RSA_CLK_EN;
|
||||
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
|
||||
SYSTEM_WIFI_CLK_BT_EN_M |
|
||||
SYSTEM_WIFI_CLK_UNUSED_BIT5 |
|
||||
SYSTEM_WIFI_CLK_UNUSED_BIT12;
|
||||
// TODO: Replace with hal implementation
|
||||
REG_CLR_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN);
|
||||
REG_CLR_BIT(LP_TEE_CLOCK_GATE_REG, LP_TEE_CLK_EN);
|
||||
REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN);
|
||||
REG_CLR_BIT(PCR_TCM_MEM_MONITOR_CONF_REG, PCR_TCM_MEM_MONITOR_CLK_EN);
|
||||
REG_CLR_BIT(PCR_PSRAM_MEM_MONITOR_CONF_REG, PCR_PSRAM_MEM_MONITOR_CLK_EN);
|
||||
REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN);
|
||||
REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN);
|
||||
WRITE_PERI_REG(PCR_CTRL_CLK_OUT_EN_REG, 0);
|
||||
|
||||
#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
|
||||
// Disable USB-Serial-JTAG clock and it's pad if not used
|
||||
usb_serial_jtag_ll_phy_enable_pad(false);
|
||||
usb_serial_jtag_ll_enable_bus_clock(false);
|
||||
usb_serial_jtag_ll_enable_mem_clock(false);
|
||||
usb_serial_jtag_ll_set_mem_pd(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
//Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state.
|
||||
common_perip_clk |= SYSTEM_I2S0_CLK_EN |
|
||||
#if CONFIG_ESP_CONSOLE_UART_NUM != 0
|
||||
SYSTEM_UART_CLK_EN |
|
||||
#endif
|
||||
#if CONFIG_ESP_CONSOLE_UART_NUM != 1
|
||||
SYSTEM_UART1_CLK_EN |
|
||||
#endif
|
||||
SYSTEM_SPI2_CLK_EN |
|
||||
SYSTEM_I2C_EXT0_CLK_EN |
|
||||
SYSTEM_UHCI0_CLK_EN |
|
||||
SYSTEM_RMT_CLK_EN |
|
||||
SYSTEM_UHCI1_CLK_EN |
|
||||
SYSTEM_SPI3_CLK_EN |
|
||||
SYSTEM_SPI4_CLK_EN |
|
||||
SYSTEM_I2C_EXT1_CLK_EN |
|
||||
SYSTEM_I2S0_CLK_EN |
|
||||
SYSTEM_SPI2_DMA_CLK_EN |
|
||||
SYSTEM_SPI3_DMA_CLK_EN;
|
||||
common_perip_clk1 = 0;
|
||||
if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CHIP_BROWN_OUT) \
|
||||
|| (rst_reason == RESET_REASON_SYS_RTC_WDT) || (rst_reason == RESET_REASON_SYS_SUPER_WDT) \
|
||||
|| (rst_reason == RESET_REASON_CORE_PWR_GLITCH)) {
|
||||
_lp_i2c_ll_enable_bus_clock(0, false);
|
||||
lp_uart_ll_sclk_disable(0);
|
||||
_lp_uart_ll_enable_bus_clock(0, false);
|
||||
_lp_core_ll_enable_bus_clock(false);
|
||||
_rtcio_ll_enable_io_clock(false);
|
||||
_lp_clkrst_ll_enable_rng_clock(false);
|
||||
_lp_clkrst_ll_enable_otp_dbg_clock(false);
|
||||
_lp_clkrst_ll_enable_lp_ana_i2c_clock(false);
|
||||
_lp_clkrst_ll_enable_lp_ext_i2c_clock(false);
|
||||
|
||||
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
|
||||
* the current is not reduced when disable I2S clock.
|
||||
*/
|
||||
// TOCK(check replacement)
|
||||
// REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
|
||||
// REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
|
||||
|
||||
/* Disable some peripheral clocks. */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
|
||||
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
|
||||
|
||||
/* Disable hardware crypto clocks. */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
|
||||
|
||||
/* Disable WiFi/BT/SDIO clocks. */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
|
||||
|
||||
/* Set WiFi light sleep clock source to RTC slow clock */
|
||||
REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M);
|
||||
SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
|
||||
|
||||
/* Enable RNG clock. */
|
||||
periph_module_enable(PERIPH_RNG_MODULE);
|
||||
#endif
|
||||
REG_CLR_BIT(LP_APM_CLOCK_GATE_REG, LP_APM_CLK_EN);
|
||||
REG_CLR_BIT(LP_APM0_CLOCK_GATE_REG, LP_APM0_CLK_EN);
|
||||
WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0);
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
||||
* precision sleep clock (for example, the BLE needs to use the main XTAL
|
||||
* oscillator (40 MHz) to provide the clock during the sleep process in some
|
||||
* scenarios), the module needs to switch to the required clock source by
|
||||
* itself. */ //TODO - WIFI-5233
|
||||
* itself. */
|
||||
soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
|
||||
modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)(\
|
||||
(rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_RC_SLOW \
|
||||
|
@ -188,7 +188,7 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
||||
* precision sleep clock (for example, the BLE needs to use the main XTAL
|
||||
* oscillator (40 MHz) to provide the clock during the sleep process in some
|
||||
* scenarios), the module needs to switch to the required clock source by
|
||||
* itself. */ //TODO - WIFI-5233
|
||||
* itself. */
|
||||
soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
|
||||
modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)(
|
||||
(rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_RC_SLOW
|
||||
|
128
components/hal/esp32c5/include/hal/clk_gate_ll.h
Normal file
128
components/hal/esp32c5/include/hal/clk_gate_ll.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_attr.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
|
||||
/**
|
||||
* Enable or disable the clock gate for ref_12m.
|
||||
* @param enable Enable / disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void _clk_gate_ll_ref_12m_clk_en(bool enable)
|
||||
{
|
||||
PCR.pll_div_clk_en.pll_12m_clk_en = enable;
|
||||
}
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_12m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_12m_clk_en(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Enable or disable the clock gate for ref_20m.
|
||||
* @param enable Enable / disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void _clk_gate_ll_ref_20m_clk_en(bool enable)
|
||||
{
|
||||
PCR.pll_div_clk_en.pll_20m_clk_en = enable;
|
||||
}
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_20m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_20m_clk_en(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Enable or disable the clock gate for ref_40m.
|
||||
* @param enable Enable / disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void _clk_gate_ll_ref_40m_clk_en(bool enable)
|
||||
{
|
||||
PCR.pll_div_clk_en.pll_40m_clk_en = enable;
|
||||
}
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_40m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_40m_clk_en(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Enable or disable the clock gate for ref_48m.
|
||||
* @param enable Enable / disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void _clk_gate_ll_ref_48m_clk_en(bool enable)
|
||||
{
|
||||
PCR.pll_div_clk_en.pll_48m_clk_en = enable;
|
||||
}
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_48m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_48m_clk_en(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Enable or disable the clock gate for ref_60m.
|
||||
* @param enable Enable / disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void _clk_gate_ll_ref_60m_clk_en(bool enable)
|
||||
{
|
||||
PCR.pll_div_clk_en.pll_60m_clk_en = enable;
|
||||
}
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_60m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_60m_clk_en(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Enable or disable the clock gate for ref_80m.
|
||||
* @param enable Enable / disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void _clk_gate_ll_ref_80m_clk_en(bool enable)
|
||||
{
|
||||
PCR.pll_div_clk_en.pll_80m_clk_en = enable;
|
||||
}
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_80m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_80m_clk_en(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Enable or disable the clock gate for ref_120m.
|
||||
* @param enable Enable / disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void _clk_gate_ll_ref_120m_clk_en(bool enable)
|
||||
{
|
||||
PCR.pll_div_clk_en.pll_120m_clk_en = enable;
|
||||
}
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_120m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_120m_clk_en(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Enable or disable the clock gate for ref_160m.
|
||||
* @param enable Enable / disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void _clk_gate_ll_ref_160m_clk_en(bool enable)
|
||||
{
|
||||
PCR.pll_div_clk_en.pll_160m_clk_en = enable;
|
||||
}
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_160m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_160m_clk_en(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Enable or disable the clock gate for ref_240m.
|
||||
* @param enable Enable / disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void _clk_gate_ll_ref_240m_clk_en(bool enable)
|
||||
{
|
||||
PCR.pll_div_clk_en.pll_240m_clk_en = enable;
|
||||
}
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_240m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_240m_clk_en(__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -568,6 +568,15 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
|
||||
HAL_ASSERT(divider == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the RTC clock calibration reference XTAL source on timer group0.
|
||||
* @param enable enable or disable the XTAL source.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_enable_timergroup_rtc_calibration_clock(bool enable)
|
||||
{
|
||||
PCR.timergroup_xtal_conf.tg0_xtal_clk_en = enable;
|
||||
}
|
||||
|
||||
/************************** LP STORAGE REGISTER STORE/LOAD **************************/
|
||||
/**
|
||||
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
|
||||
|
55
components/hal/esp32c5/include/hal/lp_clkrst_ll.h
Normal file
55
components/hal/esp32c5/include/hal/lp_clkrst_ll.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for ESP32-C5 LP_CLKRST & LP PERI register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/lp_clkrst_struct.h"
|
||||
#include "soc/lpperi_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void _lp_clkrst_ll_enable_rng_clock(bool en)
|
||||
{
|
||||
LPPERI.clk_en.rng_ck_en = en;
|
||||
}
|
||||
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
|
||||
#define lp_clkrst_ll_enable_rng_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_rng_clock(__VA_ARGS__)
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void _lp_clkrst_ll_enable_otp_dbg_clock(bool en)
|
||||
{
|
||||
LPPERI.clk_en.otp_dbg_ck_en = en;
|
||||
}
|
||||
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
|
||||
#define lp_clkrst_ll_enable_otp_dbg_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_otp_dbg_clock(__VA_ARGS__)
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void _lp_clkrst_ll_enable_lp_ana_i2c_clock(bool en)
|
||||
{
|
||||
LPPERI.clk_en.lp_ana_i2c_ck_en = en;
|
||||
}
|
||||
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
|
||||
#define lp_clkrst_ll_enable_lp_ana_i2c_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_lp_ana_i2c_clock(__VA_ARGS__)
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void _lp_clkrst_ll_enable_lp_ext_i2c_clock(bool en)
|
||||
{
|
||||
LPPERI.clk_en.lp_ext_i2c_ck_en = en;
|
||||
}
|
||||
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
|
||||
#define lp_clkrst_ll_enable_lp_ext_i2c_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_lp_ext_i2c_clock(__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -32,7 +32,7 @@ extern "C" {
|
||||
*
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void lp_core_ll_enable_bus_clock(bool enable)
|
||||
static inline void _lp_core_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
LPPERI.clk_en.lp_cpu_ck_en = enable;
|
||||
}
|
||||
@ -41,7 +41,7 @@ static inline void lp_core_ll_enable_bus_clock(bool enable)
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define lp_core_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
lp_core_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
_lp_core_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
|
@ -60,7 +60,8 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
|
||||
static inline void _rtcio_ll_enable_io_clock(bool enable)
|
||||
{
|
||||
LPPERI.clk_en.lp_io_ck_en = enable;
|
||||
while (LPPERI.clk_en.lp_io_ck_en != enable) {
|
||||
LP_GPIO.clock_gate.clk_en = enable;
|
||||
while ((LPPERI.clk_en.lp_io_ck_en != enable) || (LP_GPIO.clock_gate.clk_en != enable)) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ FORCE_INLINE_ATTR bool lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, ui
|
||||
* @param hw_id LP UART instance ID
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
|
||||
static inline void _lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
|
||||
{
|
||||
(void)hw_id;
|
||||
LPPERI.clk_en.lp_uart_ck_en = enable;
|
||||
@ -197,7 +197,7 @@ static inline void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
|
||||
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
|
||||
#define lp_uart_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
lp_uart_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
_lp_uart_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
*/
|
||||
@ -329,6 +329,25 @@ FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
|
||||
return (PCR.usb_device_conf.usb_device_clk_en && !PCR.usb_device_conf.usb_device_rst_en);
|
||||
}
|
||||
|
||||
/* ---------------------------- USB MEM Control ---------------------------- */
|
||||
/**
|
||||
* @brief Power down the power USJ mem.
|
||||
* @param clk_en True if power down the USJ mem.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void usb_serial_jtag_ll_set_mem_pd(bool pd)
|
||||
{
|
||||
USB_SERIAL_JTAG.mem_conf.usb_mem_pd = pd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the mem clock for USJ module
|
||||
* @param clk_en True if enable the clock of USJ module mem.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_mem_clock(bool clk_en)
|
||||
{
|
||||
USB_SERIAL_JTAG.mem_conf.usb_mem_clk_en = clk_en;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -255,6 +255,10 @@ config SOC_PM_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLOCK_TREE_MANAGEMENT_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPIRAM_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
@ -1671,6 +1675,10 @@ config SOC_RCC_IS_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_ANA_I2C_MST_DEPENDS_ON_MODEM_APB
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
|
||||
bool
|
||||
default y
|
||||
|
@ -124,16 +124,22 @@ typedef enum {
|
||||
SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */
|
||||
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or OSC_SLOW by configuring soc_rtc_slow_clk_src_t */
|
||||
// For digital domain: peripherals, WIFI, BLE
|
||||
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL (clock gating + fixed divider of 6), it has a fixed frequency of 80MHz */
|
||||
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from PLL (clock gating + fixed divider of 3), it has a fixed frequency of 160MHz */
|
||||
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 240MHz */
|
||||
SOC_MOD_CLK_PLL_F12M, /*!< PLL_F12M_CLK is derived from SPLL (clock gating + fixed divider of 40), it has a fixed frequency of 12MHz */
|
||||
SOC_MOD_CLK_PLL_F20M, /*!< PLL_F20M_CLK is derived from SPLL (clock gating + fixed divider of 24), it has a fixed frequency of 20MHz */
|
||||
SOC_MOD_CLK_PLL_F40M, /*!< PLL_F40M_CLK is derived from SPLL (clock gating + fixed divider of 12), it has a fixed frequency of 40MHz */
|
||||
SOC_MOD_CLK_PLL_F48M, /*!< PLL_F48M_CLK is derived from SPLL (clock gating + fixed divider of 10), it has a fixed frequency of 48MHz */
|
||||
SOC_MOD_CLK_PLL_F60M, /*!< PLL_F60M_CLK is derived from SPLL (clock gating + fixed divider of 8), it has a fixed frequency of 60MHz */
|
||||
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from SPLL (clock gating + fixed divider of 6), it has a fixed frequency of 80MHz */
|
||||
SOC_MOD_CLK_PLL_F120M, /*!< PLL_F120M_CLK is derived from SPLL (clock gating + fixed divider of 4), it has a fixed frequency of 120MHz */
|
||||
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + fixed divider of 3), it has a fixed frequency of 160MHz */
|
||||
SOC_MOD_CLK_MODEM_APB = SOC_MOD_CLK_PLL_F160M, /*!< Modem APB clock comes from the CLK_160M_REF */
|
||||
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from SPLL (clock gating + fixed divider of 2), it has a fixed frequency of 240MHz */
|
||||
SOC_MOD_CLK_SPLL, /*!< SPLL is from the main XTAL oscillator frequency multipliers, it has a "fixed" frequency of 480MHz */
|
||||
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
|
||||
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
|
||||
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 48MHz crystal */
|
||||
// For LP peripherals
|
||||
SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 48MHz crystal, passing a div of 2 to the LP peripherals */
|
||||
|
||||
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
|
||||
} soc_module_clk_t;
|
||||
|
||||
|
@ -82,6 +82,7 @@
|
||||
#define SOC_LIGHT_SLEEP_SUPPORTED 1
|
||||
#define SOC_DEEP_SLEEP_SUPPORTED 1
|
||||
#define SOC_PM_SUPPORTED 1
|
||||
#define SOC_CLOCK_TREE_MANAGEMENT_SUPPORTED 1
|
||||
|
||||
#define SOC_SPIRAM_SUPPORTED 1
|
||||
#define SOC_BT_SUPPORTED 1
|
||||
@ -658,6 +659,8 @@
|
||||
|
||||
#define SOC_RCC_IS_INDEPENDENT 1 /*!< Reset and Clock Control is independent, thanks to the PCR registers */
|
||||
|
||||
#define SOC_CLK_ANA_I2C_MST_DEPENDS_ON_MODEM_APB (1) /*!< Analog I2C master clock depends on CLK_160M_REF on clock tree */
|
||||
|
||||
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
|
||||
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
|
||||
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
|
||||
|
Reference in New Issue
Block a user