diff --git a/components/esp_eth/include/esp_eth_mac_esp.h b/components/esp_eth/include/esp_eth_mac_esp.h index f18bf4d75c..d1181db640 100644 --- a/components/esp_eth/include/esp_eth_mac_esp.h +++ b/components/esp_eth/include/esp_eth_mac_esp.h @@ -242,7 +242,7 @@ typedef enum { .smi_gpio = \ { \ .mdc_num = 31, \ - .mdio_num = 27 \ + .mdio_num = 52 \ }, \ .interface = EMAC_DATA_INTERFACE_RMII, \ .clock_config = \ diff --git a/components/esp_eth/src/mac/esp_eth_mac_esp.c b/components/esp_eth/src/mac/esp_eth_mac_esp.c index 2ceb2d15b8..f0c5881f28 100644 --- a/components/esp_eth/src/mac/esp_eth_mac_esp.c +++ b/components/esp_eth/src/mac/esp_eth_mac_esp.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,7 @@ #endif // CONFIG_IDF_TARGET_ESP32 #include "hal/clk_tree_ll.h" #include "esp_private/esp_clk.h" +#include "esp_private/esp_clk_tree_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" @@ -395,11 +396,13 @@ static esp_err_t emac_config_pll_clock(emac_esp32_t *emac) } // Set divider of MPLL clock if (real_freq > RMII_CLK_HZ) { - int32_t div = real_freq / RMII_CLK_HZ - 1; + uint32_t div = real_freq / RMII_CLK_HZ; clk_ll_pll_f50m_set_divider(div); // compute real RMII CLK frequency - real_freq /= div + 1; + real_freq /= div; } + // Enable 50MHz MPLL derived clock + esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F50M, true); #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, diff --git a/components/esp_eth/test_apps/main/Kconfig.projbuild b/components/esp_eth/test_apps/main/Kconfig.projbuild index dfe9bc894e..3314787871 100644 --- a/components/esp_eth/test_apps/main/Kconfig.projbuild +++ b/components/esp_eth/test_apps/main/Kconfig.projbuild @@ -53,6 +53,20 @@ menu "esp_eth TEST_APPS Configuration" default 18 endif + config TARGET_RMII_CLK_OUT + bool "REF RMII CLK output" + default n + + if TARGET_RMII_CLK_OUT + config TARGET_RMII_CLK_OUT_GPIO + int "REF RMII CLK Output GPIO" + default 23 + + config TARGET_RMII_CLK_IN_GPIO + int "REF RMII CLK Input GPIO" + default 32 + endif # TARGET_RMII_CLK_OUT + endif # TARGET_USE_INTERNAL_ETHERNET if TARGET_USE_SPI_ETHERNET diff --git a/components/esp_eth/test_apps/main/esp_eth_test_common.c b/components/esp_eth/test_apps/main/esp_eth_test_common.c index 4876307b86..392bccb73e 100644 --- a/components/esp_eth/test_apps/main/esp_eth_test_common.c +++ b/components/esp_eth/test_apps/main/esp_eth_test_common.c @@ -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: Unlicense OR CC0-1.0 */ @@ -39,6 +39,12 @@ esp_eth_mac_t *mac_init(void *vendor_emac_config, eth_mac_config_t *mac_config) esp32_emac_config.smi_gpio.mdc_num = CONFIG_TARGET_IO_MDC; esp32_emac_config.smi_gpio.mdio_num = CONFIG_TARGET_IO_MDIO; #endif // CONFIG_TARGET_USE_DEFAULT_EMAC_CONFIG +#if CONFIG_TARGET_RMII_CLK_OUT + esp32_emac_config.clock_config.rmii.clock_mode = EMAC_CLK_OUT; + esp32_emac_config.clock_config.rmii.clock_gpio = CONFIG_TARGET_RMII_CLK_OUT_GPIO; + esp32_emac_config.clock_config_out_in.rmii.clock_mode = EMAC_CLK_EXT_IN; + esp32_emac_config.clock_config_out_in.rmii.clock_gpio = CONFIG_TARGET_RMII_CLK_IN_GPIO; +#endif // CONFIG_TARGET_TEST_RMII_CLK_OUT if (vendor_emac_config == NULL) { vendor_emac_config = &esp32_emac_config; } diff --git a/components/esp_eth/test_apps/main/esp_eth_test_esp_emac.c b/components/esp_eth/test_apps/main/esp_eth_test_esp_emac.c index 5056c86482..33c9ec1410 100644 --- a/components/esp_eth/test_apps/main/esp_eth_test_esp_emac.c +++ b/components/esp_eth/test_apps/main/esp_eth_test_esp_emac.c @@ -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: Unlicense OR CC0-1.0 */ @@ -515,3 +515,23 @@ TEST_CASE("internal emac erroneous frames", "[esp_emac]") vEventGroupDelete(eth_event_group); vSemaphoreDelete(mutex); } + +TEST_CASE("internal emac ref rmii clk out", "[esp_emac_clk_out]") +{ + esp_eth_mac_t *mac = mac_init(NULL, NULL); + TEST_ASSERT_NOT_NULL(mac); + esp_eth_phy_t *phy = phy_init(NULL); + TEST_ASSERT_NOT_NULL(phy); + esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy); + esp_eth_handle_t eth_handle = NULL; + // install Ethernet driver + // This is a simple test and it only verifies the REF RMII output CLK is configured and started, and the internal + // EMAC is clocked by it. It does not verify the whole system functionality. As such, it can be executed on the same + // test boards which are configured to input REF RMII CLK by default with only minor HW modification. + TEST_ESP_OK(esp_eth_driver_install(ð_config, ð_handle)); + extra_eth_config(eth_handle); + TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle)); + TEST_ESP_OK(phy->del(phy)); + TEST_ESP_OK(mac->del(mac)); + extra_cleanup(); +} diff --git a/components/esp_eth/test_apps/pytest_esp_eth.py b/components/esp_eth/test_apps/pytest_esp_eth.py index 3e954ed2c7..b9d235698d 100644 --- a/components/esp_eth/test_apps/pytest_esp_eth.py +++ b/components/esp_eth/test_apps/pytest_esp_eth.py @@ -265,6 +265,38 @@ def test_esp_eth_ip101(dut: IdfDut) -> None: ethernet_l2_test(dut) +# ----------- IP101 ESP32P4 ----------- +@pytest.mark.esp32p4 +@pytest.mark.eth_ip101 +@pytest.mark.parametrize('config', [ + 'default_ip101_esp32p4', +], indirect=True) +def test_esp32p4_ethernet(dut: IdfDut) -> None: + ethernet_test(dut) + dut.serial.hard_reset() + ethernet_l2_test(dut) + + +@pytest.mark.esp32p4 +@pytest.mark.eth_ip101 +@pytest.mark.parametrize('config', [ + 'default_ip101_esp32p4', +], indirect=True) +def test_esp32p4_emac(dut: IdfDut) -> None: + ethernet_int_emac_test(dut) + dut.serial.hard_reset() + ethernet_heap_alloc_test(dut) + + +@pytest.mark.esp32p4 +@pytest.mark.eth_ip101 +@pytest.mark.parametrize('config', [ + 'rmii_clko_esp32p4', +], indirect=True) +def test_esp32p4_emac_clko(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='esp_emac_clk_out') + + # ----------- LAN8720 ----------- @pytest.mark.esp32 @pytest.mark.eth_lan8720 diff --git a/components/esp_eth/test_apps/sdkconfig.ci.default_ip101_esp32p4 b/components/esp_eth/test_apps/sdkconfig.ci.default_ip101_esp32p4 index 7a385264d3..5612e70820 100644 --- a/components/esp_eth/test_apps/sdkconfig.ci.default_ip101_esp32p4 +++ b/components/esp_eth/test_apps/sdkconfig.ci.default_ip101_esp32p4 @@ -9,5 +9,3 @@ CONFIG_TARGET_USE_INTERNAL_ETHERNET=y CONFIG_TARGET_ETH_PHY_DEVICE_IP101=y CONFIG_TARGET_USE_DEFAULT_EMAC_CONFIG=n -CONFIG_TARGET_IO_MDC=31 -CONFIG_TARGET_IO_MDIO=27 diff --git a/components/esp_eth/test_apps/sdkconfig.ci.rmii_clko_esp32p4 b/components/esp_eth/test_apps/sdkconfig.ci.rmii_clko_esp32p4 new file mode 100644 index 0000000000..5178abce87 --- /dev/null +++ b/components/esp_eth/test_apps/sdkconfig.ci.rmii_clko_esp32p4 @@ -0,0 +1,17 @@ +CONFIG_IDF_TARGET="esp32p4" + +CONFIG_UNITY_ENABLE_FIXTURE=y +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +CONFIG_ETH_USE_ESP32_EMAC=y +CONFIG_ESP_TASK_WDT_EN=n + +CONFIG_TARGET_USE_INTERNAL_ETHERNET=y +CONFIG_TARGET_ETH_PHY_DEVICE_IP101=y + +CONFIG_TARGET_USE_DEFAULT_EMAC_CONFIG=y + +CONFIG_TARGET_RMII_CLK_OUT=y +# Test board needs to be modified! +# Connect GPIO23 to GPIO32 via wire. +CONFIG_TARGET_RMII_CLK_OUT_GPIO=23 +CONFIG_TARGET_RMII_CLK_IN_GPIO=32 diff --git a/components/esp_hw_support/clk_ctrl_os.c b/components/esp_hw_support/clk_ctrl_os.c index 30842ff964..add12e4bb2 100644 --- a/components/esp_hw_support/clk_ctrl_os.c +++ b/components/esp_hw_support/clk_ctrl_os.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,14 +23,14 @@ static const char *TAG = "clk_ctrl_os"; static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED; static uint8_t s_periph_ref_counts = 0; -static uint32_t s_rc_fast_freq = 0; // Frequency of the RC_FAST clock in Hz +static uint32_t s_rc_fast_freq_hz = 0; // Frequency of the RC_FAST clock in Hz #if SOC_CLK_APLL_SUPPORTED // Current APLL frequency, in HZ. Zero if APLL is not enabled. -static uint32_t s_cur_apll_freq = 0; +static uint32_t s_cur_apll_freq_hz = 0; static int s_apll_ref_cnt = 0; #endif #if SOC_CLK_MPLL_SUPPORTED -static uint32_t s_cur_mpll_freq = 0; +static uint32_t s_cur_mpll_freq_hz = 0; static int s_mpll_ref_cnt = 0; static esp_ldo_channel_handle_t s_ldo_chan = NULL; #endif @@ -41,8 +41,8 @@ bool periph_rtc_dig_clk8m_enable(void) if (s_periph_ref_counts == 0) { rtc_dig_clk8m_enable(); #if SOC_CLK_RC_FAST_SUPPORT_CALIBRATION - s_rc_fast_freq = esp_clk_tree_rc_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT); - if (s_rc_fast_freq == 0) { + s_rc_fast_freq_hz = esp_clk_tree_rc_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT); + if (s_rc_fast_freq_hz == 0) { rtc_dig_clk8m_disable(); portEXIT_CRITICAL(&periph_spinlock); return false; @@ -60,7 +60,7 @@ uint32_t periph_rtc_dig_clk8m_get_freq(void) /* Workaround: CLK8M calibration cannot be performed, we can only return its theoretic value */ return SOC_CLK_RC_FAST_FREQ_APPROX; #else - return s_rc_fast_freq; + return s_rc_fast_freq_hz; #endif } @@ -70,7 +70,7 @@ void periph_rtc_dig_clk8m_disable(void) assert(s_periph_ref_counts > 0); s_periph_ref_counts--; if (s_periph_ref_counts == 0) { - s_rc_fast_freq = 0; + s_rc_fast_freq_hz = 0; rtc_dig_clk8m_disable(); } portEXIT_CRITICAL(&periph_spinlock); @@ -95,13 +95,13 @@ void periph_rtc_apll_release(void) s_apll_ref_cnt--; if (s_apll_ref_cnt == 0) { // If there is no peripheral using APLL, shut down the power - s_cur_apll_freq = 0; + s_cur_apll_freq_hz = 0; rtc_clk_apll_enable(false); } portEXIT_CRITICAL(&periph_spinlock); } -esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq, uint32_t *real_freq) +esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz) { uint32_t o_div = 0; uint32_t sdm0 = 0; @@ -109,21 +109,21 @@ esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq, uint32_t *real_freq) uint32_t sdm2 = 0; // Guarantee 'periph_rtc_apll_acquire' has been called before set apll freq assert(s_apll_ref_cnt > 0); - uint32_t apll_freq = rtc_clk_apll_coeff_calc(expt_freq, &o_div, &sdm0, &sdm1, &sdm2); + uint32_t apll_freq = rtc_clk_apll_coeff_calc(expt_freq_hz, &o_div, &sdm0, &sdm1, &sdm2); ESP_RETURN_ON_FALSE(apll_freq, ESP_ERR_INVALID_ARG, TAG, "APLL coefficients calculate failed"); bool need_config = true; portENTER_CRITICAL(&periph_spinlock); /* If APLL is not in use or only one peripheral in use, its frequency can be changed as will * But when more than one peripheral refers APLL, its frequency is not allowed to change once it is set */ - if (s_cur_apll_freq == 0 || s_apll_ref_cnt < 2) { - s_cur_apll_freq = apll_freq; + if (s_cur_apll_freq_hz == 0 || s_apll_ref_cnt < 2) { + s_cur_apll_freq_hz = apll_freq; } else { - apll_freq = s_cur_apll_freq; + apll_freq = s_cur_apll_freq_hz; need_config = false; } portEXIT_CRITICAL(&periph_spinlock); - *real_freq = apll_freq; + *real_freq_hz = apll_freq; if (need_config) { ESP_LOGD(TAG, "APLL will working at %"PRIu32" Hz with coefficients [sdm0] %"PRIu32" [sdm1] %"PRIu32" [sdm2] %"PRIu32" [o_div] %"PRIu32"", @@ -172,13 +172,13 @@ void periph_rtc_mpll_release(void) s_mpll_ref_cnt--; if (s_mpll_ref_cnt == 0) { // If there is no peripheral using MPLL, shut down the power - s_cur_mpll_freq = 0; + s_cur_mpll_freq_hz = 0; rtc_clk_mpll_disable(); } portEXIT_CRITICAL(&periph_spinlock); } -esp_err_t IRAM_ATTR periph_rtc_mpll_freq_set(uint32_t expt_freq, uint32_t *real_freq) +esp_err_t IRAM_ATTR periph_rtc_mpll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz) { esp_err_t ret = ESP_OK; @@ -186,21 +186,21 @@ esp_err_t IRAM_ATTR periph_rtc_mpll_freq_set(uint32_t expt_freq, uint32_t *real_ assert(s_mpll_ref_cnt > 0); portENTER_CRITICAL(&periph_spinlock); - if (s_cur_mpll_freq == expt_freq) { + if (s_cur_mpll_freq_hz == expt_freq_hz) { goto end; } /* If MPLL is not in use or only one peripheral in use, its frequency can be changed as will * But when more than one peripheral refers MPLL, its frequency is not allowed to change once it is set */ - if (s_cur_mpll_freq == 0 || s_mpll_ref_cnt < 2) { + if (s_cur_mpll_freq_hz == 0 || s_mpll_ref_cnt < 2) { uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz(); - rtc_clk_mpll_configure(xtal_freq_mhz, expt_freq / MHZ); - s_cur_mpll_freq = clk_ll_mpll_get_freq_mhz(xtal_freq_mhz); + rtc_clk_mpll_configure(xtal_freq_mhz, expt_freq_hz / MHZ); + s_cur_mpll_freq_hz = clk_ll_mpll_get_freq_mhz(xtal_freq_mhz) * MHZ; } else { ret = ESP_ERR_INVALID_STATE; } end: - if (real_freq != NULL) { - *real_freq = s_cur_mpll_freq; + if (real_freq_hz != NULL) { + *real_freq_hz = s_cur_mpll_freq_hz; } portEXIT_CRITICAL(&periph_spinlock); return ret; diff --git a/components/esp_hw_support/include/clk_ctrl_os.h b/components/esp_hw_support/include/clk_ctrl_os.h index fa2a7a679f..5a72239e02 100644 --- a/components/esp_hw_support/include/clk_ctrl_os.h +++ b/components/esp_hw_support/include/clk_ctrl_os.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,9 +67,9 @@ void periph_rtc_apll_release(void); * @return * - ESP_OK: APLL frequency set success * - ESP_ERR_INVALID_ARG: The input expt_freq is out of APLL support range - * - ESP_ERR_INVALID_STATE: APLL is refered by more than one peripherals, not allowed to change its frequency now + * - ESP_ERR_INVALID_STATE: APLL is referred by more than one peripherals, not allowed to change its frequency now */ -esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq, uint32_t *real_freq); +esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz); #endif // SOC_CLK_APLL_SUPPORTED #if SOC_CLK_MPLL_SUPPORTED @@ -96,7 +96,7 @@ void periph_rtc_mpll_release(void); * - ESP_OK: MPLL frequency set success * - ESP_ERR_INVALID_STATE: MPLL is referred by more than one peripherals, not allowed to change its frequency now */ -esp_err_t periph_rtc_mpll_freq_set(uint32_t expt_freq, uint32_t *real_freq); +esp_err_t periph_rtc_mpll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz); #endif // SOC_CLK_MPLL_SUPPORTED #ifdef __cplusplus 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..00673d8cc5 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,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ #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/esp32p4/esp_clk_tree.c b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c index 0105cb062a..4ff5117b9f 100644 --- a/components/esp_hw_support/port/esp32p4/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c @@ -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,32 @@ 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_F50M: + clk_gate_ll_ref_50m_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/hal/esp32p4/include/hal/clk_gate_ll.h b/components/hal/esp32p4/include/hal/clk_gate_ll.h index e69de29bb2..39234dedd9 100644 --- a/components/hal/esp32p4/include/hal/clk_gate_ll.h +++ b/components/hal/esp32p4/include/hal/clk_gate_ll.h @@ -0,0 +1,106 @@ +/* + * SPDX-FileCopyrightText: 2015-2025 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" +#include "soc/lp_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__) + +/** + * Enable or disable the clock gate for xtal to lp periph + * @param enable Enable / disable + */ +FORCE_INLINE_ATTR void _clk_gate_ll_xtal_to_lp_periph_en(bool enable) +{ + LP_AON_CLKRST.lp_clk_en.xtal_clk_force_on = 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_xtal_to_lp_periph_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_xtal_to_lp_periph_en(__VA_ARGS__) + +/** + * Enable or disable the clock gate for ref_50m. + * @param enable Enable / disable + */ +FORCE_INLINE_ATTR void _clk_gate_ll_ref_50m_clk_en(bool enable) +{ + HP_SYS_CLKRST.ref_clk_ctrl1.reg_ref_50m_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_50m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_50m_clk_en(__VA_ARGS__) + + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index 9f902b1673..6ff93f7a24 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -145,6 +145,7 @@ typedef enum { // For digital domain: peripherals SOC_MOD_CLK_PLL_F20M, /*!< PLL_F20M_CLK is derived from SPLL (clock gating + default divider 24), its default frequency is 20MHz */ SOC_MOD_CLK_PLL_F25M, /*!< PLL_F25M_CLK is derived from MPLL (clock gating + configurable divider), it will have a frequency of 25MHz */ + SOC_MOD_CLK_PLL_F50M, /*!< PLL_F50M_CLK is derived from MPLL (clock gating + configurable divider 10), it will have a frequency of 50MHz */ SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from SPLL (clock gating + default divider 6), its default frequency is 80MHz */ SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + default divider 3), its default frequency is 160MHz */ SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from SPLL (clock gating + default divider 2), its default frequency is 240MHz */