diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 956f768668..5579e80906 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -25,7 +25,8 @@ if(NOT BOOTLOADER_BUILD) "sleep_gpio.c" "sleep_mac_bb.c" "regi2c_ctrl.c" - "adc_share_hw_ctrl.c") + "adc_share_hw_ctrl.c" + "port/${target}/io_mux.c") if(NOT CONFIG_IDF_TARGET_ESP32 AND NOT CONFIG_IDF_TARGET_ESP32S2) list(APPEND srcs "sleep_retention.c") diff --git a/components/esp_hw_support/include/esp_private/io_mux.h b/components/esp_hw_support/include/esp_private/io_mux.h new file mode 100644 index 0000000000..3c3056d762 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/io_mux.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" +#include "soc/clk_tree_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set the clock source for IO MUX + * + * @note IO MUX clock is shared by submodules like SDM, Glitch Filter. + * The submodule drivers should call this function to detect if the user set the clock differently. + * + * @param clk_src The clock source for IO MUX + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: The IO MUX has been set to another clock source + */ +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/port/esp32/io_mux.c b/components/esp_hw_support/port/esp32/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c2/io_mux.c b/components/esp_hw_support/port/esp32c2/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32c2/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c3/io_mux.c b/components/esp_hw_support/port/esp32c3/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32c3/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c6/io_mux.c b/components/esp_hw_support/port/esp32c6/io_mux.c new file mode 100644 index 0000000000..ea7446b2ba --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/io_mux.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "freertos/FreeRTOS.h" +#include "esp_private/io_mux.h" +#include "hal/gpio_ll.h" + +static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + bool clk_conflict = false; + // check is the IO MUX has been set to another clock source + portENTER_CRITICAL(&s_io_mux_spinlock); + if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { + clk_conflict = true; + } else { + s_io_mux_clk_src = clk_src; + } + portEXIT_CRITICAL(&s_io_mux_spinlock); + + if (clk_conflict) { + return ESP_ERR_INVALID_STATE; + } + + gpio_ll_iomux_set_clk_src(clk_src); + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32h2/io_mux.c b/components/esp_hw_support/port/esp32h2/io_mux.c new file mode 100644 index 0000000000..28d99fa12c --- /dev/null +++ b/components/esp_hw_support/port/esp32h2/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // TODO: IDF-6286 + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32h4/io_mux.c b/components/esp_hw_support/port/esp32h4/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32h4/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32s2/io_mux.c b/components/esp_hw_support/port/esp32s2/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32s2/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32s3/io_mux.c b/components/esp_hw_support/port/esp32s3/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32s3/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/hal/esp32c6/include/hal/clk_tree_ll.h b/components/hal/esp32c6/include/hal/clk_tree_ll.h index c5fb811055..f64cf3cefd 100644 --- a/components/hal/esp32c6/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c6/include/hal/clk_tree_ll.h @@ -63,7 +63,7 @@ typedef struct { static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void) { SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C | - PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C); + PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG) ; } diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index 05b7b9445b..c787097bd0 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -23,6 +23,8 @@ #include "soc/lp_io_struct.h" #include "soc/pmu_reg.h" #include "soc/usb_serial_jtag_reg.h" +#include "soc/pcr_struct.h" +#include "soc/clk_tree_defs.h" #include "hal/gpio_types.h" #include "hal/assert.h" @@ -454,6 +456,26 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, gpio_ll_iomux_func_sel(IO_MUX_GPIO0_REG + (gpio_num * 4), func); } +/** + * @brief Set clock source of IO MUX module + * + * @param src IO MUX clock source (only a subset of soc_module_clk_t values are valid) + */ +static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) +{ + switch (src) { + case SOC_MOD_CLK_XTAL: + PCR.iomux_clk_conf.iomux_func_clk_sel = 3; + break; + case SOC_MOD_CLK_PLL_F80M: + PCR.iomux_clk_conf.iomux_func_clk_sel = 1; + break; + default: + // Unsupported IO_MUX clock source + HAL_ASSERT(false); + } +} + /** * @brief Enable GPIO pin to use sleep mode pin functions during light sleep. *