diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index 0106088ed8..7845b4bcc5 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/components/driver/deprecated/adc_dma_legacy.c @@ -9,6 +9,7 @@ #include #include #include "sdkconfig.h" +#include "soc/soc_caps.h" #include "esp_intr_alloc.h" #include "esp_log.h" #include "esp_pm.h" @@ -18,6 +19,7 @@ #include "freertos/semphr.h" #include "freertos/timers.h" #include "freertos/ringbuf.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" #include "esp_private/adc_share_hw_ctrl.h" #include "esp_private/sar_periph_ctrl.h" @@ -472,6 +474,9 @@ esp_err_t adc_digi_start(void) adc_hal_set_controller(ADC_UNIT_2, ADC_HAL_CONTINUOUS_READ_MODE); 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); +#endif adc_hal_digi_controller_config(&s_adc_digi_ctx->hal, &s_adc_digi_ctx->hal_digi_ctrlr_cfg); adc_dma_stop(s_adc_digi_ctx); diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index 76277ac5e5..239bb5ac40 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -16,6 +16,7 @@ #include "esp_check.h" #include "esp_pm.h" #include "soc/rtc.h" +#include "soc/soc_caps.h" #include "driver/rtc_io.h" #include "sys/lock.h" #include "driver/gpio.h" @@ -26,6 +27,7 @@ #include "hal/adc_hal.h" #include "hal/adc_ll.h" #include "hal/adc_hal_common.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" #include "driver/adc_types_legacy.h" #include "esp_clk_tree.h" @@ -775,6 +777,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); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); adc_atten_t atten = s_atten1_single[channel]; @@ -832,6 +835,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); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); diff --git a/components/driver/deprecated/mcpwm_legacy.c b/components/driver/deprecated/mcpwm_legacy.c index 974402f949..87d5cdda7c 100644 --- a/components/driver/deprecated/mcpwm_legacy.c +++ b/components/driver/deprecated/mcpwm_legacy.c @@ -14,6 +14,7 @@ #include "esp_intr_alloc.h" #include "soc/mcpwm_periph.h" #include "soc/io_mux_reg.h" +#include "soc/soc_caps.h" #include "hal/mcpwm_hal.h" #include "hal/gpio_hal.h" #include "hal/mcpwm_ll.h" @@ -22,6 +23,7 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/gpio.h" #include "esp_private/esp_clk.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_clk_tree.h" static const char *TAG = "mcpwm(legacy)"; @@ -467,6 +469,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); 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); @@ -864,6 +867,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); 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); diff --git a/components/driver/deprecated/rmt_legacy.c b/components/driver/deprecated/rmt_legacy.c index 6d28bb1193..d3c319d039 100644 --- a/components/driver/deprecated/rmt_legacy.c +++ b/components/driver/deprecated/rmt_legacy.c @@ -12,6 +12,7 @@ #include "esp_log.h" #include "esp_check.h" #include "driver/gpio.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" #include "esp_private/gpio.h" #include "driver/rmt_types_legacy.h" @@ -19,6 +20,7 @@ #include "freertos/task.h" #include "freertos/semphr.h" #include "freertos/ringbuf.h" +#include "soc/soc_caps.h" #include "soc/soc_memory_layout.h" #include "soc/rmt_periph.h" #include "soc/rmt_struct.h" @@ -438,6 +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); // `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); @@ -603,6 +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); RMT_CLOCK_SRC_ATOMIC() { rmt_ll_set_group_clock_src(dev, channel, clk_src, 1, 0, 0); rmt_ll_enable_group_clock(dev, true); diff --git a/components/driver/deprecated/timer_legacy.c b/components/driver/deprecated/timer_legacy.c index 08261f8dd1..2ee334bbeb 100644 --- a/components/driver/deprecated/timer_legacy.c +++ b/components/driver/deprecated/timer_legacy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,8 +15,10 @@ #include "hal/timer_ll.h" #include "hal/check.h" #include "soc/timer_periph.h" +#include "soc/soc_caps.h" #include "esp_clk_tree.h" #include "soc/timer_group_reg.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" static const char *TIMER_TAG = "timer_group"; @@ -326,6 +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); 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` diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 381ad55f8d..8ef8bef917 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -23,6 +23,7 @@ #include "freertos/semphr.h" #include "freertos/timers.h" #include "freertos/ringbuf.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" #include "esp_private/adc_private.h" #include "esp_private/adc_share_hw_ctrl.h" @@ -33,6 +34,7 @@ #include "hal/adc_types.h" #include "hal/adc_hal.h" #include "hal/dma_types.h" +#include "soc/soc_caps.h" #include "esp_memory_utils.h" #include "adc_continuous_internal.h" #include "esp_private/adc_dma.h" @@ -300,7 +302,9 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle) } 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); +#endif adc_hal_digi_controller_config(&handle->hal, &handle->hal_digi_ctrlr_cfg); adc_hal_digi_enable(false); diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index 2d622687c0..aabac9cfc1 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -24,11 +24,13 @@ #include "esp_private/adc_private.h" #include "esp_private/adc_share_hw_ctrl.h" #include "esp_private/sar_periph_ctrl.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/esp_sleep_internal.h" #include "hal/adc_types.h" #include "hal/adc_oneshot_hal.h" #include "hal/adc_ll.h" #include "soc/adc_periph.h" +#include "soc/soc_caps.h" #if CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM #define ADC_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) @@ -159,6 +161,9 @@ 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); @@ -176,6 +181,9 @@ 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); +#endif adc_oneshot_hal_setup(&(handle->hal), chan); #if SOC_ADC_CALIBRATION_V1_SUPPORTED adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); @@ -199,6 +207,9 @@ 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); +#endif adc_oneshot_hal_setup(&(handle->hal), chan); #if SOC_ADC_CALIBRATION_V1_SUPPORTED adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); diff --git a/components/esp_adc/linker.lf b/components/esp_adc/linker.lf index 855ebe7cbd..24769b37a5 100644 --- a/components/esp_adc/linker.lf +++ b/components/esp_adc/linker.lf @@ -4,6 +4,12 @@ entries: if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y: adc_oneshot: adc_oneshot_read_isr (noflash) +[mapping:esp_hw_support_adc] +archive: libesp_hw_support.a +entries: + if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y: + esp_clk_tree: esp_clk_tree_enable_src (noflash) + [mapping:adc_hal] archive: libhal.a entries: diff --git a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c index 49aee4a745..2769a172d8 100644 --- a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c +++ b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c @@ -22,7 +22,9 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/mipi_csi_share_hw_ctrl.h" #include "esp_private/esp_cache_private.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_cache.h" +#include "soc/soc_caps.h" #if CONFIG_CAM_CTLR_MIPI_CSI_ISR_IRAM_SAFE #define CSI_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) @@ -123,6 +125,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); PERIPH_RCC_ATOMIC() { // phy clock source setting mipi_csi_ll_set_phy_clock_source(ctlr->csi_id, clk_src); diff --git a/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c index 992ea773cc..405d8f8cea 100644 --- a/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c +++ b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c @@ -18,8 +18,10 @@ #include "esp_check.h" #include "esp_clk_tree.h" #include "soc/cam_periph.h" +#include "soc/soc_caps.h" #include "esp_cam_ctlr_dvp_cam.h" #include "esp_private/esp_cam_dvp.h" +#include "esp_private/esp_clk_tree_common.h" #include "../../dvp_share_ctrl.h" #ifdef CONFIG_CAM_CTLR_DVP_CAM_ISR_IRAM_SAFE @@ -329,6 +331,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); PERIPH_RCC_ATOMIC() { cam_ll_enable_clk(ctlr_id, true); cam_ll_select_clk_src(ctlr_id, clk_src); diff --git a/components/esp_driver_gptimer/src/gptimer_common.c b/components/esp_driver_gptimer/src/gptimer_common.c index c81288e58b..a561f6195b 100644 --- a/components/esp_driver_gptimer/src/gptimer_common.c +++ b/components/esp_driver_gptimer/src/gptimer_common.c @@ -6,8 +6,10 @@ #include "esp_check.h" #include "esp_clk_tree.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/gptimer.h" #include "gptimer_priv.h" +#include "soc/soc_caps.h" static const char *TAG = "gptimer"; @@ -196,6 +198,7 @@ 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 diff --git a/components/esp_driver_isp/src/isp_core.c b/components/esp_driver_isp/src/isp_core.c index 1f1e002d2f..f3ff71e625 100644 --- a/components/esp_driver_isp/src/isp_core.c +++ b/components/esp_driver_isp/src/isp_core.c @@ -19,6 +19,8 @@ #include "hal/hal_utils.h" #include "soc/mipi_csi_bridge_struct.h" #include "soc/isp_periph.h" +#include "soc/soc_caps.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/isp_private.h" typedef struct isp_platform_t { @@ -106,6 +108,7 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ } ; isp_hal_init(&proc->hal, proc->proc_id); + esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); PERIPH_RCC_ATOMIC() { isp_ll_select_clk_source(proc->hal.hw, clk_src); isp_ll_set_clock_div(proc->hal.hw, &clk_div); diff --git a/components/esp_driver_ledc/src/ledc.c b/components/esp_driver_ledc/src/ledc.c index a9d93f904a..2a05db23e5 100644 --- a/components/esp_driver_ledc/src/ledc.c +++ b/components/esp_driver_ledc/src/ledc.c @@ -21,6 +21,7 @@ #include "clk_ctrl_os.h" #include "esp_private/periph_ctrl.h" #include "esp_private/gpio.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/esp_gpio_reserve.h" #include "esp_memory_utils.h" @@ -563,6 +564,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); LEDC_FUNC_CLOCK_ATOMIC() { ledc_ll_enable_clock(p_ledc_obj[speed_mode]->ledc_hal.dev, true); ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), glb_clk); @@ -698,6 +700,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); ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), LEDC_LL_GLOBAL_CLK_DEFAULT); } portEXIT_CRITICAL(&ledc_spinlock); diff --git a/components/esp_driver_mcpwm/src/mcpwm_com.c b/components/esp_driver_mcpwm/src/mcpwm_com.c index 60b5443b0f..d75ffb4f9d 100644 --- a/components/esp_driver_mcpwm/src/mcpwm_com.c +++ b/components/esp_driver_mcpwm/src/mcpwm_com.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,8 +15,10 @@ #include "esp_log.h" #include "esp_check.h" #include "esp_clk_tree.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" #include "soc/mcpwm_periph.h" +#include "soc/soc_caps.h" #include "hal/mcpwm_ll.h" #include "mcpwm_private.h" @@ -172,6 +174,7 @@ esp_err_t mcpwm_select_periph_clock(mcpwm_group_t *group, soc_module_clk_t clk_s ESP_LOGD(TAG, "install NO_LIGHT_SLEEP lock for MCPWM group(%d)", group->group_id); #endif // CONFIG_PM_ENABLE + esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); MCPWM_CLOCK_SRC_ATOMIC() { mcpwm_ll_group_set_clock_source(group->group_id, clk_src); } diff --git a/components/esp_driver_parlio/src/parlio_rx.c b/components/esp_driver_parlio/src/parlio_rx.c index c6e3eadf88..411ed2aea0 100644 --- a/components/esp_driver_parlio/src/parlio_rx.c +++ b/components/esp_driver_parlio/src/parlio_rx.c @@ -23,6 +23,7 @@ #include "esp_rom_gpio.h" #include "esp_pm.h" #include "soc/parlio_periph.h" +#include "soc/soc_caps.h" #include "hal/parlio_ll.h" #include "hal/gpio_hal.h" #include "hal/dma_types.h" @@ -33,6 +34,7 @@ #include "esp_memory_utils.h" #include "esp_clk_tree.h" #include "esp_attr.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/gdma.h" #include "esp_cache.h" @@ -537,6 +539,7 @@ static esp_err_t s_parlio_select_periph_clock(parlio_rx_unit_handle_t rx_unit, c } #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); diff --git a/components/esp_driver_parlio/src/parlio_tx.c b/components/esp_driver_parlio/src/parlio_tx.c index 0e22d96b2e..dcf073ed26 100644 --- a/components/esp_driver_parlio/src/parlio_tx.c +++ b/components/esp_driver_parlio/src/parlio_tx.c @@ -27,12 +27,14 @@ #include "esp_intr_alloc.h" #include "esp_pm.h" #include "soc/parlio_periph.h" +#include "soc/soc_caps.h" #include "hal/parlio_ll.h" #include "driver/gpio.h" #include "driver/parlio_tx.h" #include "parlio_private.h" #include "esp_memory_utils.h" #include "esp_clk_tree.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/gdma.h" #include "esp_private/gdma_link.h" @@ -253,6 +255,7 @@ 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 register configuration to the module parlio_ll_tx_enable_clock(hal->regs, true); diff --git a/components/esp_driver_rmt/src/rmt_common.c b/components/esp_driver_rmt/src/rmt_common.c index c66880f9bb..d33dae1a6e 100644 --- a/components/esp_driver_rmt/src/rmt_common.c +++ b/components/esp_driver_rmt/src/rmt_common.c @@ -16,9 +16,11 @@ #include "rmt_private.h" #include "clk_ctrl_os.h" #include "soc/rtc.h" +#include "soc/soc_caps.h" #include "soc/rmt_periph.h" #include "hal/rmt_ll.h" #include "driver/gpio.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" static const char *TAG = "rmt"; @@ -207,6 +209,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); // no division for group clock source, to achieve highest resolution RMT_CLOCK_SRC_ATOMIC() { rmt_ll_set_group_clock_src(group->hal.regs, channel_id, clk_src, 1, 1, 0); diff --git a/components/esp_driver_sdmmc/src/sdmmc_host.c b/components/esp_driver_sdmmc/src/sdmmc_host.c index e8459ea9f6..f322f8316f 100644 --- a/components/esp_driver_sdmmc/src/sdmmc_host.c +++ b/components/esp_driver_sdmmc/src/sdmmc_host.c @@ -18,6 +18,7 @@ #include "esp_rom_sys.h" #include "driver/gpio.h" #include "driver/sdmmc_host.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" #include "sdmmc_private.h" #include "freertos/FreeRTOS.h" @@ -164,6 +165,7 @@ esp_err_t sdmmc_host_reset(void) */ static void sdmmc_host_set_clk_div(int div) { + esp_clk_tree_enable_src((soc_module_clk_t)SDMMC_CLK_SRC_DEFAULT, true); SDMMC_CLK_SRC_ATOMIC() { sdmmc_ll_set_clock_div(s_host_ctx.hal.dev, div); sdmmc_ll_select_clk_source(s_host_ctx.hal.dev, SDMMC_CLK_SRC_DEFAULT); diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index ebd7ee92d4..c8f5436ad2 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -21,9 +21,11 @@ #include "hal/uart_hal.h" #include "hal/gpio_hal.h" #include "soc/uart_periph.h" +#include "soc/soc_caps.h" #include "driver/uart.h" #include "driver/gpio.h" #include "driver/uart_select.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/gpio.h" #include "esp_private/uart_share_hw_ctrl.h" #include "esp_clk_tree.h" @@ -906,6 +908,7 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf 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); uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq); diff --git a/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h b/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h index c67660d1d9..4a3c895b4f 100644 --- a/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h +++ b/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include #include #include "esp_clk_tree.h" #include "soc/soc_caps.h" @@ -74,6 +75,23 @@ uint32_t esp_clk_tree_lp_slow_get_freq_hz(esp_clk_tree_src_freq_precision_t prec */ uint32_t esp_clk_tree_lp_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t precision); +/** + * @brief Enable / Disable the clock gate of the clock source + * + * @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); + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/port/esp32/esp_clk_tree.c b/components/esp_hw_support/port/esp32/esp_clk_tree.c index 8704be2c84..e748df5d4c 100644 --- a/components/esp_hw_support/port/esp32/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32/esp_clk_tree.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -69,3 +69,9 @@ uint32_t *freq_value) *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + (void)clk_src; (void)enable; + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c2/esp_clk_tree.c b/components/esp_hw_support/port/esp32c2/esp_clk_tree.c index 5426db1bea..50291204d3 100644 --- a/components/esp_hw_support/port/esp32c2/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32c2/esp_clk_tree.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,3 +63,9 @@ uint32_t *freq_value) *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + (void)clk_src; (void)enable; + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c3/esp_clk_tree.c b/components/esp_hw_support/port/esp32c3/esp_clk_tree.c index 892b1fab1d..a3eaae3200 100644 --- a/components/esp_hw_support/port/esp32c3/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32c3/esp_clk_tree.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,3 +63,9 @@ uint32_t *freq_value) *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + (void)clk_src; (void)enable; + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c5/esp_clk_tree.c b/components/esp_hw_support/port/esp32c5/esp_clk_tree.c index 62dfe1eddd..f91284e682 100644 --- a/components/esp_hw_support/port/esp32c5/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32c5/esp_clk_tree.c @@ -66,3 +66,9 @@ uint32_t *freq_value) *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + (void)clk_src; (void)enable; + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c6/esp_clk_tree.c b/components/esp_hw_support/port/esp32c6/esp_clk_tree.c index ef7621cef9..21d98303df 100644 --- a/components/esp_hw_support/port/esp32c6/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32c6/esp_clk_tree.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,3 +63,9 @@ uint32_t *freq_value) *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + (void)clk_src; (void)enable; + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c61/esp_clk_tree.c b/components/esp_hw_support/port/esp32c61/esp_clk_tree.c index 2ddaca24af..78352f59f3 100644 --- a/components/esp_hw_support/port/esp32c61/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32c61/esp_clk_tree.c @@ -60,3 +60,9 @@ uint32_t *freq_value) *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + (void)clk_src; (void)enable; + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32h2/esp_clk_tree.c b/components/esp_hw_support/port/esp32h2/esp_clk_tree.c index 3106efd679..b221582a10 100644 --- a/components/esp_hw_support/port/esp32h2/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32h2/esp_clk_tree.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,3 +60,9 @@ uint32_t *freq_value) *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + (void)clk_src; (void)enable; + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32p4/esp_clk_tree.c b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c index 546f25c34b..880dff56f9 100644 --- a/components/esp_hw_support/port/esp32p4/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,9 +9,11 @@ #include "esp_err.h" #include "esp_check.h" #include "soc/rtc.h" +#include "hal/clk_gate_ll.h" #include "hal/clk_tree_hal.h" #include "hal/clk_tree_ll.h" #include "esp_private/esp_clk_tree_common.h" +#include "esp_private/periph_ctrl.h" static const char *TAG = "esp_clk_tree"; @@ -85,3 +87,29 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + PERIPH_RCC_ATOMIC() { + switch (clk_src) { + case SOC_MOD_CLK_PLL_F20M: + clk_gate_ll_ref_20m_clk_en(enable); + break; + case SOC_MOD_CLK_PLL_F25M: + clk_gate_ll_ref_25m_clk_en(enable); + break; + case SOC_MOD_CLK_PLL_F80M: + clk_gate_ll_ref_80m_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; + } + } + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32p4/io_mux.c b/components/esp_hw_support/port/esp32p4/io_mux.c index 5f3bf951ab..64cd2aa200 100644 --- a/components/esp_hw_support/port/esp32p4/io_mux.c +++ b/components/esp_hw_support/port/esp32p4/io_mux.c @@ -7,10 +7,12 @@ #include "sdkconfig.h" #include "esp_attr.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" #include "hal/rtc_io_ll.h" +#include "soc/soc_caps.h" #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() @@ -40,6 +42,8 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) if (clk_conflict) { return ESP_ERR_INVALID_STATE; } + + esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); PERIPH_RCC_ATOMIC() { gpio_ll_iomux_set_clk_src(clk_src); } diff --git a/components/esp_hw_support/port/esp32s2/esp_clk_tree.c b/components/esp_hw_support/port/esp32s2/esp_clk_tree.c index cbaf7760ab..ff9e20571d 100644 --- a/components/esp_hw_support/port/esp32s2/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32s2/esp_clk_tree.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,3 +67,9 @@ uint32_t *freq_value) *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + (void)clk_src; (void)enable; + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32s3/esp_clk_tree.c b/components/esp_hw_support/port/esp32s3/esp_clk_tree.c index c73f2d637d..d71373714b 100644 --- a/components/esp_hw_support/port/esp32s3/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32s3/esp_clk_tree.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,3 +67,9 @@ uint32_t *freq_value) *freq_value = clk_src_freq; return ESP_OK; } + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + (void)clk_src; (void)enable; + return ESP_OK; +} diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_dport.c b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_dport.c index 72f4e6da26..834771d629 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_dport.c +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_dport.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,7 @@ #include "xtensa/hal.h" #include "esp_types.h" #include "esp_private/esp_clk.h" +#include "esp_private/esp_clk_tree_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -27,6 +28,7 @@ #include "soc/dport_reg.h" #include "dport_access.h" #include "soc/rtc.h" +#include "soc/soc_caps.h" #include "esp_cpu.h" #include "esp_intr_alloc.h" #include "esp_task.h" @@ -142,6 +144,7 @@ void run_tasks_with_change_freq_cpu(int cpu_freq_mhz) esp_rom_output_tx_wait_idle(CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM); rtc_clk_cpu_freq_set_config(&new_config); + esp_clk_tree_enable_src((soc_module_clk_t)UART_SCLK_DEFAULT, true); uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_DEFAULT); uint32_t sclk_freq; @@ -158,6 +161,7 @@ void run_tasks_with_change_freq_cpu(int cpu_freq_mhz) // return old freq. esp_rom_output_tx_wait_idle(CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM); rtc_clk_cpu_freq_set_config(&old_config); + esp_clk_tree_enable_src((soc_module_clk_t)UART_SCLK_DEFAULT, true); uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_DEFAULT); uint32_t sclk_freq; @@ -439,7 +443,7 @@ TEST_CASE("Check pre-read workaround DPORT and Hi-interrupt", "[esp32]") static uint32_t s_shift_counter; /* -The test_dport_access_reg_read() is similar DPORT_REG_READ() but has differents: +The test_dport_access_reg_read() is similar DPORT_REG_READ() but has difference: - generate an interrupt by SET_CCOMPARE - additional branch command helps get good reproducing an issue with breaking the DPORT pre-read workaround - uncomment (1) and comment (2) it allows seeing the broken pre-read workaround diff --git a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c index ca519162d6..26b75ad507 100644 --- a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c +++ b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c @@ -9,6 +9,7 @@ #include "esp_check.h" #include "esp_lcd_mipi_dsi.h" #include "esp_clk_tree.h" +#include "esp_private/esp_clk_tree_common.h" #include "mipi_dsi_priv.h" static const char *TAG = "lcd.dsi.bus"; @@ -49,6 +50,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); // enable the clock source for DSI PHY DSI_CLOCK_SRC_ATOMIC() { // set clock source for DSI PHY diff --git a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c index e4fcdc7e54..4bec7273eb 100644 --- a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c +++ b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c @@ -17,6 +17,7 @@ #include "esp_async_fbcpy.h" #include "esp_memory_utils.h" #include "esp_private/dw_gdma.h" +#include "esp_private/esp_clk_tree_common.h" #include "hal/cache_hal.h" #include "hal/cache_ll.h" @@ -232,6 +233,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); // 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); diff --git a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c index 99af62c9c2..96b8fb4ca8 100644 --- a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c @@ -29,6 +29,7 @@ #include "esp_memory_utils.h" #include "esp_cache.h" #include "driver/gpio.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/gpio.h" #include "esp_private/gdma.h" #include "esp_private/gdma_link.h" @@ -583,6 +584,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); 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 diff --git a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c index f34bb2d2e3..60165fc1c5 100644 --- a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c @@ -32,11 +32,13 @@ #include "esp_private/gdma.h" #include "driver/gpio.h" #include "esp_bit_defs.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" #include "esp_psram.h" #include "esp_lcd_common.h" #include "esp_memory_utils.h" #include "soc/lcd_periph.h" +#include "soc/soc_caps.h" #include "hal/lcd_hal.h" #include "hal/lcd_ll.h" #include "hal/cache_hal.h" @@ -902,6 +904,7 @@ static esp_err_t lcd_rgb_panel_select_clock_src(esp_rgb_panel_t *panel, lcd_cloc 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"); panel->src_clk_hz = src_clk_hz; + esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); LCD_CLOCK_SRC_ATOMIC() { lcd_ll_select_clk_src(panel->hal.dev, clk_src); } diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 7b04a08013..f7ebc0601b 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -10,6 +10,7 @@ #include #include +#include "sdkconfig.h" #include "esp_attr.h" #include "esp_err.h" #include "esp_pm.h" @@ -41,6 +42,7 @@ #include "esp_private/pm_trace.h" #include "esp_private/esp_timer_private.h" #include "esp_private/esp_clk.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/sleep_cpu.h" #include "esp_private/sleep_gpio.h" #include "esp_private/sleep_modem.h" @@ -48,7 +50,6 @@ #include "esp_sleep.h" #include "esp_memory_utils.h" -#include "sdkconfig.h" #if SOC_PERIPH_CLK_CTRL_SHARED #define HP_UART_SRC_CLK_ATOMIC() PERIPH_RCC_ATOMIC() @@ -926,6 +927,8 @@ void esp_pm_impl_init(void) while (!uart_ll_is_tx_idle(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM))) { ; } + + 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); diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c index 10ac4c2f2c..4dda52f60f 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c @@ -20,6 +20,7 @@ #include "soc/rtc.h" // for wakeup trigger defines #include "soc/rtc_periph.h" // for read rtc registers directly (cause) #include "soc/soc.h" // for direct register read macros +#include "soc/soc_caps.h" #include "esp_newlib.h" #include "test_utils.h" #include "sdkconfig.h" @@ -27,6 +28,7 @@ #include "esp_rom_sys.h" #include "esp_timer.h" #include "esp_private/esp_clk.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/uart_share_hw_ctrl.h" #include "esp_random.h" #include "nvs_flash.h" @@ -176,6 +178,7 @@ TEST_CASE("light sleep and frequency switching", "[lightsleep]") #elif SOC_UART_SUPPORT_XTAL_CLK clk_source = UART_SCLK_XTAL; #endif + esp_clk_tree_enable_src((soc_module_clk_t)clk_source, true); HP_UART_SRC_CLK_ATOMIC() { uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), (soc_module_clk_t)clk_source); } diff --git a/components/hal/esp32p4/include/hal/adc_ll.h b/components/hal/esp32p4/include/hal/adc_ll.h index fb08fa93d9..881cfd0c63 100644 --- a/components/hal/esp32p4/include/hal/adc_ll.h +++ b/components/hal/esp32p4/include/hal/adc_ll.h @@ -223,7 +223,6 @@ static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) HP_SYS_CLKRST.peri_clk_ctrl22.reg_adc_clk_src_sel = 1; break; case ADC_DIGI_CLK_SRC_PLL_F80M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_80m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl22.reg_adc_clk_src_sel = 2; break; default: diff --git a/components/hal/esp32p4/include/hal/cam_ll.h b/components/hal/esp32p4/include/hal/cam_ll.h index 638b8f7ba5..a48dba2dc8 100644 --- a/components/hal/esp32p4/include/hal/cam_ll.h +++ b/components/hal/esp32p4/include/hal/cam_ll.h @@ -96,7 +96,6 @@ static inline void cam_ll_select_clk_src(int group_id, cam_clock_source_t src) HP_SYS_CLKRST.peri_clk_ctrl119.reg_cam_clk_src_sel = 0; break; case CAM_CLK_SRC_PLL160M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_160m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl119.reg_cam_clk_src_sel = 1; break; case CAM_CLK_SRC_APLL: diff --git a/components/hal/esp32p4/include/hal/clk_gate_ll.h b/components/hal/esp32p4/include/hal/clk_gate_ll.h index e69de29bb2..8c5fc05cfb 100644 --- a/components/hal/esp32p4/include/hal/clk_gate_ll.h +++ b/components/hal/esp32p4/include/hal/clk_gate_ll.h @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "esp_attr.h" +#include "soc/hp_sys_clkrst_struct.h" + +/** + * 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) +{ + HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_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_20m. + * @param enable Enable / disable + */ +FORCE_INLINE_ATTR void _clk_gate_ll_ref_25m_clk_en(bool enable) +{ + HP_SYS_CLKRST.ref_clk_ctrl1.reg_ref_25m_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_25m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_25m_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_80m_clk_en(bool enable) +{ + HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_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_20m. + * @param enable Enable / disable + */ +FORCE_INLINE_ATTR void _clk_gate_ll_ref_160m_clk_en(bool enable) +{ + HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_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_20m. + * @param enable Enable / disable + */ +FORCE_INLINE_ATTR void _clk_gate_ll_ref_240m_clk_en(bool enable) +{ + HP_SYS_CLKRST.ref_clk_ctrl1.reg_ref_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 diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index 56f6d4d514..094cf73cb2 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -637,7 +637,6 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) HP_SYS_CLKRST.peri_clk_ctrl26.reg_iomux_clk_src_sel = 0; break; case SOC_MOD_CLK_PLL_F80M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_80m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl26.reg_iomux_clk_src_sel = 1; break; default: diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index 1f96086bac..dcbf678933 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -198,11 +198,9 @@ static inline void isp_ll_select_clk_source(isp_dev_t *hw, soc_periph_isp_clk_sr clk_val = 0; break; case ISP_CLK_SRC_PLL160: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_160m_clk_en = 1; clk_val = 1; break; case ISP_CLK_SRC_PLL240: - HP_SYS_CLKRST.ref_clk_ctrl1.reg_ref_240m_clk_en = 1; clk_val = 2; break; default: diff --git a/components/hal/esp32p4/include/hal/lcd_ll.h b/components/hal/esp32p4/include/hal/lcd_ll.h index e10f8c8eee..99e41cfc68 100644 --- a/components/hal/esp32p4/include/hal/lcd_ll.h +++ b/components/hal/esp32p4/include/hal/lcd_ll.h @@ -102,7 +102,6 @@ static inline void lcd_ll_select_clk_src(lcd_cam_dev_t *dev, lcd_clock_source_t HP_SYS_CLKRST.peri_clk_ctrl19.reg_lcd_clk_src_sel = 0; break; case LCD_CLK_SRC_PLL160M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_160m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl19.reg_lcd_clk_src_sel = 1; break; case LCD_CLK_SRC_APLL: diff --git a/components/hal/esp32p4/include/hal/ledc_ll.h b/components/hal/esp32p4/include/hal/ledc_ll.h index 8d13cc6ee3..dea593b889 100644 --- a/components/hal/esp32p4/include/hal/ledc_ll.h +++ b/components/hal/esp32p4/include/hal/ledc_ll.h @@ -103,7 +103,6 @@ static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t clk_sel_val = 1; break; case LEDC_SLOW_CLK_PLL_DIV: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_80m_clk_en = 1; clk_sel_val = 2; break; default: diff --git a/components/hal/esp32p4/include/hal/mcpwm_ll.h b/components/hal/esp32p4/include/hal/mcpwm_ll.h index 870f7ef23e..4031c06070 100644 --- a/components/hal/esp32p4/include/hal/mcpwm_ll.h +++ b/components/hal/esp32p4/include/hal/mcpwm_ll.h @@ -168,7 +168,6 @@ static inline void mcpwm_ll_group_set_clock_source(int group_id, soc_module_clk_ clk_id = 1; break; case SOC_MOD_CLK_PLL_F160M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_160m_clk_en = 1; clk_id = 2; break; default: diff --git a/components/hal/esp32p4/include/hal/mipi_csi_ll.h b/components/hal/esp32p4/include/hal/mipi_csi_ll.h index 9c007b8884..c6c72f0c66 100644 --- a/components/hal/esp32p4/include/hal/mipi_csi_ll.h +++ b/components/hal/esp32p4/include/hal/mipi_csi_ll.h @@ -69,14 +69,12 @@ static inline void mipi_csi_ll_set_phy_clock_source(int group_id, mipi_csi_phy_c (void)group_id; switch (source) { case MIPI_CSI_PHY_CLK_SRC_PLL_F20M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_20m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_csi_dphy_clk_src_sel = 0; break; case MIPI_CSI_PHY_CLK_SRC_RC_FAST: HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_csi_dphy_clk_src_sel = 1; break; case MIPI_CSI_PHY_CLK_SRC_PLL_F25M: - HP_SYS_CLKRST.ref_clk_ctrl1.reg_ref_25m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_csi_dphy_clk_src_sel = 2; break; default: diff --git a/components/hal/esp32p4/include/hal/mipi_dsi_ll.h b/components/hal/esp32p4/include/hal/mipi_dsi_ll.h index 2021c636cc..e310ef7c8e 100644 --- a/components/hal/esp32p4/include/hal/mipi_dsi_ll.h +++ b/components/hal/esp32p4/include/hal/mipi_dsi_ll.h @@ -107,11 +107,9 @@ static inline void mipi_dsi_ll_set_dpi_clock_source(int group_id, mipi_dsi_dpi_c HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 0; break; case MIPI_DSI_DPI_CLK_SRC_PLL_F160M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_160m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 2; break; case MIPI_DSI_DPI_CLK_SRC_PLL_F240M: - // PLL240 has no gating by default in esp_perip_clk_init. HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 1; break; default: @@ -182,14 +180,12 @@ static inline void mipi_dsi_ll_set_phy_clock_source(int group_id, mipi_dsi_phy_c (void)group_id; switch (source) { case MIPI_DSI_PHY_CLK_SRC_PLL_F20M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_20m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 0; break; case MIPI_DSI_PHY_CLK_SRC_RC_FAST: HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 1; break; case MIPI_DSI_PHY_CLK_SRC_PLL_F25M: - HP_SYS_CLKRST.ref_clk_ctrl1.reg_ref_25m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 2; break; default: diff --git a/components/hal/esp32p4/include/hal/parlio_ll.h b/components/hal/esp32p4/include/hal/parlio_ll.h index 46ffb279bb..c982049870 100644 --- a/components/hal/esp32p4/include/hal/parlio_ll.h +++ b/components/hal/esp32p4/include/hal/parlio_ll.h @@ -103,7 +103,6 @@ static inline void _parlio_ll_rx_set_clock_source(parl_io_dev_t *dev, parlio_clo clk_sel = 1; break; case PARLIO_CLK_SRC_PLL_F160M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_160m_clk_en = 1; clk_sel = 2; break; case PARLIO_CLK_SRC_EXTERNAL: @@ -428,7 +427,6 @@ static inline void _parlio_ll_tx_set_clock_source(parl_io_dev_t *dev, parlio_clo clk_sel = 1; break; case PARLIO_CLK_SRC_PLL_F160M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_160m_clk_en = 1; clk_sel = 2; break; case PARLIO_CLK_SRC_EXTERNAL: diff --git a/components/hal/esp32p4/include/hal/rmt_ll.h b/components/hal/esp32p4/include/hal/rmt_ll.h index 04c3052820..affcc3eeac 100644 --- a/components/hal/esp32p4/include/hal/rmt_ll.h +++ b/components/hal/esp32p4/include/hal/rmt_ll.h @@ -98,7 +98,6 @@ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl22, reg_rmt_clk_div_denominator, divider_denominator); switch (src) { case RMT_CLK_SRC_PLL_F80M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_80m_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl22.reg_rmt_clk_src_sel = 2; break; case RMT_CLK_SRC_RC_FAST: diff --git a/components/hal/esp32p4/include/hal/sdmmc_ll.h b/components/hal/esp32p4/include/hal/sdmmc_ll.h index f859496af2..1141854f5c 100644 --- a/components/hal/esp32p4/include/hal/sdmmc_ll.h +++ b/components/hal/esp32p4/include/hal/sdmmc_ll.h @@ -135,7 +135,6 @@ static inline void sdmmc_ll_select_clk_source(sdmmc_dev_t *hw, soc_periph_sdmmc_ uint32_t clk_val = 0; switch (clk_src) { case SDMMC_CLK_SRC_PLL160M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_160m_clk_en = 1; clk_val = 0; break; // case SDMMC_CLK_SRC_PLL200M: // TODO: IDF-8886 diff --git a/components/hal/esp32p4/include/hal/timer_ll.h b/components/hal/esp32p4/include/hal/timer_ll.h index c13de5bda3..ba229bd0be 100644 --- a/components/hal/esp32p4/include/hal/timer_ll.h +++ b/components/hal/esp32p4/include/hal/timer_ll.h @@ -142,7 +142,6 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, clk_id = 0; break; case GPTIMER_CLK_SRC_PLL_F80M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_80m_clk_en = 1; clk_id = 2; break; case GPTIMER_CLK_SRC_RC_FAST: diff --git a/components/hal/esp32p4/include/hal/uart_ll.h b/components/hal/esp32p4/include/hal/uart_ll.h index ed3e327c97..9b62cea267 100644 --- a/components/hal/esp32p4/include/hal/uart_ll.h +++ b/components/hal/esp32p4/include/hal/uart_ll.h @@ -431,7 +431,6 @@ FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_ sel_value = 1; break; case UART_SCLK_PLL_F80M: - HP_SYS_CLKRST.ref_clk_ctrl2.reg_ref_80m_clk_en = 1; sel_value = 2; break; default: