From 6096a10b9a6511b4874f74c0ec9c8434ba848825 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 28 May 2024 13:22:46 -0300 Subject: [PATCH] drivers: clock_control: Refactor for ESP32C6 Added support for C6 to allow CPU clock config Signed-off-by: Raffael Rostagno --- .../esp32c6_devkitc/esp32c6_devkitc.dts | 4 - drivers/clock_control/clock_control_esp32.c | 99 ++++++++++++++++++- .../espressif/esp32c6/esp32c6_common.dtsi | 23 +++-- .../clock_control/esp32_clock_control.h | 2 + .../zephyr/dt-bindings/clock/esp32c6_clock.h | 37 ++++--- soc/espressif/esp32c6/Kconfig.rtc | 50 ---------- soc/espressif/esp32c6/soc.c | 5 - 7 files changed, 133 insertions(+), 87 deletions(-) delete mode 100644 soc/espressif/esp32c6/Kconfig.rtc diff --git a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.dts b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.dts index 93f4e959a56..3917430cdb2 100644 --- a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.dts +++ b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.dts @@ -37,10 +37,6 @@ }; }; -&cpu0 { - clock-frequency = ; -}; - &uart0 { status = "okay"; current-speed = <115200>; diff --git a/drivers/clock_control/clock_control_esp32.c b/drivers/clock_control/clock_control_esp32.c index 3dd40792486..02cf64d52b5 100644 --- a/drivers/clock_control/clock_control_esp32.c +++ b/drivers/clock_control/clock_control_esp32.c @@ -32,6 +32,15 @@ #define DT_CPU_COMPAT espressif_riscv #include #include +#elif CONFIG_SOC_SERIES_ESP32C6 +#define DT_CPU_COMPAT espressif_riscv +#include +#include +#include +#include +#include +#include +#include #endif /* CONFIG_SOC_SERIES_ESP32xx */ #include @@ -68,6 +77,49 @@ static bool reset_reason_is_cpu_reset(void) return false; } +#if defined(CONFIG_SOC_SERIES_ESP32C6) +static void esp32_clock_perip_init(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)) { + + periph_ll_disable_clk_set_rst(PERIPH_UART1_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_I2C0_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_RMT_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_LEDC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_TIMG1_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_TWAI0_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_TWAI1_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_I2S1_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_PCNT_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_ETM_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_MCPWM0_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_PARLIO_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_GDMA_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_SPI2_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_TEMPSENSOR_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_SDIO_SLAVE_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE); + + REG_CLR_BIT(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); + REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN); + REG_CLR_BIT(PCR_RETENTION_CONF_REG, PCR_RETENTION_CLK_EN); + REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_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); + } +} +#else static void esp32_clock_perip_init(void) { uint32_t common_perip_clk; @@ -330,6 +382,7 @@ static void esp32_clock_perip_init(void) periph_module_enable(PERIPH_TIMG0_MODULE); #endif } +#endif static enum clock_control_status clock_control_esp32_get_status(const struct device *dev, clock_control_subsys_t sys) @@ -389,7 +442,11 @@ static int clock_control_esp32_get_rate(const struct device *dev, clock_control_ static int esp32_select_rtc_slow_clk(uint8_t slow_clk) { +#if !defined(CONFIG_SOC_SERIES_ESP32C6) soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk & RTC_CNTL_ANA_CLK_RTC_SEL_V; +#else + soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk; +#endif uint32_t cal_val = 0; /* number of times to repeat 32k XTAL calibration * before giving up and switching to the internal RC @@ -424,9 +481,15 @@ static int esp32_select_rtc_slow_clk(uint8_t slow_clk) return -ENODEV; } } +#if defined(CONFIG_SOC_SERIES_ESP32C6) + } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { + rtc_clk_rc32k_enable(true); + } +#else } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { rtc_clk_8m_enable(true, true); } +#endif rtc_clk_slow_src_set(rtc_slow_clk_src); if (CONFIG_RTC_CLK_CAL_CYCLES > 0) { @@ -458,22 +521,36 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf esp_rom_uart_tx_wait_idle(ESP_CONSOLE_UART_NUM); +#if defined(CONFIG_SOC_SERIES_ESP32C6) + rtc_clk_modem_clock_domain_active_state_icg_map_preinit(); + + REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, rtc_clk_cfg.clk_8m_dfreq); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); + REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, rtc_clk_cfg.rc32k_dfreq); +#else REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, rtc_clk_cfg.clk_8m_dfreq); +#endif -#if !defined(CONFIG_SOC_SERIES_ESP32) +#if defined(CONFIG_SOC_SERIES_ESP32) + REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, rtc_clk_cfg.clk_8m_div - 1); +#elif defined(CONFIG_SOC_SERIES_ESP32C6) + clk_ll_rc_fast_tick_conf(); +#else /* Configure 150k clock division */ rtc_clk_divider_set(rtc_clk_cfg.clk_rtc_clk_div); /* Configure 8M clock division */ rtc_clk_8m_divider_set(rtc_clk_cfg.clk_8m_clk_div); -#else - REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, rtc_clk_cfg.clk_8m_div - 1); #endif + +#if !defined(CONFIG_SOC_SERIES_ESP32C6) /* Reset (disable) i2c internal bus for all regi2c registers */ regi2c_ctrl_ll_i2c_reset(); /* Enable the internal bus used to configure BBPLL */ regi2c_ctrl_ll_i2c_bbpll_enable(); +#endif + #if defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32) regi2c_ctrl_ll_i2c_apll_enable(); #endif @@ -481,7 +558,16 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf #if !defined(CONFIG_SOC_SERIES_ESP32S2) rtc_clk_xtal_freq_update(rtc_clk_cfg.xtal_freq); #endif +#if defined(CONFIG_SOC_SERIES_ESP32C6) + /* On ESP32C6, MSPI source clock's default HS divider leads to 120MHz, + * which is unusable before calibration. Therefore, before switching + * SOC_ROOT_CLK to HS, we need to set MSPI source clock HS divider + * to make it run at 80MHz after the switch. PLL = 480MHz, so divider is 6. + */ + clk_ll_mspi_fast_set_hs_divider(6); +#else rtc_clk_apb_freq_update(rtc_clk_cfg.xtal_freq * MHZ(1)); +#endif /* Set CPU frequency */ rtc_clk_cpu_freq_get_config(&old_config); @@ -498,6 +584,7 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * rtc_clk_cfg.cpu_freq_mhz / old_config.freq_mhz); +#if !defined(CONFIG_SOC_SERIES_ESP32C6) #if ESP_ROM_UART_CLK_IS_XTAL uart_clock_src_hz = (uint32_t)rtc_clk_xtal_freq_get() * MHZ(1); #else @@ -507,6 +594,7 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf #if !defined(ESP_CONSOLE_UART_NONE) esp_rom_uart_set_clock_baudrate(ESP_CONSOLE_UART_NUM, uart_clock_src_hz, ESP_CONSOLE_UART_BAUDRATE); +#endif #endif return 0; } @@ -546,10 +634,10 @@ static int clock_control_esp32_configure(const struct device *dev, clock_control static int clock_control_esp32_init(const struct device *dev) { const struct esp32_clock_config *cfg = dev->config; - struct esp32_clock_data *data = dev->data; + bool ret; +#if !defined(CONFIG_SOC_SERIES_ESP32C6) soc_reset_reason_t rst_reas; rtc_config_t rtc_cfg = RTC_CONFIG_DEFAULT(); - bool ret; rst_reas = esp_rom_get_reset_reason(0); #if !defined(CONFIG_SOC_SERIES_ESP32) @@ -562,6 +650,7 @@ static int clock_control_esp32_init(const struct device *dev) } #endif rtc_init(rtc_cfg); +#endif ret = esp32_cpu_clock_configure(&cfg->cpu); if (ret) { diff --git a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi index 38e2be850af..fc3f61cdcb3 100644 --- a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi +++ b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include #include #include @@ -26,6 +27,9 @@ compatible = "espressif,riscv"; riscv,isa = "rv32imc_zicsr"; reg = <0>; + clock-source = ; + clock-frequency = ; + xtal-freq = ; }; }; @@ -65,17 +69,20 @@ rtc: rtc@600b000 { compatible = "espressif,esp32-rtc"; reg = <0x600B000 DT_SIZE_K(1)>; - xtal-freq = ; + fast-clk-src = ; + slow-clk-src = ; #clock-cells = <1>; status = "okay"; - rtc_timer: rtc_timer { - compatible = "espressif,esp32-rtc-timer"; - slow-clk-freq = ; - interrupts = ; - interrupt-parent = <&intc>; - status = "okay"; - }; + }; + + rtc_timer: rtc_timer@600b0c00 { + compatible = "espressif,esp32-rtc-timer"; + reg = <0x600B0C00 DT_SIZE_K(1)>; + clocks = <&rtc ESP32_MODULE_MAX>; + interrupts = ; + interrupt-parent = <&intc>; + status = "okay"; }; spi2: spi@60081000 { diff --git a/include/zephyr/drivers/clock_control/esp32_clock_control.h b/include/zephyr/drivers/clock_control/esp32_clock_control.h index d74b2c0aeff..aa83d78e396 100644 --- a/include/zephyr/drivers/clock_control/esp32_clock_control.h +++ b/include/zephyr/drivers/clock_control/esp32_clock_control.h @@ -15,6 +15,8 @@ #include #elif defined(CONFIG_SOC_SERIES_ESP32C3) #include +#elif defined(CONFIG_SOC_SERIES_ESP32C6) +#include #endif /* CONFIG_SOC_SERIES_ESP32xx */ #define ESP32_CLOCK_CONTROL_SUBSYS_CPU 50 diff --git a/include/zephyr/dt-bindings/clock/esp32c6_clock.h b/include/zephyr/dt-bindings/clock/esp32c6_clock.h index c1ccc604986..9aa39b2c51e 100644 --- a/include/zephyr/dt-bindings/clock/esp32c6_clock.h +++ b/include/zephyr/dt-bindings/clock/esp32c6_clock.h @@ -7,27 +7,34 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_ESP32C6_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_ESP32C6_H_ -/* System Clock Source */ -#define ESP32_CLK_SRC_XTAL 0U -#define ESP32_CLK_SRC_PLL 1U -#define ESP32_CLK_SRC_RC_FAST 2U +/* Supported CPU clock Sources */ +#define ESP32_CPU_CLK_SRC_XTAL 0U +#define ESP32_CPU_CLK_SRC_PLL 1U +#define ESP32_CLK_SRC_RC_FAST 2U -/* Supported CPU Frequencies */ -#define ESP32_CLK_CPU_80M 80000000 -#define ESP32_CLK_CPU_160M 160000000 +/* Supported CPU frequencies */ +#define ESP32_CLK_CPU_PLL_80M 80000000 +#define ESP32_CLK_CPU_PLL_160M 160000000 +#define ESP32_CLK_CPU_RC_FAST_FREQ 17500000 /* Supported XTAL Frequencies */ -#define ESP32_CLK_XTAL_32M 32 -#define ESP32_CLK_XTAL_40M 40 +#define ESP32_CLK_XTAL_32M 32000000 +#define ESP32_CLK_XTAL_40M 40000000 -/* Supported RTC fast clock frequencies */ -#define ESP32_RTC_FAST_CLK_FREQ_8M 8500000U -#define ESP32_RTC_FAST_CLK_FREQ_APPROX ESP32_RTC_FAST_CLK_FREQ_8M +/* Supported RTC fast clock sources */ +#define ESP32_RTC_FAST_CLK_SRC_RC_FAST 0 +#define ESP32_RTC_FAST_CLK_SRC_XTAL_D2 1 /* Supported RTC slow clock frequencies */ -#define ESP32_RTC_SLOW_CLK_FREQ_90K 90000U -#define ESP32_RTC_SLOW_CLK_FREQ_8MD256 (ESP32_RTC_FAST_CLK_FREQ_APPROX / 256) -#define ESP32_RTC_SLOW_CLK_FREQ_32K 32768U +#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW 0 +#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K 1 +#define ESP32_RTC_SLOW_CLK_SRC_RC32K 2 +#define ESP32_RTC_SLOW_CLK_32K_EXT_OSC 9 + +/* RTC slow clock frequencies */ +#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ 136000 +#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K_FREQ 32768 +#define ESP32_RTC_SLOW_CLK_SRC_RC32K_FREQ 32768 /* Modules IDs * These IDs are actually offsets in CLK and RST Control registers. diff --git a/soc/espressif/esp32c6/Kconfig.rtc b/soc/espressif/esp32c6/Kconfig.rtc deleted file mode 100644 index 2a9a864d01b..00000000000 --- a/soc/espressif/esp32c6/Kconfig.rtc +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. -# SPDX-License-Identifier: Apache-2.0 - -if SOC_SERIES_ESP32C6 - -choice RTC_CLK_SRC - prompt "RTC clock source" - default RTC_CLK_SRC_INT_RC - help - Choose which clock is used as RTC clock source. - -config RTC_CLK_SRC_INT_RC - bool "Internal 136kHz RC oscillator" - -config RTC_CLK_SRC_EXT_CRYS - bool "External 32kHz crystal" - select ESP_SYSTEM_RTC_EXT_XTAL - -config RTC_CLK_SRC_EXT_OSC - bool "External 32kHz oscillator at 32K_XP pin" - select ESP_SYSTEM_RTC_EXT_OSC - -config RTC_CLK_SRC_INT_8MD256 - bool "Internal 17.5MHz oscillator, divided by 256" - -endchoice # ESP32C6_RTC_CLK_SRC - -config RTC_CLK_CAL_CYCLES - int "Number of cycles for RTC_SLOW_CLK calibration" - default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 - default 1024 if RTC_CLK_SRC_INT_RC - range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 - range 0 32766 if RTC_CLK_SRC_INT_RC - help - When the startup code initializes RTC_SLOW_CLK, it can perform - calibration by comparing the RTC_SLOW_CLK frequency with main XTAL - frequency. This option sets the number of RTC_SLOW_CLK cycles measured - by the calibration routine. Higher numbers increase calibration - precision, which may be important for applications which spend a lot of - time in deep sleep. Lower numbers reduce startup time. - - When this option is set to 0, clock calibration will not be performed at - startup, and approximate clock frequencies will be assumed: - - - 150000 Hz if internal RC oscillator is used as clock source. For this use value 1024. - - 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more. - In case more value will help improve the definition of the launch of the crystal. - If the crystal could not start, it will be switched to internal RC. - -endif # SOC_SERIES_ESP32C6 diff --git a/soc/espressif/esp32c6/soc.c b/soc/espressif/esp32c6/soc.c index 4bdfacbc057..2a30fe45731 100644 --- a/soc/espressif/esp32c6/soc.c +++ b/soc/espressif/esp32c6/soc.c @@ -56,11 +56,6 @@ void IRAM_ATTR __esp_platform_start(void) wdt_hal_disable(&rtc_wdt_ctx); wdt_hal_write_protect_enable(&rtc_wdt_ctx); - /* Configures the CPU clock, RTC slow and fast clocks, and performs - * RTC slow clock calibration. - */ - esp_clk_init(); - esp_timer_early_init(); #if CONFIG_SOC_FLASH_ESP32